From 3e21fdeb337b1959df636022221667860466314b Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Mon, 30 May 2011 23:51:04 -0400 Subject: [PATCH 01/27] Doesn't Xcode 3 have nice compile ordering? Not even worth trying to group the rest at this point... *grumble grumble* --- Xcode/stepmania.xcodeproj/project.pbxproj | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/Xcode/stepmania.xcodeproj/project.pbxproj b/Xcode/stepmania.xcodeproj/project.pbxproj index 37d917deb0..0efeaa2235 100644 --- a/Xcode/stepmania.xcodeproj/project.pbxproj +++ b/Xcode/stepmania.xcodeproj/project.pbxproj @@ -5901,6 +5901,7 @@ AA29CD410558741A00961A51 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; + comments = "We need a better way of organizing compile order here."; files = ( B7B0914B1393481B00C33E6B /* glew.c in Sources */, AA29CD520558741A00961A51 /* RageUtil.cpp in Sources */, @@ -5935,10 +5936,16 @@ AA29CD660558741A00961A51 /* NotesLoader.cpp in Sources */, AA29CD670558741A00961A51 /* NotesLoaderBMS.cpp in Sources */, AA29CD680558741A00961A51 /* NotesLoaderDWI.cpp in Sources */, + 2B9C2E8D137A138B004C92F3 /* NotesLoaderJson.cpp in Sources */, AA29CD690558741A00961A51 /* NotesLoaderKSF.cpp in Sources */, + EE2153A910A75BEE0074B01B /* NotesLoaderPMS.cpp in Sources */, AA29CD6A0558741A00961A51 /* NotesLoaderSM.cpp in Sources */, + 2B76698C132FF71500586512 /* NotesLoaderSMA.cpp in Sources */, + 2BA7925E1304F20D002BD8E1 /* NotesLoaderSSC.cpp in Sources */, AA29CD6B0558741A00961A51 /* NotesWriterDWI.cpp in Sources */, + 2B9C2E8F137A138B004C92F3 /* NotesWriterJson.cpp in Sources */, AA29CD6C0558741A00961A51 /* NotesWriterSM.cpp in Sources */, + B75CE3B6137963350076A82D /* SongPosition.cpp in Sources */, AA29CD6D0558741A00961A51 /* NoteTypes.cpp in Sources */, AA29CD6E0558741A00961A51 /* Player.cpp in Sources */, AA29CD6F0558741A00961A51 /* PlayerAI.cpp in Sources */, @@ -6293,19 +6300,16 @@ 3659B56F0F902143002B6B68 /* CommandLineActions.cpp in Sources */, 36CA531C0F91564A0063D59D /* ScreenOptionsCourseOverview.cpp in Sources */, 36CA53200F9156860063D59D /* ScreenOptionsEditCourse.cpp in Sources */, - EE2153A910A75BEE0074B01B /* NotesLoaderPMS.cpp in Sources */, EEA7C84310A805A300082E7B /* ScreenPackagesSSC.cpp in Sources */, 36C6888311297FFE00453295 /* RageFileDriverReadAhead.cpp in Sources */, 36C6888511297FFE00453295 /* RageFileManager_ReadAhead.cpp in Sources */, EE906F6612BF3A1B00146C96 /* ScreenInstallOverlay.cpp in Sources */, EE906F8212BF3AF800146C96 /* JsonUtil.cpp in Sources */, EE906F8A12BF3C7C00146C96 /* FileDownload.cpp in Sources */, - 2BA7925E1304F20D002BD8E1 /* NotesLoaderSSC.cpp in Sources */, 2BA792601304F20D002BD8E1 /* NotesWriterSSC.cpp in Sources */, 2B30D6821315EA7E00044B68 /* MouseDevice.cpp in Sources */, EE879B60132DEE720078FDDC /* RageDisplay_Legacy_Helpers.cpp in Sources */, EE879B62132DEE720078FDDC /* RageDisplay_Legacy.cpp in Sources */, - 2B76698C132FF71500586512 /* NotesLoaderSMA.cpp in Sources */, 2BD06FF1137242680018CB9F /* json_reader.cpp in Sources */, 2BD06FF2137242680018CB9F /* json_value.cpp in Sources */, 2BD06FF4137242680018CB9F /* json_writer.cpp in Sources */, @@ -6324,9 +6328,6 @@ 2BC6133813773C8E00CC8BBD /* pngwrite.c in Sources */, 2BC6133913773C8E00CC8BBD /* pngwtran.c in Sources */, 2BC6133A13773C8E00CC8BBD /* pngwutil.c in Sources */, - B75CE3B6137963350076A82D /* SongPosition.cpp in Sources */, - 2B9C2E8D137A138B004C92F3 /* NotesLoaderJson.cpp in Sources */, - 2B9C2E8F137A138B004C92F3 /* NotesWriterJson.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; From e90b81d3c36a9027bd4289f8e9c633ddf1d42b16 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 31 May 2011 00:17:46 -0400 Subject: [PATCH 02/27] Working towards refactoring TimingSegments. Hope I took care of the Windows 20** files right. --- Xcode/stepmania.xcodeproj/project.pbxproj | 8 +++ src/Makefile.am | 2 +- src/StepMania-net2008.vcproj | 2 + src/StepMania-net2010.vcxproj | 4 +- src/StepMania-net2010.vcxproj.filters | 8 ++- src/TimingSegments.cpp | 55 ++++++++++++++ src/TimingSegments.h | 88 +++++++++++++++++++++++ 7 files changed, 164 insertions(+), 3 deletions(-) create mode 100644 src/TimingSegments.cpp create mode 100644 src/TimingSegments.h diff --git a/Xcode/stepmania.xcodeproj/project.pbxproj b/Xcode/stepmania.xcodeproj/project.pbxproj index 0efeaa2235..e135889337 100644 --- a/Xcode/stepmania.xcodeproj/project.pbxproj +++ b/Xcode/stepmania.xcodeproj/project.pbxproj @@ -25,6 +25,8 @@ 1215D7A208C6559A00B87D8B /* ScreenGameplayNormal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1215D7A008C6559A00B87D8B /* ScreenGameplayNormal.cpp */; }; 2B30D6821315EA7E00044B68 /* MouseDevice.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B30D6801315EA7E00044B68 /* MouseDevice.cpp */; }; 2B30D6831315EA7E00044B68 /* MouseDevice.h in Headers */ = {isa = PBXBuildFile; fileRef = 2B30D6811315EA7E00044B68 /* MouseDevice.h */; }; + 2B43509513949F37006FA051 /* TimingSegments.h in Headers */ = {isa = PBXBuildFile; fileRef = 2B43509313949F37006FA051 /* TimingSegments.h */; }; + 2B43509613949F37006FA051 /* TimingSegments.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B43509413949F37006FA051 /* TimingSegments.cpp */; }; 2B76698B132FF71500586512 /* NotesLoaderSMA.h in Headers */ = {isa = PBXBuildFile; fileRef = 2B766989132FF71500586512 /* NotesLoaderSMA.h */; }; 2B76698C132FF71500586512 /* NotesLoaderSMA.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B76698A132FF71500586512 /* NotesLoaderSMA.cpp */; }; 2B9C2E8D137A138B004C92F3 /* NotesLoaderJson.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2B9C2E89137A138B004C92F3 /* NotesLoaderJson.cpp */; }; @@ -1802,6 +1804,8 @@ 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 2B30D6801315EA7E00044B68 /* MouseDevice.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MouseDevice.cpp; sourceTree = ""; }; 2B30D6811315EA7E00044B68 /* MouseDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MouseDevice.h; sourceTree = ""; }; + 2B43509313949F37006FA051 /* TimingSegments.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TimingSegments.h; path = ../src/TimingSegments.h; sourceTree = SOURCE_ROOT; }; + 2B43509413949F37006FA051 /* TimingSegments.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = TimingSegments.cpp; path = ../src/TimingSegments.cpp; sourceTree = SOURCE_ROOT; }; 2B766989132FF71500586512 /* NotesLoaderSMA.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NotesLoaderSMA.h; path = ../src/NotesLoaderSMA.h; sourceTree = SOURCE_ROOT; }; 2B76698A132FF71500586512 /* NotesLoaderSMA.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NotesLoaderSMA.cpp; path = ../src/NotesLoaderSMA.cpp; sourceTree = SOURCE_ROOT; }; 2B9C2E89137A138B004C92F3 /* NotesLoaderJson.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NotesLoaderJson.cpp; path = ../src/NotesLoaderJson.cpp; sourceTree = SOURCE_ROOT; }; @@ -3961,6 +3965,8 @@ AA21D5A10712AE16008B825F /* ThemeMetric.h */, AA729C420599B50D00779F33 /* TimingData.cpp */, AA729C430599B50D00779F33 /* TimingData.h */, + 2B43509413949F37006FA051 /* TimingSegments.cpp */, + 2B43509313949F37006FA051 /* TimingSegments.h */, AA6EFE0E04770C79005F316C /* TitleSubstitution.cpp */, AA6EFE0F04770C79005F316C /* TitleSubstitution.h */, AA70E3650663112800DAE1FD /* Trail.cpp */, @@ -5065,6 +5071,7 @@ B75CE3B5137963350076A82D /* SongPosition.h in Headers */, 2B9C2E8E137A138B004C92F3 /* NotesLoaderJson.h in Headers */, 2B9C2E90137A138B004C92F3 /* NotesWriterJson.h in Headers */, + 2B43509513949F37006FA051 /* TimingSegments.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -6328,6 +6335,7 @@ 2BC6133813773C8E00CC8BBD /* pngwrite.c in Sources */, 2BC6133913773C8E00CC8BBD /* pngwtran.c in Sources */, 2BC6133A13773C8E00CC8BBD /* pngwutil.c in Sources */, + 2B43509613949F37006FA051 /* TimingSegments.cpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/src/Makefile.am b/src/Makefile.am index 178a263f39..2abcf7c4be 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -182,7 +182,7 @@ SongOptions.cpp SongOptions.h SongUtil.cpp SongUtil.h StageStats.cpp StageStats. SoundEffectControl.cpp SoundEffectControl.h \ StepsUtil.cpp StepsUtil.h Style.cpp Style.h StyleUtil.cpp StyleUtil.h \ SubscriptionManager.h \ -TimingData.cpp TimingData.h \ +TimingData.cpp TimingData.h TimingSegments.cpp TimingSegments.h \ ThemeMetric.h \ Trail.cpp Trail.h TrailUtil.cpp TrailUtil.h TitleSubstitution.cpp TitleSubstitution.h \ Tween.cpp Tween.h diff --git a/src/StepMania-net2008.vcproj b/src/StepMania-net2008.vcproj index d4a1f01a8a..bcc20ea4b9 100644 --- a/src/StepMania-net2008.vcproj +++ b/src/StepMania-net2008.vcproj @@ -1524,6 +1524,8 @@ RelativePath="TimingData.h" > + + diff --git a/src/StepMania-net2010.vcxproj b/src/StepMania-net2010.vcxproj index d44826bcdc..ebc0108298 100644 --- a/src/StepMania-net2010.vcxproj +++ b/src/StepMania-net2010.vcxproj @@ -478,6 +478,7 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir) + @@ -1798,6 +1799,7 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir) + @@ -2369,4 +2371,4 @@ cl /Zl /nologo /c verstub.cpp /Fo$(IntDir) - \ No newline at end of file + diff --git a/src/StepMania-net2010.vcxproj.filters b/src/StepMania-net2010.vcxproj.filters index 37961b681b..0d28f9a2c7 100644 --- a/src/StepMania-net2010.vcxproj.filters +++ b/src/StepMania-net2010.vcxproj.filters @@ -507,6 +507,9 @@ Data Structures + + Data Structures + Data Structures @@ -2027,6 +2030,9 @@ Data Structures + + Data Structures + Data Structures @@ -3148,4 +3154,4 @@ BaseClasses - \ No newline at end of file + diff --git a/src/TimingSegments.cpp b/src/TimingSegments.cpp new file mode 100644 index 0000000000..254c905403 --- /dev/null +++ b/src/TimingSegments.cpp @@ -0,0 +1,55 @@ +#include "TimingSegments.h" + +TimingSegment::TimingSegment() : startingRow(-1) {} + +TimingSegment::TimingSegment(int s) : startingRow(s) {} + +TimingSegment::TimingSegment(float s) : startingRow(BeatToNoteRow(s)) {} + +TimingSegment::~TimingSegment() {} + +void TimingSegment::SetRow(const int s) +{ + this->startingRow = s; +} +void TimingSegment::SetBeat(const float s) +{ + this->startingRow = BeatToNoteRow(s); +} + +int TimingSegment::GetRow() const +{ + return this->startingRow; +} + +float TimingSegment::GetBeat() const +{ + return NoteRowToBeat(this->startingRow); +} + +/** + * @file + * @author Jason Felds (c) 2011 + * @section LICENSE + * 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. + */ diff --git a/src/TimingSegments.h b/src/TimingSegments.h new file mode 100644 index 0000000000..6d61d8a88e --- /dev/null +++ b/src/TimingSegments.h @@ -0,0 +1,88 @@ +#ifndef TIMING_SEGMENTS_H +#define TIMING_SEGMENTS_H + +#include "NoteTypes.h" // Converting rows to beats and vice~versa. + +/** + * @brief Compare a TimingData segment's properties with one another. + * + * This will be removed once we start respecting public & private data.*/ +#define COMPARE(x) if(x!=other.x) return false; + +/** + * @brief The general TimingSegment for all of the changing glory. + * + * Each segment is supposed to derive from this one. */ +struct TimingSegment +{ + /** @brief Set up a TimingSegment with default values. */ + TimingSegment(); + /** + * @brief Set up a TimingSegment with specified values. + * @param s the starting row. */ + TimingSegment(int s); + /** + * @brief Set up a TimingSegment with specified values. + * @param s the starting beat. */ + TimingSegment(float s); + + virtual ~TimingSegment(); + + /** + * @brief Set the starting row of the TimingSegment. + * + * This is virtual to allow other segments to implement validation + * as required by them. + * @param s the supplied row. */ + virtual void SetRow( const int s ); + /** + * @brief Set the starting beat of the TimingSegment. + * + * This is virtual to allow other segments to implement validation + * as required by them. + * @param s the supplied beat. */ + virtual void SetBeat( const float s ); + /** + * @brief Get the starting row of the TimingSegment. + * @return the starting row. */ + int GetRow() const; + /** + * @brief Get the starting beat of the TimingSegment. + * @return the starting beat. */ + float GetBeat() const; + +private: + /** @brief The row in which this segment activates. */ + int startingRow; +}; + +#undef COMPARE + +#endif + +/** + * @file + * @author Jason Felds (c) 2011 + * @section LICENSE + * 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. + */ From 62365ee9e9df0b850ea9edeebbad9b3794cb2c85 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 31 May 2011 00:24:23 -0400 Subject: [PATCH 03/27] Get this code ready. Future commits may be in big batches as segments are brought in one at a time. This is going to take until at least the next night. --- src/TimingData.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/TimingData.h b/src/TimingData.h index e65bcfbf16..3f9c35d7cc 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -2,6 +2,7 @@ #define TIMING_DATA_H #include "NoteTypes.h" +#include "TimingSegments.h" #include "PrefsManager.h" struct lua_State; From 1d3000e5201f9ce31d5ab2c0a818742c04c03e41 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 31 May 2011 00:51:25 -0400 Subject: [PATCH 04/27] FakeSegments refactored. Few things of note: 1) Slowly going away from hungarian notation. 2) Trying to respect public/private members. 2a) Yes, structs can work like this. 3) Trying to not require horizontal scrolling. If anyone else wants a crack, go ahead: we have 9 segments left. :) --- src/NoteField.cpp | 6 +-- src/NotesWriterSSC.cpp | 2 +- src/TimingData.cpp | 40 ++++++++------- src/TimingData.h | 108 ----------------------------------------- src/TimingSegments.cpp | 68 ++++++++++++++++++++++++-- src/TimingSegments.h | 98 +++++++++++++++++++++++++++++++++++++ 6 files changed, 189 insertions(+), 133 deletions(-) diff --git a/src/NoteField.cpp b/src/NoteField.cpp index fb1ac42670..86373a7b34 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -1012,11 +1012,11 @@ void NoteField::DrawPrimitives() { FOREACH_CONST( FakeSegment, timing.m_FakeSegments, seg ) { - if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) + if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw ) { - float fBeat = NoteRowToBeat(seg->m_iStartRow); + float fBeat = seg->GetBeat(); if( IS_ON_SCREEN(fBeat) ) - DrawFakeText( fBeat, seg->m_fLengthBeats ); + DrawFakeText( fBeat, seg->GetLength() ); } } } diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index 468f26da1c..716a34f7c5 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -146,7 +146,7 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo { w.Init( "FAKES" ); FOREACH_CONST( FakeSegment, timing.m_FakeSegments, fs ) - w.Write( fs->m_iStartRow, fs->m_fLengthBeats ); + w.Write( fs->GetRow(), fs->GetLength() ); w.Finish(); } diff --git a/src/TimingData.cpp b/src/TimingData.cpp index 8ad0a813f8..bee63236e2 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -327,7 +327,7 @@ void TimingData::SetFakeAtRow( int iRow, float fNew ) { unsigned i; for( i=0; i 0 && fNew > 0; if( i == m_FakeSegments.size() ) @@ -341,7 +341,7 @@ void TimingData::SetFakeAtRow( int iRow, float fNew ) { if( valid ) { - m_FakeSegments[i].m_fLengthBeats = fNew; + m_FakeSegments[i].SetLength(fNew); } else m_FakeSegments.erase( m_FakeSegments.begin()+i, m_FakeSegments.begin()+i+1 ); @@ -442,9 +442,9 @@ float TimingData::GetFakeAtRow( int iFakeRow ) const { for( unsigned i=0; i iNoteRow ) + if( s.GetRow() > iNoteRow ) break; } return static_cast(i); @@ -574,7 +574,8 @@ bool TimingData::IsFakeAtRow( int iNoteRow ) const int i = GetFakeSegmentIndexAtRow( iNoteRow ); const FakeSegment& s = m_FakeSegments[i]; - if( s.m_iStartRow <= iNoteRow && iNoteRow < ( s.m_iStartRow + BeatToNoteRow(s.m_fLengthBeats) ) ) + float beatRow = NoteRowToBeat(iNoteRow); + if( s.GetBeat() <= beatRow && beatRow < ( s.GetBeat() + s.GetLength() ) ) { return true; } @@ -1114,21 +1115,24 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool for( unsigned i = 0; i < m_FakeSegments.size(); i++ ) { - const int iSegStartRow = m_FakeSegments[i].m_iStartRow; - const int iSegEndRow = iSegStartRow + BeatToNoteRow( m_FakeSegments[i].m_fLengthBeats ); + FakeSegment &f = m_FakeSegments[i]; + const int iSegStartRow = f.GetRow(); + const int iSegEndRow = iSegStartRow + BeatToNoteRow( f.GetLength() ); if( iSegEndRow >= iStartIndex ) { if( iSegEndRow > iEndIndex ) - m_FakeSegments[i].m_fLengthBeats += NoteRowToBeat(lrintf((iEndIndex - iStartIndex) * (fScale - 1))); + f.SetLength(f.GetLength() + + NoteRowToBeat(lrintf((iEndIndex - iStartIndex) * (fScale - 1)))); else - m_FakeSegments[i].m_fLengthBeats = NoteRowToBeat(lrintf((iSegEndRow - iStartIndex) * fScale)); + f.SetLength(NoteRowToBeat(lrintf((iSegEndRow - iStartIndex) * fScale))); } if( iSegStartRow < iStartIndex ) continue; else if( iSegStartRow > iEndIndex ) - m_FakeSegments[i].m_iStartRow += lrintf((iEndIndex - iStartIndex) * (fScale - 1)); + f.SetRow(f.GetRow() + + lrintf((iEndIndex - iStartIndex) * (fScale - 1))); else - m_FakeSegments[i].m_iStartRow = lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex; + f.SetRow(lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex); } for( unsigned i = 0; i < m_ScrollSegments.size(); i++ ) @@ -1236,9 +1240,9 @@ void TimingData::InsertRows( int iStartRow, int iRowsToAdd ) for( unsigned i = 0; i < m_FakeSegments.size(); i++ ) { FakeSegment &fake = m_FakeSegments[i]; - if( fake.m_iStartRow < iStartRow ) + if( fake.GetRow() < iStartRow ) continue; - fake.m_iStartRow += iRowsToAdd; + fake.SetRow(fake.GetRow() + iRowsToAdd); } for( unsigned i = 0; i < m_ScrollSegments.size(); i++ ) @@ -1422,18 +1426,18 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) for( unsigned i = 0; i < m_FakeSegments.size(); i++ ) { FakeSegment &fake = m_FakeSegments[i]; - - if( fake.m_iStartRow < iStartRow ) + int keyRow = fake.GetRow(); + if( keyRow < iStartRow ) continue; - if( fake.m_iStartRow < iStartRow+iRowsToDelete ) + if( keyRow < iStartRow+iRowsToDelete ) { m_FakeSegments.erase( m_FakeSegments.begin()+i, m_FakeSegments.begin()+i+1 ); --i; continue; } - fake.m_iStartRow -= iRowsToDelete; + fake.SetRow(keyRow - iRowsToDelete); } for( unsigned i = 0; i < m_ScrollSegments.size(); i++ ) diff --git a/src/TimingData.h b/src/TimingData.h index 3f9c35d7cc..d3465a0fe3 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -854,114 +854,6 @@ struct ScrollSegment bool operator>=( const ScrollSegment &other ) const { return !operator<(other); } }; -/** - * @brief Identifies when a whole region of arrows is to be ignored. - * - * FakeSegments are similar to the Fake Tap Notes in that the contents - * inside are neither for nor against the player. They can be useful for - * mission modes, in conjunction with WarpSegments, or perhaps other - * uses not thought up at the time of this comment. Unlike the Warp - * Segments, these are not magically jumped over: instead, these are - * drawn normally. - * - * These were inspired by the Pump It Up series. */ -struct FakeSegment -{ - /** - * @brief Create a simple Fake Segment with default values. - * - * It is best to override the values as soon as possible. - */ - FakeSegment() : m_iStartRow(-1), m_fLengthBeats(-1) { } - /** - * @brief Create a Fake Segment with the specified values. - * @param s the starting row of this segment. - * @param r the number of rows this segment lasts. - */ - FakeSegment( int s, int r ): m_iStartRow(s), - m_fLengthBeats(NoteRowToBeat(r)) {} - /** - * @brief Creates a Fake Segment with the specified values. - * @param s the starting row of this segment. - * @param b the number of beats this segment lasts. - */ - FakeSegment( int s, float b ): m_iStartRow(max(0, s)), - m_fLengthBeats(max(0, b)) {} - /** - * @brief Create a Fake Segment with the specified values. - * @param s the starting beat in this segment. - * @param r the number of rows this segment lasts. - */ - FakeSegment( float s, int r ): - m_iStartRow(max(0, BeatToNoteRow(s))), - m_fLengthBeats(max(0, NoteRowToBeat(r))) {} - /** - * @brief Creates a Fake Segment with the specified values. - * @param s the starting beat of this segment. - * @param b the number of beats this segment lasts. - */ - FakeSegment( float s, float b ): - m_iStartRow(BeatToNoteRow(s)), - m_fLengthBeats(b) {} - /** - * @brief The row in which the FakeSegment activates. - */ - int m_iStartRow; - /** - * @brief The number of beats the FakeSegment is alive for. - */ - float m_fLengthBeats; - /** - * @brief Compares two FakeSegments to see if they are equal to each other. - * @param other the other FakeSegment to compare to. - * @return the equality of the two segments. - */ - bool operator==( const FakeSegment &other ) const - { - COMPARE( m_iStartRow ); - COMPARE( m_fLengthBeats ); - return true; - } - /** - * @brief Compares two FakeSegments to see if they are not equal to each other. - * @param other the other FakeSegment to compare to. - * @return the inequality of the two segments. - */ - bool operator!=( const FakeSegment &other ) const { return !operator==(other); } - /** - * @brief Compares two FakeSegments to see if one is less than the other. - * @param other the other FakeSegment to compare to. - * @return the truth/falsehood of if the first is less than the second. - */ - bool operator<( const FakeSegment &other ) const - { - return m_iStartRow < other.m_iStartRow || - ( m_iStartRow == other.m_iStartRow && m_fLengthBeats < other.m_fLengthBeats ); - } - /** - * @brief Compares two FakeSegments to see if one is less than or equal to the other. - * @param other the other FakeSegment to compare to. - * @return the truth/falsehood of if the first is less or equal to than the second. - */ - bool operator<=( const FakeSegment &other ) const - { - return ( operator<(other) || operator==(other) ); - } - /** - * @brief Compares two FakeSegments to see if one is greater than the other. - * @param other the other FakeSegment to compare to. - * @return the truth/falsehood of if the first is greater than the second. - */ - bool operator>( const FakeSegment &other ) const { return !operator<=(other); } - /** - * @brief Compares two FakeSegments to see if one is greater than or equal to the other. - * @param other the other FakeSegment to compare to. - * @return the truth/falsehood of if the first is greater than or equal to the second. - */ - bool operator>=( const FakeSegment &other ) const { return !operator<(other); } -}; - - /** * @brief Holds data for translating beats<->seconds. */ diff --git a/src/TimingSegments.cpp b/src/TimingSegments.cpp index 254c905403..4d1f6df95d 100644 --- a/src/TimingSegments.cpp +++ b/src/TimingSegments.cpp @@ -1,10 +1,13 @@ #include "TimingSegments.h" -TimingSegment::TimingSegment() : startingRow(-1) {} +TimingSegment::TimingSegment() : + startingRow(-1) {} -TimingSegment::TimingSegment(int s) : startingRow(s) {} +TimingSegment::TimingSegment(int s) : + startingRow(s) {} -TimingSegment::TimingSegment(float s) : startingRow(BeatToNoteRow(s)) {} +TimingSegment::TimingSegment(float s) : + startingRow(BeatToNoteRow(s)) {} TimingSegment::~TimingSegment() {} @@ -27,6 +30,65 @@ float TimingSegment::GetBeat() const return NoteRowToBeat(this->startingRow); } +FakeSegment::FakeSegment(): + TimingSegment(-1), lengthBeats(-1) {} + +FakeSegment::FakeSegment( int s, int r ): + TimingSegment(max(0, s)), lengthBeats(NoteRowToBeat(max(0, r))) {} + +FakeSegment::FakeSegment( int s, float b ): + TimingSegment(max(0, s)), lengthBeats(max(0, b)) {} + +FakeSegment::FakeSegment( float s, int r ): + TimingSegment(max(0, s)), lengthBeats(max(0, NoteRowToBeat(r))) {} + +FakeSegment::FakeSegment( float s, float b ): + TimingSegment(max(0, s)), lengthBeats(max(0, b)) {} + +float FakeSegment::GetLength() const +{ + return this->lengthBeats; +} + +void FakeSegment::SetLength(const float b) +{ + this->lengthBeats = b; +} + +bool FakeSegment::operator==( const FakeSegment &other ) const +{ + if (this->GetRow() != other.GetRow()) return false; + if (this->GetLength() != other.GetLength()) return false; + return true; +} + +bool FakeSegment::operator!=( const FakeSegment &other ) const +{ + return !this->operator==(other); +} + +bool FakeSegment::operator<( const FakeSegment &other ) const +{ + if (this->GetRow() < other.GetRow()) return true; + if (this->GetRow() > other.GetRow()) return false; + return this->GetLength() < other.GetLength(); +} + +bool FakeSegment::operator<=( const FakeSegment &other ) const +{ + return ( this->operator<(other) || this->operator==(other) ); +} + +bool FakeSegment::operator>( const FakeSegment &other ) const +{ + return !this->operator<=(other); +} + +bool FakeSegment::operator>=( const FakeSegment &other ) const +{ + return !this->operator<(other); +} + /** * @file * @author Jason Felds (c) 2011 diff --git a/src/TimingSegments.h b/src/TimingSegments.h index 6d61d8a88e..44c2050bc2 100644 --- a/src/TimingSegments.h +++ b/src/TimingSegments.h @@ -56,6 +56,104 @@ private: int startingRow; }; +/** + * @brief Identifies when a whole region of arrows is to be ignored. + * + * FakeSegments are similar to the Fake Tap Notes in that the contents + * inside are neither for nor against the player. They can be useful for + * mission modes, in conjunction with WarpSegments, or perhaps other + * uses not thought up at the time of this comment. Unlike the Warp + * Segments, these are not magically jumped over: instead, these are + * drawn normally. + * + * These were inspired by the Pump It Up series. */ +struct FakeSegment : public TimingSegment +{ + /** + * @brief Create a simple Fake Segment with default values. + * + * It is best to override the values as soon as possible. + */ + FakeSegment(); + /** + * @brief Create a Fake Segment with the specified values. + * @param s the starting row of this segment. + * @param r the number of rows this segment lasts. + */ + FakeSegment( int s, int r ); + /** + * @brief Creates a Fake Segment with the specified values. + * @param s the starting row of this segment. + * @param b the number of beats this segment lasts. + */ + FakeSegment( int s, float b ); + /** + * @brief Create a Fake Segment with the specified values. + * @param s the starting beat in this segment. + * @param r the number of rows this segment lasts. + */ + FakeSegment( float s, int r ); + /** + * @brief Creates a Fake Segment with the specified values. + * @param s the starting beat of this segment. + * @param b the number of beats this segment lasts. + */ + FakeSegment( float s, float b ); + + /** + * @brief Get the length in beats of the FakeSegment. + * @return the length in beats. */ + float GetLength() const; + + /** + * @brief Set the length in beats of the FakeSegment. + * @param b the length in beats. */ + void SetLength(const float b); + + /** + * @brief Compares two FakeSegments to see if they are equal to each other. + * @param other the other FakeSegment to compare to. + * @return the equality of the two segments. + */ + bool operator==( const FakeSegment &other ) const; + /** + * @brief Compares two FakeSegments to see if they are not equal to each other. + * @param other the other FakeSegment to compare to. + * @return the inequality of the two segments. + */ + bool operator!=( const FakeSegment &other ) const; + /** + * @brief Compares two FakeSegments to see if one is less than the other. + * @param other the other FakeSegment to compare to. + * @return the truth/falsehood of if the first is less than the second. + */ + bool operator<( const FakeSegment &other ) const; + /** + * @brief Compares two FakeSegments to see if one is less than or equal to the other. + * @param other the other FakeSegment to compare to. + * @return the truth/falsehood of if the first is less or equal to than the second. + */ + bool operator<=( const FakeSegment &other ) const; + /** + * @brief Compares two FakeSegments to see if one is greater than the other. + * @param other the other FakeSegment to compare to. + * @return the truth/falsehood of if the first is greater than the second. + */ + bool operator>( const FakeSegment &other ) const; + /** + * @brief Compares two FakeSegments to see if one is greater than or equal to the other. + * @param other the other FakeSegment to compare to. + * @return the truth/falsehood of if the first is greater than or equal to the second. + */ + bool operator>=( const FakeSegment &other ) const; +private: + /** + * @brief The number of beats the FakeSegment is alive for. + */ + float lengthBeats; +}; + + #undef COMPARE #endif From 8a315634dc664b040e4c53c4a165b998a56ff6a0 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 31 May 2011 01:20:22 -0400 Subject: [PATCH 05/27] Bring TickcountSegments to refactored level. I wonder how many of the 8 will be claimed upon wakeup. --- src/NoteField.cpp | 6 +-- src/NotesLoaderKSF.cpp | 7 ++-- src/NotesWriterSSC.cpp | 2 +- src/TimingData.cpp | 33 +++++++-------- src/TimingData.h | 77 ----------------------------------- src/TimingSegments.cpp | 61 +++++++++++++++++++++++++++- src/TimingSegments.h | 92 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 176 insertions(+), 102 deletions(-) diff --git a/src/NoteField.cpp b/src/NoteField.cpp index 86373a7b34..e54b650bd5 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -946,11 +946,11 @@ void NoteField::DrawPrimitives() // Tickcount text FOREACH_CONST( TickcountSegment, timing.m_TickcountSegments, seg ) { - if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) + if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw ) { - float fBeat = NoteRowToBeat(seg->m_iStartRow); + float fBeat = seg->GetBeat(); if( IS_ON_SCREEN(fBeat) ) - DrawTickcountText( fBeat, seg->m_iTicks ); + DrawTickcountText( fBeat, seg->GetTicks() ); } } } diff --git a/src/NotesLoaderKSF.cpp b/src/NotesLoaderKSF.cpp index 276f0c1e49..604c049ea1 100644 --- a/src/NotesLoaderKSF.cpp +++ b/src/NotesLoaderKSF.cpp @@ -541,13 +541,12 @@ static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant * and stops. It will be called again in LoadFromKSFFile for the * actual steps. */ iTickCount = StringToInt( sParams[1] ); - iTickCount = iTickCount > 0 ? iTickCount : 2; // again, Direct Move uses 4 as a default. + iTickCount = iTickCount > 0 ? iTickCount : 4; // add a tickcount for those using the [Player] // CheckpointsUseTimeSignatures metric. -aj // It's not with timesigs now -DaisuMaster - TickcountSegment tcs; - tcs.m_iStartRow = BeatToNoteRow(0.0f); - tcs.m_iTicks = iTickCount > ROWS_PER_BEAT ? ROWS_PER_BEAT : iTickCount; + TickcountSegment tcs(0); + tcs.SetTicks(iTickCount > ROWS_PER_BEAT ? ROWS_PER_BEAT : iTickCount); out.m_SongTiming.AddTickcountSegment( tcs ); } else if ( sValueName=="STEP" ) diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index 716a34f7c5..46b12ee872 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -122,7 +122,7 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo ASSERT( !timing.m_TickcountSegments.empty() ); w.Init( "TICKCOUNTS" ); FOREACH_CONST( TickcountSegment, timing.m_TickcountSegments, ts ) - w.Write( ts->m_iStartRow, ts->m_iTicks ); + w.Write( ts->GetRow(), ts->GetTicks() ); w.Finish(); ASSERT( !timing.m_ComboSegments.empty() ); diff --git a/src/TimingData.cpp b/src/TimingData.cpp index bee63236e2..2cf4bded87 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -205,21 +205,21 @@ void TimingData::SetTickcountAtRow( int iRow, int iTicks ) { unsigned i; for( i=0; i= iRow ) + if( m_TickcountSegments[i].GetRow() >= iRow ) break; - if( i == m_TickcountSegments.size() || m_TickcountSegments[i].m_iStartRow != iRow ) + if( i == m_TickcountSegments.size() || m_TickcountSegments[i].GetRow() != iRow ) { // No TickcountSegment here. Make a new segment if required. - if( i == 0 || m_TickcountSegments[i-1].m_iTicks != iTicks ) + if( i == 0 || m_TickcountSegments[i-1].GetTicks() != iTicks ) AddTickcountSegment( TickcountSegment(iRow, iTicks ) ); } else // TickcountSegment being modified is m_TickcountSegments[i] { - if( i > 0 && m_TickcountSegments[i-1].m_iTicks == iTicks ) + if( i > 0 && m_TickcountSegments[i-1].GetTicks() == iTicks ) m_TickcountSegments.erase( m_TickcountSegments.begin()+i, m_TickcountSegments.begin()+i+1 ); else - m_TickcountSegments[i].m_iTicks = iTicks; + m_TickcountSegments[i].SetTicks(iTicks); } } @@ -732,7 +732,7 @@ int TimingData::GetTickcountSegmentIndexAtRow( int iRow ) const { unsigned i; for (i=0; i < m_TickcountSegments.size() - 1; i++ ) - if( m_TickcountSegments[i+1].m_iStartRow > iRow ) + if( m_TickcountSegments[i+1].GetRow() > iRow ) break; return static_cast(i); } @@ -749,7 +749,7 @@ TickcountSegment& TimingData::GetTickcountSegmentAtRow( int iRow ) int TimingData::GetTickcountAtRow( int iRow ) const { - return m_TickcountSegments[GetTickcountSegmentIndexAtRow( iRow )].m_iTicks; + return m_TickcountSegments[GetTickcountSegmentIndexAtRow( iRow )].GetTicks(); } float TimingData::GetPreviousLabelSegmentBeatAtRow( int iRow ) const @@ -1071,13 +1071,14 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool for ( unsigned i = 0; i < m_TickcountSegments.size(); i++ ) { - const int iSegStart = m_TickcountSegments[i].m_iStartRow; + TickcountSegment &t = m_TickcountSegments[i]; + const int iSegStart = t.GetRow(); if( iSegStart < iStartIndex ) continue; else if( iSegStart > iEndIndex ) - m_TickcountSegments[i].m_iStartRow += lrintf( (iEndIndex - iStartIndex) * (fScale - 1) ); + t.SetRow(t.GetRow() + lrintf( (iEndIndex - iStartIndex) * (fScale - 1) )); else - m_TickcountSegments[i].m_iStartRow = lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex; + t.SetRow(lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex); } for ( unsigned i = 0; i < m_ComboSegments.size(); i++ ) @@ -1209,9 +1210,9 @@ void TimingData::InsertRows( int iStartRow, int iRowsToAdd ) for( unsigned i = 0; i < m_TickcountSegments.size(); i++ ) { TickcountSegment &tick = m_TickcountSegments[i]; - if( tick.m_iStartRow < iStartRow ) + if( tick.GetRow() < iStartRow ) continue; - tick.m_iStartRow += iRowsToAdd; + tick.SetRow(tick.GetRow() + iRowsToAdd); } for( unsigned i = 0; i < m_ComboSegments.size(); i++ ) @@ -1354,13 +1355,13 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) for( unsigned i = 0; i < m_TickcountSegments.size(); i++ ) { TickcountSegment &tick = m_TickcountSegments[i]; - + int keyRow = tick.GetRow(); // Before deleted region: - if( tick.m_iStartRow < iStartRow ) + if( keyRow < iStartRow ) continue; // Inside deleted region: - if( tick.m_iStartRow < iStartRow+iRowsToDelete ) + if( keyRow < iStartRow+iRowsToDelete ) { m_TickcountSegments.erase( m_TickcountSegments.begin()+i, m_TickcountSegments.begin()+i+1 ); --i; @@ -1368,7 +1369,7 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) } // After deleted region: - tick.m_iStartRow -= iRowsToDelete; + tick.SetRow(keyRow - iRowsToDelete); } for( unsigned i = 0; i < m_ComboSegments.size(); i++ ) diff --git a/src/TimingData.h b/src/TimingData.h index d3465a0fe3..8c003c5e85 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -412,83 +412,6 @@ struct WarpSegment bool operator>=( const WarpSegment &other ) const { return !operator<(other); } }; -/** - * @brief Identifies when a chart is to have a different tickcount value for hold notes. - * - * A tickcount segment is used to better replicate the checkpoint hold - * system used by various based video games. The number is used to - * represent how many ticks can be counted in one beat. - */ -struct TickcountSegment -{ - /** - * @brief Creates a simple Tickcount Segment with default values. - * - * It is best to override the values as soon as possible. - */ - TickcountSegment() : m_iStartRow(-1), m_iTicks(2) { } - /** - * @brief Creates a Tickcount Segment with the specified starting row and beats per second. - * @param s the starting row of this segment. - * @param t the amount of ticks counted per beat. - */ - TickcountSegment( int s, int t ): m_iStartRow(max(0, s)), - m_iTicks(max(0, t)) {} - /** - * @brief The row in which the TickcountSegment activates. - */ - int m_iStartRow; - /** - * @brief The amount of ticks counted per beat. - */ - int m_iTicks; - - /** - * @brief Compares two TickcountSegments to see if they are equal to each other. - * @param other the other TickcountSegment to compare to. - * @return the equality of the two segments. - */ - bool operator==( const TickcountSegment &other ) const - { - COMPARE( m_iStartRow ); - COMPARE( m_iTicks ); - return true; - } - /** - * @brief Compares two TickcountSegments to see if they are not equal to each other. - * @param other the other TickcountSegment to compare to. - * @return the inequality of the two segments. - */ - bool operator!=( const TickcountSegment &other ) const { return !operator==(other); } - /** - * @brief Compares two TickcountSegments to see if one is less than the other. - * @param other the other TickcountSegment to compare to. - * @return the truth/falsehood of if the first is less than the second. - */ - bool operator<( const TickcountSegment &other ) const { return m_iStartRow < other.m_iStartRow; } - /** - * @brief Compares two TickcountSegments to see if one is less than or equal to the other. - * @param other the other TickcountSegment to compare to. - * @return the truth/falsehood of if the first is less or equal to than the second. - */ - bool operator<=( const TickcountSegment &other ) const - { - return ( operator<(other) || operator==(other) ); - } - /** - * @brief Compares two TickcountSegments to see if one is greater than the other. - * @param other the other TickcountSegment to compare to. - * @return the truth/falsehood of if the first is greater than the second. - */ - bool operator>( const TickcountSegment &other ) const { return !operator<=(other); } - /** - * @brief Compares two TickcountSegments to see if one is greater than or equal to the other. - * @param other the other TickcountSegment to compare to. - * @return the truth/falsehood of if the first is greater than or equal to the second. - */ - bool operator>=( const TickcountSegment &other ) const { return !operator<(other); } -}; - /** * @brief Identifies when a chart is to have a different combo multiplier value. * diff --git a/src/TimingSegments.cpp b/src/TimingSegments.cpp index 4d1f6df95d..2cf8c3da51 100644 --- a/src/TimingSegments.cpp +++ b/src/TimingSegments.cpp @@ -31,7 +31,7 @@ float TimingSegment::GetBeat() const } FakeSegment::FakeSegment(): - TimingSegment(-1), lengthBeats(-1) {} + TimingSegment(), lengthBeats(-1) {} FakeSegment::FakeSegment( int s, int r ): TimingSegment(max(0, s)), lengthBeats(NoteRowToBeat(max(0, r))) {} @@ -89,6 +89,65 @@ bool FakeSegment::operator>=( const FakeSegment &other ) const return !this->operator<(other); } +TickcountSegment::TickcountSegment() : + TimingSegment(), ticks(4) {} + +TickcountSegment::TickcountSegment(int s) : + TimingSegment(s), ticks(4) {} + +TickcountSegment::TickcountSegment(float s) : + TimingSegment(s), ticks(4) {} + +TickcountSegment::TickcountSegment( int s, int t ): + TimingSegment(max(0, s)), ticks(max(0, t)) {} + +TickcountSegment::TickcountSegment( float s, int t ): + TimingSegment(max(0, s)), ticks(max(0, t)) {} + +int TickcountSegment::GetTicks() const +{ + return this->ticks; +} + +void TickcountSegment::SetTicks(const int i) +{ + this->ticks = i; +} + +bool TickcountSegment::operator==( const TickcountSegment &other ) const +{ + if (this->GetRow() != other.GetRow()) return false; + if (this->GetTicks() != other.GetTicks()) return false; + return true; +} + +bool TickcountSegment::operator!=( const TickcountSegment &other ) const +{ + return !this->operator==(other); +} + +bool TickcountSegment::operator<( const TickcountSegment &other ) const +{ + if (this->GetRow() < other.GetRow()) return true; + if (this->GetRow() > other.GetRow()) return false; + return this->GetTicks() < other.GetTicks(); +} + +bool TickcountSegment::operator<=( const TickcountSegment &other ) const +{ + return ( this->operator<(other) || this->operator==(other) ); +} + +bool TickcountSegment::operator>( const TickcountSegment &other ) const +{ + return !this->operator<=(other); +} + +bool TickcountSegment::operator>=( const TickcountSegment &other ) const +{ + return !this->operator<(other); +} + /** * @file * @author Jason Felds (c) 2011 diff --git a/src/TimingSegments.h b/src/TimingSegments.h index 44c2050bc2..5c34e7ac6b 100644 --- a/src/TimingSegments.h +++ b/src/TimingSegments.h @@ -153,6 +153,98 @@ private: float lengthBeats; }; +/** + * @brief Identifies when a chart is to have a different tickcount value + * for hold notes. + * + * A tickcount segment is used to better replicate the checkpoint hold + * system used by various based video games. The number is used to + * represent how many ticks can be counted in one beat. + */ +struct TickcountSegment : public TimingSegment +{ + /** + * @brief Creates a simple Tickcount Segment with default values. + * + * It is best to override the values as soon as possible. + */ + TickcountSegment(); + /** + * @brief Creates a TickcountSegment with specified values. + * @param s the starting row. */ + TickcountSegment(int s); + /** + * @brief Creates a TickcountSegment with specified values. + * @param s the starting beat. */ + TickcountSegment(float s); + /** + * @brief Creates a Tickcount Segment with the specified values. + * @param s the starting row. + * @param t the amount of ticks counted per beat. + */ + TickcountSegment( int s, int t ); + /** + * @brief Creates a Tickcount Segment with the specified values. + * @param s the starting beat. + * @param t the amount of ticks counted per beat. + */ + TickcountSegment( float s, int t ); + + /** + * @brief Get the number of ticks in this TickcountSegment. + * @return the tickcount. */ + int GetTicks() const; + + /** + * @brief Set the number of ticks in this TickcountSegment. + * @param i the tickcount. */ + void SetTicks(const int i); + + /** + * @brief Compares two TickcountSegments to see if they are equal to each other. + * @param other the other TickcountSegment to compare to. + * @return the equality of the two segments. + */ + bool operator==( const TickcountSegment &other ) const; + /** + * @brief Compares two TickcountSegments to see if they are not equal to each other. + * @param other the other TickcountSegment to compare to. + * @return the inequality of the two segments. + */ + bool operator!=( const TickcountSegment &other ) const; + /** + * @brief Compares two TickcountSegments to see if one is less than the other. + * @param other the other TickcountSegment to compare to. + * @return the truth/falsehood of if the first is less than the second. + */ + bool operator<( const TickcountSegment &other ) const; + /** + * @brief Compares two TickcountSegments to see if one is less than or equal to the other. + * @param other the other TickcountSegment to compare to. + * @return the truth/falsehood of if the first is less or equal to than the second. + */ + bool operator<=( const TickcountSegment &other ) const; + /** + * @brief Compares two TickcountSegments to see if one is greater than the other. + * @param other the other TickcountSegment to compare to. + * @return the truth/falsehood of if the first is greater than the second. + */ + bool operator>( const TickcountSegment &other ) const; + /** + * @brief Compares two TickcountSegments to see if one is greater than or equal to the other. + * @param other the other TickcountSegment to compare to. + * @return the truth/falsehood of if the first is greater than or equal to the second. + */ + bool operator>=( const TickcountSegment &other ) const; + +private: + /** + * @brief The amount of ticks counted per beat. + */ + int ticks; +}; + + #undef COMPARE From 0d4f95eda15a58126089df69d8c17c820af83f74 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 31 May 2011 01:33:56 -0400 Subject: [PATCH 06/27] Added the BattleRaveMirror metric. If you guys want your battles to not be mirrored/turned, this is the metric to change. By default, it's on ITG behavior. --- Docs/Changelog_sm5.txt | 10 ++++++++++ Themes/_fallback/metrics.ini | 1 + src/Player.cpp | 36 +++++++++++++++++++++--------------- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/Docs/Changelog_sm5.txt b/Docs/Changelog_sm5.txt index 757f1377ea..6785197f3f 100644 --- a/Docs/Changelog_sm5.txt +++ b/Docs/Changelog_sm5.txt @@ -4,6 +4,16 @@ The StepMania 5 Changelog covers all post-sm-ssc changes. For a list of changes from StepMania 4 alpha 5 to sm-ssc v1.2.5, see Changelog_sm-ssc.txt. ________________________________________________________________________________ +================================================================================ +StepMania 5.0 ????????? | 20110??? +-------------------------------------------------------------------------------- + +2011/05/31 +---------- +* [Player] Added the BattleRaveMirror metric. This determines if Battle and + Rave mode will have the two players with mirrored charts or not. By default, + this is set to true, preserving the ITG style behavior. [Wolfman2000] + ================================================================================ StepMania 5.0 Preview 1 | 20110529 -------------------------------------------------------------------------------- diff --git a/Themes/_fallback/metrics.ini b/Themes/_fallback/metrics.ini index ef5587c558..1c5d45139a 100644 --- a/Themes/_fallback/metrics.ini +++ b/Themes/_fallback/metrics.ini @@ -1080,6 +1080,7 @@ PercentUntilColorCombo=0.25 ComboStoppedAt=50 AttackRunTimeRandom=6 AttackRunTimeMine=7 +BattleRaveMirror=true [PlayerOptions] RandomSpeedChance=0.2 diff --git a/src/Player.cpp b/src/Player.cpp index 6a9def4af2..5caa7b5a65 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -198,6 +198,9 @@ ThemeMetric COMBO_STOPPED_AT ( "Player", "ComboStoppedAt" ); ThemeMetric ATTACK_RUN_TIME_RANDOM ( "Player", "AttackRunTimeRandom" ); ThemeMetric ATTACK_RUN_TIME_MINE ( "Player", "AttackRunTimeMine" ); +/** @brief Will battle modes have their steps mirrored or kept the same? */ +ThemeMetric BATTLE_RAVE_MIRROR ( "Player", "BattleRaveMirror" ); + float Player::GetWindowSeconds( TimingWindow tw ) { float fSecs = m_fTimingWindowSeconds[tw]; @@ -558,23 +561,26 @@ void Player::Load() StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType; NoteDataUtil::TransformNoteData( m_NoteData, m_pPlayerState->m_PlayerOptions.GetStage(), st ); - // shuffle either p1 or p2 - static int count = 0; - switch( count ) + if (BATTLE_RAVE_MIRROR) { - case 0: - case 3: - NoteDataUtil::Turn( m_NoteData, st, NoteDataUtil::left); - break; - case 1: - case 2: - NoteDataUtil::Turn( m_NoteData, st, NoteDataUtil::right); - break; - default: - ASSERT(0); + // shuffle either p1 or p2 + static int count = 0; + switch( count ) + { + case 0: + case 3: + NoteDataUtil::Turn( m_NoteData, st, NoteDataUtil::left); + break; + case 1: + case 2: + NoteDataUtil::Turn( m_NoteData, st, NoteDataUtil::right); + break; + default: + ASSERT(0); + } + count++; + count %= 4; } - count++; - count %= 4; } break; } From f7e849f045e75b35074e1a98dca187a8b5750dc2 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Tue, 31 May 2011 19:39:28 +0700 Subject: [PATCH 07/27] further refactorization of TimingSegments (use more templates!) --- src/NoteTypes.h | 29 ++++++ src/TimingSegments.cpp | 122 +++++----------------- src/TimingSegments.h | 223 ++++++++++++++++++++--------------------- 3 files changed, 163 insertions(+), 211 deletions(-) diff --git a/src/NoteTypes.h b/src/NoteTypes.h index a91e6aa693..3d99c63252 100644 --- a/src/NoteTypes.h +++ b/src/NoteTypes.h @@ -307,6 +307,35 @@ inline int BeatToNoteRowNotRounded( float fBeatNum ) { return (int)( fBeatNum * @return the beat. */ inline float NoteRowToBeat( int iRow ) { return iRow / (float)ROWS_PER_BEAT; } +// These functions can be useful for function templates, +// where both rows and beats can be specified. + +/** + * @brief Convert the note row to note row (returns itself). + * @param row the row to convert. + */ +static inline int ToNoteRow(int row) { return row; } + +/** + * @brief Convert the beat to note row. + * @param beat the beat to convert. + */ +static inline int ToNoteRow(float beat) { return BeatToNoteRow(beat); } + +/** + * @brief Convert the note row to beat. + * @param row the row to convert. + */ +static inline float ToBeat(int row) { return NoteRowToBeat(row); } + +/** + * @brief Convert the beat row to beat (return itself). + * @param beat the beat to convert. + */ +static inline float ToBeat(float beat) { return beat; } + + + #endif /** diff --git a/src/TimingSegments.cpp b/src/TimingSegments.cpp index 2cf8c3da51..1cf3780772 100644 --- a/src/TimingSegments.cpp +++ b/src/TimingSegments.cpp @@ -1,49 +1,40 @@ #include "TimingSegments.h" -TimingSegment::TimingSegment() : - startingRow(-1) {} +#define LTCOMPARE(x) if(this->x < other.x) return true; if(this->x > other.x) return false; -TimingSegment::TimingSegment(int s) : - startingRow(s) {} +BaseTimingSegment::~BaseTimingSegment() {} -TimingSegment::TimingSegment(float s) : - startingRow(BeatToNoteRow(s)) {} -TimingSegment::~TimingSegment() {} - -void TimingSegment::SetRow(const int s) +void BaseTimingSegment::SetRow(const int s) { this->startingRow = s; } -void TimingSegment::SetBeat(const float s) + +void BaseTimingSegment::SetBeat(const float s) { - this->startingRow = BeatToNoteRow(s); + SetRow(BeatToNoteRow(s)); } -int TimingSegment::GetRow() const +int BaseTimingSegment::GetRow() const { return this->startingRow; } -float TimingSegment::GetBeat() const +float BaseTimingSegment::GetBeat() const { - return NoteRowToBeat(this->startingRow); + return NoteRowToBeat(GetRow()); } -FakeSegment::FakeSegment(): - TimingSegment(), lengthBeats(-1) {} +template +bool TimingSegment::operator<( const DerivedSegment &other ) const +{ + LTCOMPARE(GetRow()); + return false; +} -FakeSegment::FakeSegment( int s, int r ): - TimingSegment(max(0, s)), lengthBeats(NoteRowToBeat(max(0, r))) {} -FakeSegment::FakeSegment( int s, float b ): - TimingSegment(max(0, s)), lengthBeats(max(0, b)) {} - -FakeSegment::FakeSegment( float s, int r ): - TimingSegment(max(0, s)), lengthBeats(max(0, NoteRowToBeat(r))) {} - -FakeSegment::FakeSegment( float s, float b ): - TimingSegment(max(0, s)), lengthBeats(max(0, b)) {} +/* ====================================================== + Here comes the actual timing segments implementation!! */ float FakeSegment::GetLength() const { @@ -55,54 +46,14 @@ void FakeSegment::SetLength(const float b) this->lengthBeats = b; } -bool FakeSegment::operator==( const FakeSegment &other ) const -{ - if (this->GetRow() != other.GetRow()) return false; - if (this->GetLength() != other.GetLength()) return false; - return true; -} - -bool FakeSegment::operator!=( const FakeSegment &other ) const -{ - return !this->operator==(other); -} - bool FakeSegment::operator<( const FakeSegment &other ) const { - if (this->GetRow() < other.GetRow()) return true; - if (this->GetRow() > other.GetRow()) return false; - return this->GetLength() < other.GetLength(); + LTCOMPARE(GetRow()); + LTCOMPARE(GetLength()); + return false; } -bool FakeSegment::operator<=( const FakeSegment &other ) const -{ - return ( this->operator<(other) || this->operator==(other) ); -} -bool FakeSegment::operator>( const FakeSegment &other ) const -{ - return !this->operator<=(other); -} - -bool FakeSegment::operator>=( const FakeSegment &other ) const -{ - return !this->operator<(other); -} - -TickcountSegment::TickcountSegment() : - TimingSegment(), ticks(4) {} - -TickcountSegment::TickcountSegment(int s) : - TimingSegment(s), ticks(4) {} - -TickcountSegment::TickcountSegment(float s) : - TimingSegment(s), ticks(4) {} - -TickcountSegment::TickcountSegment( int s, int t ): - TimingSegment(max(0, s)), ticks(max(0, t)) {} - -TickcountSegment::TickcountSegment( float s, int t ): - TimingSegment(max(0, s)), ticks(max(0, t)) {} int TickcountSegment::GetTicks() const { @@ -114,38 +65,11 @@ void TickcountSegment::SetTicks(const int i) this->ticks = i; } -bool TickcountSegment::operator==( const TickcountSegment &other ) const -{ - if (this->GetRow() != other.GetRow()) return false; - if (this->GetTicks() != other.GetTicks()) return false; - return true; -} - -bool TickcountSegment::operator!=( const TickcountSegment &other ) const -{ - return !this->operator==(other); -} - bool TickcountSegment::operator<( const TickcountSegment &other ) const { - if (this->GetRow() < other.GetRow()) return true; - if (this->GetRow() > other.GetRow()) return false; - return this->GetTicks() < other.GetTicks(); -} - -bool TickcountSegment::operator<=( const TickcountSegment &other ) const -{ - return ( this->operator<(other) || this->operator==(other) ); -} - -bool TickcountSegment::operator>( const TickcountSegment &other ) const -{ - return !this->operator<=(other); -} - -bool TickcountSegment::operator>=( const TickcountSegment &other ) const -{ - return !this->operator<(other); + LTCOMPARE(GetRow()); + LTCOMPARE(GetTicks()); + return false; } /** diff --git a/src/TimingSegments.h b/src/TimingSegments.h index 5c34e7ac6b..d01674c0f3 100644 --- a/src/TimingSegments.h +++ b/src/TimingSegments.h @@ -10,52 +10,116 @@ #define COMPARE(x) if(x!=other.x) return false; /** - * @brief The general TimingSegment for all of the changing glory. - * - * Each segment is supposed to derive from this one. */ -struct TimingSegment + * @brief The base timing segment for all of the changing glory. + * + * Do not derive from this class!! Instead, derive from TimingSegment! + */ +struct BaseTimingSegment { - /** @brief Set up a TimingSegment with default values. */ - TimingSegment(); - /** - * @brief Set up a TimingSegment with specified values. - * @param s the starting row. */ - TimingSegment(int s); - /** - * @brief Set up a TimingSegment with specified values. - * @param s the starting beat. */ - TimingSegment(float s); - - virtual ~TimingSegment(); + + /** @brief Set up a BaseTimingSegment with default values. */ + BaseTimingSegment(): + startingRow(-1) {}; /** - * @brief Set the starting row of the TimingSegment. + * @brief Set up a BaseTimingSegment with specified values. + * @param s the starting row / beat. */ + template + BaseTimingSegment(StartType s): + startingRow(ToNoteRow(s)) {}; + + virtual ~BaseTimingSegment(); + + /** + * @brief Set the starting row of the BaseTimingSegment. * * This is virtual to allow other segments to implement validation * as required by them. * @param s the supplied row. */ virtual void SetRow( const int s ); + /** - * @brief Set the starting beat of the TimingSegment. + * @brief Set the starting beat of the BaseTimingSegment. * - * This is virtual to allow other segments to implement validation - * as required by them. * @param s the supplied beat. */ - virtual void SetBeat( const float s ); + void SetBeat( const float s ); + /** - * @brief Get the starting row of the TimingSegment. + * @brief Get the starting row of the BaseTimingSegment. * @return the starting row. */ int GetRow() const; + /** - * @brief Get the starting beat of the TimingSegment. + * @brief Get the starting beat of the BaseTimingSegment. * @return the starting beat. */ float GetBeat() const; - -private: + +protected: /** @brief The row in which this segment activates. */ int startingRow; + }; +/** + * @brief The general TimingSegment for all of the changing glory. + * + * Each segment is supposed to derive from this one. */ +template +struct TimingSegment: public BaseTimingSegment +{ + + TimingSegment(): BaseTimingSegment() {}; + + template + TimingSegment(StartType s): BaseTimingSegment(s) {}; + + /** + * @brief Compares two DrivedSegments to see if one is less than the other. + * @param other the other TimingSegments to compare to. + * @return the truth/falsehood of if the first is less than the second. + * + * This is virtual to allow other segments to implement comparison + * as required by them. + */ + virtual bool operator<( const DerivedSegment &other ) const; + + /** + * @brief Compares two DrivedSegments to see if they are equal to each other. + * @param other the other FakeSegment to compare to. + * @return the equality of the two segments. + * + * This is virtual to allow other segments to implement comparison + * as required by them. + */ + bool operator==( const DerivedSegment &other ) const { return !this->operator<(other) && !other.operator<(*static_cast(this)); }; + /** + * @brief Compares two DrivedSegments to see if they are not equal to each other. + * @param other the other DrivedSegments to compare to. + * @return the inequality of the two segments. + */ + bool operator!=( const DerivedSegment &other ) const { return !this->operator==(other); }; + /** + * @brief Compares two DrivedSegments to see if one is less than or equal to the other. + * @param other the other DrivedSegments to compare to. + * @return the truth/falsehood of if the first is less or equal to than the second. + */ + bool operator<=( const DerivedSegment &other ) const { return !this->operator>(other); }; + /** + * @brief Compares two DrivedSegments to see if one is greater than the other. + * @param other the other DrivedSegments to compare to. + * @return the truth/falsehood of if the first is greater than the second. + */ + bool operator>( const DerivedSegment &other ) const { return other.operator<(*static_cast(this)); }; + /** + * @brief Compares two DrivedSegments to see if one is greater than or equal to the other. + * @param other the other DrivedSegments to compare to. + * @return the truth/falsehood of if the first is greater than or equal to the second. + */ + bool operator>=( const DerivedSegment &other ) const { return !this->operator<(other); }; + +}; + + /** * @brief Identifies when a whole region of arrows is to be ignored. * @@ -67,38 +131,24 @@ private: * drawn normally. * * These were inspired by the Pump It Up series. */ -struct FakeSegment : public TimingSegment +struct FakeSegment : public TimingSegment { /** * @brief Create a simple Fake Segment with default values. * * It is best to override the values as soon as possible. */ - FakeSegment(); + FakeSegment(): + TimingSegment(), lengthBeats(-1) {}; + /** * @brief Create a Fake Segment with the specified values. * @param s the starting row of this segment. * @param r the number of rows this segment lasts. */ - FakeSegment( int s, int r ); - /** - * @brief Creates a Fake Segment with the specified values. - * @param s the starting row of this segment. - * @param b the number of beats this segment lasts. - */ - FakeSegment( int s, float b ); - /** - * @brief Create a Fake Segment with the specified values. - * @param s the starting beat in this segment. - * @param r the number of rows this segment lasts. - */ - FakeSegment( float s, int r ); - /** - * @brief Creates a Fake Segment with the specified values. - * @param s the starting beat of this segment. - * @param b the number of beats this segment lasts. - */ - FakeSegment( float s, float b ); + template + FakeSegment( StartType s, LengthType r ): + TimingSegment(max((StartType)0, s)), lengthBeats(ToBeat(max((LengthType)0, r))) {}; /** * @brief Get the length in beats of the FakeSegment. @@ -116,36 +166,13 @@ struct FakeSegment : public TimingSegment * @return the equality of the two segments. */ bool operator==( const FakeSegment &other ) const; - /** - * @brief Compares two FakeSegments to see if they are not equal to each other. - * @param other the other FakeSegment to compare to. - * @return the inequality of the two segments. - */ - bool operator!=( const FakeSegment &other ) const; /** * @brief Compares two FakeSegments to see if one is less than the other. * @param other the other FakeSegment to compare to. * @return the truth/falsehood of if the first is less than the second. */ bool operator<( const FakeSegment &other ) const; - /** - * @brief Compares two FakeSegments to see if one is less than or equal to the other. - * @param other the other FakeSegment to compare to. - * @return the truth/falsehood of if the first is less or equal to than the second. - */ - bool operator<=( const FakeSegment &other ) const; - /** - * @brief Compares two FakeSegments to see if one is greater than the other. - * @param other the other FakeSegment to compare to. - * @return the truth/falsehood of if the first is greater than the second. - */ - bool operator>( const FakeSegment &other ) const; - /** - * @brief Compares two FakeSegments to see if one is greater than or equal to the other. - * @param other the other FakeSegment to compare to. - * @return the truth/falsehood of if the first is greater than or equal to the second. - */ - bool operator>=( const FakeSegment &other ) const; + private: /** * @brief The number of beats the FakeSegment is alive for. @@ -161,34 +188,30 @@ private: * system used by various based video games. The number is used to * represent how many ticks can be counted in one beat. */ -struct TickcountSegment : public TimingSegment +struct TickcountSegment : public TimingSegment { /** * @brief Creates a simple Tickcount Segment with default values. * * It is best to override the values as soon as possible. */ - TickcountSegment(); + TickcountSegment(): + TimingSegment(), ticks(4) {}; + /** * @brief Creates a TickcountSegment with specified values. - * @param s the starting row. */ - TickcountSegment(int s); + * @param s the starting row / beat. */ + template + TickcountSegment( StartType s ): + TimingSegment(max((StartType)0, s)), ticks(4) {}; + /** * @brief Creates a TickcountSegment with specified values. - * @param s the starting beat. */ - TickcountSegment(float s); - /** - * @brief Creates a Tickcount Segment with the specified values. - * @param s the starting row. - * @param t the amount of ticks counted per beat. - */ - TickcountSegment( int s, int t ); - /** - * @brief Creates a Tickcount Segment with the specified values. - * @param s the starting beat. - * @param t the amount of ticks counted per beat. - */ - TickcountSegment( float s, int t ); + * @param s the starting row / beat. + * @param t the amount of ticks counted per beat. */ + template + TickcountSegment( StartType s, int t ): + TimingSegment(max((StartType)0, s)), ticks(max(0, t)) {}; /** * @brief Get the number of ticks in this TickcountSegment. @@ -206,36 +229,12 @@ struct TickcountSegment : public TimingSegment * @return the equality of the two segments. */ bool operator==( const TickcountSegment &other ) const; - /** - * @brief Compares two TickcountSegments to see if they are not equal to each other. - * @param other the other TickcountSegment to compare to. - * @return the inequality of the two segments. - */ - bool operator!=( const TickcountSegment &other ) const; /** * @brief Compares two TickcountSegments to see if one is less than the other. * @param other the other TickcountSegment to compare to. * @return the truth/falsehood of if the first is less than the second. */ bool operator<( const TickcountSegment &other ) const; - /** - * @brief Compares two TickcountSegments to see if one is less than or equal to the other. - * @param other the other TickcountSegment to compare to. - * @return the truth/falsehood of if the first is less or equal to than the second. - */ - bool operator<=( const TickcountSegment &other ) const; - /** - * @brief Compares two TickcountSegments to see if one is greater than the other. - * @param other the other TickcountSegment to compare to. - * @return the truth/falsehood of if the first is greater than the second. - */ - bool operator>( const TickcountSegment &other ) const; - /** - * @brief Compares two TickcountSegments to see if one is greater than or equal to the other. - * @param other the other TickcountSegment to compare to. - * @return the truth/falsehood of if the first is greater than or equal to the second. - */ - bool operator>=( const TickcountSegment &other ) const; private: /** From 26ecddfc9d1a7aafac3631927c6c6bd0bb23fe91 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Tue, 31 May 2011 21:14:36 +0700 Subject: [PATCH 08/27] beat should be private --- src/TimingSegments.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TimingSegments.h b/src/TimingSegments.h index d01674c0f3..58b389662b 100644 --- a/src/TimingSegments.h +++ b/src/TimingSegments.h @@ -54,7 +54,7 @@ struct BaseTimingSegment * @return the starting beat. */ float GetBeat() const; -protected: +private: /** @brief The row in which this segment activates. */ int startingRow; From 1fcf29057182cbfe946317eef653b52f55df3e55 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 31 May 2011 10:59:18 -0400 Subject: [PATCH 09/27] Warps are properly templated. Seven more to go I believe. --- src/NoteField.cpp | 6 +-- src/NotesWriterSM.cpp | 4 +- src/NotesWriterSSC.cpp | 2 +- src/TimingData.cpp | 51 ++++++++++---------- src/TimingData.h | 103 ----------------------------------------- src/TimingSegments.cpp | 17 +++++++ src/TimingSegments.h | 76 ++++++++++++++++++++++++++---- 7 files changed, 117 insertions(+), 142 deletions(-) diff --git a/src/NoteField.cpp b/src/NoteField.cpp index e54b650bd5..5b958d43a0 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -921,11 +921,11 @@ void NoteField::DrawPrimitives() // Warp text FOREACH_CONST( WarpSegment, timing.m_WarpSegments, seg ) { - if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) + if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw ) { - float fBeat = NoteRowToBeat(seg->m_iStartRow); + float fBeat = seg->GetBeat(); if( IS_ON_SCREEN(fBeat) ) - DrawWarpText( fBeat, seg->m_fLengthBeats ); + DrawWarpText( fBeat, seg->GetLength() ); } } diff --git a/src/NotesWriterSM.cpp b/src/NotesWriterSM.cpp index 55bbeeb65c..2bd84f945f 100644 --- a/src/NotesWriterSM.cpp +++ b/src/NotesWriterSM.cpp @@ -113,9 +113,9 @@ static void WriteGlobalTags( RageFile &f, Song &out ) { for( unsigned i=0; i < wSize; i++ ) { - int iRow = out.m_SongTiming.m_WarpSegments[i].m_iStartRow; + int iRow = out.m_SongTiming.m_WarpSegments[i].GetRow(); float fBPS = 60 / out.m_SongTiming.GetBPMAtRow(iRow); - float fSkip = fBPS * out.m_SongTiming.m_WarpSegments[i].m_fLengthBeats; + float fSkip = fBPS * out.m_SongTiming.m_WarpSegments[i].GetLength(); StopSegment ss; ss.m_iStartRow = iRow; ss.m_fStopSeconds = -fSkip; diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index 46b12ee872..051ae94806 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -110,7 +110,7 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo w.Init( "WARPS" ); FOREACH_CONST( WarpSegment, timing.m_WarpSegments, ws ) - w.Write( ws->m_iStartRow, ws->m_fLengthBeats ); + w.Write( ws->GetRow(), ws->GetLength() ); w.Finish(); ASSERT( !timing.m_vTimeSignatureSegments.empty() ); diff --git a/src/TimingData.cpp b/src/TimingData.cpp index 2cf4bded87..f59dda63bf 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -179,7 +179,7 @@ void TimingData::SetWarpAtRow( int iRow, float fNew ) { unsigned i; for( i=0; i 0 && fNew > 0; if( i == m_WarpSegments.size() ) @@ -193,7 +193,7 @@ void TimingData::SetWarpAtRow( int iRow, float fNew ) { if( valid ) { - m_WarpSegments[i].m_fLengthBeats = fNew; + m_WarpSegments[i].SetLength(fNew); } else m_WarpSegments.erase( m_WarpSegments.begin()+i, m_WarpSegments.begin()+i+1 ); @@ -410,9 +410,9 @@ float TimingData::GetWarpAtRow( int iWarpRow ) const { for( unsigned i=0; i iNoteRow ) + if( s.GetRow() > iNoteRow ) break; } return static_cast(i); @@ -551,7 +551,8 @@ bool TimingData::IsWarpAtRow( int iNoteRow ) const int i = GetWarpSegmentIndexAtRow( iNoteRow ); const WarpSegment& s = m_WarpSegments[i]; - if( s.m_iStartRow <= iNoteRow && iNoteRow < (s.m_iStartRow + BeatToNoteRow(s.m_fLengthBeats) ) ) + float beatRow = NoteRowToBeat(iNoteRow); + if( s.GetBeat() <= beatRow && beatRow < (s.GetBeat() + s.GetLength() ) ) { // Allow stops inside warps to allow things like stop, warp, stop, warp, stop, and so on. if( m_StopSegments.empty() ) @@ -844,9 +845,9 @@ void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float iEventRow = itSS->m_iStartRow; iEventType = FOUND_STOP; } - if( itWS != m_WarpSegments.end() && itWS->m_iStartRow < iEventRow ) + if( itWS != m_WarpSegments.end() && itWS->GetRow() < iEventRow ) { - iEventRow = itWS->m_iStartRow; + iEventRow = itWS->GetRow(); iEventType = FOUND_WARP; } if( iEventType == NOT_FOUND ) @@ -889,7 +890,7 @@ void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float case FOUND_WARP: { bIsWarping = true; - float fWarpSum = itWS->m_fLengthBeats + NoteRowToBeat( itWS->m_iStartRow ); + float fWarpSum = itWS->GetLength() + itWS->GetBeat(); if( fWarpSum > fWarpDestination ) { fWarpDestination = fWarpSum; @@ -956,9 +957,9 @@ float TimingData::GetElapsedTimeFromBeatNoOffset( float fBeat ) const iEventRow = itSS->m_iStartRow; iEventType = FOUND_STOP; } - if( itWS != m_WarpSegments.end() && itWS->m_iStartRow < iEventRow ) + if( itWS != m_WarpSegments.end() && itWS->GetRow() < iEventRow ) { - iEventRow = itWS->m_iStartRow; + iEventRow = itWS->GetRow(); iEventType = FOUND_WARP; } float fTimeToNextEvent = bIsWarping ? 0 : NoteRowToBeat( iEventRow - iLastRow ) / fBPS; @@ -984,7 +985,7 @@ float TimingData::GetElapsedTimeFromBeatNoOffset( float fBeat ) const case FOUND_WARP: { bIsWarping = true; - float fWarpSum = itWS->m_fLengthBeats + NoteRowToBeat( itWS->m_iStartRow ); + float fWarpSum = itWS->GetLength() + itWS->GetBeat(); if( fWarpSum > fWarpDestination ) { fWarpDestination = fWarpSum; @@ -1052,21 +1053,23 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool for( unsigned i = 0; i < m_WarpSegments.size(); i++ ) { - const int iSegStartRow = m_WarpSegments[i].m_iStartRow; - const int iSegEndRow = iSegStartRow + BeatToNoteRow( m_WarpSegments[i].m_fLengthBeats ); + WarpSegment &w = m_WarpSegments[i]; + const int iSegStartRow = w.GetRow(); + const int iSegEndRow = iSegStartRow + BeatToNoteRow( w.GetLength() ); if( iSegEndRow >= iStartIndex ) { if( iSegEndRow > iEndIndex ) - m_WarpSegments[i].m_fLengthBeats += NoteRowToBeat(lrintf((iEndIndex - iStartIndex) * (fScale - 1))); + w.SetLength(w.GetLength() + + NoteRowToBeat(lrintf((iEndIndex - iStartIndex) * (fScale - 1)))); else - m_WarpSegments[i].m_fLengthBeats = NoteRowToBeat(lrintf((iSegEndRow - iStartIndex) * fScale)); + w.SetLength(NoteRowToBeat(lrintf((iSegEndRow - iStartIndex) * fScale))); } if( iSegStartRow < iStartIndex ) continue; else if( iSegStartRow > iEndIndex ) - m_WarpSegments[i].m_iStartRow += lrintf((iEndIndex - iStartIndex) * (fScale - 1)); + w.SetRow(w.GetRow() + lrintf((iEndIndex - iStartIndex) * (fScale - 1))); else - m_WarpSegments[i].m_iStartRow = lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex; + w.SetRow(lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex); } for ( unsigned i = 0; i < m_TickcountSegments.size(); i++ ) @@ -1194,9 +1197,9 @@ void TimingData::InsertRows( int iStartRow, int iRowsToAdd ) for( unsigned i = 0; i < m_WarpSegments.size(); i++ ) { WarpSegment &warp = m_WarpSegments[i]; - if( warp.m_iStartRow < iStartRow ) + if( warp.GetRow() < iStartRow ) continue; - warp.m_iStartRow += iRowsToAdd; + warp.SetRow(warp.GetRow() + iRowsToAdd); } for( unsigned i = 0; i < m_vTimeSignatureSegments.size(); i++ ) @@ -1314,18 +1317,18 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) for( unsigned i = 0; i < m_WarpSegments.size(); i++ ) { WarpSegment &warp = m_WarpSegments[i]; - - if( warp.m_iStartRow < iStartRow ) + int keyRow = warp.GetRow(); + if( keyRow < iStartRow ) continue; - if( warp.m_iStartRow < iStartRow+iRowsToDelete ) + if( keyRow < iStartRow+iRowsToDelete ) { m_WarpSegments.erase( m_WarpSegments.begin()+i, m_WarpSegments.begin()+i+1 ); --i; continue; } - warp.m_iStartRow -= iRowsToDelete; + warp.SetRow(keyRow - iRowsToDelete); } for( unsigned i = 0; i < m_vTimeSignatureSegments.size(); i++ ) diff --git a/src/TimingData.h b/src/TimingData.h index 8c003c5e85..aad3b22eab 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -309,109 +309,6 @@ struct TimeSignatureSegment bool operator>= (const TimeSignatureSegment &other ) const { return !operator<(other); } }; -/** - * @brief Identifies when a song needs to warp to a new beat. - * - * A warp segment is used to replicate the effects of Negative BPMs without - * abusing negative BPMs. Negative BPMs should be converted to warp segments. - * WarpAt=WarpToRelative is the format, where both are in beats. - * (Technically they're both rows though.) */ -struct WarpSegment -{ - /** - * @brief Create a simple Warp Segment with default values. - * - * It is best to override the values as soon as possible. - */ - WarpSegment() : m_iStartRow(-1), m_fLengthBeats(-1) { } - /** - * @brief Create a Warp Segment with the specified starting row and row to warp to. - * @param s the starting row of this segment. - * @param r the number of rows to jump ahead. - */ - WarpSegment( int s, int r ): m_iStartRow(s), - m_fLengthBeats(NoteRowToBeat(r)) {} - /** - * @brief Creates a Warp Segment with the specified starting row and beat to warp to. - * @param s the starting row of this segment. - * @param b the number of beats to jump ahead. - */ - WarpSegment( int s, float b ): m_iStartRow(max(0, s)), - m_fLengthBeats(max(0, b)) {} - /** - * @brief Create a Warp Segment with the specified starting beat and row to warp to. - * @param s the starting beat in this segment. - * @param r the number of rows to jump ahead. - */ - WarpSegment( float s, int r ): - m_iStartRow(max(0, BeatToNoteRow(s))), - m_fLengthBeats(max(0, NoteRowToBeat(r))) {} - /** - * @brief Creates a Warp Segment with the specified starting beat and beat to warp to. - * @param s the starting beat of this segment. - * @param b the number of beats to jump ahead. - */ - WarpSegment( float s, float b ): - m_iStartRow(BeatToNoteRow(s)), - m_fLengthBeats(b) {} - /** - * @brief The row in which the WarpSegment activates. - */ - int m_iStartRow; - /** - * @brief The number of beats to warp ahead by. - */ - float m_fLengthBeats; - /** - * @brief Compares two WarpSegments to see if they are equal to each other. - * @param other the other WarpSegment to compare to. - * @return the equality of the two segments. - */ - bool operator==( const WarpSegment &other ) const - { - COMPARE( m_iStartRow ); - COMPARE( m_fLengthBeats ); - return true; - } - /** - * @brief Compares two WarpSegments to see if they are not equal to each other. - * @param other the other WarpSegment to compare to. - * @return the inequality of the two segments. - */ - bool operator!=( const WarpSegment &other ) const { return !operator==(other); } - /** - * @brief Compares two WarpSegments to see if one is less than the other. - * @param other the other WarpSegment to compare to. - * @return the truth/falsehood of if the first is less than the second. - */ - bool operator<( const WarpSegment &other ) const - { - return m_iStartRow < other.m_iStartRow || - ( m_iStartRow == other.m_iStartRow && m_fLengthBeats < other.m_fLengthBeats ); - } - /** - * @brief Compares two WarpSegments to see if one is less than or equal to the other. - * @param other the other WarpSegment to compare to. - * @return the truth/falsehood of if the first is less or equal to than the second. - */ - bool operator<=( const WarpSegment &other ) const - { - return ( operator<(other) || operator==(other) ); - } - /** - * @brief Compares two WarpSegments to see if one is greater than the other. - * @param other the other WarpSegment to compare to. - * @return the truth/falsehood of if the first is greater than the second. - */ - bool operator>( const WarpSegment &other ) const { return !operator<=(other); } - /** - * @brief Compares two WarpSegments to see if one is greater than or equal to the other. - * @param other the other WarpSegment to compare to. - * @return the truth/falsehood of if the first is greater than or equal to the second. - */ - bool operator>=( const WarpSegment &other ) const { return !operator<(other); } -}; - /** * @brief Identifies when a chart is to have a different combo multiplier value. * diff --git a/src/TimingSegments.cpp b/src/TimingSegments.cpp index 1cf3780772..38550ee137 100644 --- a/src/TimingSegments.cpp +++ b/src/TimingSegments.cpp @@ -53,6 +53,23 @@ bool FakeSegment::operator<( const FakeSegment &other ) const return false; } +float WarpSegment::GetLength() const +{ + return this->lengthBeats; +} + +void WarpSegment::SetLength(const float b) +{ + this->lengthBeats = b; +} + +bool WarpSegment::operator<( const WarpSegment &other ) const +{ + LTCOMPARE(GetRow()); + LTCOMPARE(GetLength()); + return false; +} + int TickcountSegment::GetTicks() const diff --git a/src/TimingSegments.h b/src/TimingSegments.h index 58b389662b..e7bed65128 100644 --- a/src/TimingSegments.h +++ b/src/TimingSegments.h @@ -3,12 +3,6 @@ #include "NoteTypes.h" // Converting rows to beats and vice~versa. -/** - * @brief Compare a TimingData segment's properties with one another. - * - * This will be removed once we start respecting public & private data.*/ -#define COMPARE(x) if(x!=other.x) return false; - /** * @brief The base timing segment for all of the changing glory. * @@ -91,7 +85,11 @@ struct TimingSegment: public BaseTimingSegment * This is virtual to allow other segments to implement comparison * as required by them. */ - bool operator==( const DerivedSegment &other ) const { return !this->operator<(other) && !other.operator<(*static_cast(this)); }; + bool operator==( const DerivedSegment &other ) const + { + return !this->operator<(other) && + !other.operator<(*static_cast(this)); + }; /** * @brief Compares two DrivedSegments to see if they are not equal to each other. * @param other the other DrivedSegments to compare to. @@ -109,7 +107,10 @@ struct TimingSegment: public BaseTimingSegment * @param other the other DrivedSegments to compare to. * @return the truth/falsehood of if the first is greater than the second. */ - bool operator>( const DerivedSegment &other ) const { return other.operator<(*static_cast(this)); }; + bool operator>( const DerivedSegment &other ) const + { + return other.operator<(*static_cast(this)); + }; /** * @brief Compares two DrivedSegments to see if one is greater than or equal to the other. * @param other the other DrivedSegments to compare to. @@ -148,7 +149,8 @@ struct FakeSegment : public TimingSegment */ template FakeSegment( StartType s, LengthType r ): - TimingSegment(max((StartType)0, s)), lengthBeats(ToBeat(max((LengthType)0, r))) {}; + TimingSegment(max((StartType)0, s)), + lengthBeats(ToBeat(max((LengthType)0, r))) {}; /** * @brief Get the length in beats of the FakeSegment. @@ -180,6 +182,62 @@ private: float lengthBeats; }; +/** + * @brief Identifies when a song needs to warp to a new beat. + * + * A warp segment is used to replicate the effects of Negative BPMs without + * abusing negative BPMs. Negative BPMs should be converted to warp segments. + * WarpAt=WarpToRelative is the format, where both are in beats. + * (Technically they're both rows though.) */ +struct WarpSegment : public TimingSegment +{ + /** + * @brief Create a simple Warp Segment with default values. + * + * It is best to override the values as soon as possible. + */ + WarpSegment(): + TimingSegment(), lengthBeats(-1) {}; + + /** + * @brief Create a Warp Segment with the specified values. + * @param s the starting row of this segment. + * @param r the number of rows this segment lasts. + */ + template + WarpSegment( StartType s, LengthType r ): + TimingSegment(max((StartType)0, s)), + lengthBeats(ToBeat(max((LengthType)0, r))) {}; + + /** + * @brief Get the length in beats of the WarpSegment. + * @return the length in beats. */ + float GetLength() const; + + /** + * @brief Set the length in beats of the WarpSegment. + * @param b the length in beats. */ + void SetLength(const float b); + + /** + * @brief Compares two WarpSegments to see if they are equal to each other. + * @param other the other WarpSegment to compare to. + * @return the equality of the two segments. + */ + bool operator==( const WarpSegment &other ) const; + /* + * @brief Compares two WarpSegments to see if one is less than the other. + * @param other the other WarpSegment to compare to. + * @return the truth/falsehood of if the first is less than the second. + */ + bool operator<( const WarpSegment &other ) const; +private: + /** + * @brief The number of beats the FakeSegment is alive for. + */ + float lengthBeats; +}; + /** * @brief Identifies when a chart is to have a different tickcount value * for hold notes. From 860f6c76f01548aaec59627509bedc192dbab7be Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Tue, 31 May 2011 22:05:04 +0700 Subject: [PATCH 10/27] I forgot to remove the unused operator== functions from TimingSegments.h --- src/TimingSegments.h | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/TimingSegments.h b/src/TimingSegments.h index e7bed65128..c5c0c31f81 100644 --- a/src/TimingSegments.h +++ b/src/TimingSegments.h @@ -162,12 +162,6 @@ struct FakeSegment : public TimingSegment * @param b the length in beats. */ void SetLength(const float b); - /** - * @brief Compares two FakeSegments to see if they are equal to each other. - * @param other the other FakeSegment to compare to. - * @return the equality of the two segments. - */ - bool operator==( const FakeSegment &other ) const; /** * @brief Compares two FakeSegments to see if one is less than the other. * @param other the other FakeSegment to compare to. @@ -219,12 +213,6 @@ struct WarpSegment : public TimingSegment * @param b the length in beats. */ void SetLength(const float b); - /** - * @brief Compares two WarpSegments to see if they are equal to each other. - * @param other the other WarpSegment to compare to. - * @return the equality of the two segments. - */ - bool operator==( const WarpSegment &other ) const; /* * @brief Compares two WarpSegments to see if one is less than the other. * @param other the other WarpSegment to compare to. @@ -281,12 +269,6 @@ struct TickcountSegment : public TimingSegment * @param i the tickcount. */ void SetTicks(const int i); - /** - * @brief Compares two TickcountSegments to see if they are equal to each other. - * @param other the other TickcountSegment to compare to. - * @return the equality of the two segments. - */ - bool operator==( const TickcountSegment &other ) const; /** * @brief Compares two TickcountSegments to see if one is less than the other. * @param other the other TickcountSegment to compare to. From da733968953c6b5e494ebf7a6415d3113a1b53ce Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 31 May 2011 11:22:21 -0400 Subject: [PATCH 11/27] Labels templated. Six more to go. --- src/NoteField.cpp | 6 +-- src/NotesWriterSSC.cpp | 2 +- src/TimingData.cpp | 49 +++++++++++++------------ src/TimingData.h | 83 ------------------------------------------ src/TimingSegments.cpp | 17 +++++++++ src/TimingSegments.h | 50 +++++++++++++++++++++++++ 6 files changed, 96 insertions(+), 111 deletions(-) diff --git a/src/NoteField.cpp b/src/NoteField.cpp index 5b958d43a0..2e05aac08b 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -972,11 +972,11 @@ void NoteField::DrawPrimitives() // Label text FOREACH_CONST( LabelSegment, timing.m_LabelSegments, seg ) { - if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) + if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw ) { - float fBeat = NoteRowToBeat(seg->m_iStartRow); + float fBeat = seg->GetBeat(); if( IS_ON_SCREEN(fBeat) ) - DrawLabelText( fBeat, seg->m_sLabel ); + DrawLabelText( fBeat, seg->GetLabel() ); } } diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index 051ae94806..8f8e32d86c 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -152,7 +152,7 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo w.Init( "LABELS" ); FOREACH_CONST( LabelSegment, timing.m_LabelSegments, ls ) - w.Write( ls->m_iStartRow, ls->m_sLabel.c_str() ); + w.Write( ls->GetRow(), ls->GetLabel().c_str() ); w.Finish(); } diff --git a/src/TimingData.cpp b/src/TimingData.cpp index f59dda63bf..3e267852cc 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -248,20 +248,20 @@ void TimingData::SetLabelAtRow( int iRow, const RString sLabel ) { unsigned i; for( i=0; i= iRow ) + if( m_LabelSegments[i].GetRow() >= iRow ) break; - if( i == m_LabelSegments.size() || m_LabelSegments[i].m_iStartRow != iRow ) + if( i == m_LabelSegments.size() || m_LabelSegments[i].GetRow() != iRow ) { - if( i == 0 || m_LabelSegments[i-1].m_sLabel != sLabel ) + if( i == 0 || m_LabelSegments[i-1].GetLabel() != sLabel ) AddLabelSegment( LabelSegment(iRow, sLabel ) ); } else { - if( i > 0 && ( m_LabelSegments[i-1].m_sLabel == sLabel || sLabel == "" ) ) + if( i > 0 && ( m_LabelSegments[i-1].GetLabel() == sLabel || sLabel == "" ) ) m_LabelSegments.erase( m_LabelSegments.begin()+i, m_LabelSegments.begin()+i+1 ); else - m_LabelSegments[i].m_sLabel = sLabel; + m_LabelSegments[i].SetLabel(sLabel); } } @@ -403,7 +403,7 @@ int TimingData::GetComboAtRow( int iNoteRow ) const RString TimingData::GetLabelAtRow( int iRow ) const { - return m_LabelSegments[GetLabelSegmentIndexAtRow( iRow )].m_sLabel; + return m_LabelSegments[GetLabelSegmentIndexAtRow( iRow )].GetLabel(); } float TimingData::GetWarpAtRow( int iWarpRow ) const @@ -610,7 +610,7 @@ int TimingData::GetLabelSegmentIndexAtRow( int iRow ) const for( i=0; i iRow ) + if( s.GetRow() > iRow ) break; } return static_cast(i); @@ -694,7 +694,7 @@ LabelSegment& TimingData::GetLabelSegmentAtRow( int iRow ) { unsigned i; for( i=0; i iRow ) + if( m_LabelSegments[i+1].GetRow() > iRow ) break; return m_LabelSegments[i]; } @@ -758,11 +758,11 @@ float TimingData::GetPreviousLabelSegmentBeatAtRow( int iRow ) const float backup = -1; for (unsigned i = 0; i < m_LabelSegments.size(); i++ ) { - if( m_LabelSegments[i].m_iStartRow >= iRow ) + if( m_LabelSegments[i].GetRow() >= iRow ) { break; } - backup = NoteRowToBeat(m_LabelSegments[i].m_iStartRow); + backup = m_LabelSegments[i].GetBeat(); } return (backup > -1) ? backup : NoteRowToBeat(iRow); } @@ -771,11 +771,11 @@ float TimingData::GetNextLabelSegmentBeatAtRow( int iRow ) const { for (unsigned i = 0; i < m_LabelSegments.size(); i++ ) { - if( m_LabelSegments[i].m_iStartRow <= iRow ) + if( m_LabelSegments[i].GetRow() <= iRow ) { continue; } - return NoteRowToBeat(m_LabelSegments[i].m_iStartRow); + return m_LabelSegments[i].GetBeat(); } return NoteRowToBeat(iRow); } @@ -784,7 +784,7 @@ bool TimingData::DoesLabelExist( RString sLabel ) const { FOREACH_CONST( LabelSegment, m_LabelSegments, seg ) { - if( seg->m_sLabel == sLabel ) + if( seg->GetLabel() == sLabel ) return true; } return false; @@ -1097,13 +1097,14 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool for ( unsigned i = 0; i < m_LabelSegments.size(); i++ ) { - const int iSegStart = m_LabelSegments[i].m_iStartRow; + LabelSegment &l = m_LabelSegments[i]; + const int iSegStart = l.GetRow(); if( iSegStart < iStartIndex ) continue; else if( iSegStart > iEndIndex ) - m_LabelSegments[i].m_iStartRow += lrintf( (iEndIndex - iStartIndex) * (fScale - 1) ); + l.SetRow(l.GetRow() + lrintf( (iEndIndex - iStartIndex) * (fScale - 1) )); else - m_LabelSegments[i].m_iStartRow = lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex; + l.SetRow(lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex); } for ( unsigned i = 0; i < m_SpeedSegments.size(); i++ ) @@ -1228,9 +1229,9 @@ void TimingData::InsertRows( int iStartRow, int iRowsToAdd ) for( unsigned i = 0; i < m_LabelSegments.size(); i++ ) { LabelSegment &labl = m_LabelSegments[i]; - if( labl.m_iStartRow < iStartRow ) + if( labl.GetRow() < iStartRow ) continue; - labl.m_iStartRow += iRowsToAdd; + labl.SetRow(labl.GetRow() + iRowsToAdd); } for( unsigned i = 0; i < m_SpeedSegments.size(); i++ ) @@ -1398,17 +1399,17 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) for( unsigned i = 0; i < m_LabelSegments.size(); i++ ) { LabelSegment &labl = m_LabelSegments[i]; - - if( labl.m_iStartRow < iStartRow ) + int keyRow = labl.GetRow(); + if( keyRow < iStartRow ) continue; - if( labl.m_iStartRow < iStartRow+iRowsToDelete ) + if( keyRow < iStartRow+iRowsToDelete ) { m_LabelSegments.erase( m_LabelSegments.begin()+i, m_LabelSegments.begin()+i+1 ); --i; continue; } - labl.m_iStartRow -= iRowsToDelete; + labl.SetRow(keyRow - iRowsToDelete); } for( unsigned i = 0; i < m_SpeedSegments.size(); i++ ) @@ -1693,8 +1694,8 @@ public: vector vLabels; FOREACH_CONST( LabelSegment, p->m_LabelSegments, seg ) { - const float fStartRow = NoteRowToBeat(seg->m_iStartRow); - const RString sLabel = seg->m_sLabel; + const float fStartRow = seg->GetBeat(); + const RString sLabel = seg->GetLabel(); vLabels.push_back( ssprintf("%f=%s", fStartRow, sLabel.c_str()) ); } LuaHelpers::CreateTableFromArray(vLabels, L); diff --git a/src/TimingData.h b/src/TimingData.h index aad3b22eab..f39ce7a139 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -385,89 +385,6 @@ struct ComboSegment bool operator>=( const ComboSegment &other ) const { return !operator<(other); } }; -/** - * @brief Identifies when a chart is entering a different section. - * - * This is meant for helping to identify different sections of a chart - * versus relying on measures and beats alone. - */ -struct LabelSegment -{ - /** - * @brief Creates a simple Label Segment with default values. - * - * It is best to override the values as soon as possible. - */ - LabelSegment() : m_iStartRow(-1), m_sLabel("") { } - /** - * @brief Creates a Label Segment with the specified starting row and label. - * @param s the starting row of this segment. - * @param l the label for this section. - */ - LabelSegment( int s, RString l ): m_iStartRow(max(0, s)), - m_sLabel(l) {} - /** - * @brief Creates a Label Segment with the specified starting beat and label. - * @param s the starting beat of this segment. - * @param l the label for this section. - */ - LabelSegment( float s, RString l ): - m_iStartRow(max(0, BeatToNoteRow(s))), m_sLabel(l) {} - /** - * @brief The row in which the ComboSegment activates. - */ - int m_iStartRow; - /** - * @brief The label/section name for this point. - */ - RString m_sLabel; - - /** - * @brief Compares two LabelSegments to see if they are equal to each other. - * @param other the other LabelSegment to compare to. - * @return the equality of the two segments. - */ - bool operator==( const LabelSegment &other ) const - { - COMPARE( m_iStartRow ); - COMPARE( m_sLabel ); - return true; - } - /** - * @brief Compares two LabelSegments to see if they are not equal to each other. - * @param other the other LabelSegment to compare to. - * @return the inequality of the two segments. - */ - bool operator!=( const LabelSegment &other ) const { return !operator==(other); } - /** - * @brief Compares two LabelSegments to see if one is less than the other. - * @param other the other LabelSegment to compare to. - * @return the truth/falsehood of if the first is less than the second. - */ - bool operator<( const LabelSegment &other ) const { return m_iStartRow < other.m_iStartRow; } - /** - * @brief Compares two LabelSegments to see if one is less than or equal to the other. - * @param other the other LabelSegment to compare to. - * @return the truth/falsehood of if the first is less or equal to than the second. - */ - bool operator<=( const LabelSegment &other ) const - { - return ( operator<(other) || operator==(other) ); - } - /** - * @brief Compares two LabelSegments to see if one is greater than the other. - * @param other the other LabelSegment to compare to. - * @return the truth/falsehood of if the first is greater than the second. - */ - bool operator>( const LabelSegment &other ) const { return !operator<=(other); } - /** - * @brief Compares two LabelSegments to see if one is greater than or equal to the other. - * @param other the other LabelSegment to compare to. - * @return the truth/falsehood of if the first is greater than or equal to the second. - */ - bool operator>=( const LabelSegment &other ) const { return !operator<(other); } -}; - /** * @brief Identifies when the arrow scroll changes. * diff --git a/src/TimingSegments.cpp b/src/TimingSegments.cpp index 38550ee137..ed7b96637e 100644 --- a/src/TimingSegments.cpp +++ b/src/TimingSegments.cpp @@ -89,6 +89,23 @@ bool TickcountSegment::operator<( const TickcountSegment &other ) const return false; } +RString LabelSegment::GetLabel() const +{ + return this->label; +} + +void LabelSegment::SetLabel(const RString l) +{ + this->label = l; +} + +bool LabelSegment::operator<( const LabelSegment &other ) const +{ + LTCOMPARE(GetRow()); + LTCOMPARE(GetLabel()); + return false; +} + /** * @file * @author Jason Felds (c) 2011 diff --git a/src/TimingSegments.h b/src/TimingSegments.h index c5c0c31f81..7beed060fe 100644 --- a/src/TimingSegments.h +++ b/src/TimingSegments.h @@ -283,6 +283,56 @@ private: int ticks; }; +/** + * @brief Identifies when a chart is entering a different section. + * + * This is meant for helping to identify different sections of a chart + * versus relying on measures and beats alone. + */ +struct LabelSegment : public TimingSegment +{ + /** + * @brief Creates a simple Label Segment with default values. + * + * It is best to override the values as soon as possible. + */ + LabelSegment() : + TimingSegment(), label("") { } + /** + * @brief Creates a Label Segment with the specified values. + * @param s the starting row / beat of this segment. + * @param l the label for this section. + */ + template + LabelSegment( StartType s, RString l ): + TimingSegment(max((StartType)0, s)), + label(l) {} + + /** + * @brief Get the label in this LabelSegment. + * @return the label. */ + RString GetLabel() const; + + /** + * @brief Set the label in this LabelSegment. + * @param l the label. */ + void SetLabel(const RString l); + + /** + * @brief Compares two LabelSegments to see if one is less than the other. + * @param other the other LabelSegment to compare to. + * @return the truth/falsehood of if the first is less than the second. + */ + bool operator<( const LabelSegment &other ) const; + +private: + /** + * @brief The label/section name for this point. + */ + RString label; +}; + + #undef COMPARE From 714427f154d323bcf4ebef0fef81f44d726c6084 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 31 May 2011 11:45:25 -0400 Subject: [PATCH 12/27] ComboSegments brought in. Five to go I believe. --- src/NoteField.cpp | 6 ++-- src/NotesWriterSSC.cpp | 2 +- src/ScoreKeeperNormal.cpp | 4 +-- src/TimingData.cpp | 35 +++++++++--------- src/TimingData.h | 76 --------------------------------------- src/TimingSegments.cpp | 17 +++++++++ src/TimingSegments.h | 49 +++++++++++++++++++++++++ 7 files changed, 90 insertions(+), 99 deletions(-) diff --git a/src/NoteField.cpp b/src/NoteField.cpp index 2e05aac08b..0385dee466 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -960,11 +960,11 @@ void NoteField::DrawPrimitives() // Combo text FOREACH_CONST( ComboSegment, timing.m_ComboSegments, seg ) { - if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) + if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw ) { - float fBeat = NoteRowToBeat(seg->m_iStartRow); + float fBeat = seg->GetBeat(); if( IS_ON_SCREEN(fBeat) ) - DrawComboText( fBeat, seg->m_iCombo ); + DrawComboText( fBeat, seg->GetCombo() ); } } } diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index 8f8e32d86c..8ab6b71d52 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -128,7 +128,7 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo ASSERT( !timing.m_ComboSegments.empty() ); w.Init( "COMBOS" ); FOREACH_CONST( ComboSegment, timing.m_ComboSegments, cs ) - w.Write( cs->m_iStartRow, cs->m_iCombo ); + w.Write( cs->GetRow(), cs->GetCombo() ); w.Finish(); // Song Timing should only have the initial value. diff --git a/src/ScoreKeeperNormal.cpp b/src/ScoreKeeperNormal.cpp index 8106effb3a..ce3874aa5a 100644 --- a/src/ScoreKeeperNormal.cpp +++ b/src/ScoreKeeperNormal.cpp @@ -445,7 +445,7 @@ void ScoreKeeperNormal::HandleComboInternal( int iNumHitContinueCombo, int iNumH if( iNumBreakCombo == 0 ) { TimingData td = GAMESTATE->m_pCurSteps[m_pPlayerState->m_PlayerNumber]->m_Timing; - int multiplier = ( iRow == -1 ? 1 : td.GetComboSegmentAtRow( iRow ).m_iCombo ); + int multiplier = ( iRow == -1 ? 1 : td.GetComboSegmentAtRow( iRow ).GetCombo() ); m_pPlayerStageStats->m_iCurCombo += iNumHitContinueCombo * multiplier; } else @@ -465,7 +465,7 @@ void ScoreKeeperNormal::HandleRowComboInternal( TapNoteScore tns, int iNumTapsIn { m_pPlayerStageStats->m_iCurMissCombo = 0; TimingData td = GAMESTATE->m_pCurSteps[m_pPlayerState->m_PlayerNumber]->m_Timing; - int multiplier = ( iRow == -1 ? 1 : td.GetComboSegmentAtRow( iRow ).m_iCombo ); + int multiplier = ( iRow == -1 ? 1 : td.GetComboSegmentAtRow( iRow ).GetCombo() ); m_pPlayerStageStats->m_iCurCombo += iNumTapsInRow * multiplier; } else if ( tns < m_MinScoreToMaintainCombo ) diff --git a/src/TimingData.cpp b/src/TimingData.cpp index 3e267852cc..a7ae78db9b 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -227,20 +227,20 @@ void TimingData::SetComboAtRow( int iRow, int iCombo ) { unsigned i; for( i=0; i= iRow ) + if( m_ComboSegments[i].GetRow() >= iRow ) break; - if( i == m_ComboSegments.size() || m_ComboSegments[i].m_iStartRow != iRow ) + if( i == m_ComboSegments.size() || m_ComboSegments[i].GetRow() != iRow ) { - if( i == 0 || m_ComboSegments[i-1].m_iCombo != iCombo ) + if( i == 0 || m_ComboSegments[i-1].GetCombo() != iCombo ) AddComboSegment( ComboSegment(iRow, iCombo ) ); } else { - if( i > 0 && m_ComboSegments[i-1].m_iCombo == iCombo ) + if( i > 0 && m_ComboSegments[i-1].GetCombo() == iCombo ) m_ComboSegments.erase( m_ComboSegments.begin()+i, m_ComboSegments.begin()+i+1 ); else - m_ComboSegments[i].m_iCombo = iCombo; + m_ComboSegments[i].SetCombo(iCombo); } } @@ -398,7 +398,7 @@ float TimingData::GetDelayAtRow( int iRow ) const int TimingData::GetComboAtRow( int iNoteRow ) const { - return m_ComboSegments[GetComboSegmentIndexAtRow( iNoteRow )].m_iCombo; + return m_ComboSegments[GetComboSegmentIndexAtRow( iNoteRow )].GetCombo(); } RString TimingData::GetLabelAtRow( int iRow ) const @@ -598,7 +598,7 @@ int TimingData::GetComboSegmentIndexAtRow( int iRow ) const for( i=0; i iRow ) + if( s.GetRow() > iRow ) break; } return static_cast(i); @@ -685,7 +685,7 @@ ComboSegment& TimingData::GetComboSegmentAtRow( int iRow ) { unsigned i; for( i=0; i iRow ) + if( m_ComboSegments[i+1].GetRow() > iRow ) break; return m_ComboSegments[i]; } @@ -1086,13 +1086,14 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool for ( unsigned i = 0; i < m_ComboSegments.size(); i++ ) { - const int iSegStart = m_ComboSegments[i].m_iStartRow; + ComboSegment &c = m_ComboSegments[i]; + const int iSegStart = c.GetRow(); if( iSegStart < iStartIndex ) continue; else if( iSegStart > iEndIndex ) - m_ComboSegments[i].m_iStartRow += lrintf( (iEndIndex - iStartIndex) * (fScale - 1) ); + c.SetRow(c.GetRow() + lrintf( (iEndIndex - iStartIndex) * (fScale - 1) )); else - m_ComboSegments[i].m_iStartRow = lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex; + c.SetRow(lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex); } for ( unsigned i = 0; i < m_LabelSegments.size(); i++ ) @@ -1222,9 +1223,9 @@ void TimingData::InsertRows( int iStartRow, int iRowsToAdd ) for( unsigned i = 0; i < m_ComboSegments.size(); i++ ) { ComboSegment &comb = m_ComboSegments[i]; - if( comb.m_iStartRow < iStartRow ) + if( comb.GetRow() < iStartRow ) continue; - comb.m_iStartRow += iRowsToAdd; + comb.SetRow(comb.GetRow() + iRowsToAdd); } for( unsigned i = 0; i < m_LabelSegments.size(); i++ ) { @@ -1379,13 +1380,13 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) for( unsigned i = 0; i < m_ComboSegments.size(); i++ ) { ComboSegment &comb = m_ComboSegments[i]; - + int keyRow = comb.GetRow(); // Before deleted region: - if( comb.m_iStartRow < iStartRow ) + if( keyRow < iStartRow ) continue; // Inside deleted region: - if( comb.m_iStartRow < iStartRow+iRowsToDelete ) + if( keyRow < iStartRow+iRowsToDelete ) { m_ComboSegments.erase( m_ComboSegments.begin()+i, m_ComboSegments.begin()+i+1 ); --i; @@ -1393,7 +1394,7 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) } // After deleted region: - comb.m_iStartRow -= iRowsToDelete; + comb.SetRow(keyRow - iRowsToDelete); } for( unsigned i = 0; i < m_LabelSegments.size(); i++ ) diff --git a/src/TimingData.h b/src/TimingData.h index f39ce7a139..2fab07ecca 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -309,82 +309,6 @@ struct TimeSignatureSegment bool operator>= (const TimeSignatureSegment &other ) const { return !operator<(other); } }; -/** - * @brief Identifies when a chart is to have a different combo multiplier value. - * - * Admitedly, this would primarily be used for mission mode style charts. However, - * it can have its place during normal gameplay. - */ -struct ComboSegment -{ - /** - * @brief Creates a simple Combo Segment with default values. - * - * It is best to override the values as soon as possible. - */ - ComboSegment() : m_iStartRow(-1), m_iCombo(1) { } - /** - * @brief Creates a Combo Segment with the specified starting row and combo factor. - * @param s the starting row of this segment. - * @param t the amount the combo increases on a succesful hit. - */ - ComboSegment( int s, int t ): m_iStartRow(max(0, s)), - m_iCombo(max(0,t)) {} - /** - * @brief The row in which the ComboSegment activates. - */ - int m_iStartRow; - /** - * @brief The amount the combo increases at this point. - */ - int m_iCombo; - - /** - * @brief Compares two ComboSegments to see if they are equal to each other. - * @param other the other ComboSegment to compare to. - * @return the equality of the two segments. - */ - bool operator==( const ComboSegment &other ) const - { - COMPARE( m_iStartRow ); - COMPARE( m_iCombo ); - return true; - } - /** - * @brief Compares two ComboSegments to see if they are not equal to each other. - * @param other the other ComboSegment to compare to. - * @return the inequality of the two segments. - */ - bool operator!=( const ComboSegment &other ) const { return !operator==(other); } - /** - * @brief Compares two ComboSegments to see if one is less than the other. - * @param other the other ComboSegment to compare to. - * @return the truth/falsehood of if the first is less than the second. - */ - bool operator<( const ComboSegment &other ) const { return m_iStartRow < other.m_iStartRow; } - /** - * @brief Compares two ComboSegments to see if one is less than or equal to the other. - * @param other the other ComboSegment to compare to. - * @return the truth/falsehood of if the first is less or equal to than the second. - */ - bool operator<=( const ComboSegment &other ) const - { - return ( operator<(other) || operator==(other) ); - } - /** - * @brief Compares two ComboSegments to see if one is greater than the other. - * @param other the other ComboSegment to compare to. - * @return the truth/falsehood of if the first is greater than the second. - */ - bool operator>( const ComboSegment &other ) const { return !operator<=(other); } - /** - * @brief Compares two ComboSegments to see if one is greater than or equal to the other. - * @param other the other ComboSegment to compare to. - * @return the truth/falsehood of if the first is greater than or equal to the second. - */ - bool operator>=( const ComboSegment &other ) const { return !operator<(other); } -}; - /** * @brief Identifies when the arrow scroll changes. * diff --git a/src/TimingSegments.cpp b/src/TimingSegments.cpp index ed7b96637e..73d5c1919d 100644 --- a/src/TimingSegments.cpp +++ b/src/TimingSegments.cpp @@ -89,6 +89,23 @@ bool TickcountSegment::operator<( const TickcountSegment &other ) const return false; } +int ComboSegment::GetCombo() const +{ + return this->combo; +} + +void ComboSegment::SetCombo(const int i) +{ + this->combo = i; +} + +bool ComboSegment::operator<( const ComboSegment &other ) const +{ + LTCOMPARE(GetRow()); + LTCOMPARE(GetCombo()); + return false; +} + RString LabelSegment::GetLabel() const { return this->label; diff --git a/src/TimingSegments.h b/src/TimingSegments.h index 7beed060fe..f9f2b37add 100644 --- a/src/TimingSegments.h +++ b/src/TimingSegments.h @@ -283,6 +283,55 @@ private: int ticks; }; +/** + * @brief Identifies when a chart is to have a different combo multiplier value. + * + * Admitedly, this would primarily be used for mission mode style charts. However, + * it can have its place during normal gameplay. + */ +struct ComboSegment : public TimingSegment +{ + /** + * @brief Creates a simple Combo Segment with default values. + * + * It is best to override the values as soon as possible. + */ + ComboSegment() : + TimingSegment(), combo(1) { } + /** + * @brief Creates a Combo Segment with the specified values. + * @param s the starting row / beat of this segment. + * @param t the amount the combo increases on a succesful hit. + */ + template + ComboSegment( StartType s, int t ): + TimingSegment(max((StartType)0, s)), + combo(max(0,t)) {} + + /** + * @brief Get the combo in this ComboSegment. + * @return the combo. */ + int GetCombo() const; + + /** + * @brief Set the combo in this ComboSegment. + * @param i the combo. */ + void SetCombo(const int i); + + /** + * @brief Compares two ComboSegments to see if one is less than the other. + * @param other the other ComboSegment to compare to. + * @return the truth/falsehood of if the first is less than the second. + */ + bool operator<( const ComboSegment &other ) const; +private: + /** + * @brief The amount the combo increases at this point. + */ + int combo; +}; + + /** * @brief Identifies when a chart is entering a different section. * From 1d2dd19ab14df0134dbd9ff4f64a76b7f9ebb0b5 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Tue, 31 May 2011 23:41:39 +0700 Subject: [PATCH 13/27] Yeah, BPM segments, big one :D --- src/Background.cpp | 6 +-- src/NoteField.cpp | 4 +- src/NotesLoaderJson.cpp | 4 +- src/NotesLoaderMidi.cpp | 4 +- src/NotesLoaderPMS.cpp | 2 +- src/NotesWriterDWI.cpp | 4 +- src/NotesWriterJson.cpp | 4 +- src/NotesWriterSM.cpp | 2 +- src/NotesWriterSSC.cpp | 2 +- src/ScreenSyncOverlay.cpp | 2 +- src/TimingData.cpp | 65 +++++++++++++++-------------- src/TimingData.h | 86 +-------------------------------------- src/TimingSegments.cpp | 42 +++++++++++++++++++ src/TimingSegments.h | 58 ++++++++++++++++++++++++++ 14 files changed, 150 insertions(+), 135 deletions(-) diff --git a/src/Background.cpp b/src/Background.cpp index 8c5a64c5fa..d8cef11d4e 100644 --- a/src/Background.cpp +++ b/src/Background.cpp @@ -450,7 +450,7 @@ void BackgroundImpl::LoadFromRandom( float fFirstBeat, float fEndBeat, const Bac bool bAtBeginningOfMeasure = false; FOREACH_CONST( TimeSignatureSegment, timing.m_vTimeSignatureSegments, iter ) { - if( (bpmseg.m_iStartRow - iter->m_iStartRow) % iter->GetNoteRowsPerMeasure() == 0 ) + if( (bpmseg.GetRow() - iter->m_iStartRow) % iter->GetNoteRowsPerMeasure() == 0 ) { bAtBeginningOfMeasure = true; break; @@ -461,7 +461,7 @@ void BackgroundImpl::LoadFromRandom( float fFirstBeat, float fEndBeat, const Bac continue; // skip // start so that we don't create a BGChange right on top of fEndBeat - bool bInRange = bpmseg.m_iStartRow >= iStartRow && bpmseg.m_iStartRow < iEndRow; + bool bInRange = bpmseg.GetRow() >= iStartRow && bpmseg.GetRow() < iEndRow; if( !bInRange ) continue; // skip @@ -471,7 +471,7 @@ void BackgroundImpl::LoadFromRandom( float fFirstBeat, float fEndBeat, const Bac BackgroundChange c = change; c.m_def.m_sFile1 = bd.m_sFile1; c.m_def.m_sFile2 = bd.m_sFile2; - c.m_fStartBeat = NoteRowToBeat(bpmseg.m_iStartRow); + c.m_fStartBeat = bpmseg.GetBeat(); m_Layer[0].m_aBGChanges.push_back( c ); } } diff --git a/src/NoteField.cpp b/src/NoteField.cpp index 0385dee466..3abb6bf177 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -899,9 +899,9 @@ void NoteField::DrawPrimitives() // BPM text FOREACH_CONST( BPMSegment, timing.m_BPMSegments, seg ) { - if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) + if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw ) { - float fBeat = NoteRowToBeat(seg->m_iStartRow); + float fBeat = seg->GetBeat(); if( IS_ON_SCREEN(fBeat) ) DrawBPMText( fBeat, seg->GetBPM() ); } diff --git a/src/NotesLoaderJson.cpp b/src/NotesLoaderJson.cpp index e460a0eaba..4478423e6b 100644 --- a/src/NotesLoaderJson.cpp +++ b/src/NotesLoaderJson.cpp @@ -17,8 +17,8 @@ void NotesLoaderJson::GetApplicableFiles( const RString &sPath, vector void Deserialize(BPMSegment &seg, const Json::Value &root) { - seg.m_iStartRow = BeatToNoteRow((float)root["Beat"].asDouble()); - seg.m_fBPS = (float)(root["BPM"].asDouble() / 60); + seg.SetBeat((float)(root["Beat"].asDouble())); + seg.SetBPM((float)(root["BPM"].asDouble())); } static void Deserialize(StopSegment &seg, const Json::Value &root) diff --git a/src/NotesLoaderMidi.cpp b/src/NotesLoaderMidi.cpp index 9673cdb14d..0d2a49b5e6 100644 --- a/src/NotesLoaderMidi.cpp +++ b/src/NotesLoaderMidi.cpp @@ -678,9 +678,9 @@ static bool LoadFromMidi( const RString &sPath, Song &songOut ) FOREACH_CONST( MidiFileIn::TempoChange, midi.tempoEvents_, iter ) { BPMSegment bpmSeg; - bpmSeg.m_iStartRow = MidiCountToNoteRow( iter->count ); + bpmSeg.SetRow( MidiCountToNoteRow( iter->count ) ); double fSecondsPerBeat = (iter->tickSeconds * GUITAR_MIDI_COUNTS_PER_BEAT); - bpmSeg.m_fBPS = float( 1. / fSecondsPerBeat ); + bpmSeg.SetBPS( float( 1. / fSecondsPerBeat ) ); songOut.m_SongTiming.AddBPMSegment( bpmSeg ); } diff --git a/src/NotesLoaderPMS.cpp b/src/NotesLoaderPMS.cpp index f9ef5bf1cc..749710abde 100644 --- a/src/NotesLoaderPMS.cpp +++ b/src/NotesLoaderPMS.cpp @@ -751,7 +751,7 @@ static void ReadGlobalTags( const NameToData_t &mapNameToData, Song &out, Measur { BPMSegment newSeg( iStepIndex, fBPM ); out.m_SongTiming.AddBPMSegment( newSeg ); - LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", NoteRowToBeat(newSeg.m_iStartRow), newSeg.GetBPM() ); + LOG->Trace( "Inserting new BPM change at beat %f, BPM %f", newSeg.GetBeat(), newSeg.GetBPM() ); } else diff --git a/src/NotesWriterDWI.cpp b/src/NotesWriterDWI.cpp index 260728a70d..4694c1f6db 100644 --- a/src/NotesWriterDWI.cpp +++ b/src/NotesWriterDWI.cpp @@ -350,7 +350,7 @@ bool NotesWriterDWI::Write( RString sPath, const Song &out ) /* Write transliterations, if we have them, since DWI doesn't support UTF-8. */ f.PutLine( ssprintf("#TITLE:%s;", DwiEscape(out.GetTranslitFullTitle()).c_str()) ); f.PutLine( ssprintf("#ARTIST:%s;", DwiEscape(out.GetTranslitArtist()).c_str()) ); - ASSERT( out.m_SongTiming.m_BPMSegments[0].m_iStartRow == 0 ); + ASSERT( out.m_SongTiming.m_BPMSegments[0].GetRow() == 0 ); f.PutLine( ssprintf("#FILE:%s;", DwiEscape(out.m_sMusicFile).c_str()) ); f.PutLine( ssprintf("#BPM:%.3f;", out.m_SongTiming.m_BPMSegments[0].GetBPM()) ); f.PutLine( ssprintf("#GAP:%ld;", -lrintf( out.m_SongTiming.m_fBeat0OffsetInSeconds*1000 )) ); @@ -395,7 +395,7 @@ bool NotesWriterDWI::Write( RString sPath, const Song &out ) for( unsigned i=1; i &lines, TimingData timing, bool bIsSo w.Init( "BPMS" ); FOREACH_CONST( BPMSegment, timing.m_BPMSegments, bs ) - w.Write( bs->m_iStartRow, bs->GetBPM() ); + w.Write( bs->GetRow(), bs->GetBPM() ); w.Finish(); w.Init( "STOPS" ); diff --git a/src/ScreenSyncOverlay.cpp b/src/ScreenSyncOverlay.cpp index 5f5d8e37f4..3596c91e70 100644 --- a/src/ScreenSyncOverlay.cpp +++ b/src/ScreenSyncOverlay.cpp @@ -222,7 +222,7 @@ bool ScreenSyncOverlay::OverlayInput( const InputEventPlus &input ) if( GAMESTATE->m_pCurSong != NULL ) { BPMSegment& seg = GAMESTATE->m_pCurSong->m_SongTiming.GetBPMSegmentAtBeat( GAMESTATE->m_Position.m_fSongBeat ); - seg.m_fBPS += fDelta; + seg.SetBPS( seg.GetBPS() + fDelta ); } } break; diff --git a/src/TimingData.cpp b/src/TimingData.cpp index a7ae78db9b..19ae6a591f 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -86,25 +86,24 @@ void TimingData::AddFakeSegment( const FakeSegment &seg ) /* Change an existing BPM segment, merge identical segments together or insert a new one. */ void TimingData::SetBPMAtRow( int iNoteRow, float fBPM ) { - float fBPS = fBPM / 60.0f; unsigned i; for( i=0; i= iNoteRow ) + if( m_BPMSegments[i].GetRow() >= iNoteRow ) break; - if( i == m_BPMSegments.size() || m_BPMSegments[i].m_iStartRow != iNoteRow ) + if( i == m_BPMSegments.size() || m_BPMSegments[i].GetRow() != iNoteRow ) { // There is no BPMSegment at the specified beat. If the BPM being set differs // from the last BPMSegment's BPM, create a new BPMSegment. - if( i == 0 || fabsf(m_BPMSegments[i-1].m_fBPS - fBPS) > 1e-5f ) + if( i == 0 || fabsf(m_BPMSegments[i-1].GetBPM() - fBPM) > 1e-5f ) AddBPMSegment( BPMSegment(iNoteRow, fBPM) ); } else // BPMSegment being modified is m_BPMSegments[i] { - if( i > 0 && fabsf(m_BPMSegments[i-1].m_fBPS - fBPS) < 1e-5f ) + if( i > 0 && fabsf(m_BPMSegments[i-1].GetBPM() - fBPM) < 1e-5f ) m_BPMSegments.erase( m_BPMSegments.begin()+i, m_BPMSegments.begin()+i+1 ); else - m_BPMSegments[i].m_fBPS = fBPS; + m_BPMSegments[i].SetBPM(fBPM); } } @@ -456,9 +455,9 @@ void TimingData::MultiplyBPMInBeatRange( int iStartIndex, int iEndIndex, float f // Change all other BPM segments in this range. for( unsigned i=0; i iStartIndex ) { BPMSegment b = m_BPMSegments[i]; - b.m_iStartRow = iStartIndexNextSegment; + b.SetRow(iStartIndexNextSegment); m_BPMSegments.insert( m_BPMSegments.begin()+i+1, b ); /* Don't apply the BPM change to the first half of the segment we @@ -480,13 +479,13 @@ void TimingData::MultiplyBPMInBeatRange( int iStartIndex, int iEndIndex, float f if( iStartIndexThisSegment < iEndIndex && iStartIndexNextSegment > iEndIndex ) { BPMSegment b = m_BPMSegments[i]; - b.m_iStartRow = iEndIndex; + b.SetRow(iEndIndex); m_BPMSegments.insert( m_BPMSegments.begin()+i+1, b ); } else if( iStartIndexNextSegment > iEndIndex ) continue; - m_BPMSegments[i].m_fBPS = m_BPMSegments[i].m_fBPS * fFactor; + m_BPMSegments[i].SetBPM(m_BPMSegments[i].GetBPM() * fFactor); } } @@ -494,7 +493,7 @@ float TimingData::GetBPMAtRow( int iNoteRow ) const { unsigned i; for( i=0; i iNoteRow ) + if( m_BPMSegments[i+1].GetRow() > iNoteRow ) break; return m_BPMSegments[i].GetBPM(); } @@ -503,7 +502,7 @@ int TimingData::GetBPMSegmentIndexAtRow( int iNoteRow ) const { unsigned i; for( i=0; i iNoteRow ) + if( m_BPMSegments[i+1].GetRow() > iNoteRow ) break; return static_cast(i); } @@ -835,9 +834,9 @@ void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float iEventRow = BeatToNoteRow(fWarpDestination); iEventType = FOUND_WARP_DESTINATION; } - if( itBPMS != m_BPMSegments.end() && itBPMS->m_iStartRow < iEventRow ) + if( itBPMS != m_BPMSegments.end() && itBPMS->GetRow() < iEventRow ) { - iEventRow = itBPMS->m_iStartRow; + iEventRow = itBPMS->GetRow(); iEventType = FOUND_BPM_CHANGE; } if( itSS != m_StopSegments.end() && itSS->m_iStartRow < iEventRow ) @@ -867,7 +866,7 @@ void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset( float fElapsedTime, float bIsWarping = false; break; case FOUND_BPM_CHANGE: - fBPS = itBPMS->m_fBPS; + fBPS = itBPMS->GetBPS(); itBPMS ++; break; case FOUND_STOP: @@ -937,9 +936,9 @@ float TimingData::GetElapsedTimeFromBeatNoOffset( float fBeat ) const iEventRow = BeatToNoteRow(fWarpDestination); iEventType = FOUND_WARP_DESTINATION; } - if( itBPMS != m_BPMSegments.end() && itBPMS->m_iStartRow < iEventRow ) + if( itBPMS != m_BPMSegments.end() && itBPMS->GetRow() < iEventRow ) { - iEventRow = itBPMS->m_iStartRow; + iEventRow = itBPMS->GetRow(); iEventType = FOUND_BPM_CHANGE; } if( itSS != m_StopSegments.end() && itSS->m_bDelay && itSS->m_iStartRow < iEventRow ) // delays (come before marker) @@ -971,7 +970,7 @@ float TimingData::GetElapsedTimeFromBeatNoOffset( float fBeat ) const bIsWarping = false; break; case FOUND_BPM_CHANGE: - fBPS = itBPMS->m_fBPS; + fBPS = itBPMS->GetBPS(); itBPMS ++; break; case FOUND_STOP: @@ -1020,13 +1019,13 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool for ( unsigned i = 0; i < m_BPMSegments.size(); i++ ) { - const int iSegStart = m_BPMSegments[i].m_iStartRow; + const int iSegStart = m_BPMSegments[i].GetRow(); if( iSegStart < iStartIndex ) continue; else if( iSegStart > iEndIndex ) - m_BPMSegments[i].m_iStartRow += lrintf( (iEndIndex - iStartIndex) * (fScale - 1) ); + m_BPMSegments[i].SetRow( m_BPMSegments[i].GetRow() + lrintf( (iEndIndex - iStartIndex) * (fScale - 1) ) ); else - m_BPMSegments[i].m_iStartRow = lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex; + m_BPMSegments[i].SetRow( lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex ); } for( unsigned i = 0; i < m_StopSegments.size(); i++ ) @@ -1161,13 +1160,13 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool // adjust BPM changes "between" iStartIndex and iNewEndIndex for ( unsigned i = 0; i < m_BPMSegments.size(); i++ ) { - const int iSegStart = m_BPMSegments[i].m_iStartRow; + const int iSegStart = m_BPMSegments[i].GetRow(); if( iSegStart <= iStartIndex ) continue; else if( iSegStart >= iNewEndIndex ) continue; else - m_BPMSegments[i].m_fBPS *= fScale; + m_BPMSegments[i].SetBPM( m_BPMSegments[i].GetBPM() * fScale ); } // set BPM at iStartIndex and iNewEndIndex. @@ -1183,9 +1182,9 @@ void TimingData::InsertRows( int iStartRow, int iRowsToAdd ) for( unsigned i = 0; i < m_BPMSegments.size(); i++ ) { BPMSegment &bpm = m_BPMSegments[i]; - if( bpm.m_iStartRow < iStartRow ) + if( bpm.GetRow() < iStartRow ) continue; - bpm.m_iStartRow += iRowsToAdd; + bpm.SetRow( bpm.GetRow() + iRowsToAdd ); } for( unsigned i = 0; i < m_StopSegments.size(); i++ ) @@ -1264,7 +1263,7 @@ void TimingData::InsertRows( int iStartRow, int iRowsToAdd ) /* If we're shifting up at the beginning, we just shifted up the first * BPMSegment. That segment must always begin at 0. */ ASSERT( m_BPMSegments.size() > 0 ); - m_BPMSegments[0].m_iStartRow = 0; + m_BPMSegments[0].SetRow(0); } } @@ -1281,11 +1280,11 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) BPMSegment &bpm = m_BPMSegments[i]; // Before deleted region: - if( bpm.m_iStartRow < iStartRow ) + if( bpm.GetRow() < iStartRow ) continue; // Inside deleted region: - if( bpm.m_iStartRow < iStartRow+iRowsToDelete ) + if( bpm.GetRow() < iStartRow+iRowsToDelete ) { m_BPMSegments.erase( m_BPMSegments.begin()+i, m_BPMSegments.begin()+i+1 ); --i; @@ -1293,7 +1292,7 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) } // After deleted region: - bpm.m_iStartRow -= iRowsToDelete; + bpm.SetRow( bpm.GetRow() - iRowsToDelete ); } for( unsigned i = 0; i < m_StopSegments.size(); i++ ) @@ -1520,8 +1519,8 @@ void TimingData::TidyUpData() } // Make sure the first BPM segment starts at beat 0. - if( m_BPMSegments[0].m_iStartRow != 0 ) - m_BPMSegments[0].m_iStartRow = 0; + if( m_BPMSegments[0].GetRow() != 0 ) + m_BPMSegments[0].SetRow(0); // If no time signature specified, assume 4/4 time for the whole song. if( m_vTimeSignatureSegments.empty() ) @@ -1707,7 +1706,7 @@ public: vector vBPMs; FOREACH_CONST( BPMSegment, p->m_BPMSegments, seg ) { - const float fStartRow = NoteRowToBeat(seg->m_iStartRow); + const float fStartRow = seg->GetBeat(); const float fBPM = seg->GetBPM(); vBPMs.push_back( ssprintf("%f=%f", fStartRow, fBPM) ); } diff --git a/src/TimingData.h b/src/TimingData.h index 2fab07ecca..8c66e205f8 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -9,92 +9,8 @@ struct lua_State; /** @brief Compare a TimingData segment's properties with one another. */ #define COMPARE(x) if(x!=other.x) return false; -/** - * @brief Identifies when a song changes its BPM. - */ -struct BPMSegment -{ - /** - * @brief Creates a simple BPM Segment with default values. - * - * It is best to override the values as soon as possible. - */ - BPMSegment() : m_iStartRow(-1), m_fBPS(-1.0f) { } - /** - * @brief Creates a BPM Segment with the specified starting row and beats per second. - * @param s the starting row of this segment. - * @param b the beats per second to be turned into beats per minute. - */ - BPMSegment( int s, float b ): m_iStartRow(max(0, s)), m_fBPS(0) { SetBPM( b ); } - /** - * @brief The row in which the BPMSegment activates. - */ - int m_iStartRow; - /** - * @brief The BPS to use when this row is reached. - */ - float m_fBPS; - - /** - * @brief Converts the BPS to a BPM. - * @param f The BPM. - */ - void SetBPM( float f ) { m_fBPS = f / 60.0f; } - /** - * @brief Retrieves the BPM from the BPS. - * @return the BPM. - */ - float GetBPM() const { return m_fBPS * 60.0f; } - /** - * @brief Compares two BPMSegments to see if they are equal to each other. - * @param other the other BPMSegment to compare to. - * @return the equality of the two segments. - */ - bool operator==( const BPMSegment &other ) const - { - COMPARE( m_iStartRow ); - COMPARE( m_fBPS ); - return true; - } - /** - * @brief Compares two BPMSegments to see if they are not equal to each other. - * @param other the other BPMSegment to compare to. - * @return the inequality of the two segments. - */ - bool operator!=( const BPMSegment &other ) const { return !operator==(other); } - /** - * @brief Compares two BPMSegments to see if one is less than the other. - * @param other the other BPMSegment to compare to. - * @return the truth/falsehood of if the first is less than the second. - */ - bool operator<( const BPMSegment &other ) const - { - return m_iStartRow < other.m_iStartRow || - ( m_iStartRow == other.m_iStartRow && m_fBPS < other.m_fBPS ); - } - /** - * @brief Compares two BPMSegments to see if one is less than or equal to the other. - * @param other the other BPMSegment to compare to. - * @return the truth/falsehood of if the first is less or equal to than the second. - */ - bool operator<=( const BPMSegment &other ) const - { - return ( operator<(other) || operator==(other) ); - } - /** - * @brief Compares two BPMSegments to see if one is greater than the other. - * @param other the other BPMSegment to compare to. - * @return the truth/falsehood of if the first is greater than the second. - */ - bool operator>( const BPMSegment &other ) const { return !operator<=(other); } - /** - * @brief Compares two BPMSegments to see if one is greater than or equal to the other. - * @param other the other BPMSegment to compare to. - * @return the truth/falsehood of if the first is greater than or equal to the second. - */ - bool operator>=( const BPMSegment &other ) const { return !operator<(other); } -}; + /** * @brief Identifies when a song has a stop or a delay. * diff --git a/src/TimingSegments.cpp b/src/TimingSegments.cpp index 73d5c1919d..dadb2efd9c 100644 --- a/src/TimingSegments.cpp +++ b/src/TimingSegments.cpp @@ -53,6 +53,9 @@ bool FakeSegment::operator<( const FakeSegment &other ) const return false; } + + + float WarpSegment::GetLength() const { return this->lengthBeats; @@ -72,6 +75,7 @@ bool WarpSegment::operator<( const WarpSegment &other ) const + int TickcountSegment::GetTicks() const { return this->ticks; @@ -89,6 +93,9 @@ bool TickcountSegment::operator<( const TickcountSegment &other ) const return false; } + + + int ComboSegment::GetCombo() const { return this->combo; @@ -106,6 +113,9 @@ bool ComboSegment::operator<( const ComboSegment &other ) const return false; } + + + RString LabelSegment::GetLabel() const { return this->label; @@ -123,6 +133,38 @@ bool LabelSegment::operator<( const LabelSegment &other ) const return false; } + + +float BPMSegment::GetBPM() const +{ + return this->bps * 60.0f; +} + +void BPMSegment::SetBPM(const float bpm) +{ + this->bps = bpm / 60.0f; +} + +float BPMSegment::GetBPS() const +{ + return this->bps; +} + +void BPMSegment::SetBPS(const float newBPS) +{ + this->bps = newBPS; +} + +bool BPMSegment::operator<( const BPMSegment &other ) const +{ + LTCOMPARE(GetRow()); + LTCOMPARE(GetBPM()); + return false; +} + + + + /** * @file * @author Jason Felds (c) 2011 diff --git a/src/TimingSegments.h b/src/TimingSegments.h index f9f2b37add..f901973458 100644 --- a/src/TimingSegments.h +++ b/src/TimingSegments.h @@ -383,6 +383,64 @@ private: +/** + * @brief Identifies when a song changes its BPM. + */ +struct BPMSegment : public TimingSegment +{ + /** + * @brief Creates a simple BPM Segment with default values. + * + * It is best to override the values as soon as possible. + */ + BPMSegment() : + TimingSegment(), bps(-1.0f) { } + + /** + * @brief Creates a BPM Segment with the specified starting row and beats per second. + * @param s the starting row / beat of this segment. + * @param b the beats per minute to be turned into beats per second. + */ + template + BPMSegment( StartType s, float bpm ): + TimingSegment(max((StartType)0, s)), bps(0.0f) { SetBPM(bpm); } + + /** + * @brief Get the label in this LabelSegment. + * @return the label. */ + float GetBPM() const; + + /** + * @brief Set the label in this LabelSegment. + * @param l the label. */ + void SetBPM(const float bpm); + + /** + * @brief Get the label in this LabelSegment. + * @return the label. */ + float GetBPS() const; + + /** + * @brief Set the label in this LabelSegment. + * @param l the label. */ + void SetBPS(const float newBPS); + + /** + * @brief Compares two LabelSegments to see if one is less than the other. + * @param other the other LabelSegment to compare to. + * @return the truth/falsehood of if the first is less than the second. + */ + bool operator<( const BPMSegment &other ) const; + +private: + /** + * @brief The label/section name for this point. + */ + float bps; +}; + + + #undef COMPARE From 642ec5ac811829f078600fc1f9c6b8ecb9c8422d Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 31 May 2011 14:04:35 -0400 Subject: [PATCH 14/27] Minor cleanup before I dive back into segments. --- src/TimingData.cpp | 35 ++++++++++++++++++++--------------- src/TimingSegments.cpp | 2 +- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/TimingData.cpp b/src/TimingData.cpp index 19ae6a591f..0bf1a8f794 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -1019,35 +1019,38 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool for ( unsigned i = 0; i < m_BPMSegments.size(); i++ ) { - const int iSegStart = m_BPMSegments[i].GetRow(); + BPMSegment &b = m_BPMSegments[i]; + const int iSegStart = b.GetRow(); if( iSegStart < iStartIndex ) continue; else if( iSegStart > iEndIndex ) - m_BPMSegments[i].SetRow( m_BPMSegments[i].GetRow() + lrintf( (iEndIndex - iStartIndex) * (fScale - 1) ) ); + b.SetRow( b.GetRow() + lrintf( (iEndIndex - iStartIndex) * (fScale - 1) ) ); else - m_BPMSegments[i].SetRow( lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex ); + b.SetRow( lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex ); } for( unsigned i = 0; i < m_StopSegments.size(); i++ ) { - const int iSegStartRow = m_StopSegments[i].m_iStartRow; + StopSegment &s = m_StopSegments[i]; + const int iSegStartRow = s.m_iStartRow; if( iSegStartRow < iStartIndex ) continue; else if( iSegStartRow > iEndIndex ) - m_StopSegments[i].m_iStartRow += lrintf((iEndIndex - iStartIndex) * (fScale - 1)); + s.m_iStartRow += lrintf((iEndIndex - iStartIndex) * (fScale - 1)); else - m_StopSegments[i].m_iStartRow = lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex; + s.m_iStartRow = lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex; } for( unsigned i = 0; i < m_vTimeSignatureSegments.size(); i++ ) { - const int iSegStartRow = m_vTimeSignatureSegments[i].m_iStartRow; + TimeSignatureSegment &t = m_vTimeSignatureSegments[i]; + const int iSegStartRow = t.m_iStartRow; if( iSegStartRow < iStartIndex ) continue; else if( iSegStartRow > iEndIndex ) - m_vTimeSignatureSegments[i].m_iStartRow += lrintf((iEndIndex - iStartIndex) * (fScale - 1)); + t.m_iStartRow += lrintf((iEndIndex - iStartIndex) * (fScale - 1)); else - m_vTimeSignatureSegments[i].m_iStartRow = lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex; + t.m_iStartRow = lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex; } for( unsigned i = 0; i < m_WarpSegments.size(); i++ ) @@ -1109,13 +1112,14 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool for ( unsigned i = 0; i < m_SpeedSegments.size(); i++ ) { - const int iSegStart = m_SpeedSegments[i].m_iStartRow; + SpeedSegment &s = m_SpeedSegments[i]; + const int iSegStart = s.m_iStartRow; if( iSegStart < iStartIndex ) continue; else if( iSegStart > iEndIndex ) - m_SpeedSegments[i].m_iStartRow += lrintf( (iEndIndex - iStartIndex) * (fScale - 1) ); + s.m_iStartRow += lrintf( (iEndIndex - iStartIndex) * (fScale - 1) ); else - m_SpeedSegments[i].m_iStartRow = lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex; + s.m_iStartRow = lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex; } for( unsigned i = 0; i < m_FakeSegments.size(); i++ ) @@ -1142,13 +1146,14 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool for( unsigned i = 0; i < m_ScrollSegments.size(); i++ ) { - const int iSegStartRow = m_ScrollSegments[i].m_iStartRow; + ScrollSegment &s = m_ScrollSegments[i]; + const int iSegStartRow = s.m_iStartRow; if( iSegStartRow < iStartIndex ) continue; else if( iSegStartRow > iEndIndex ) - m_ScrollSegments[i].m_iStartRow += lrintf((iEndIndex - iStartIndex) * (fScale - 1)); + s.m_iStartRow += lrintf((iEndIndex - iStartIndex) * (fScale - 1)); else - m_ScrollSegments[i].m_iStartRow = lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex; + s.m_iStartRow = lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex; } // adjust BPM changes to preserve timing diff --git a/src/TimingSegments.cpp b/src/TimingSegments.cpp index dadb2efd9c..a3ce904119 100644 --- a/src/TimingSegments.cpp +++ b/src/TimingSegments.cpp @@ -158,7 +158,7 @@ void BPMSegment::SetBPS(const float newBPS) bool BPMSegment::operator<( const BPMSegment &other ) const { LTCOMPARE(GetRow()); - LTCOMPARE(GetBPM()); + LTCOMPARE(GetBPS()); return false; } From b1eab1059441bb1ded511e42b0839f10326ad482 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 31 May 2011 14:27:55 -0400 Subject: [PATCH 15/27] Time Signatures, the other big one. :D --- src/Background.cpp | 6 +-- src/NoteField.cpp | 14 +++--- src/NotesLoaderMidi.cpp | 7 ++- src/NotesLoaderSM.cpp | 8 +-- src/NotesLoaderSMA.cpp | 4 +- src/NotesWriterSSC.cpp | 2 +- src/Player.cpp | 2 +- src/ScreenEdit.cpp | 15 ++++-- src/TimingData.cpp | 54 ++++++++++---------- src/TimingData.h | 106 ---------------------------------------- src/TimingSegments.cpp | 33 +++++++++++++ src/TimingSegments.h | 85 ++++++++++++++++++++++++++++++++ 12 files changed, 177 insertions(+), 159 deletions(-) diff --git a/src/Background.cpp b/src/Background.cpp index d8cef11d4e..2761fd3b18 100644 --- a/src/Background.cpp +++ b/src/Background.cpp @@ -426,9 +426,9 @@ void BackgroundImpl::LoadFromRandom( float fFirstBeat, float fEndBeat, const Bac { vector::const_iterator next = iter; next++; - int iSegmentEndRow = (next == timing.m_vTimeSignatureSegments.end()) ? iEndRow : next->m_iStartRow; + int iSegmentEndRow = (next == timing.m_vTimeSignatureSegments.end()) ? iEndRow : next->GetRow(); - for( int i=max(iter->m_iStartRow,iStartRow); iGetNoteRowsPerMeasure() ) + for( int i=max(iter->GetRow(),iStartRow); iGetNoteRowsPerMeasure() ) { // Don't fade. It causes frame rate dip, especially on slower machines. BackgroundDef bd = m_Layer[0].CreateRandomBGA( m_pSong, change.m_def.m_sEffect, m_RandomBGAnimations, this ); @@ -450,7 +450,7 @@ void BackgroundImpl::LoadFromRandom( float fFirstBeat, float fEndBeat, const Bac bool bAtBeginningOfMeasure = false; FOREACH_CONST( TimeSignatureSegment, timing.m_vTimeSignatureSegments, iter ) { - if( (bpmseg.GetRow() - iter->m_iStartRow) % iter->GetNoteRowsPerMeasure() == 0 ) + if( (bpmseg.GetRow() - iter->GetRow()) % iter->GetNoteRowsPerMeasure() == 0 ) { bAtBeginningOfMeasure = true; break; diff --git a/src/NoteField.cpp b/src/NoteField.cpp index 3abb6bf177..5df25d3f79 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -857,16 +857,16 @@ void NoteField::DrawPrimitives() { vector::const_iterator next = iter; next++; - int iSegmentEndRow = (next == vTimeSignatureSegments.end()) ? iLastRowToDraw : next->m_iStartRow; + int iSegmentEndRow = (next == vTimeSignatureSegments.end()) ? iLastRowToDraw : next->GetRow(); // beat bars every 16th note - int iDrawBeatBarsEveryRows = BeatToNoteRow( ((float)iter->m_iDenominator) / 4 ) / 4; + int iDrawBeatBarsEveryRows = BeatToNoteRow( ((float)iter->GetDen()) / 4 ) / 4; // In 4/4, every 16th beat bar is a measure - int iMeasureBarFrequency = iter->m_iNumerator * 4; + int iMeasureBarFrequency = iter->GetNum() * 4; int iBeatBarsDrawn = 0; - for( int i=iter->m_iStartRow; i < iSegmentEndRow; i += iDrawBeatBarsEveryRows ) + for( int i=iter->GetRow(); i < iSegmentEndRow; i += iDrawBeatBarsEveryRows ) { bool bMeasureBar = iBeatBarsDrawn % iMeasureBarFrequency == 0; BeatBarType type = quarter_beat; @@ -933,11 +933,11 @@ void NoteField::DrawPrimitives() // Time Signature text FOREACH_CONST( TimeSignatureSegment, timing.m_vTimeSignatureSegments, seg ) { - if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) + if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw ) { - float fBeat = NoteRowToBeat(seg->m_iStartRow); + float fBeat = seg->GetBeat(); if( IS_ON_SCREEN(fBeat) ) - DrawTimeSignatureText( fBeat, seg->m_iNumerator, seg->m_iDenominator ); + DrawTimeSignatureText( fBeat, seg->GetNum(), seg->GetDen() ); } } diff --git a/src/NotesLoaderMidi.cpp b/src/NotesLoaderMidi.cpp index 0d2a49b5e6..8a3377b527 100644 --- a/src/NotesLoaderMidi.cpp +++ b/src/NotesLoaderMidi.cpp @@ -687,10 +687,9 @@ static bool LoadFromMidi( const RString &sPath, Song &songOut ) FOREACH_CONST( MidiFileIn::TimeSignatureChange, midi.timeSignatureEvents_, iter ) { - TimeSignatureSegment seg; - seg.m_iStartRow = MidiCountToNoteRow( iter->count ); - seg.m_iNumerator = iter->numerator; - seg.m_iDenominator = iter->denominator; + TimeSignatureSegment seg(MidiCountToNoteRow( iter->count ), + iter->numerator, + iter->denominator); songOut.m_SongTiming.AddTimeSignatureSegment( seg ); } diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index 3497af6534..78a6734eec 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -382,15 +382,15 @@ void SMLoader::ProcessTimeSignatures( TimingData &out, const RString sParam ) continue; } - if( seg.m_iNumerator < 1 ) + if( seg.GetNum() < 1 ) { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iNumerator %i.", fBeat, seg.m_iNumerator ); + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iNumerator %i.", fBeat, seg.GetNum() ); continue; } - if( seg.m_iDenominator < 1 ) + if( seg.GetDen() < 1 ) { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iDenominator %i.", fBeat, seg.m_iDenominator ); + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iDenominator %i.", fBeat, seg.GetDen() ); continue; } diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index 347399adfa..26101bc5ee 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -296,9 +296,9 @@ void SMALoader::ProcessBeatsPerMeasure( TimingData &out, const RString sParam ) continue; } - if( seg.m_iNumerator < 1 ) + if( seg.GetNum() < 1 ) { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iNumerator %i.", fBeat, seg.m_iNumerator ); + LOG->UserLog( "Song file", "(UNKNOWN)", "has an invalid time signature change with beat %f, iNumerator %i.", fBeat, seg.GetNum() ); continue; } diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index de5658b127..0960496c76 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -116,7 +116,7 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo ASSERT( !timing.m_vTimeSignatureSegments.empty() ); w.Init( "TIMESIGNATURES" ); FOREACH_CONST( TimeSignatureSegment, timing.m_vTimeSignatureSegments, iter ) - w.Write( iter->m_iStartRow, iter->m_iNumerator, iter->m_iDenominator ); + w.Write( iter->GetRow(), iter->GetNum(), iter->GetDen() ); w.Finish(); ASSERT( !timing.m_TickcountSegments.empty() ); diff --git a/src/Player.cpp b/src/Player.cpp index 5caa7b5a65..5bd48778f8 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -2881,7 +2881,7 @@ void Player::CrossedRows( int iLastRowCrossed, const RageTimer &now ) TimeSignatureSegment tSignature = m_Timing->GetTimeSignatureSegmentAtBeat( NoteRowToBeat( iLastRowCrossed ) ); // Most songs are in 4/4 time. The frequency for checking tick counts should reflect that. - iCheckpointFrequencyRows = ROWS_PER_BEAT * tSignature.m_iDenominator / (tSignature.m_iNumerator * 4); + iCheckpointFrequencyRows = ROWS_PER_BEAT * tSignature.GetDen() / (tSignature.GetNum() * 4); } if( iCheckpointFrequencyRows > 0 ) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 1eedad0540..21c1b874c3 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -1307,7 +1307,9 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) m_iShiftAnchor = -1; return; } - int beatsPerMeasure = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ).m_iNumerator; + TimingData &sTiming = GAMESTATE->m_pCurSong->m_SongTiming; + float playerBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; + int beatsPerMeasure = sTiming.GetTimeSignatureSegmentAtBeat( playerBeat ).GetNum(); switch( EditB ) { @@ -3967,13 +3969,16 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ); break; case time_signature: + { + TimeSignatureSegment &ts = GetAppropriateTiming().GetTimeSignatureSegmentAtBeat( GetBeat() ); ScreenTextEntry::TextEntry( SM_BackFromTimeSignatureChange, ENTER_TIME_SIGNATURE_VALUE, - ssprintf( "%d/%d", GetAppropriateTiming().GetTimeSignatureSegmentAtBeat( GetBeat() ).m_iNumerator, GetAppropriateTiming().GetTimeSignatureSegmentAtBeat( GetBeat() ).m_iDenominator ), + ssprintf( "%d/%d", ts.GetNum(), ts.GetDen() ), 8 ); break; + } case tickcount: ScreenTextEntry::TextEntry( SM_BackFromTickcountChange, @@ -4259,7 +4264,7 @@ void ScreenEdit::CheckNumberOfNotesAndUndo() return; TimeSignatureSegment curTime = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ); - int rowsPerMeasure = curTime.m_iDenominator * curTime.m_iNumerator; + int rowsPerMeasure = curTime.GetDen() * curTime.GetNum(); for( int row=0; row<=m_NoteDataEdit.GetLastRow(); row+=rowsPerMeasure ) { @@ -4310,7 +4315,9 @@ float ScreenEdit::GetMaximumBeatForNewNote() const /* Round up to the next measure end. Some songs end on weird beats * mid-measure, and it's odd to have movement capped to these weird * beats. */ - int beatsPerMeasure = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ).m_iNumerator; + TimingData &songTiming = GAMESTATE->m_pCurSong->m_SongTiming; + float playerBeat = GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat; + int beatsPerMeasure = songTiming.GetTimeSignatureSegmentAtBeat( playerBeat ).GetNum(); fEndBeat += beatsPerMeasure; fEndBeat = ftruncf( fEndBeat, (float)beatsPerMeasure ); diff --git a/src/TimingData.cpp b/src/TimingData.cpp index 0bf1a8f794..a158c761b7 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -138,40 +138,40 @@ void TimingData::SetTimeSignatureAtRow( int iRow, int iNumerator, int iDenominat unsigned i; for( i = 0; i < m_vTimeSignatureSegments.size(); i++ ) { - if( m_vTimeSignatureSegments[i].m_iStartRow >= iRow) + if( m_vTimeSignatureSegments[i].GetRow() >= iRow) break; // We found our segment. } - if ( i == m_vTimeSignatureSegments.size() || m_vTimeSignatureSegments[i].m_iStartRow != iRow ) + if ( i == m_vTimeSignatureSegments.size() || m_vTimeSignatureSegments[i].GetRow() != iRow ) { // No specific segmeent here: place one if it differs. if( i == 0 || - ( m_vTimeSignatureSegments[i-1].m_iNumerator != iNumerator - || m_vTimeSignatureSegments[i-1].m_iDenominator != iDenominator ) ) + ( m_vTimeSignatureSegments[i-1].GetNum() != iNumerator + || m_vTimeSignatureSegments[i-1].GetDen() != iDenominator ) ) AddTimeSignatureSegment( TimeSignatureSegment(iRow, iNumerator, iDenominator) ); } else // TimeSignatureSegment being modified is m_vTimeSignatureSegments[i] { - if( i > 0 && m_vTimeSignatureSegments[i-1].m_iNumerator == iNumerator - && m_vTimeSignatureSegments[i-1].m_iDenominator == iDenominator ) + if( i > 0 && m_vTimeSignatureSegments[i-1].GetNum() == iNumerator + && m_vTimeSignatureSegments[i-1].GetDen() == iDenominator ) m_vTimeSignatureSegments.erase( m_vTimeSignatureSegments.begin()+i, m_vTimeSignatureSegments.begin()+i+1 ); else { - m_vTimeSignatureSegments[i].m_iNumerator = iNumerator; - m_vTimeSignatureSegments[i].m_iDenominator = iDenominator; + m_vTimeSignatureSegments[i].SetNum(iNumerator); + m_vTimeSignatureSegments[i].SetDen(iDenominator); } } } void TimingData::SetTimeSignatureNumeratorAtRow( int iRow, int iNumerator ) { - SetTimeSignatureAtRow( iRow, iNumerator, GetTimeSignatureSegmentAtBeat( NoteRowToBeat( iRow ) ).m_iDenominator ); + SetTimeSignatureAtRow( iRow, iNumerator, GetTimeSignatureSegmentAtBeat( NoteRowToBeat( iRow ) ).GetDen() ); } void TimingData::SetTimeSignatureDenominatorAtRow( int iRow, int iDenominator ) { - SetTimeSignatureAtRow( iRow, GetTimeSignatureSegmentAtBeat( NoteRowToBeat( iRow ) ).m_iNumerator, iDenominator ); + SetTimeSignatureAtRow( iRow, GetTimeSignatureSegmentAtBeat( NoteRowToBeat( iRow ) ).GetNum(), iDenominator ); } void TimingData::SetWarpAtRow( int iRow, float fNew ) @@ -586,7 +586,7 @@ int TimingData::GetTimeSignatureSegmentIndexAtRow( int iRow ) const { unsigned i; for (i=0; i < m_vTimeSignatureSegments.size() - 1; i++ ) - if( m_vTimeSignatureSegments[i+1].m_iStartRow > iRow ) + if( m_vTimeSignatureSegments[i+1].GetRow() > iRow ) break; return static_cast(i); } @@ -647,7 +647,7 @@ TimeSignatureSegment& TimingData::GetTimeSignatureSegmentAtRow( int iRow ) { unsigned i; for( i=0; i iRow ) + if( m_vTimeSignatureSegments[i+1].GetRow() > iRow ) break; return m_vTimeSignatureSegments[i]; } @@ -672,12 +672,12 @@ ScrollSegment& TimingData::GetScrollSegmentAtRow( int iRow ) int TimingData::GetTimeSignatureNumeratorAtRow( int iRow ) { - return GetTimeSignatureSegmentAtRow( iRow ).m_iNumerator; + return GetTimeSignatureSegmentAtRow( iRow ).GetNum(); } int TimingData::GetTimeSignatureDenominatorAtRow( int iRow ) { - return GetTimeSignatureSegmentAtRow( iRow ).m_iDenominator; + return GetTimeSignatureSegmentAtRow( iRow ).GetDen(); } ComboSegment& TimingData::GetComboSegmentAtRow( int iRow ) @@ -1044,13 +1044,13 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool for( unsigned i = 0; i < m_vTimeSignatureSegments.size(); i++ ) { TimeSignatureSegment &t = m_vTimeSignatureSegments[i]; - const int iSegStartRow = t.m_iStartRow; + const int iSegStartRow = t.GetRow(); if( iSegStartRow < iStartIndex ) continue; else if( iSegStartRow > iEndIndex ) - t.m_iStartRow += lrintf((iEndIndex - iStartIndex) * (fScale - 1)); + t.SetRow(t.GetRow() + lrintf((iEndIndex - iStartIndex) * (fScale - 1))); else - t.m_iStartRow = lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex; + t.SetRow(lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex); } for( unsigned i = 0; i < m_WarpSegments.size(); i++ ) @@ -1211,9 +1211,9 @@ void TimingData::InsertRows( int iStartRow, int iRowsToAdd ) for( unsigned i = 0; i < m_vTimeSignatureSegments.size(); i++ ) { TimeSignatureSegment &time = m_vTimeSignatureSegments[i]; - if( time.m_iStartRow < iStartRow ) + if( time.GetRow() < iStartRow ) continue; - time.m_iStartRow += iRowsToAdd; + time.SetRow(time.GetRow() + iRowsToAdd); } for( unsigned i = 0; i < m_TickcountSegments.size(); i++ ) @@ -1340,13 +1340,13 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) for( unsigned i = 0; i < m_vTimeSignatureSegments.size(); i++ ) { TimeSignatureSegment &time = m_vTimeSignatureSegments[i]; - + int keyRow = time.GetRow(); // Before deleted region: - if( time.m_iStartRow < iStartRow ) + if( keyRow < iStartRow ) continue; // Inside deleted region: - if( time.m_iStartRow < iStartRow+iRowsToDelete ) + if( keyRow < iStartRow+iRowsToDelete ) { m_vTimeSignatureSegments.erase( m_vTimeSignatureSegments.begin()+i, @@ -1358,7 +1358,7 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) // After deleted region: - time.m_iStartRow -= iRowsToDelete; + time.SetRow(keyRow - iRowsToDelete); } for( unsigned i = 0; i < m_TickcountSegments.size(); i++ ) @@ -1614,14 +1614,14 @@ void TimingData::NoteRowToMeasureAndBeat( int iNoteRow, int &iMeasureIndexOut, i { vector::const_iterator next = iter; next++; - int iSegmentEndRow = (next == m_vTimeSignatureSegments.end()) ? INT_MAX : next->m_iStartRow; + int iSegmentEndRow = (next == m_vTimeSignatureSegments.end()) ? INT_MAX : next->GetRow(); int iRowsPerMeasureThisSegment = iter->GetNoteRowsPerMeasure(); - if( iNoteRow >= iter->m_iStartRow ) + if( iNoteRow >= iter->GetRow() ) { // iNoteRow lands in this segment - int iNumRowsThisSegment = iNoteRow - iter->m_iStartRow; + int iNumRowsThisSegment = iNoteRow - iter->GetRow(); int iNumMeasuresThisSegment = (iNumRowsThisSegment) / iRowsPerMeasureThisSegment; // don't round up iMeasureIndexOut += iNumMeasuresThisSegment; iBeatIndexOut = iNumRowsThisSegment / iRowsPerMeasureThisSegment; @@ -1631,7 +1631,7 @@ void TimingData::NoteRowToMeasureAndBeat( int iNoteRow, int &iMeasureIndexOut, i else { // iNoteRow lands after this segment - int iNumRowsThisSegment = iSegmentEndRow - iter->m_iStartRow; + int iNumRowsThisSegment = iSegmentEndRow - iter->GetRow(); int iNumMeasuresThisSegment = (iNumRowsThisSegment + iRowsPerMeasureThisSegment - 1) / iRowsPerMeasureThisSegment; // round up iMeasureIndexOut += iNumMeasuresThisSegment; } diff --git a/src/TimingData.h b/src/TimingData.h index 8c66e205f8..a060b77056 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -119,112 +119,6 @@ struct StopSegment bool operator>=( const StopSegment &other ) const { return !operator<(other); } }; -/** - * @brief Identifies when a song changes its time signature. - * - * This only supports simple time signatures. The upper number (called the numerator here, though this isn't - * properly a fraction) is the number of beats per measure. The lower number (denominator here) - * is the note value representing one beat. */ -struct TimeSignatureSegment -{ - /** - * @brief Creates a simple Time Signature Segment with default values. - */ - TimeSignatureSegment() : m_iStartRow(-1), m_iNumerator(4), m_iDenominator(4) { } - /** - * @brief Creates a Time Signature Segment at the given row with a supplied numerator. - * - * The denominator will be 4 if this is called. - * @param r the starting row of the segment. - * @param n the numerator for the segment. - */ - TimeSignatureSegment( int r, int n ): m_iStartRow(max(0, r)), - m_iNumerator(max(1, n)), m_iDenominator(4) {} - /** - * @brief Creates a Time Signature Segment at the given row with a supplied numerator & denominator. - * @param r the starting row of the segment. - * @param n the numerator for the segment. - * @param d the denonimator for the segment. - */ - TimeSignatureSegment( int r, int n, int d ): m_iStartRow(max(0, r)), - m_iNumerator(max(1, n)), m_iDenominator(max(1, d)) {} - /** - * @brief The row in which the TimeSignatureSegment activates. - */ - int m_iStartRow; - /** - * @brief The numerator of the TimeSignatureSegment. - */ - int m_iNumerator; - /** - * @brief The denominator of the TimeSignatureSegment. - */ - int m_iDenominator; - - /** - * @brief Retrieve the number of note rows per measure within the TimeSignatureSegment. - * - * With BeatToNoteRow(1) rows per beat, then we should have BeatToNoteRow(1)*m_iNumerator - * beats per measure. But if we assume that every BeatToNoteRow(1) rows is a quarter note, - * and we want the beats to be 1/m_iDenominator notes, then we should have - * BeatToNoteRow(1)*4 is rows per whole note and thus BeatToNoteRow(1)*4/m_iDenominator is - * rows per beat. Multiplying by m_iNumerator gives rows per measure. - * @returns the number of note rows per measure. - */ - int GetNoteRowsPerMeasure() const { return BeatToNoteRow(1) * 4 * m_iNumerator / m_iDenominator; } - /** - * @brief Compares two TimeSignatureSegments to see if they are equal to each other. - * @param other the other TimeSignatureSegment to compare to. - * @return the equality of the two segments. - */ - bool operator==( const TimeSignatureSegment &other ) const - { - COMPARE( m_iStartRow ); - COMPARE( m_iNumerator ); - COMPARE( m_iDenominator ); - return true; - } - /** - * @brief Compares two TimeSignatureSegments to see if they are not equal to each other. - * @param other the other TimeSignatureSegment to compare to. - * @return the inequality of the two segments. - */ - bool operator!=( const TimeSignatureSegment &other ) const { return !operator==(other); } - /** - * @brief Compares two TimeSignatureSegments to see if one is less than the other. - * @param other the other TimeSignatureSegment to compare to. - * @return the truth/falsehood of if the first is less than the second. - */ - bool operator<( const TimeSignatureSegment &other ) const - { - return m_iStartRow < other.m_iStartRow || - ( m_iStartRow == other.m_iStartRow && - ( m_iNumerator < other.m_iNumerator || - ( m_iNumerator == other.m_iNumerator && m_iDenominator < other.m_iDenominator ))); - } - /** - * @brief Compares two TimeSignatureSegments to see if one is less than or equal to the other. - * @param other the other TimeSignatureSegment to compare to. - * @return the truth/falsehood of if the first is less or equal to than the second. - */ - bool operator<=( const TimeSignatureSegment &other ) const - { - return ( operator<(other) || operator==(other) ); - } - /** - * @brief Compares two TimeSignatureSegments to see if one is greater than the other. - * @param other the other TimeSignatureSegment to compare to. - * @return the truth/falsehood of if the first is greater than the second. - */ - bool operator>( const TimeSignatureSegment &other ) const { return !operator<=(other); } - /** - * @brief Compares two TimeSignatureSegments to see if one is greater than or equal to the other. - * @param other the other TimeSignatureSegment to compare to. - * @return the truth/falsehood of if the first is greater than or equal to the second. - */ - bool operator>= (const TimeSignatureSegment &other ) const { return !operator<(other); } -}; - /** * @brief Identifies when the arrow scroll changes. * diff --git a/src/TimingSegments.cpp b/src/TimingSegments.cpp index a3ce904119..3b7d198c50 100644 --- a/src/TimingSegments.cpp +++ b/src/TimingSegments.cpp @@ -162,6 +162,39 @@ bool BPMSegment::operator<( const BPMSegment &other ) const return false; } +int TimeSignatureSegment::GetNum() const +{ + return this->numerator; +} + +void TimeSignatureSegment::SetNum(const int i) +{ + this->numerator = i; +} + +int TimeSignatureSegment::GetDen() const +{ + return this->denominator; +} + +void TimeSignatureSegment::SetDen(const int i) +{ + this->denominator = i; +} + +int TimeSignatureSegment::GetNoteRowsPerMeasure() const +{ + return BeatToNoteRow(1) * 4 * numerator / denominator; +} + +bool TimeSignatureSegment::operator<( const TimeSignatureSegment &other ) const +{ + LTCOMPARE(GetRow()); + LTCOMPARE(GetNum()); + LTCOMPARE(GetDen()); + return false; +} + diff --git a/src/TimingSegments.h b/src/TimingSegments.h index f901973458..7ed4f1fbc1 100644 --- a/src/TimingSegments.h +++ b/src/TimingSegments.h @@ -439,6 +439,91 @@ private: float bps; }; +/** + * @brief Identifies when a song changes its time signature. + * + * This only supports simple time signatures. The upper number + * (called the numerator here, though this isn't properly a + * fraction) is the number of beats per measure. The lower number + * (denominator here) is the note value representing one beat. */ +struct TimeSignatureSegment : public TimingSegment +{ + /** + * @brief Creates a simple Time Signature Segment with default values. + */ + TimeSignatureSegment(): + TimingSegment(), + numerator(4), denominator(4) { } + /** + * @brief Creates a Time Signature Segment with supplied values. + * + * The denominator will be 4 if this is called. + * @param r the starting row / beat of the segment. + * @param n the numerator for the segment. + */ + template + TimeSignatureSegment( StartType r, int n ): + TimingSegment(max((StartType)0, r)), + numerator(max(1, n)), denominator(4) {} + /** + * @brief Creates a Time Signature Segment with supplied values. + * @param r the starting row of the segment. + * @param n the numerator for the segment. + * @param d the denonimator for the segment. + */ + template + TimeSignatureSegment( StartType r, int n, int d ): + TimingSegment(max((StartType)0, r)), + numerator(max(1, n)), denominator(max(1, d)) {} + + /** + * @brief Get the numerator in this TimeSignatureSegment. + * @return the numerator. */ + int GetNum() const; + + /** + * @brief Set the numerator in this TimeSignatureSegment. + * @param i the numerator. */ + void SetNum(const int i); + + /** + * @brief Get the denominator in this TimeSignatureSegment. + * @return the denominator. */ + int GetDen() const; + + /** + * @brief Set the denominator in this TimeSignatureSegment. + * @param i the denominator. */ + void SetDen(const int i); + + /** + * @brief Retrieve the number of note rows per measure within the TimeSignatureSegment. + * + * With BeatToNoteRow(1) rows per beat, then we should have BeatToNoteRow(1)*m_iNumerator + * beats per measure. But if we assume that every BeatToNoteRow(1) rows is a quarter note, + * and we want the beats to be 1/m_iDenominator notes, then we should have + * BeatToNoteRow(1)*4 is rows per whole note and thus BeatToNoteRow(1)*4/m_iDenominator is + * rows per beat. Multiplying by m_iNumerator gives rows per measure. + * @returns the number of note rows per measure. + */ + int GetNoteRowsPerMeasure() const; + + /** + * @brief Compares two TimeSignatureSegments to see if one is less than the other. + * @param other the other TimeSignatureSegment to compare to. + * @return the truth/falsehood of if the first is less than the second. + */ + bool operator<( const TimeSignatureSegment &other ) const; +private: + /** + * @brief The numerator of the TimeSignatureSegment. + */ + int numerator; + /** + * @brief The denominator of the TimeSignatureSegment. + */ + int denominator; +}; From 604bf364e58ab2f098922b86758d6c8c917816ef Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 31 May 2011 14:45:17 -0400 Subject: [PATCH 16/27] Forgot to remove the counterpart. --- src/TimingSegments.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/TimingSegments.h b/src/TimingSegments.h index 7ed4f1fbc1..32cdfbb462 100644 --- a/src/TimingSegments.h +++ b/src/TimingSegments.h @@ -525,10 +525,6 @@ private: int denominator; }; - - -#undef COMPARE - #endif /** From 2084237b6dc40ddf8a7cbdae423f4b6d2b31300f Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 31 May 2011 15:01:20 -0400 Subject: [PATCH 17/27] Try this one. --- src/ScreenEdit.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 21c1b874c3..ecca82476c 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -4263,7 +4263,7 @@ void ScreenEdit::CheckNumberOfNotesAndUndo() if( EDIT_MODE.GetValue() != EditMode_Home ) return; - TimeSignatureSegment curTime = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ); + TimeSignatureSegment &curTime = GAMESTATE->m_pCurSong->m_SongTiming.GetTimeSignatureSegmentAtBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ); int rowsPerMeasure = curTime.GetDen() * curTime.GetNum(); for( int row=0; row<=m_NoteDataEdit.GetLastRow(); row+=rowsPerMeasure ) From f9eb6fb38741400eda2119aa74993231e285ea60 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 31 May 2011 15:27:27 -0400 Subject: [PATCH 18/27] Speed Segments Satisfied. --- src/NoteField.cpp | 7 ++- src/NotesLoaderSMA.cpp | 7 ++- src/NotesLoaderSSC.cpp | 7 ++- src/NotesWriterSSC.cpp | 2 +- src/ScreenEdit.cpp | 6 +- src/TimingData.cpp | 73 +++++++++++------------ src/TimingData.h | 130 ----------------------------------------- src/TimingSegments.cpp | 43 ++++++++++++++ src/TimingSegments.h | 110 ++++++++++++++++++++++++++++++++++ 9 files changed, 206 insertions(+), 179 deletions(-) diff --git a/src/NoteField.cpp b/src/NoteField.cpp index 5df25d3f79..8b9684d2d1 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -984,11 +984,12 @@ void NoteField::DrawPrimitives() { FOREACH_CONST( SpeedSegment, timing.m_SpeedSegments, seg ) { - if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) + if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw ) { - float fBeat = NoteRowToBeat(seg->m_iStartRow); + float fBeat = seg->GetBeat(); if( IS_ON_SCREEN(fBeat) ) - DrawSpeedText( fBeat, seg->m_fPercent, seg->m_fWait, seg->m_usMode ); + DrawSpeedText(fBeat, seg->GetRatio(), + seg->GetLength(), seg->GetUnit() ); } } } diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index 26101bc5ee..a45a87f9c2 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -340,7 +340,8 @@ void SMALoader::ProcessSpeeds( TimingData &out, const int iRowsPerBeat, const RS unsigned short tmp = ( (vs2[2].find("s") || vs2[2].find("S") ) ? 1 : 0); - SpeedSegment seg( fBeat, StringToFloat( vs2[1] ), StringToFloat( vs2[2] ), tmp); + SpeedSegment seg(fBeat, StringToFloat( vs2[1] ), StringToFloat(vs2[2])); + seg.SetUnit(tmp); if( fBeat < 0 ) { @@ -348,9 +349,9 @@ void SMALoader::ProcessSpeeds( TimingData &out, const int iRowsPerBeat, const RS continue; } - if( seg.m_fWait < 0 ) + if( seg.GetLength() < 0 ) { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with beat %f, fWait %f.", fBeat, seg.m_fWait ); + LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with beat %f, length %f.", fBeat, seg.GetLength() ); continue; } diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index e73fd69158..04a4fdc167 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -158,7 +158,8 @@ void SSCLoader::ProcessSpeeds( TimingData &out, const RString sParam ) const float fBeat = StringToFloat( vs2[0] ); - SpeedSegment seg( fBeat, StringToFloat( vs2[1] ), StringToFloat( vs2[2] ), static_cast(StringToInt(vs2[3]))); + SpeedSegment seg( fBeat, StringToFloat( vs2[1] ), StringToFloat( vs2[2] )); + seg.SetUnit(StringToInt(vs2[3])); if( fBeat < 0 ) { @@ -166,9 +167,9 @@ void SSCLoader::ProcessSpeeds( TimingData &out, const RString sParam ) continue; } - if( seg.m_fWait < 0 ) + if( seg.GetLength() < 0 ) { - LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with beat %f, fWait %f.", fBeat, seg.m_fWait ); + LOG->UserLog( "Song file", "(UNKNOWN)", "has an speed change with beat %f, length %f.", fBeat, seg.GetLength() ); continue; } diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index 0960496c76..5dfb891826 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -134,7 +134,7 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo // Song Timing should only have the initial value. w.Init( "SPEEDS" ); FOREACH_CONST( SpeedSegment, timing.m_SpeedSegments, ss ) - w.Write( ss->m_iStartRow, ss->m_fPercent, ss->m_fWait, ss->m_usMode ); + w.Write( ss->GetRow(), ss->GetRatio(), ss->GetLength(), ss->GetUnit() ); w.Finish(); w.Init( "SCROLLS" ); diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index ecca82476c..d2aa616e1c 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -3224,7 +3224,7 @@ void ScreenEdit::DisplayTimingMenu() { float fBeat = GetBeat(); TimingData &pTime = GetAppropriateTiming(); - bool bHasSpeedOnThisRow = pTime.GetSpeedSegmentAtBeat( fBeat ).m_iStartRow == BeatToNoteRow( fBeat ); + bool bHasSpeedOnThisRow = pTime.GetSpeedSegmentAtBeat( fBeat ).GetBeat() == fBeat; g_TimingDataInformation.rows[beat_0_offset].SetOneUnthemedChoice( ssprintf("%.5f", pTime.m_fBeat0OffsetInSeconds) ); g_TimingDataInformation.rows[bpm].SetOneUnthemedChoice( ssprintf("%.5f", pTime.GetBPMAtBeat( fBeat ) ) ); @@ -4015,7 +4015,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromSpeedPercentChange, ENTER_SPEED_PERCENT_VALUE, - ssprintf( "%.5f", GetAppropriateTiming().GetSpeedSegmentAtBeat( GetBeat() ).m_fPercent ), + ssprintf( "%.5f", GetAppropriateTiming().GetSpeedSegmentAtBeat( GetBeat() ).GetRatio() ), 10 ); break; @@ -4031,7 +4031,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromSpeedWaitChange, ENTER_SPEED_WAIT_VALUE, - ssprintf( "%.5f", GetAppropriateTiming().GetSpeedSegmentAtBeat( GetBeat() ).m_fWait ), + ssprintf( "%.5f", GetAppropriateTiming().GetSpeedSegmentAtBeat( GetBeat() ).GetLength() ), 10 ); break; diff --git a/src/TimingData.cpp b/src/TimingData.cpp index a158c761b7..8e1672e580 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -269,27 +269,27 @@ void TimingData::SetSpeedAtRow( int iRow, float fPercent, float fWait, unsigned unsigned i; for( i = 0; i < m_SpeedSegments.size(); i++ ) { - if( m_SpeedSegments[i].m_iStartRow >= iRow) + if( m_SpeedSegments[i].GetRow() >= iRow) break; } - if ( i == m_SpeedSegments.size() || m_SpeedSegments[i].m_iStartRow != iRow ) + if ( i == m_SpeedSegments.size() || m_SpeedSegments[i].GetRow() != iRow ) { // the core mod itself matters the most for comparisons. - if( i == 0 || m_SpeedSegments[i-1].m_fPercent != fPercent ) + if( i == 0 || m_SpeedSegments[i-1].GetRatio() != fPercent ) AddSpeedSegment( SpeedSegment(iRow, fPercent, fWait, usMode) ); } else { // The others aren't compared: only the mod itself matters. - if( i > 0 && m_SpeedSegments[i-1].m_fPercent == fPercent ) + if( i > 0 && m_SpeedSegments[i-1].GetRatio() == fPercent ) m_SpeedSegments.erase( m_SpeedSegments.begin()+i, m_SpeedSegments.begin()+i+1 ); else { - m_SpeedSegments[i].m_fPercent = fPercent; - m_SpeedSegments[i].m_fWait = fWait; - m_SpeedSegments[i].m_usMode = usMode; + m_SpeedSegments[i].SetRatio(fPercent); + m_SpeedSegments[i].SetLength(fWait); + m_SpeedSegments[i].SetUnit(usMode); } } } @@ -351,23 +351,23 @@ void TimingData::SetSpeedPercentAtRow( int iRow, float fPercent ) { SetSpeedAtRow( iRow, fPercent, - GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).m_fWait, - GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).m_usMode); + GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).GetLength(), + GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).GetUnit()); } void TimingData::SetSpeedWaitAtRow( int iRow, float fWait ) { SetSpeedAtRow( iRow, - GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).m_fPercent, + GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).GetRatio(), fWait, - GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).m_usMode); + GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).GetUnit()); } void TimingData::SetSpeedModeAtRow( int iRow, unsigned short usMode ) { SetSpeedAtRow( iRow, - GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).m_fPercent, - GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).m_fWait, + GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).GetRatio(), + GetSpeedSegmentAtBeat( NoteRowToBeat( iRow ) ).GetLength(), usMode ); } @@ -419,17 +419,17 @@ float TimingData::GetWarpAtRow( int iWarpRow ) const float TimingData::GetSpeedPercentAtRow( int iRow ) { - return GetSpeedSegmentAtRow( iRow ).m_fPercent; + return GetSpeedSegmentAtRow( iRow ).GetRatio(); } float TimingData::GetSpeedWaitAtRow( int iRow ) { - return GetSpeedSegmentAtRow( iRow ).m_fWait; + return GetSpeedSegmentAtRow( iRow ).GetLength(); } unsigned short TimingData::GetSpeedModeAtRow( int iRow ) { - return GetSpeedSegmentAtRow( iRow ).m_usMode; + return GetSpeedSegmentAtRow( iRow ).GetUnit(); } float TimingData::GetScrollAtRow( int iRow ) @@ -619,7 +619,7 @@ int TimingData::GetSpeedSegmentIndexAtRow( int iRow ) const { unsigned i; for (i=0; i < m_SpeedSegments.size() - 1; i++ ) - if( m_SpeedSegments[i+1].m_iStartRow > iRow ) + if( m_SpeedSegments[i+1].GetRow() > iRow ) break; return static_cast(i); } @@ -656,7 +656,7 @@ SpeedSegment& TimingData::GetSpeedSegmentAtRow( int iRow ) { unsigned i; for( i=0; i iRow ) + if( m_SpeedSegments[i+1].GetRow() > iRow ) break; return m_SpeedSegments[i]; } @@ -1113,13 +1113,13 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool for ( unsigned i = 0; i < m_SpeedSegments.size(); i++ ) { SpeedSegment &s = m_SpeedSegments[i]; - const int iSegStart = s.m_iStartRow; + const int iSegStart = s.GetRow(); if( iSegStart < iStartIndex ) continue; else if( iSegStart > iEndIndex ) - s.m_iStartRow += lrintf( (iEndIndex - iStartIndex) * (fScale - 1) ); + s.SetRow(s.GetRow() + lrintf( (iEndIndex - iStartIndex) * (fScale - 1) )); else - s.m_iStartRow = lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex; + s.SetRow(lrintf( (iSegStart - iStartIndex) * fScale ) + iStartIndex); } for( unsigned i = 0; i < m_FakeSegments.size(); i++ ) @@ -1242,9 +1242,9 @@ void TimingData::InsertRows( int iStartRow, int iRowsToAdd ) for( unsigned i = 0; i < m_SpeedSegments.size(); i++ ) { SpeedSegment &sped = m_SpeedSegments[i]; - if( sped.m_iStartRow < iStartRow ) + if( sped.GetRow() < iStartRow ) continue; - sped.m_iStartRow += iRowsToAdd; + sped.SetRow(sped.GetRow() + iRowsToAdd); } for( unsigned i = 0; i < m_FakeSegments.size(); i++ ) @@ -1420,17 +1420,17 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) for( unsigned i = 0; i < m_SpeedSegments.size(); i++ ) { SpeedSegment &sped = m_SpeedSegments[i]; - - if( sped.m_iStartRow < iStartRow ) + int keyRow = sped.GetRow(); + if( keyRow < iStartRow ) continue; - if( sped.m_iStartRow < iStartRow+iRowsToDelete ) + if( keyRow < iStartRow+iRowsToDelete ) { m_SpeedSegments.erase( m_SpeedSegments.begin()+i, m_SpeedSegments.begin()+i+1 ); --i; continue; } - sped.m_iStartRow -= iRowsToDelete; + sped.SetRow(keyRow - iRowsToDelete); } for( unsigned i = 0; i < m_FakeSegments.size(); i++ ) @@ -1477,38 +1477,39 @@ float TimingData::GetDisplayedSpeedPercent( float fSongBeat, float fMusicSeconds const int index = GetSpeedSegmentIndexAtBeat( fSongBeat ); const SpeedSegment &seg = m_SpeedSegments[index]; - float fStartBeat = NoteRowToBeat(seg.m_iStartRow); + float fStartBeat = seg.GetBeat(); float fStartTime = GetElapsedTimeFromBeat( fStartBeat ) - GetDelayAtBeat( fStartBeat ); float fEndTime; float fCurTime = fMusicSeconds; - if( seg.m_usMode == 1 ) // seconds + if( seg.GetUnit() == 1 ) // seconds { - fEndTime = fStartTime + seg.m_fWait; + fEndTime = fStartTime + seg.GetLength(); } else { - fEndTime = GetElapsedTimeFromBeat( fStartBeat + seg.m_fWait ) - GetDelayAtBeat( fStartBeat + seg.m_fWait ); + fEndTime = GetElapsedTimeFromBeat( fStartBeat + seg.GetLength() ) + - GetDelayAtBeat( fStartBeat + seg.GetLength() ); } - if( ( index == 0 && m_SpeedSegments[0].m_fWait > 0.0 ) && fCurTime < fStartTime ) + if( ( index == 0 && m_SpeedSegments[0].GetLength() > 0.0 ) && fCurTime < fStartTime ) { return 1.0; } - else if( fEndTime >= fCurTime && ( index > 0 || m_SpeedSegments[0].m_fWait > 0.0 ) ) + else if( fEndTime >= fCurTime && ( index > 0 || m_SpeedSegments[0].GetLength() > 0.0 ) ) { - const float fPriorSpeed = ( index == 0 ? 1 : m_SpeedSegments[index - 1].m_fPercent ); + const float fPriorSpeed = ( index == 0 ? 1 : m_SpeedSegments[index - 1].GetRatio() ); float fTimeUsed = fCurTime - fStartTime; float fDuration = fEndTime - fStartTime; float fRatioUsed = fDuration == 0.0 ? 1 : fTimeUsed / fDuration; - float fDistance = fPriorSpeed - seg.m_fPercent; + float fDistance = fPriorSpeed - seg.GetRatio(); float fRatioNeed = fRatioUsed * -fDistance; return (fPriorSpeed + fRatioNeed); } else { - return seg.m_fPercent; + return seg.GetRatio(); } } diff --git a/src/TimingData.h b/src/TimingData.h index a060b77056..45f81fe268 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -119,136 +119,6 @@ struct StopSegment bool operator>=( const StopSegment &other ) const { return !operator<(other); } }; -/** - * @brief Identifies when the arrow scroll changes. - * - * SpeedSegments take a Player's scrolling BPM (Step's BPM * speed mod), - * and then multiplies it with the percentage value. No matter the player's - * speed mod, the ratio will be the same. Unlike forced attacks, these - * cannot be turned off at a set time: reset it by setting the precentage - * back to 1. - * - * These were inspired by the Pump It Up series. */ -struct SpeedSegment -{ - /** @brief Sets up the SpeedSegment with default values. */ - SpeedSegment(): m_iStartRow(0), - m_fPercent(1), m_fWait(0), m_usMode(0) {} - - /** - * @brief Sets up the SpeedSegment with specified values. - * @param i The row this activates. - * @param p The percentage to use. */ - SpeedSegment(int i, float p): m_iStartRow(i), - m_fPercent(p), m_fWait(0), m_usMode(0) {} - - /** - * @brief Sets up the SpeedSegment with specified values. - * @param r The beat this activates. - * @param p The percentage to use. */ - SpeedSegment(float r, float p): m_iStartRow(BeatToNoteRow(r)), - m_fPercent(p), m_fWait(0), m_usMode(0) {} - - /** - * @brief Sets up the SpeedSegment with specified values. - * @param i The row this activates. - * @param p The percentage to use. - * @param w The number of beats to wait. */ - SpeedSegment(int i, float p, float w): m_iStartRow(i), - m_fPercent(p), m_fWait(w), m_usMode(0) {} - - /** - * @brief Sets up the SpeedSegment with specified values. - * @param r The beat this activates. - * @param p The percentage to use. - * @param w The number of beats to wait. */ - SpeedSegment(float r, float p, float w): m_iStartRow(BeatToNoteRow(r)), - m_fPercent(p), m_fWait(w), m_usMode(0) {} - - /** - * @brief Sets up the SpeedSegment with specified values. - * @param i The row this activates. - * @param p The percentage to use. - * @param w The number of beats/seconds to wait. - * @param k The mode used for the wait variable. */ - SpeedSegment(int i, float p, float w, unsigned short k): m_iStartRow(i), - m_fPercent(p), m_fWait(w), m_usMode(k) {} - - /** - * @brief Sets up the SpeedSegment with specified values. - * @param r The beat this activates. - * @param p The percentage to use. - * @param w The number of beats/seconds to wait. - * @param k The mode used for the wait variable.*/ - SpeedSegment(float r, float p, float w, unsigned short k): m_iStartRow(BeatToNoteRow(r)), - m_fPercent(p), m_fWait(w), m_usMode(k) {} - - /** @brief The row in which the ComboSegment activates. */ - int m_iStartRow; - /** @brief The percentage to use when multiplying the Player's BPM. */ - float m_fPercent; - /** - * @brief The number of beats or seconds to wait for the change to take place. - * - * A value of 0 means this is immediate. */ - float m_fWait; - /** - * @brief The mode that this segment uses for the math. - * - * 0: beats - * 1: seconds - * other - */ - unsigned short m_usMode; - - /** - * @brief Compares two SpeedSegments to see if they are equal to each other. - * @param other the other SpeedSegment to compare to. - * @return the equality of the two segments. - */ - bool operator==( const SpeedSegment &other ) const - { - COMPARE( m_iStartRow ); - COMPARE( m_fPercent ); - COMPARE( m_usMode ); - COMPARE( m_fWait ); - return true; - } - /** - * @brief Compares two SpeedSegments to see if they are not equal to each other. - * @param other the other SpeedSegment to compare to. - * @return the inequality of the two segments. - */ - bool operator!=( const SpeedSegment &other ) const { return !operator==(other); } - /** - * @brief Compares two SpeedSegments to see if one is less than the other. - * @param other the other SpeedSegment to compare to. - * @return the truth/falsehood of if the first is less than the second. - */ - bool operator<( const SpeedSegment &other ) const { return m_iStartRow < other.m_iStartRow; } - /** - * @brief Compares two SpeedSegments to see if one is less than or equal to the other. - * @param other the other SpeedSegment to compare to. - * @return the truth/falsehood of if the first is less or equal to than the second. - */ - bool operator<=( const SpeedSegment &other ) const - { - return ( operator<(other) || operator==(other) ); - } - /** - * @brief Compares two SpeedSegments to see if one is greater than the other. - * @param other the other SpeedSegment to compare to. - * @return the truth/falsehood of if the first is greater than the second. - */ - bool operator>( const SpeedSegment &other ) const { return !operator<=(other); } - /** - * @brief Compares two SpeedSegments to see if one is greater than or equal to the other. - * @param other the other SpeedSegment to compare to. - * @return the truth/falsehood of if the first is greater than or equal to the second. - */ - bool operator>=( const SpeedSegment &other ) const { return !operator<(other); } -}; - /** * @brief Identifies when the chart scroll changes. * diff --git a/src/TimingSegments.cpp b/src/TimingSegments.cpp index 3b7d198c50..6208296cba 100644 --- a/src/TimingSegments.cpp +++ b/src/TimingSegments.cpp @@ -195,7 +195,50 @@ bool TimeSignatureSegment::operator<( const TimeSignatureSegment &other ) const return false; } +float SpeedSegment::GetRatio() const +{ + return this->ratio; +} +void SpeedSegment::SetRatio(const float i) +{ + this->ratio = i; +} + +float SpeedSegment::GetLength() const +{ + return this->length; +} + +void SpeedSegment::SetLength(const float i) +{ + this->length = i; +} + + +unsigned short SpeedSegment::GetUnit() const +{ + return this->unit; +} + +void SpeedSegment::SetUnit(const unsigned short i) +{ + this->unit = i; +} + +void SpeedSegment::SetUnit(const int i) +{ + this->unit = static_cast(i); +} + +bool SpeedSegment::operator<( const SpeedSegment &other ) const +{ + LTCOMPARE(GetRow()); + LTCOMPARE(GetRatio()); + LTCOMPARE(GetLength()); + LTCOMPARE(GetUnit()); + return false; +} /** diff --git a/src/TimingSegments.h b/src/TimingSegments.h index 32cdfbb462..c1a867afa4 100644 --- a/src/TimingSegments.h +++ b/src/TimingSegments.h @@ -525,6 +525,116 @@ private: int denominator; }; +/** + * @brief Identifies when the arrow scroll changes. + * + * SpeedSegments take a Player's scrolling BPM (Step's BPM * speed mod), + * and then multiplies it with the percentage value. No matter the player's + * speed mod, the ratio will be the same. Unlike forced attacks, these + * cannot be turned off at a set time: reset it by setting the precentage + * back to 1. + * + * These were inspired by the Pump It Up series. */ +struct SpeedSegment : public TimingSegment +{ + /** @brief Sets up the SpeedSegment with default values. */ + SpeedSegment(): + TimingSegment(0), + ratio(1), length(0), unit(0) {} + + /** + * @brief Sets up the SpeedSegment with specified values. + * @param r The row / beat this activates. + * @param p The percentage to use. */ + template + SpeedSegment( StartType r, float p): + TimingSegment(max((StartType)0, r)), + ratio(p), length(0), unit(0) {} + + /** + * @brief Sets up the SpeedSegment with specified values. + * @param r The row / beat this activates. + * @param p The percentage to use. + * @param w The number of beats to wait. */ + template + SpeedSegment(StartType r, float p, float w): + TimingSegment(max((StartType)0, r)), + ratio(p), length(w), unit(0) {} + + + /** + * @brief Sets up the SpeedSegment with specified values. + * @param r The row / beat this activates. + * @param p The percentage to use. + * @param w The number of beats/seconds to wait. + * @param k The mode used for the wait variable. */ + template + SpeedSegment(StartType r, float p, float w, unsigned short k): + TimingSegment(max((StartType)0, r)), + ratio(p), length(w), unit(k) {} + + /** + * @brief Get the ratio in this SpeedSegment. + * @return the ratio. */ + float GetRatio() const; + + /** + * @brief Set the ratio in this SpeedSegment. + * @param i the ratio. */ + void SetRatio(const float i); + + /** + * @brief Get the length in this SpeedSegment. + * @return the length. */ + float GetLength() const; + + /** + * @brief Set the length in this SpeedSegment. + * @param i the length. */ + void SetLength(const float i); + + /** + * @brief Get the unit in this SpeedSegment. + * @return the unit. */ + unsigned short GetUnit() const; + + /** + * @brief Set the unit in this SpeedSegment. + * @param i the unit. */ + void SetUnit(const unsigned short i); + + /** + * @brief Set the unit in this SpeedSegment. + * + * This one is offered for quicker compatibility. + * @param i the unit. */ + void SetUnit(const int i); + + /** + * @brief Compares two SpeedSegments to see if one is less than the other. + * @param other the other SpeedSegment to compare to. + * @return the truth/falsehood of if the first is less than the second. + */ + bool operator<( const SpeedSegment &other ) const; +private: + /** @brief The percentage (ratio) to use when multiplying the Player's BPM. */ + float ratio; + /** + * @brief The number of beats or seconds to wait for the change to take place. + * + * A value of 0 means this is immediate. */ + float length; + /** + * @brief The mode that this segment uses for the math. + * + * 0: beats + * 1: seconds + * other + */ + unsigned short unit; + +}; + #endif /** From 5d496c41a7b5bf64ae11ec7202c9af143ae25520 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 31 May 2011 18:37:19 -0400 Subject: [PATCH 19/27] I was told I needed a copy ctor here. May as well see if this builds on Mac OS X. --- src/TimingSegments.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/TimingSegments.h b/src/TimingSegments.h index c1a867afa4..a738c2c682 100644 --- a/src/TimingSegments.h +++ b/src/TimingSegments.h @@ -14,6 +14,11 @@ struct BaseTimingSegment /** @brief Set up a BaseTimingSegment with default values. */ BaseTimingSegment(): startingRow(-1) {}; + + BaseTimingSegment(const BaseTimingSegment &b) + { + *this = b; + } /** * @brief Set up a BaseTimingSegment with specified values. From aa9ba8a31b1f81d5d29ff3991f7a8acaec46ce7a Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 31 May 2011 18:39:52 -0400 Subject: [PATCH 20/27] May as well add these to .ignore too. --- .hgignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.hgignore b/.hgignore index 2d684e1742..b29a2fa6af 100644 --- a/.hgignore +++ b/.hgignore @@ -87,6 +87,9 @@ BuildLog.htm .hgrc src/UpgradeLog*.XML src/_UpgradeReport_Files +src/*/sm-ssc.lib +src/*/StepMania.lib +src/libtom*/*/libtom*.lib syntax: regexp .*\#.*\#$ glob:Cache/Banners/AdditionalSongs_Airspace Preview_Derailed_Derailed bn.png From 69c03da03255d08934449cc2bc9cb6f62eea121a Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 31 May 2011 19:22:51 -0400 Subject: [PATCH 21/27] Bad file, but need a record of key comment. I think this is the key issue. gcc is doing some magic for us. VS20** is forcing us to do it right. Yes AJ, that means Windows is better on something. Revert this file if needed: the record is now made. --- src/TimingSegments.h | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/TimingSegments.h b/src/TimingSegments.h index a738c2c682..01768c4b71 100644 --- a/src/TimingSegments.h +++ b/src/TimingSegments.h @@ -13,7 +13,7 @@ struct BaseTimingSegment /** @brief Set up a BaseTimingSegment with default values. */ BaseTimingSegment(): - startingRow(-1) {}; + startingRow(static_cast(-1)) {}; BaseTimingSegment(const BaseTimingSegment &b) { @@ -22,10 +22,11 @@ struct BaseTimingSegment /** * @brief Set up a BaseTimingSegment with specified values. - * @param s the starting row / beat. */ + * @param s the starting row / beat. + * + * NOTE: On Windows, it's passing in the Segments, not ints or floats. */ template - BaseTimingSegment(StartType s): - startingRow(ToNoteRow(s)) {}; + BaseTimingSegment(StartType s): startingRow(ToNoteRow(s)) {} virtual ~BaseTimingSegment(); @@ -67,7 +68,7 @@ template struct TimingSegment: public BaseTimingSegment { - TimingSegment(): BaseTimingSegment() {}; + TimingSegment(): BaseTimingSegment(static_cast(-1)) {}; template TimingSegment(StartType s): BaseTimingSegment(s) {}; @@ -399,7 +400,10 @@ struct BPMSegment : public TimingSegment * It is best to override the values as soon as possible. */ BPMSegment() : - TimingSegment(), bps(-1.0f) { } + TimingSegment(static_cast(-1)), bps(-1.0f) { } + + operator int() const { return 1; } + operator float() const { return 2.0f; } /** * @brief Creates a BPM Segment with the specified starting row and beats per second. @@ -408,7 +412,7 @@ struct BPMSegment : public TimingSegment */ template BPMSegment( StartType s, float bpm ): - TimingSegment(max((StartType)0, s)), bps(0.0f) { SetBPM(bpm); } + TimingSegment(max((StartType)0, ToNoteRow(s))), bps(0.0f) { SetBPM(bpm); } /** * @brief Get the label in this LabelSegment. From 3b2f9510cd916a591ec6e70da6958f8410f792c6 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Tue, 31 May 2011 22:25:53 -0400 Subject: [PATCH 22/27] Right, how'd I forget global.h in here?!? --- src/TimingSegments.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/TimingSegments.cpp b/src/TimingSegments.cpp index 6208296cba..dc5149c41b 100644 --- a/src/TimingSegments.cpp +++ b/src/TimingSegments.cpp @@ -1,3 +1,4 @@ +#include "global.h" #include "TimingSegments.h" #define LTCOMPARE(x) if(this->x < other.x) return true; if(this->x > other.x) return false; From d0ff9413e7321761018a1a90761715877e337cd3 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Wed, 1 Jun 2011 01:08:53 -0400 Subject: [PATCH 23/27] Trying this once again... We need to prevent Segments from being the variable type sent into TimingSegment. Just have it be ints or floats I think. --- src/TimingSegments.h | 47 ++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/src/TimingSegments.h b/src/TimingSegments.h index 01768c4b71..665ee7cda8 100644 --- a/src/TimingSegments.h +++ b/src/TimingSegments.h @@ -13,7 +13,7 @@ struct BaseTimingSegment /** @brief Set up a BaseTimingSegment with default values. */ BaseTimingSegment(): - startingRow(static_cast(-1)) {}; + startingRow(-1) {}; BaseTimingSegment(const BaseTimingSegment &b) { @@ -26,7 +26,7 @@ struct BaseTimingSegment * * NOTE: On Windows, it's passing in the Segments, not ints or floats. */ template - BaseTimingSegment(StartType s): startingRow(ToNoteRow(s)) {} + BaseTimingSegment(StartType s): startingRow(s) {} virtual ~BaseTimingSegment(); @@ -68,10 +68,11 @@ template struct TimingSegment: public BaseTimingSegment { - TimingSegment(): BaseTimingSegment(static_cast(-1)) {}; + TimingSegment(): BaseTimingSegment(-1) {}; - template - TimingSegment(StartType s): BaseTimingSegment(s) {}; + TimingSegment(int s): BaseTimingSegment(s) {}; + + TimingSegment(float s): BaseTimingSegment(ToNoteRow(s)) {}; /** * @brief Compares two DrivedSegments to see if one is less than the other. @@ -146,7 +147,7 @@ struct FakeSegment : public TimingSegment * It is best to override the values as soon as possible. */ FakeSegment(): - TimingSegment(), lengthBeats(-1) {}; + TimingSegment(-1), lengthBeats(-1) {}; /** * @brief Create a Fake Segment with the specified values. @@ -400,7 +401,7 @@ struct BPMSegment : public TimingSegment * It is best to override the values as soon as possible. */ BPMSegment() : - TimingSegment(static_cast(-1)), bps(-1.0f) { } + TimingSegment(-1), bps(-1.0f) { } operator int() const { return 1; } operator float() const { return 2.0f; } @@ -412,7 +413,7 @@ struct BPMSegment : public TimingSegment */ template BPMSegment( StartType s, float bpm ): - TimingSegment(max((StartType)0, ToNoteRow(s))), bps(0.0f) { SetBPM(bpm); } + TimingSegment(max((StartType)0, s)), bps(0.0f) { SetBPM(bpm); } /** * @brief Get the label in this LabelSegment. @@ -467,22 +468,22 @@ struct TimeSignatureSegment : public TimingSegment * @brief Creates a Time Signature Segment with supplied values. * * The denominator will be 4 if this is called. - * @param r the starting row / beat of the segment. + * @param s the starting row / beat of the segment. * @param n the numerator for the segment. */ template - TimeSignatureSegment( StartType r, int n ): - TimingSegment(max((StartType)0, r)), + TimeSignatureSegment( StartType s, int n ): + TimingSegment(max((StartType)0, s)), numerator(max(1, n)), denominator(4) {} /** * @brief Creates a Time Signature Segment with supplied values. - * @param r the starting row of the segment. + * @param s the starting row of the segment. * @param n the numerator for the segment. * @param d the denonimator for the segment. */ template - TimeSignatureSegment( StartType r, int n, int d ): - TimingSegment(max((StartType)0, r)), + TimeSignatureSegment( StartType s, int n, int d ): + TimingSegment(max((StartType)0, s)), numerator(max(1, n)), denominator(max(1, d)) {} /** @@ -553,33 +554,33 @@ struct SpeedSegment : public TimingSegment /** * @brief Sets up the SpeedSegment with specified values. - * @param r The row / beat this activates. + * @param s The row / beat this activates. * @param p The percentage to use. */ template - SpeedSegment( StartType r, float p): - TimingSegment(max((StartType)0, r)), + SpeedSegment( StartType s, float p): + TimingSegment(max((StartType)0, s)), ratio(p), length(0), unit(0) {} /** * @brief Sets up the SpeedSegment with specified values. - * @param r The row / beat this activates. + * @param s The row / beat this activates. * @param p The percentage to use. * @param w The number of beats to wait. */ template - SpeedSegment(StartType r, float p, float w): - TimingSegment(max((StartType)0, r)), + SpeedSegment(StartType s, float p, float w): + TimingSegment(max((StartType)0, s)), ratio(p), length(w), unit(0) {} /** * @brief Sets up the SpeedSegment with specified values. - * @param r The row / beat this activates. + * @param s The row / beat this activates. * @param p The percentage to use. * @param w The number of beats/seconds to wait. * @param k The mode used for the wait variable. */ template - SpeedSegment(StartType r, float p, float w, unsigned short k): - TimingSegment(max((StartType)0, r)), + SpeedSegment(StartType s, float p, float w, unsigned short k): + TimingSegment(max((StartType)0, s)), ratio(p), length(w), unit(k) {} /** From 6f83556da718eba6fb5d890dd5441850c7e5d491 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Wed, 1 Jun 2011 14:21:57 +0700 Subject: [PATCH 24/27] fix the template mess! it now builds on windows but not sure if it works or if it will build on other platforms. --- src/TimingSegments.cpp | 7 ---- src/TimingSegments.h | 83 +++++++++++++++++++++++++++++++++--------- 2 files changed, 66 insertions(+), 24 deletions(-) diff --git a/src/TimingSegments.cpp b/src/TimingSegments.cpp index dc5149c41b..4184eff487 100644 --- a/src/TimingSegments.cpp +++ b/src/TimingSegments.cpp @@ -26,13 +26,6 @@ float BaseTimingSegment::GetBeat() const return NoteRowToBeat(GetRow()); } -template -bool TimingSegment::operator<( const DerivedSegment &other ) const -{ - LTCOMPARE(GetRow()); - return false; -} - /* ====================================================== Here comes the actual timing segments implementation!! */ diff --git a/src/TimingSegments.h b/src/TimingSegments.h index 665ee7cda8..07a6ceb046 100644 --- a/src/TimingSegments.h +++ b/src/TimingSegments.h @@ -15,18 +15,15 @@ struct BaseTimingSegment BaseTimingSegment(): startingRow(-1) {}; - BaseTimingSegment(const BaseTimingSegment &b) - { - *this = b; - } - /** * @brief Set up a BaseTimingSegment with specified values. - * @param s the starting row / beat. - * - * NOTE: On Windows, it's passing in the Segments, not ints or floats. */ - template - BaseTimingSegment(StartType s): startingRow(s) {} + * @param s the starting row / beat. */ + BaseTimingSegment(int s): startingRow(ToNoteRow(s)) {} + BaseTimingSegment(float s): startingRow(ToNoteRow(s)) {} + + template + BaseTimingSegment(const DerivedSegment &other): + startingRow(other.GetRow()) {}; virtual ~BaseTimingSegment(); @@ -68,11 +65,11 @@ template struct TimingSegment: public BaseTimingSegment { - TimingSegment(): BaseTimingSegment(-1) {}; - - TimingSegment(int s): BaseTimingSegment(s) {}; - - TimingSegment(float s): BaseTimingSegment(ToNoteRow(s)) {}; + TimingSegment(): BaseTimingSegment() {}; + TimingSegment(const DerivedSegment &other): BaseTimingSegment(other) {}; + + template + TimingSegment(StartType s): BaseTimingSegment(s) {}; /** * @brief Compares two DrivedSegments to see if one is less than the other. @@ -82,7 +79,10 @@ struct TimingSegment: public BaseTimingSegment * This is virtual to allow other segments to implement comparison * as required by them. */ - virtual bool operator<( const DerivedSegment &other ) const; + virtual bool operator<( const DerivedSegment &other ) const + { + return this->GetRow() < other.GetRow(); + }; /** * @brief Compares two DrivedSegments to see if they are equal to each other. @@ -149,6 +149,14 @@ struct FakeSegment : public TimingSegment FakeSegment(): TimingSegment(-1), lengthBeats(-1) {}; + /** + * @brief Create a copy of another Fake Segment. + * @param other the other fake segment + */ + FakeSegment(const FakeSegment &other): + TimingSegment(other), + lengthBeats(other.GetLength()) {}; + /** * @brief Create a Fake Segment with the specified values. * @param s the starting row of this segment. @@ -200,6 +208,14 @@ struct WarpSegment : public TimingSegment WarpSegment(): TimingSegment(), lengthBeats(-1) {}; + /** + * @brief Create a copy of another Warp Segment. + * @param other the other warp segment + */ + WarpSegment(const WarpSegment &other): + TimingSegment(other.GetRow()), + lengthBeats(other.GetLength()) {}; + /** * @brief Create a Warp Segment with the specified values. * @param s the starting row of this segment. @@ -207,7 +223,7 @@ struct WarpSegment : public TimingSegment */ template WarpSegment( StartType s, LengthType r ): - TimingSegment(max((StartType)0, s)), + TimingSegment(s), lengthBeats(ToBeat(max((LengthType)0, r))) {}; /** @@ -251,6 +267,14 @@ struct TickcountSegment : public TimingSegment TickcountSegment(): TimingSegment(), ticks(4) {}; + /** + * @brief Create a copy of another Tickcount Segment. + * @param other the other tickcount segment + */ + TickcountSegment(const TickcountSegment &other): + TimingSegment(other), + ticks(other.GetTicks()) {}; + /** * @brief Creates a TickcountSegment with specified values. * @param s the starting row / beat. */ @@ -305,6 +329,11 @@ struct ComboSegment : public TimingSegment */ ComboSegment() : TimingSegment(), combo(1) { } + + ComboSegment(const ComboSegment &other) : + TimingSegment(other), + combo(other.GetCombo()) {}; + /** * @brief Creates a Combo Segment with the specified values. * @param s the starting row / beat of this segment. @@ -354,6 +383,11 @@ struct LabelSegment : public TimingSegment */ LabelSegment() : TimingSegment(), label("") { } + + LabelSegment(const LabelSegment &other) : + TimingSegment(other), + label(other.GetLabel()) {}; + /** * @brief Creates a Label Segment with the specified values. * @param s the starting row / beat of this segment. @@ -403,6 +437,10 @@ struct BPMSegment : public TimingSegment BPMSegment() : TimingSegment(-1), bps(-1.0f) { } + BPMSegment(const BPMSegment &other) : + TimingSegment(other), + bps(other.GetBPS()) {}; + operator int() const { return 1; } operator float() const { return 2.0f; } @@ -464,6 +502,11 @@ struct TimeSignatureSegment : public TimingSegment TimeSignatureSegment(): TimingSegment(), numerator(4), denominator(4) { } + + TimeSignatureSegment(const TimeSignatureSegment &other) : + TimingSegment(other), + numerator(other.GetNum()), + denominator(other.GetDen()) {}; /** * @brief Creates a Time Signature Segment with supplied values. * @@ -552,6 +595,12 @@ struct SpeedSegment : public TimingSegment TimingSegment(0), ratio(1), length(0), unit(0) {} + SpeedSegment(const SpeedSegment &other) : + TimingSegment(other), + ratio(other.GetRatio()), + length(other.GetLength()), + unit(other.GetUnit()) {}; + /** * @brief Sets up the SpeedSegment with specified values. * @param s The row / beat this activates. From 6ca0cd1e70dfa0f95560e17b89d4f3439dd57cf3 Mon Sep 17 00:00:00 2001 From: Thai Pangsakulyanont Date: Wed, 1 Jun 2011 16:01:14 +0700 Subject: [PATCH 25/27] optimizations to NoteDataUtil::CalculateRadarValues, results in 3x faster loading. --- src/NoteDataUtil.cpp | 117 ++++++++++++++++++++++++++++++++++++++----- 1 file changed, 104 insertions(+), 13 deletions(-) diff --git a/src/NoteDataUtil.cpp b/src/NoteDataUtil.cpp index c892d3d52b..022691c700 100644 --- a/src/NoteDataUtil.cpp +++ b/src/NoteDataUtil.cpp @@ -778,27 +778,118 @@ void NoteDataUtil::LoadTransformedLightsFromTwo( const NoteData &marquee, const NoteDataUtil::RemoveMines( out ); } +struct RadarStats { + int taps; + int jumps; + int hands; + int quads; +}; + +RadarStats CalculateRadarStatsFast( const NoteData &in, RadarStats &out ) +{ + out.taps = 0; + out.jumps = 0; + out.hands = 0; + out.quads = 0; + map simultaneousMap; + map simultaneousMapNoHold; + map simultaneousMapTapHoldHead; + map::iterator itr; + for( int t=0; tsecond++; + + if( (itr = simultaneousMapNoHold.find(r)) == simultaneousMapNoHold.end() ) + simultaneousMapNoHold[r] = 1; + else + itr->second++; + + if( tn.type == TapNote::tap || tn.type == TapNote::lift || tn.type == TapNote::hold_head ) + { + simultaneousMapTapHoldHead[r] = 1; + } + + if( tn.type == TapNote::hold_head ) + { + int searchStartRow = r + 1; + int searchEndRow = r + tn.iDuration; + FOREACH_NONEMPTY_ROW_ALL_TRACKS_RANGE( in, rr, searchStartRow, searchEndRow ) + { + switch( in.GetTapNote(t, rr).type ) + { + case TapNote::mine: + case TapNote::empty: + case TapNote::fake: + continue; // skip these types - they don't count + } + if( (itr = simultaneousMap.find(rr)) == simultaneousMap.end() ) + simultaneousMap[rr] = 1; + else + itr->second++; + } + } + } + } + for( itr = simultaneousMap.begin(); itr != simultaneousMap.end(); itr ++ ) + { + if( itr->second >= 3 ) + { + out.hands ++; + if( itr->second >= 4 ) + { + out.quads ++; + } + } + } + for( itr = simultaneousMapNoHold.begin(); itr != simultaneousMapNoHold.end(); itr ++ ) + { + if( itr->second >= 2 ) + { + out.jumps ++; + } + } + out.taps = simultaneousMapTapHoldHead.size(); + return out; +} + void NoteDataUtil::CalculateRadarValues( const NoteData &in, float fSongSeconds, RadarValues& out ) { + RadarStats stats; + CalculateRadarStatsFast( in, stats ); + // The for loop and the assert are used to ensure that all fields of // RadarValue get set in here. FOREACH_ENUM( RadarCategory, rc ) { switch( rc ) { - case RadarCategory_Stream: out[rc] = GetStreamRadarValue( in, fSongSeconds ); break; - case RadarCategory_Voltage: out[rc] = GetVoltageRadarValue( in, fSongSeconds ); break; - case RadarCategory_Air: out[rc] = GetAirRadarValue( in, fSongSeconds ); break; - case RadarCategory_Freeze: out[rc] = GetFreezeRadarValue( in, fSongSeconds ); break; - case RadarCategory_Chaos: out[rc] = GetChaosRadarValue( in, fSongSeconds ); break; - case RadarCategory_TapsAndHolds: out[rc] = (float) in.GetNumRowsWithTapOrHoldHead(); break; - case RadarCategory_Jumps: out[rc] = (float) in.GetNumJumps(); break; - case RadarCategory_Holds: out[rc] = (float) in.GetNumHoldNotes(); break; - case RadarCategory_Mines: out[rc] = (float) in.GetNumMines(); break; - case RadarCategory_Hands: out[rc] = (float) in.GetNumHands(); break; - case RadarCategory_Rolls: out[rc] = (float) in.GetNumRolls(); break; - case RadarCategory_Lifts: out[rc] = (float) in.GetNumLifts(); break; - case RadarCategory_Fakes: out[rc] = (float) in.GetNumFakes(); break; + case RadarCategory_Stream: out[rc] = GetStreamRadarValue( in, fSongSeconds ); break; + case RadarCategory_Voltage: out[rc] = GetVoltageRadarValue( in, fSongSeconds ); break; + case RadarCategory_Air: out[rc] = GetAirRadarValue( in, fSongSeconds ); break; + case RadarCategory_Freeze: out[rc] = GetFreezeRadarValue( in, fSongSeconds ); break; + case RadarCategory_Chaos: out[rc] = GetChaosRadarValue( in, fSongSeconds ); break; + case RadarCategory_TapsAndHolds: out[rc] = (float) stats.taps; break; + case RadarCategory_Jumps: out[rc] = (float) stats.jumps; break; + case RadarCategory_Holds: out[rc] = (float) in.GetNumHoldNotes(); break; + case RadarCategory_Mines: out[rc] = (float) in.GetNumMines(); break; + case RadarCategory_Hands: out[rc] = (float) stats.hands; break; + case RadarCategory_Rolls: out[rc] = (float) in.GetNumRolls(); break; + case RadarCategory_Lifts: out[rc] = (float) in.GetNumLifts(); break; + case RadarCategory_Fakes: out[rc] = (float) in.GetNumFakes(); break; default: ASSERT(0); } } From d50eb4830d62268e48d95527ac0b0b83c8ad226a Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Wed, 1 Jun 2011 07:48:59 -0400 Subject: [PATCH 26/27] The others are just other. Stay consistent. --- src/TimingSegments.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TimingSegments.h b/src/TimingSegments.h index 07a6ceb046..06d0c544a3 100644 --- a/src/TimingSegments.h +++ b/src/TimingSegments.h @@ -213,7 +213,7 @@ struct WarpSegment : public TimingSegment * @param other the other warp segment */ WarpSegment(const WarpSegment &other): - TimingSegment(other.GetRow()), + TimingSegment(other), lengthBeats(other.GetLength()) {}; /** From 50e93045cc592a057219c1a28fc7b05e6350ce5f Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Wed, 1 Jun 2011 08:44:09 -0400 Subject: [PATCH 27/27] Scroll Segments Satisfied. Just the Stops and Delays...in one segment. Yeah, maybe those should be split up at some point. --- src/NoteField.cpp | 6 ++-- src/NotesWriterSSC.cpp | 2 +- src/ScreenEdit.cpp | 2 +- src/TimingData.cpp | 41 ++++++++++++----------- src/TimingData.h | 76 ------------------------------------------ src/TimingSegments.cpp | 16 +++++++++ src/TimingSegments.h | 50 ++++++++++++++++++++++++++- 7 files changed, 92 insertions(+), 101 deletions(-) diff --git a/src/NoteField.cpp b/src/NoteField.cpp index 8b9684d2d1..1bee23ef11 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -999,11 +999,11 @@ void NoteField::DrawPrimitives() { FOREACH_CONST( ScrollSegment, timing.m_ScrollSegments, seg ) { - if( seg->m_iStartRow >= iFirstRowToDraw && seg->m_iStartRow <= iLastRowToDraw ) + if( seg->GetRow() >= iFirstRowToDraw && seg->GetRow() <= iLastRowToDraw ) { - float fBeat = NoteRowToBeat(seg->m_iStartRow); + float fBeat = seg->GetBeat(); if( IS_ON_SCREEN(fBeat) ) - DrawScrollText( fBeat, seg->m_fPercent ); + DrawScrollText( fBeat, seg->GetRatio() ); } } } diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index 5dfb891826..9c74594e6d 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -139,7 +139,7 @@ static void GetTimingTags( vector &lines, TimingData timing, bool bIsSo w.Init( "SCROLLS" ); FOREACH_CONST( ScrollSegment, timing.m_ScrollSegments, ss ) - w.Write( ss->m_iStartRow, ss->m_fPercent ); + w.Write( ss->GetRow(), ss->GetRatio() ); w.Finish(); if( !bIsSong ) diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index d2aa616e1c..695ff7fe63 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -4023,7 +4023,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromScrollChange, ENTER_SCROLL_VALUE, - ssprintf( "%.5f", GetAppropriateTiming().GetScrollSegmentAtBeat( GetBeat() ).m_fPercent ), + ssprintf( "%.5f", GetAppropriateTiming().GetScrollSegmentAtBeat( GetBeat() ).GetRatio() ), 10 ); break; diff --git a/src/TimingData.cpp b/src/TimingData.cpp index 8e1672e580..fb84c926ea 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -299,25 +299,25 @@ void TimingData::SetScrollAtRow( int iRow, float fPercent ) unsigned i; for( i = 0; i < m_ScrollSegments.size(); i++ ) { - if( m_ScrollSegments[i].m_iStartRow >= iRow) + if( m_ScrollSegments[i].GetRow() >= iRow) break; } - if ( i == m_ScrollSegments.size() || m_ScrollSegments[i].m_iStartRow != iRow ) + if ( i == m_ScrollSegments.size() || m_ScrollSegments[i].GetRow() != iRow ) { // the core mod itself matters the most for comparisons. - if( i == 0 || m_ScrollSegments[i-1].m_fPercent != fPercent ) + if( i == 0 || m_ScrollSegments[i-1].GetRatio() != fPercent ) AddScrollSegment( ScrollSegment(iRow, fPercent) ); } else { // The others aren't compared: only the mod itself matters. - if( i > 0 && m_ScrollSegments[i-1].m_fPercent == fPercent ) + if( i > 0 && m_ScrollSegments[i-1].GetRatio() == fPercent ) m_ScrollSegments.erase( m_ScrollSegments.begin()+i, m_ScrollSegments.begin()+i+1 ); else { - m_ScrollSegments[i].m_fPercent = fPercent; + m_ScrollSegments[i].SetRatio(fPercent); } } } @@ -434,7 +434,7 @@ unsigned short TimingData::GetSpeedModeAtRow( int iRow ) float TimingData::GetScrollAtRow( int iRow ) { - return GetScrollSegmentAtRow( iRow ).m_fPercent; + return GetScrollSegmentAtRow( iRow ).GetRatio(); } float TimingData::GetFakeAtRow( int iFakeRow ) const @@ -628,7 +628,7 @@ int TimingData::GetScrollSegmentIndexAtRow( int iRow ) const { unsigned i; for (i=0; i < m_ScrollSegments.size() - 1; i++ ) - if( m_ScrollSegments[i+1].m_iStartRow > iRow ) + if( m_ScrollSegments[i+1].GetRow() > iRow ) break; return static_cast(i); } @@ -665,7 +665,7 @@ ScrollSegment& TimingData::GetScrollSegmentAtRow( int iRow ) { unsigned i; for( i=0; i iRow ) + if( m_ScrollSegments[i+1].GetRow() > iRow ) break; return m_ScrollSegments[i]; } @@ -1003,10 +1003,13 @@ float TimingData::GetElapsedTimeFromBeatNoOffset( float fBeat ) const float TimingData::GetDisplayedBeat( float fBeat ) const { unsigned index = GetScrollSegmentIndexAtBeat(fBeat); - float fOutBeat = ( fBeat - NoteRowToBeat(m_ScrollSegments[index].m_iStartRow) ) * m_ScrollSegments[index].m_fPercent; + const ScrollSegment &s = m_ScrollSegments[index]; + float fOutBeat = ( fBeat - s.GetBeat() ) * s.GetRatio(); for( unsigned i = 0; i < index; i ++ ) { - fOutBeat += ( NoteRowToBeat(m_ScrollSegments[i + 1].m_iStartRow) - NoteRowToBeat(m_ScrollSegments[i].m_iStartRow) ) * m_ScrollSegments[i].m_fPercent; + const ScrollSegment &future = m_ScrollSegments[i+1]; + const ScrollSegment ¤t = m_ScrollSegments[i]; + fOutBeat += ( future.GetBeat() - current.GetBeat() ) * current.GetRatio(); } return fOutBeat; } @@ -1147,13 +1150,13 @@ void TimingData::ScaleRegion( float fScale, int iStartIndex, int iEndIndex, bool for( unsigned i = 0; i < m_ScrollSegments.size(); i++ ) { ScrollSegment &s = m_ScrollSegments[i]; - const int iSegStartRow = s.m_iStartRow; + const int iSegStartRow = s.GetRow(); if( iSegStartRow < iStartIndex ) continue; else if( iSegStartRow > iEndIndex ) - s.m_iStartRow += lrintf((iEndIndex - iStartIndex) * (fScale - 1)); + s.SetRow(s.GetRow() + lrintf((iEndIndex - iStartIndex) * (fScale - 1))); else - s.m_iStartRow = lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex; + s.SetRow(lrintf((iSegStartRow - iStartIndex) * fScale) + iStartIndex); } // adjust BPM changes to preserve timing @@ -1258,9 +1261,9 @@ void TimingData::InsertRows( int iStartRow, int iRowsToAdd ) for( unsigned i = 0; i < m_ScrollSegments.size(); i++ ) { ScrollSegment &scrl = m_ScrollSegments[i]; - if( scrl.m_iStartRow < iStartRow ) + if( scrl.GetRow() < iStartRow ) continue; - scrl.m_iStartRow += iRowsToAdd; + scrl.SetRow(scrl.GetRow() + iRowsToAdd); } if( iStartRow == 0 ) @@ -1453,17 +1456,17 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) for( unsigned i = 0; i < m_ScrollSegments.size(); i++ ) { ScrollSegment &scrl = m_ScrollSegments[i]; - - if( scrl.m_iStartRow < iStartRow ) + int keyRow = scrl.GetRow(); + if( keyRow < iStartRow ) continue; - if( scrl.m_iStartRow < iStartRow+iRowsToDelete ) + if( keyRow < iStartRow+iRowsToDelete ) { m_ScrollSegments.erase( m_ScrollSegments.begin()+i, m_ScrollSegments.begin()+i+1 ); --i; continue; } - scrl.m_iStartRow -= iRowsToDelete; + scrl.SetRow(keyRow - iRowsToDelete); } this->SetBPMAtRow( iStartRow, fNewBPM ); diff --git a/src/TimingData.h b/src/TimingData.h index 45f81fe268..ff876a9c5f 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -119,82 +119,6 @@ struct StopSegment bool operator>=( const StopSegment &other ) const { return !operator<(other); } }; -/** - * @brief Identifies when the chart scroll changes. - * - * ScrollSegments adjusts the scrolling speed of the note field. - * Unlike forced attacks, these cannot be turned off at a set time: - * reset it by setting the precentage back to 1. - * - * These were inspired by the Pump It Up series. */ -struct ScrollSegment -{ - /** @brief Sets up the ScrollSegment with default values. */ - ScrollSegment(): m_iStartRow(0), m_fPercent(1) {} - - /** - * @brief Sets up the ScrollSegment with specified values. - * @param i The row this activates. - * @param p The percentage to use. */ - ScrollSegment(int i, float p): m_iStartRow(i), m_fPercent(p) {} - - /** - * @brief Sets up the ScrollSegment with specified values. - * @param r The beat this activates. - * @param p The percentage to use. */ - ScrollSegment(float r, float p): m_iStartRow(BeatToNoteRow(r)), m_fPercent(p) {} - - /** @brief The row in which the ScrollSegment activates. */ - int m_iStartRow; - /** @brief The percentage to use when multiplying the chart's scroll rate. */ - float m_fPercent; - - /** - * @brief Compares two ScrollSegment to see if they are equal to each other. - * @param other the other ScrollSegment to compare to. - * @return the equality of the two segments. - */ - bool operator==( const ScrollSegment &other ) const - { - COMPARE( m_iStartRow ); - COMPARE( m_fPercent ); - return true; - } - /** - * @brief Compares two ScrollSegment to see if they are not equal to each other. - * @param other the other ScrollSegment to compare to. - * @return the inequality of the two segments. - */ - bool operator!=( const ScrollSegment &other ) const { return !operator==(other); } - /** - * @brief Compares two ScrollSegment to see if one is less than the other. - * @param other the other ScrollSegment to compare to. - * @return the truth/falsehood of if the first is less than the second. - */ - bool operator<( const ScrollSegment &other ) const { return m_iStartRow < other.m_iStartRow; } - /** - * @brief Compares two ScrollSegment to see if one is less than or equal to the other. - * @param other the other ScrollSegment to compare to. - * @return the truth/falsehood of if the first is less or equal to than the second. - */ - bool operator<=( const ScrollSegment &other ) const - { - return ( operator<(other) || operator==(other) ); - } - /** - * @brief Compares two ScrollSegment to see if one is greater than the other. - * @param other the other ScrollSegment to compare to. - * @return the truth/falsehood of if the first is greater than the second. - */ - bool operator>( const ScrollSegment &other ) const { return !operator<=(other); } - /** - * @brief Compares two ScrollSegment to see if one is greater than or equal to the other. - * @param other the other ScrollSegment to compare to. - * @return the truth/falsehood of if the first is greater than or equal to the second. - */ - bool operator>=( const ScrollSegment &other ) const { return !operator<(other); } -}; - /** * @brief Holds data for translating beats<->seconds. */ diff --git a/src/TimingSegments.cpp b/src/TimingSegments.cpp index 4184eff487..8d6db81913 100644 --- a/src/TimingSegments.cpp +++ b/src/TimingSegments.cpp @@ -234,6 +234,22 @@ bool SpeedSegment::operator<( const SpeedSegment &other ) const return false; } +float ScrollSegment::GetRatio() const +{ + return this->ratio; +} + +void ScrollSegment::SetRatio(const float i) +{ + this->ratio = i; +} + +bool ScrollSegment::operator<( const ScrollSegment &other ) const +{ + LTCOMPARE(GetRow()); + LTCOMPARE(GetRatio()); + return false; +} /** * @file diff --git a/src/TimingSegments.h b/src/TimingSegments.h index 06d0c544a3..eedf256c62 100644 --- a/src/TimingSegments.h +++ b/src/TimingSegments.h @@ -688,12 +688,60 @@ private: * * 0: beats * 1: seconds - * other + * other values are undetermined at this time, but we're prepared this way. */ unsigned short unit; }; +/** + * @brief Identifies when the chart scroll changes. + * + * ScrollSegments adjusts the scrolling speed of the note field. + * Unlike forced attacks, these cannot be turned off at a set time: + * reset it by setting the precentage back to 1. + * + * These were inspired by the Pump It Up series. */ +struct ScrollSegment : public TimingSegment +{ + /** @brief Sets up the ScrollSegment with default values. */ + ScrollSegment(): TimingSegment(0), + ratio(1) {} + + /** + * @brief Sets up the ScrollSegment with specified values. + * @param s The row / beat this activates. + * @param p The percentage to use. */ + template + ScrollSegment( StartType s, float p): + TimingSegment(max((StartType)0, s)), + ratio(p) {} + + ScrollSegment(const ScrollSegment &other) : + TimingSegment(other), + ratio(other.GetRatio()) {} + + /** + * @brief Get the ratio in this SpeedSegment. + * @return the ratio. */ + float GetRatio() const; + + /** + * @brief Set the ratio in this SpeedSegment. + * @param i the ratio. */ + void SetRatio(const float i); + + /** + * @brief Compares two ScrollSegment to see if one is less than the other. + * @param other the other ScrollSegment to compare to. + * @return the truth/falsehood of if the first is less than the second. + */ + bool operator<( const ScrollSegment &other ) const; +private: + /** @brief The ratio / percentage to use when multiplying the chart's scroll rate. */ + float ratio; +}; + #endif /**