make NoteDataUtil::LoadTransformedLights work
This commit is contained in:
@@ -375,8 +375,17 @@ void NoteData::RemoveHoldNote( int iHoldIndex )
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Return true if a hold note lies on the given spot. Must be in 2sAnd3s. */
|
/* Return true if a hold note lies on the given spot. Must be in 2sAnd3s. */
|
||||||
bool NoteData::IsHoldNoteAtBeat( int iTrack, int iRow ) const
|
bool NoteData::IsHoldNoteAtBeat( int iTrack, int iRow, int *pHeadRow, int *pTailRow ) const
|
||||||
{
|
{
|
||||||
|
/* If neither the actual head nor tail row were requested, search for the head to
|
||||||
|
* determine the return value. */
|
||||||
|
int iDummy;
|
||||||
|
if( pHeadRow == NULL )
|
||||||
|
pHeadRow = &iDummy;
|
||||||
|
|
||||||
|
bool bFoundHead = false;
|
||||||
|
if( pHeadRow != NULL )
|
||||||
|
{
|
||||||
/* Starting at iRow, search upwards. If we find a TapNote::hold_head, we're within
|
/* Starting at iRow, search upwards. If we find a TapNote::hold_head, we're within
|
||||||
* a hold. If we find a tap, mine or attack, we're not--those never lie within hold
|
* a hold. If we find a tap, mine or attack, we're not--those never lie within hold
|
||||||
* notes. Ignore autoKeysound. */
|
* notes. Ignore autoKeysound. */
|
||||||
@@ -386,7 +395,9 @@ bool NoteData::IsHoldNoteAtBeat( int iTrack, int iRow ) const
|
|||||||
switch( tn.type )
|
switch( tn.type )
|
||||||
{
|
{
|
||||||
case TapNote::hold_head:
|
case TapNote::hold_head:
|
||||||
return true;
|
*pHeadRow = r;
|
||||||
|
bFoundHead = true;
|
||||||
|
break;
|
||||||
|
|
||||||
case TapNote::tap:
|
case TapNote::tap:
|
||||||
case TapNote::mine:
|
case TapNote::mine:
|
||||||
@@ -403,9 +414,62 @@ bool NoteData::IsHoldNoteAtBeat( int iTrack, int iRow ) const
|
|||||||
default:
|
default:
|
||||||
FAIL_M( ssprintf("%i", tn.type) );
|
FAIL_M( ssprintf("%i", tn.type) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( bFoundHead )
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If we didn't find a matching head, we're not within a hold note, so don't bother
|
||||||
|
* searching for a tail. */
|
||||||
|
if( !bFoundHead )
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bFoundTail = false;
|
||||||
|
if( pTailRow != NULL )
|
||||||
|
{
|
||||||
|
FOREACH_NONEMPTY_ROW_IN_TRACK_RANGE( *this, iTrack, r, iRow, MAX_NOTE_ROW )
|
||||||
|
{
|
||||||
|
const TapNote &tn = GetTapNote( iTrack, r );
|
||||||
|
|
||||||
|
switch( tn.type )
|
||||||
|
{
|
||||||
|
case TapNote::hold_tail:
|
||||||
|
*pTailRow = r;
|
||||||
|
bFoundTail = true;
|
||||||
|
break;
|
||||||
|
case TapNote::tap:
|
||||||
|
case TapNote::mine:
|
||||||
|
case TapNote::attack:
|
||||||
|
return false;
|
||||||
|
case TapNote::hold_head:
|
||||||
|
/* If iRow is a hold head, we're within a hold note, and need to continue searching;
|
||||||
|
* if any row after that is a head, we're not in it, so stop. This is different
|
||||||
|
* than above, since holds are [head,tail); the row of the tail isn't actually
|
||||||
|
* part of the hold. */
|
||||||
|
if( r == iRow )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
case TapNote::empty:
|
||||||
|
case TapNote::autoKeysound:
|
||||||
|
/* ignore */
|
||||||
|
continue;
|
||||||
|
case TapNote::hold:
|
||||||
|
/* Don't call this function when in 4s mode! */
|
||||||
|
FAIL_M("hold");
|
||||||
|
default:
|
||||||
|
FAIL_M( ssprintf("%i", tn.type) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( bFoundTail )
|
||||||
|
break;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bFoundHead || bFoundTail;
|
||||||
}
|
}
|
||||||
|
|
||||||
int NoteData::GetFirstRow() const
|
int NoteData::GetFirstRow() const
|
||||||
|
|||||||
@@ -104,7 +104,12 @@ public:
|
|||||||
void RemoveHoldNote( int index );
|
void RemoveHoldNote( int index );
|
||||||
HoldNote &GetHoldNote( int index ) { ASSERT( index < (int) m_HoldNotes.size() ); return m_HoldNotes[index]; }
|
HoldNote &GetHoldNote( int index ) { ASSERT( index < (int) m_HoldNotes.size() ); return m_HoldNotes[index]; }
|
||||||
const HoldNote &GetHoldNote( int index ) const { ASSERT( index < (int) m_HoldNotes.size() ); return m_HoldNotes[index]; }
|
const HoldNote &GetHoldNote( int index ) const { ASSERT( index < (int) m_HoldNotes.size() ); return m_HoldNotes[index]; }
|
||||||
bool IsHoldNoteAtBeat( int iTrack, int iRow ) const; /* must be in 2sAnd3s */
|
|
||||||
|
/* Determine if a given spot is within a hold note (being on the tail doesn't count).
|
||||||
|
* Return true if so. If pHeadRow is non-NULL, return the row of the head. If pTailRow is
|
||||||
|
* non-NULL, return the row of the tail. This function is faster if pTailRow is NULL.
|
||||||
|
* Must be in 2sAnd3s. */
|
||||||
|
bool IsHoldNoteAtBeat( int iTrack, int iRow, int *pHeadRow = NULL, int *pTailRow = NULL ) const;
|
||||||
|
|
||||||
//
|
//
|
||||||
// statistics
|
// statistics
|
||||||
|
|||||||
@@ -381,6 +381,21 @@ void NoteDataUtil::LoadOverlapped( const NoteData &input, NoteData &out, int iNe
|
|||||||
out.Convert4sToHoldNotes();
|
out.Convert4sToHoldNotes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int FindLongestOverlappingHoldNoteForAnyTrack( const NoteData &in, int iRow )
|
||||||
|
{
|
||||||
|
int iMaxTailRow = -1;
|
||||||
|
for( int t=0; t<in.GetNumTracks(); t++ )
|
||||||
|
{
|
||||||
|
int iTailRow;
|
||||||
|
if( !in.IsHoldNoteAtBeat( t, iRow, NULL, &iTailRow ) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
iMaxTailRow = max( iMaxTailRow, iTailRow );
|
||||||
|
}
|
||||||
|
|
||||||
|
return iMaxTailRow;
|
||||||
|
}
|
||||||
|
|
||||||
void NoteDataUtil::LoadTransformedLights( const NoteData &in, NoteData &out, int iNewNumTracks )
|
void NoteDataUtil::LoadTransformedLights( const NoteData &in, NoteData &out, int iNewNumTracks )
|
||||||
{
|
{
|
||||||
// reset all notes
|
// reset all notes
|
||||||
@@ -393,26 +408,38 @@ void NoteDataUtil::LoadTransformedLights( const NoteData &in, NoteData &out, int
|
|||||||
|
|
||||||
FOREACH_NONEMPTY_ROW_ALL_TRACKS( in, r )
|
FOREACH_NONEMPTY_ROW_ALL_TRACKS( in, r )
|
||||||
{
|
{
|
||||||
|
/* If any row starts a hold note, find the end of the hold note, and keep searching
|
||||||
|
* until we've extended to the end of the latest overlapping hold note. */
|
||||||
|
int iHoldStart = r;
|
||||||
|
int iHoldEnd = -1;
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
int iMaxTailRow = FindLongestOverlappingHoldNoteForAnyTrack( Original, r );
|
||||||
|
if( iMaxTailRow == -1 )
|
||||||
|
break;
|
||||||
|
iHoldEnd = iMaxTailRow;
|
||||||
|
r = iMaxTailRow;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( iHoldEnd != -1 )
|
||||||
|
{
|
||||||
|
/* If we found a hold note, add it to all tracks. */
|
||||||
|
HoldNote hn( 0, iHoldStart, iHoldEnd );
|
||||||
|
for( int t=0; t<Original.GetNumTracks(); t++ )
|
||||||
|
{
|
||||||
|
hn.iTrack = t;
|
||||||
|
out.AddHoldNote( hn );
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if( Original.IsRowEmpty( r ) )
|
if( Original.IsRowEmpty( r ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Enable every track in the output. If there are any hold notes in the source
|
/* Enable every track in the output. */
|
||||||
* on this row, output hold notes; otherwise tap notes. This is to 1: prevent
|
|
||||||
* converting everything to hold notes, and 2: so if it's written to an SM, we
|
|
||||||
* don't write huge streams of tap notes. */
|
|
||||||
bool bHoldNoteOnThisRow = false;
|
|
||||||
for( int t=0; t<Original.GetNumTracks(); t++ )
|
|
||||||
if( Original.IsHoldNoteAtBeat(t,r) )
|
|
||||||
bHoldNoteOnThisRow = true;
|
|
||||||
|
|
||||||
for( int t=0; t<out.GetNumTracks(); t++ )
|
for( int t=0; t<out.GetNumTracks(); t++ )
|
||||||
{
|
out.SetTapNote( t, r, TAP_ORIGINAL_TAP );
|
||||||
TapNote tn = bHoldNoteOnThisRow ? TAP_ORIGINAL_HOLD : TAP_ORIGINAL_TAP;
|
|
||||||
out.SetTapNote( t, r, tn );
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
out.Convert2sAnd3sToHoldNotes();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NoteDataUtil::GetRadarValues( const NoteData &in, float fSongSeconds, RadarValues& out )
|
void NoteDataUtil::GetRadarValues( const NoteData &in, float fSongSeconds, RadarValues& out )
|
||||||
|
|||||||
Reference in New Issue
Block a user