Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members

NoteData.h

Go to the documentation of this file.
00001 /* NoteData - Holds data about the notes that the player is supposed to hit. */ 00002 00003 #ifndef NOTEDATA_H 00004 #define NOTEDATA_H 00005 00006 #include "NoteTypes.h" 00007 #include <map> 00008 #include <set> 00009 #include "Attack.h" 00010 00011 #define FOREACH_NONEMPTY_ROW_IN_TRACK( nd, track, row ) \ 00012 for( int row = -1; (nd).GetNextTapNoteRowForTrack(track,row); ) 00013 #define FOREACH_NONEMPTY_ROW_IN_TRACK_RANGE( nd, track, row, start, last ) \ 00014 for( int row = start-1; (nd).GetNextTapNoteRowForTrack(track,row) && row < (last); ) 00015 #define FOREACH_NONEMPTY_ROW_IN_TRACK_RANGE_REVERSE( nd, track, row, start, last ) \ 00016 for( int row = last; (nd).GetPrevTapNoteRowForTrack(track,row) && row >= (start); ) 00017 #define FOREACH_NONEMPTY_ROW_ALL_TRACKS( nd, row ) \ 00018 for( int row = -1; (nd).GetNextTapNoteRowForAllTracks(row); ) 00019 #define FOREACH_NONEMPTY_ROW_ALL_TRACKS_RANGE( nd, row, start, last ) \ 00020 for( int row = start-1; (nd).GetNextTapNoteRowForAllTracks(row) && row < (last); ) 00021 00022 class NoteData 00023 { 00024 public: 00025 typedef map<int,TapNote> TrackMap; 00026 typedef map<int,TapNote>::iterator iterator; 00027 typedef map<int,TapNote>::const_iterator const_iterator; 00028 00029 private: 00030 // There's no point in inserting empty notes into the map. 00031 // Any blank space in the map is defined to be empty. 00032 vector<TrackMap> m_TapNotes; 00033 00034 public: 00035 NoteData(); 00036 ~NoteData(); 00037 void Init(); 00038 00039 int GetNumTracks() const { return m_TapNotes.size(); } 00040 void SetNumTracks( int iNewNumTracks ); 00041 00042 /* Return the note at the given track and row. Row may be out of 00043 * range; pretend the song goes on with TAP_EMPTYs indefinitely. */ 00044 inline const TapNote &GetTapNote(unsigned track, int row) const 00045 { 00046 const TrackMap &mapTrack = m_TapNotes[track]; 00047 TrackMap::const_iterator iter = mapTrack.find( row ); 00048 if( iter != mapTrack.end() ) 00049 return iter->second; 00050 else 00051 return TAP_EMPTY; 00052 } 00053 00054 iterator begin( int iTrack ) { return m_TapNotes[iTrack].begin(); } 00055 const_iterator begin( int iTrack ) const { return m_TapNotes[iTrack].begin(); } 00056 iterator end( int iTrack ) { return m_TapNotes[iTrack].end(); } 00057 const_iterator end( int iTrack ) const { return m_TapNotes[iTrack].end(); } 00058 00059 inline iterator FindTapNote( unsigned iTrack, int iRow ) { return m_TapNotes[iTrack].find( iRow ); } 00060 inline const_iterator FindTapNote( unsigned iTrack, int iRow ) const { return m_TapNotes[iTrack].find( iRow ); } 00061 void RemoveTapNote( unsigned iTrack, iterator it ) { m_TapNotes[iTrack].erase( it ); } 00062 00063 /* Return an iterator range including exactly iStartRow to iEndRow. */ 00064 void GetTapNoteRange( int iTrack, int iStartRow, int iEndRow, const_iterator &begin, const_iterator &end ) const; 00065 void GetTapNoteRange( int iTrack, int iStartRow, int iEndRow, TrackMap::iterator &begin, TrackMap::iterator &end ); 00066 00067 /* Return an iterator range include iStartRow to iEndRow. Extend the range to include 00068 * hold notes overlapping the boundary. */ 00069 void GetTapNoteRangeInclusive( int iTrack, int iStartRow, int iEndRow, const_iterator &begin, const_iterator &end, bool bIncludeAdjacent=false ) const; 00070 void GetTapNoteRangeInclusive( int iTrack, int iStartRow, int iEndRow, iterator &begin, iterator &end, bool bIncludeAdjacent=false ); 00071 00072 /* Return an iterator range include iStartRow to iEndRow. Shrink the range to exclude 00073 * hold notes overlapping the boundary. */ 00074 void GetTapNoteRangeExclusive( int iTrack, int iStartRow, int iEndRow, const_iterator &begin, const_iterator &end ) const; 00075 void GetTapNoteRangeExclusive( int iTrack, int iStartRow, int iEndRow, iterator &begin, iterator &end ); 00076 00077 00078 // Use this to iterate over notes. 00079 // Returns the row index of the first TapNote on the track that has a row 00080 // index > afterRow. 00081 bool GetNextTapNoteRowForTrack( int track, int &rowInOut ) const; 00082 bool GetNextTapNoteRowForAllTracks( int &rowInOut ) const; 00083 bool GetPrevTapNoteRowForTrack( int track, int &rowInOut ) const; 00084 00085 void MoveTapNoteTrack( int dest, int src ); 00086 void SetTapNote( int track, int row, const TapNote& tn ); 00087 void AddHoldNote( int iTrack, int iStartRow, int iEndRow, TapNote tn ); // add note hold note merging overlapping HoldNotes and destroying TapNotes underneath 00088 00089 void ClearRangeForTrack( int rowBegin, int rowEnd, int iTrack ); 00090 void ClearRange( int rowBegin, int rowEnd ); 00091 void ClearAll(); 00092 void CopyRange( const NoteData& from, int rowFromBegin, int rowFromEnd, int rowToBegin = 0 ); 00093 void CopyAll( const NoteData& from ); 00094 00095 bool IsRowEmpty( int row ) const; 00096 bool IsRangeEmpty( int track, int rowBegin, int rowEnd ) const; 00097 int GetNumTapNonEmptyTracks( int row ) const; 00098 void GetTapNonEmptyTracks( int row, set<int>& addTo ) const; 00099 bool GetTapFirstNonEmptyTrack( int row, int &iNonEmptyTrackOut ) const; // return false if no non-empty tracks at row 00100 bool GetTapFirstEmptyTrack( int row, int &iEmptyTrackOut ) const; // return false if no non-empty tracks at row 00101 bool GetTapLastEmptyTrack( int row, int &iEmptyTrackOut ) const; // return false if no empty tracks at row 00102 int GetNumTracksWithTap( int row ) const; 00103 int GetNumTracksWithTapOrHoldHead( int row ) const; 00104 int GetFirstTrackWithTap( int row ) const; 00105 int GetFirstTrackWithTapOrHoldHead( int row ) const; 00106 00107 inline bool IsThereATapAtRow( int row ) const 00108 { 00109 return GetFirstTrackWithTap( row ) != -1; 00110 } 00111 inline bool IsThereATapOrHoldHeadAtRow( int row ) const 00112 { 00113 return GetFirstTrackWithTapOrHoldHead( row ) != -1; 00114 } 00115 void GetTracksHeldAtRow( int row, set<int>& addTo ); 00116 int GetNumTracksHeldAtRow( int row ); 00117 00118 /* Determine if a given spot is within a hold note (being on the tail doesn't count). 00119 * Return true if so. If pHeadRow is non-NULL, return the row of the head. If pTailRow is 00120 * non-NULL, return the row of the tail. This function is faster if pTailRow is NULL. */ 00121 bool IsHoldNoteAtBeat( int iTrack, int iRow, int *pHeadRow = NULL ) const; 00122 00123 // 00124 // statistics 00125 // 00126 int GetFirstRow() const; // return the beat number of the first note 00127 float GetFirstBeat() const { return NoteRowToBeat( GetFirstRow() ); } 00128 int GetLastRow() const; // return the beat number of the last note 00129 float GetLastBeat() const { return NoteRowToBeat( GetLastRow() ); } 00130 int GetNumTapNotes( int iStartIndex = 0, int iEndIndex = MAX_NOTE_ROW ) const; 00131 int GetNumMines( int iStartIndex = 0, int iEndIndex = MAX_NOTE_ROW ) const; 00132 int GetNumHands( int iStartIndex = 0, int iEndIndex = MAX_NOTE_ROW ) const; 00133 int GetNumRowsWithTap( int iStartIndex = 0, int iEndIndex = MAX_NOTE_ROW ) const; 00134 int GetNumRowsWithTapOrHoldHead( int iStartIndex = 0, int iEndIndex = MAX_NOTE_ROW ) const; 00135 int GetNumN( int iMinTaps, int iStartIndex = 0, int iEndIndex = MAX_NOTE_ROW ) const; 00136 // should hands also count as a jump? 00137 int GetNumDoubles( int iStartIndex = 0, int iEndIndex = MAX_NOTE_ROW ) const { return GetNumN( 2, iStartIndex, iEndIndex ); } 00138 /* optimization: for the default of start to end, use the second (faster) */ 00139 int GetNumHoldNotes( int iStartIndex = 0, int iEndIndex = MAX_NOTE_ROW ) const; 00140 int RowNeedsHands( int row ) const; 00141 00142 // Transformations 00143 void LoadTransformed( const NoteData& original, int iNewNumTracks, const int iOriginalTrackToTakeFrom[] ); // -1 for iOriginalTracksToTakeFrom means no track 00144 00145 /* hold_tail is only used to make SM parsing easier. */ 00146 void InsertHoldTails(); 00147 void RemoveHoldTails(); /* adjusts iDuration */ 00148 }; 00149 00150 00151 #endif 00152 00153 /* 00154 * (c) 2001-2004 Chris Danford, Glenn Maynard 00155 * All rights reserved. 00156 * 00157 * Permission is hereby granted, free of charge, to any person obtaining a 00158 * copy of this software and associated documentation files (the 00159 * "Software"), to deal in the Software without restriction, including 00160 * without limitation the rights to use, copy, modify, merge, publish, 00161 * distribute, and/or sell copies of the Software, and to permit persons to 00162 * whom the Software is furnished to do so, provided that the above 00163 * copyright notice(s) and this permission notice appear in all copies of 00164 * the Software and that both the above copyright notice(s) and this 00165 * permission notice appear in supporting documentation. 00166 * 00167 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 00168 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 00169 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF 00170 * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS 00171 * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT 00172 * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS 00173 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 00174 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 00175 * PERFORMANCE OF THIS SOFTWARE. 00176 */

Generated on Thu Jan 27 20:57:26 2005 for StepMania by doxygen 1.3.7