no message
This commit is contained in:
@@ -125,7 +125,7 @@ void Background::Update( float fDeltaTime )
|
||||
switch( PREFSMAN->m_visMode )
|
||||
{
|
||||
case VIS_MODE_ANIMATION:
|
||||
if( m_pCurBackgroundAnimation )
|
||||
if( m_pCurBackgroundAnimation && !m_bFreeze )
|
||||
m_pCurBackgroundAnimation->Update( fDeltaTime, m_fSongBeat );
|
||||
else
|
||||
m_sprSongBackground.Update( fDeltaTime );
|
||||
|
||||
@@ -29,7 +29,7 @@ public:
|
||||
virtual void Update( float fDeltaTime );
|
||||
virtual void DrawPrimitives();
|
||||
|
||||
void SetSongBeat( const float fSongBeat ) { m_fSongBeat = fSongBeat; };
|
||||
void SetSongBeat( const float fSongBeat, const bool bFreeze ) { m_fSongBeat = fSongBeat; m_bFreeze = bFreeze; };
|
||||
|
||||
virtual void SetDiffuseColor( D3DXCOLOR c )
|
||||
{
|
||||
@@ -60,5 +60,6 @@ protected:
|
||||
bool m_bShowDanger;
|
||||
|
||||
float m_fSongBeat;
|
||||
bool m_bFreeze;
|
||||
};
|
||||
|
||||
|
||||
@@ -154,6 +154,18 @@ inline CString DifficultyClassToString( DifficultyClass dc )
|
||||
}
|
||||
}
|
||||
|
||||
inline DifficultyClass StringToDifficultyClass( CString sDC )
|
||||
{
|
||||
for( int i=0; i<NUM_DIFFICULTY_CLASSES; i++ )
|
||||
{
|
||||
DifficultyClass dc = (DifficultyClass)i;
|
||||
if( sDC == DifficultyClassToString(dc) )
|
||||
return dc;
|
||||
}
|
||||
return CLASS_INVALID;
|
||||
}
|
||||
|
||||
|
||||
enum NotesType
|
||||
{
|
||||
NOTES_TYPE_DANCE_SINGLE = 0,
|
||||
@@ -169,7 +181,7 @@ enum NotesType
|
||||
NOTES_TYPE_INVALID,
|
||||
};
|
||||
|
||||
inline int NotesTypeToNumColumns( NotesType nt )
|
||||
inline int NotesTypeToNumTracks( NotesType nt )
|
||||
{
|
||||
switch( nt )
|
||||
{
|
||||
@@ -188,6 +200,7 @@ inline int NotesTypeToNumColumns( NotesType nt )
|
||||
|
||||
inline NotesType StringToNotesType( CString sNotesType )
|
||||
{
|
||||
sNotesType.MakeLower();
|
||||
if ( sNotesType == "dance-single" ) return NOTES_TYPE_DANCE_SINGLE;
|
||||
else if( sNotesType == "dance-double" ) return NOTES_TYPE_DANCE_DOUBLE;
|
||||
else if( sNotesType == "dance-couple" ) return NOTES_TYPE_DANCE_COUPLE;
|
||||
|
||||
@@ -38,8 +38,8 @@ void LifeMeterBar::ChangeLife( TapNoteScore score )
|
||||
float fDeltaLife;
|
||||
switch( score )
|
||||
{
|
||||
case TNS_PERFECT: fDeltaLife = +0.015f; break;
|
||||
case TNS_GREAT: fDeltaLife = +0.008f; break;
|
||||
case TNS_PERFECT: fDeltaLife = +0.008f; break;
|
||||
case TNS_GREAT: fDeltaLife = +0.004f; break;
|
||||
case TNS_GOOD: fDeltaLife = +0.000f; break;
|
||||
case TNS_BOO: fDeltaLife = -0.040f; break;
|
||||
case TNS_MISS: fDeltaLife = -0.080f; break;
|
||||
|
||||
@@ -82,6 +82,8 @@ void WheelItemData::Load( WheelItemType wit, Song* pSong, const CString &sSectio
|
||||
|
||||
WheelItemDisplay::WheelItemDisplay()
|
||||
{
|
||||
m_fPercentGray = 0;
|
||||
|
||||
m_MusicStatusDisplay.SetXY( -136, 0 );
|
||||
|
||||
m_TextBanner.SetHorizAlign( align_left );
|
||||
@@ -271,6 +273,15 @@ void WheelItemDisplay::DrawPrimitives()
|
||||
m_TextBanner.Draw();
|
||||
for( int p=0; p<NUM_PLAYERS; p++ )
|
||||
m_GradeDisplay[p].Draw();
|
||||
|
||||
if( m_fPercentGray > 0 )
|
||||
{
|
||||
m_sprSongBar.SetDiffuseColor( D3DXCOLOR(1,1,1,0) );
|
||||
m_sprSongBar.SetAddColor( D3DXCOLOR(0,0,0,m_fPercentGray) );
|
||||
m_sprSongBar.Draw();
|
||||
m_sprSongBar.SetDiffuseColor( D3DXCOLOR(1,1,1,1) );
|
||||
m_sprSongBar.SetAddColor( D3DXCOLOR(0,0,0,0) );
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TYPE_COURSE:
|
||||
@@ -403,7 +414,7 @@ MusicWheel::~MusicWheel()
|
||||
PREFSMAN->m_SongSortOrder = m_SortOrder;
|
||||
}
|
||||
|
||||
void MusicWheel::BuildWheelItemDatas( CArray<WheelItemData, WheelItemData&> &arrayWheelItemDatas, SongSortOrder so )
|
||||
void MusicWheel::BuildWheelItemDatas( CArray<WheelItemData, WheelItemData&> &arrayWheelItemDatas, SongSortOrder so, bool bRoulette )
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -469,6 +480,9 @@ void MusicWheel::BuildWheelItemDatas( CArray<WheelItemData, WheelItemData&> &arr
|
||||
case SORT_TITLE: bUseSections = true; break;
|
||||
default: ASSERT( false );
|
||||
}
|
||||
if( bRoulette )
|
||||
bUseSections = false;
|
||||
|
||||
|
||||
if( bUseSections )
|
||||
{
|
||||
@@ -556,7 +570,7 @@ void MusicWheel::BuildWheelItemDatas( CArray<WheelItemData, WheelItemData&> &arr
|
||||
arrayWheelItemDatas.SetSize( 1 );
|
||||
arrayWheelItemDatas[0].Load( TYPE_SECTION, NULL, "NO SONGS", NULL, D3DXCOLOR(1,0,0,1) );
|
||||
}
|
||||
else if( PREFSMAN->m_PlayMode == PLAY_MODE_ARCADE )
|
||||
else if( PREFSMAN->m_PlayMode == PLAY_MODE_ARCADE && !bRoulette )
|
||||
{
|
||||
arrayWheelItemDatas.SetSize( arrayWheelItemDatas.GetSize()+1 );
|
||||
arrayWheelItemDatas[arrayWheelItemDatas.GetSize()-1].Load( TYPE_ROULETTE, NULL, "", NULL, D3DXCOLOR(1,0,0,1) );
|
||||
@@ -696,6 +710,11 @@ void MusicWheel::DrawPrimitives()
|
||||
break;
|
||||
};
|
||||
|
||||
if( m_WheelState == STATE_LOCKED && i != NUM_WHEEL_ITEMS_TO_DRAW/2 )
|
||||
display.m_fPercentGray = 0.5f;
|
||||
else
|
||||
display.m_fPercentGray = 0;
|
||||
|
||||
display.Draw();
|
||||
}
|
||||
|
||||
@@ -720,7 +739,7 @@ void MusicWheel::Update( float fDeltaTime )
|
||||
|
||||
if( m_WheelState == STATE_ROULETTE_SPINNING )
|
||||
{
|
||||
NextMusic(); // spin as fast as possible
|
||||
NextMusic( false ); // spin as fast as possible
|
||||
}
|
||||
|
||||
if( m_fTimeLeftBeforePlayMusicSample > 0 )
|
||||
@@ -895,7 +914,7 @@ void MusicWheel::Update( float fDeltaTime )
|
||||
}
|
||||
|
||||
|
||||
void MusicWheel::PrevMusic()
|
||||
void MusicWheel::PrevMusic( bool bSendSongChangedMessage )
|
||||
{
|
||||
if( m_WheelState == STATE_LOCKED )
|
||||
{
|
||||
@@ -935,9 +954,12 @@ void MusicWheel::PrevMusic()
|
||||
m_fPositionOffsetFromSelection -= 1;
|
||||
|
||||
m_soundChangeMusic.Play();
|
||||
|
||||
if( bSendSongChangedMessage )
|
||||
SCREENMAN->SendMessageToTopScreen( SM_SongChanged, 0 );
|
||||
}
|
||||
|
||||
void MusicWheel::NextMusic()
|
||||
void MusicWheel::NextMusic( bool bSendSongChangedMessage )
|
||||
{
|
||||
if( m_WheelState == STATE_LOCKED )
|
||||
{
|
||||
@@ -978,6 +1000,9 @@ void MusicWheel::NextMusic()
|
||||
m_fPositionOffsetFromSelection += 1;
|
||||
|
||||
m_soundChangeMusic.Play();
|
||||
|
||||
if( bSendSongChangedMessage )
|
||||
SCREENMAN->SendMessageToTopScreen( SM_SongChanged, 0 );
|
||||
}
|
||||
|
||||
void MusicWheel::PrevSort()
|
||||
@@ -1054,6 +1079,10 @@ bool MusicWheel::Select() // return true of a playable item was chosen
|
||||
case TYPE_ROULETTE:
|
||||
m_soundExpand.Play();
|
||||
m_WheelState = STATE_ROULETTE_SPINNING;
|
||||
m_SortOrder = SORT_GROUP;
|
||||
m_MusicSortDisplay.SetDiffuseColor( D3DXCOLOR(1,1,1,0) );
|
||||
m_MusicSortDisplay.SetEffectNone();
|
||||
BuildWheelItemDatas( m_WheelItemDatas[SORT_GROUP], SORT_GROUP, true );
|
||||
return false;
|
||||
|
||||
case TYPE_SONG:
|
||||
|
||||
@@ -68,6 +68,8 @@ public:
|
||||
void LoadFromWheelItemData( WheelItemData* pWID );
|
||||
void RefreshGrades();
|
||||
|
||||
float m_fPercentGray;
|
||||
|
||||
// for TYPE_SECTION and TYPE_ROULETTE
|
||||
Sprite m_sprSectionBar;
|
||||
// for TYPE_SECTION
|
||||
@@ -100,8 +102,8 @@ public:
|
||||
virtual void TweenOnScreen();
|
||||
virtual void TweenOffScreen();
|
||||
|
||||
void PrevMusic();
|
||||
void NextMusic();
|
||||
void PrevMusic( bool bSendSongChangedMessage = true );
|
||||
void NextMusic( bool bSendSongChangedMessage = true );
|
||||
void PrevSort();
|
||||
void NextSort();
|
||||
void NotesChanged( PlayerNumber pn ); // update grade graphics and top score
|
||||
@@ -119,7 +121,7 @@ public:
|
||||
|
||||
|
||||
protected:
|
||||
void BuildWheelItemDatas( CArray<WheelItemData, WheelItemData&> &arrayWheelItems, SongSortOrder so );
|
||||
void BuildWheelItemDatas( CArray<WheelItemData, WheelItemData&> &arrayWheelItems, SongSortOrder so, bool bRoulette = false );
|
||||
void RebuildWheelItemDisplays();
|
||||
void SwitchSortOrder();
|
||||
|
||||
|
||||
@@ -36,43 +36,6 @@ NoteData::~NoteData()
|
||||
{
|
||||
}
|
||||
|
||||
void NoteData::WriteToCacheFile( FILE* file )
|
||||
{
|
||||
LOG->WriteLine( "NoteData::WriteToCacheFile()" );
|
||||
|
||||
ConvertHoldNotesTo2sAnd3s();
|
||||
|
||||
int iNumRows = GetLastRow();
|
||||
fprintf( file, "%d\n", iNumRows );
|
||||
fwrite( m_TapNotes, sizeof(TapNote), MAX_NOTE_TRACKS*iNumRows, file );
|
||||
fprintf( file, "\n" );
|
||||
|
||||
Convert2sAnd3sToHoldNotes();
|
||||
}
|
||||
|
||||
void NoteData::ReadFromCacheFile( FILE* file )
|
||||
{
|
||||
LOG->WriteLine( "NoteData::ReadFromCacheFile()" );
|
||||
|
||||
int iNumRows;
|
||||
fscanf( file, "%d\n", &iNumRows );
|
||||
fread( m_TapNotes, sizeof(TapNote), MAX_NOTE_TRACKS*iNumRows, file );
|
||||
fscanf( file, "\n", &iNumRows );
|
||||
|
||||
Convert2sAnd3sToHoldNotes();
|
||||
}
|
||||
|
||||
void NoteData::SkipOverDataInCacheFile( FILE* file )
|
||||
{
|
||||
LOG->WriteLine( "NoteData::SkipOverDataInCacheFile()" );
|
||||
|
||||
int iNumRows;
|
||||
fscanf( file, "%d\n", &iNumRows );
|
||||
int retval = fseek( file, sizeof(TapNote)*MAX_NOTE_TRACKS*iNumRows, SEEK_CUR );
|
||||
ASSERT( retval == 0 );
|
||||
fscanf( file, "\n", &iNumRows );
|
||||
}
|
||||
|
||||
|
||||
void NoteData::ClearRange( int iNoteIndexBegin, int iNoteIndexEnd )
|
||||
{
|
||||
@@ -633,97 +596,6 @@ void NoteData::SnapToNearestNoteType( NoteType nt1, NoteType nt2, float fBeginBe
|
||||
}
|
||||
|
||||
|
||||
void NoteData::GetMeasureStrings( CStringArray &arrayMeasureStrings )
|
||||
{
|
||||
ConvertHoldNotesTo2sAnd3s();
|
||||
|
||||
float fLastBeat = this->GetLastBeat();
|
||||
int iLastMeasure = int( fLastBeat/BEATS_PER_MEASURE );
|
||||
|
||||
for( int m=0; m<=iLastMeasure; m++ ) // foreach measure
|
||||
{
|
||||
CString sMeasureString;
|
||||
|
||||
int iMeasureStartIndex = m * ELEMENTS_PER_MEASURE;
|
||||
int iMeasureLastIndex = (m+1) * ELEMENTS_PER_MEASURE - 1;
|
||||
|
||||
// probe to find the smallest note type
|
||||
NoteType nt;
|
||||
int iNoteIndexSpacing;
|
||||
for( nt=(NoteType)0; nt<NUM_NOTE_TYPES; nt=NoteType(nt+1) )
|
||||
{
|
||||
float fBeatSpacing = NoteTypeToBeat( nt );
|
||||
iNoteIndexSpacing = roundf( fBeatSpacing * ELEMENTS_PER_BEAT );
|
||||
|
||||
bool bFoundSmallerNote = false;
|
||||
for( int i=iMeasureStartIndex; i<=iMeasureLastIndex; i++ ) // for each index in this measure
|
||||
{
|
||||
if( i % iNoteIndexSpacing == 0 )
|
||||
continue; // skip
|
||||
|
||||
if( !IsRowEmpty(i) )
|
||||
{
|
||||
bFoundSmallerNote = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if( bFoundSmallerNote )
|
||||
continue; // keep searching
|
||||
else
|
||||
break; // stop searching
|
||||
}
|
||||
|
||||
if( nt == NUM_NOTE_TYPES ) // we didn't find one
|
||||
iNoteIndexSpacing = 1;
|
||||
|
||||
for( int i=iMeasureStartIndex; i<=iMeasureLastIndex; i+=iNoteIndexSpacing )
|
||||
{
|
||||
for( int c=0; c<m_iNumTracks; c++ )
|
||||
sMeasureString += m_TapNotes[c][i];
|
||||
sMeasureString += '\n';
|
||||
}
|
||||
|
||||
arrayMeasureStrings.Add( sMeasureString );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void NoteData::SetFromMeasureStrings( CStringArray &arrayMeasureStrings )
|
||||
{
|
||||
for( int m=0; m<arrayMeasureStrings.GetSize(); m++ )
|
||||
{
|
||||
CString sMeasureString = arrayMeasureStrings[m];
|
||||
sMeasureString.TrimLeft();
|
||||
sMeasureString.TrimRight();
|
||||
|
||||
CStringArray arrayNoteLines;
|
||||
split( sMeasureString, "\n", arrayNoteLines );
|
||||
|
||||
int iNumNoteLines = arrayNoteLines.GetSize();
|
||||
|
||||
for( int l=0; l<arrayNoteLines.GetSize(); l++ )
|
||||
{
|
||||
const float fPercentIntoMeasure = l/(float)arrayNoteLines.GetSize();
|
||||
const float fBeat = (m + fPercentIntoMeasure) * BEATS_PER_MEASURE;
|
||||
const int iIndex = BeatToNoteRow( fBeat );
|
||||
|
||||
CString sNoteLine = arrayNoteLines[l];
|
||||
sNoteLine.TrimRight();
|
||||
|
||||
m_iNumTracks = max( m_iNumTracks, sNoteLine.GetLength() );
|
||||
|
||||
for( int c=0; c<sNoteLine.GetLength(); c++ )
|
||||
{
|
||||
m_TapNotes[c][iIndex] = sNoteLine[c];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT( m_iNumTracks != 0 );
|
||||
}
|
||||
|
||||
|
||||
float NoteData::GetStreamRadarValue( float fSongSeconds )
|
||||
{
|
||||
// density of steps
|
||||
|
||||
@@ -47,17 +47,6 @@ public:
|
||||
void Init();
|
||||
~NoteData();
|
||||
|
||||
// used for loading
|
||||
void SetFromMeasureStrings( CStringArray &arrayMeasureStrings ); // for loading from a .notes file
|
||||
void SetFromDWIInfo(); // for loading from a .dwi file
|
||||
void SetFromBMSInfo(); // for loading from a .bms file
|
||||
void ReadFromCacheFile( FILE* file );
|
||||
static void SkipOverDataInCacheFile( FILE* file );
|
||||
|
||||
// used for saving
|
||||
void GetMeasureStrings( CStringArray &arrayMeasureStrings ); // for saving to a .notes file
|
||||
void WriteToCacheFile( FILE* file );
|
||||
|
||||
int m_iNumTracks;
|
||||
TapNote m_TapNotes[MAX_NOTE_TRACKS][MAX_TAP_NOTE_ROWS];
|
||||
HoldNote m_HoldNotes[MAX_HOLD_NOTE_ELEMENTS];
|
||||
|
||||
+141
-138
@@ -42,8 +42,12 @@ enum {
|
||||
|
||||
Notes::Notes()
|
||||
{
|
||||
m_NotesType = NOTES_TYPE_DANCE_SINGLE;
|
||||
m_DifficultyClass = CLASS_EASY;
|
||||
m_iMeter = 0;
|
||||
for( int r=0; r<NUM_RADAR_VALUES; r++ )
|
||||
m_fRadarValues[r] = 0;
|
||||
|
||||
m_iNumTimesPlayed = 0;
|
||||
m_iMaxCombo = 0;
|
||||
m_iTopScore = 0;
|
||||
@@ -57,54 +61,6 @@ Notes::~Notes()
|
||||
DeleteNoteData();
|
||||
}
|
||||
|
||||
void Notes::WriteToCacheFile( FILE* file )
|
||||
{
|
||||
LOG->WriteLine( "Notes::WriteToCacheFile()" );
|
||||
|
||||
fprintf( file, "%d\n", m_NotesType );
|
||||
WriteStringToFile( file, m_sDescription );
|
||||
WriteStringToFile( file, m_sCredit );
|
||||
fprintf( file, "%d\n", m_DifficultyClass );
|
||||
fprintf( file, "%d\n", m_iMeter );
|
||||
for( int i=0; i<NUM_RADAR_VALUES; i++ )
|
||||
fprintf( file, "%f\n", m_fRadarValues[i] );
|
||||
|
||||
fprintf( file, "%d\n", m_TopGrade );
|
||||
fprintf( file, "%d\n", m_iTopScore );
|
||||
fprintf( file, "%d\n", m_iMaxCombo );
|
||||
fprintf( file, "%d\n", m_iNumTimesPlayed );
|
||||
|
||||
ASSERT( m_pNoteData != NULL );
|
||||
m_pNoteData->WriteToCacheFile( file );
|
||||
}
|
||||
|
||||
void Notes::ReadFromCacheFile( FILE* file, bool bLoadNoteData )
|
||||
{
|
||||
LOG->WriteLine( "Notes::ReadFromCacheFile( %d )", bLoadNoteData );
|
||||
|
||||
fscanf( file, "%d\n", &m_NotesType );
|
||||
ReadStringFromFile( file, m_sDescription );
|
||||
ReadStringFromFile( file, m_sCredit );
|
||||
fscanf( file, "%d\n", &m_DifficultyClass );
|
||||
fscanf( file, "%d\n", &m_iMeter );
|
||||
for( int i=0; i<NUM_RADAR_VALUES; i++ )
|
||||
fscanf( file, "%f\n", &m_fRadarValues[i] );
|
||||
|
||||
fscanf( file, "%d\n", &m_TopGrade );
|
||||
fscanf( file, "%d\n", &m_iTopScore );
|
||||
fscanf( file, "%d\n", &m_iMaxCombo );
|
||||
fscanf( file, "%d\n", &m_iNumTimesPlayed );
|
||||
|
||||
if( bLoadNoteData )
|
||||
{
|
||||
GetNoteData()->ReadFromCacheFile( file );
|
||||
}
|
||||
else
|
||||
{
|
||||
DeleteNoteData();
|
||||
NoteData::SkipOverDataInCacheFile( file );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// BMS encoding: tap-hold
|
||||
@@ -655,116 +611,163 @@ bool Notes::LoadFromDWITokens(
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Notes::LoadFromNotesFile( const CString &sPath )
|
||||
void Notes::LoadFromSMTokens(
|
||||
const CString &sNotesType,
|
||||
const CString &sDescription,
|
||||
const CString &sCredit,
|
||||
const CString &sDifficultyClass,
|
||||
const CString &sMeter,
|
||||
const CString &sRadarValues,
|
||||
const CString &sNoteDataOut,
|
||||
const bool bLoadNoteData
|
||||
)
|
||||
{
|
||||
LOG->WriteLine( "Notes::LoadFromNotesFile( '%s' )", sPath );
|
||||
LOG->WriteLine( "Notes::LoadFromSMTokens( %d )", bLoadNoteData );
|
||||
|
||||
CStdioFile file;
|
||||
if( !file.Open( sPath, CFile::modeRead|CFile::shareDenyNone ) )
|
||||
throw RageException( "Error opening DWI file '%s'.", sPath );
|
||||
m_NotesType = StringToNotesType(sNotesType);
|
||||
m_sDescription = sDescription;
|
||||
m_sCredit = sCredit;
|
||||
m_DifficultyClass = StringToDifficultyClass( sDifficultyClass );
|
||||
m_iMeter = atoi(sMeter);
|
||||
CStringArray saValues;
|
||||
split( sRadarValues, ",", saValues, true );
|
||||
if( saValues.GetSize() == NUM_RADAR_VALUES )
|
||||
for( int r=0; r<NUM_RADAR_VALUES; r++ )
|
||||
m_fRadarValues[r] = (float)atof(saValues[r]);
|
||||
|
||||
// read the whole file into a sFileText
|
||||
CString sFileText;
|
||||
CString buffer;
|
||||
while( file.ReadString(buffer) )
|
||||
sFileText += buffer + "\n";
|
||||
file.Close();
|
||||
if( m_iMeter < 1 || m_iMeter > 10 )
|
||||
m_iMeter = 4;
|
||||
if( m_DifficultyClass == CLASS_INVALID )
|
||||
m_DifficultyClass = DifficultyClassFromDescriptionAndMeter( sDescription, m_iMeter );
|
||||
|
||||
|
||||
// strip comments out of sFileText
|
||||
while( sFileText.Find("//") != -1 )
|
||||
//
|
||||
// Load NoteData
|
||||
//
|
||||
NoteData *pND = GetNoteData();
|
||||
|
||||
pND->m_iNumTracks = NotesTypeToNumTracks( m_NotesType );
|
||||
|
||||
CStringArray asNoteData;
|
||||
split( sNoteDataOut, ",", asNoteData, true );
|
||||
for( int i=0; i<asNoteData.GetSize(); i+=2 )
|
||||
{
|
||||
int iIndexCommentStart = sFileText.Find("//");
|
||||
int iIndexCommentEnd = sFileText.Find("\n", iIndexCommentStart);
|
||||
if( iIndexCommentEnd == -1 ) // comment doesn't have an end?
|
||||
sFileText.Delete( iIndexCommentStart, 2 );
|
||||
else
|
||||
sFileText.Delete( iIndexCommentStart, iIndexCommentEnd-iIndexCommentStart );
|
||||
int iNumRowsInMeasure = atoi( asNoteData[i] );
|
||||
|
||||
CString sMeasureString = asNoteData[i+1];
|
||||
sMeasureString.TrimLeft();
|
||||
sMeasureString.TrimRight();
|
||||
|
||||
CStringArray arrayNoteLines;
|
||||
split( sMeasureString, "\n", arrayNoteLines );
|
||||
|
||||
if( arrayNoteLines.GetSize() != iNumRowsInMeasure )
|
||||
throw RageException( "Actual number of note rows (%d) doesn't match what tag says (%d).", arrayNoteLines.GetSize(), iNumRowsInMeasure );
|
||||
|
||||
for( int l=0; l<iNumRowsInMeasure; l++ )
|
||||
{
|
||||
const float fPercentIntoMeasure = l/(float)arrayNoteLines.GetSize();
|
||||
const float fBeat = (i + fPercentIntoMeasure) * BEATS_PER_MEASURE;
|
||||
const int iIndex = BeatToNoteRow( fBeat );
|
||||
|
||||
CString sNoteLine = arrayNoteLines[l];
|
||||
sNoteLine.TrimRight();
|
||||
|
||||
if( pND->m_iNumTracks != sNoteLine.GetLength() )
|
||||
throw RageException( "Actual number of note columns (%d) is different from the NotesType (%d).", pND->m_iNumTracks, sNoteLine.GetLength() );
|
||||
|
||||
for( int c=0; c<sNoteLine.GetLength(); c++ )
|
||||
pND->m_TapNotes[c][iIndex] = sNoteLine[c];
|
||||
}
|
||||
}
|
||||
|
||||
// split sFileText into strings containing each value expression
|
||||
CStringArray arrayValueStrings;
|
||||
split( sFileText, ";", arrayValueStrings );
|
||||
|
||||
}
|
||||
|
||||
void Notes::WriteSMNotesTag( FILE* fp )
|
||||
{
|
||||
fprintf( fp, "#NOTES:\n" );
|
||||
fprintf( fp, " %s:\n", NotesTypeToString(m_NotesType) );
|
||||
fprintf( fp, " %s:\n", m_sDescription );
|
||||
fprintf( fp, " %s:\n", m_sCredit );
|
||||
fprintf( fp, " %s:\n", DifficultyClassToString(m_DifficultyClass) );
|
||||
fprintf( fp, " %d:\n", m_iMeter );
|
||||
|
||||
CStringArray asRadarValues;
|
||||
for( int r=0; r<NUM_RADAR_VALUES; r++ )
|
||||
asRadarValues.Add( ssprintf("%.1f", m_fRadarValues[r]) );
|
||||
fprintf( fp, " %s:\n", join(",",asRadarValues) );
|
||||
|
||||
|
||||
// for each value expression string, parse it into a value name and data
|
||||
for( int i=0; i < arrayValueStrings.GetSize(); i++ )
|
||||
//
|
||||
// fill in sNoteDataOut
|
||||
//
|
||||
NoteData* pND = GetNoteData();
|
||||
|
||||
pND->ConvertHoldNotesTo2sAnd3s();
|
||||
|
||||
float fLastBeat = pND->GetLastBeat();
|
||||
int iLastMeasure = int( fLastBeat/BEATS_PER_MEASURE );
|
||||
|
||||
for( int m=0; m<=iLastMeasure; m++ ) // foreach measure
|
||||
{
|
||||
CString sValueString = arrayValueStrings[i];
|
||||
int iMeasureStartIndex = m * ELEMENTS_PER_MEASURE;
|
||||
int iMeasureLastIndex = (m+1) * ELEMENTS_PER_MEASURE - 1;
|
||||
|
||||
// split the value string into tokens
|
||||
CStringArray arrayValueTokens;
|
||||
split( sValueString, ":", arrayValueTokens, false );
|
||||
|
||||
if( arrayValueTokens.GetSize() == 0 )
|
||||
continue;
|
||||
|
||||
CString sValueName = arrayValueTokens.GetAt( 0 );
|
||||
sValueName.TrimLeft();
|
||||
sValueName.TrimRight();
|
||||
|
||||
// handle the data
|
||||
if( sValueName == "#TYPE" )
|
||||
m_NotesType = StringToNotesType( arrayValueTokens[1] );
|
||||
|
||||
else if( sValueName == "#DESCRIPTION" )
|
||||
m_sDescription = arrayValueTokens[1];
|
||||
|
||||
else if( sValueName == "#CREDIT" )
|
||||
m_sCredit = arrayValueTokens[1];
|
||||
|
||||
else if( sValueName == "#METER" )
|
||||
m_iMeter = atoi( arrayValueTokens[1] );
|
||||
|
||||
else if( sValueName == "#NOTES" )
|
||||
// probe to find the smallest note type
|
||||
NoteType nt;
|
||||
int iNoteIndexSpacing;
|
||||
for( nt=(NoteType)0; nt<NUM_NOTE_TYPES; nt=NoteType(nt+1) )
|
||||
{
|
||||
arrayValueTokens.RemoveAt( 0 );
|
||||
float fBeatSpacing = NoteTypeToBeat( nt );
|
||||
iNoteIndexSpacing = roundf( fBeatSpacing * ELEMENTS_PER_BEAT );
|
||||
|
||||
ASSERT( m_pNoteData == NULL ); // if not, then we're loading this NoteData twice
|
||||
m_pNoteData = new NoteData;
|
||||
|
||||
m_pNoteData->SetFromMeasureStrings( arrayValueTokens );
|
||||
bool bFoundSmallerNote = false;
|
||||
for( int i=iMeasureStartIndex; i<=iMeasureLastIndex; i++ ) // for each index in this measure
|
||||
{
|
||||
if( i % iNoteIndexSpacing == 0 )
|
||||
continue; // skip
|
||||
|
||||
if( !pND->IsRowEmpty(i) )
|
||||
{
|
||||
bFoundSmallerNote = true;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if( bFoundSmallerNote )
|
||||
continue; // keep searching
|
||||
else
|
||||
break; // stop searching
|
||||
}
|
||||
|
||||
else
|
||||
LOG->WriteLine( "Unexpected value named '%s'", sValueName );
|
||||
if( nt == NUM_NOTE_TYPES ) // we didn't find one
|
||||
iNoteIndexSpacing = 1;
|
||||
|
||||
fprintf( fp, "%d, // measure %d\n", ELEMENTS_PER_MEASURE/iNoteIndexSpacing, m+1 );
|
||||
|
||||
for( int i=iMeasureStartIndex; i<=iMeasureLastIndex; i+=iNoteIndexSpacing )
|
||||
{
|
||||
CString sLineString;
|
||||
for( int c=0; c<pND->m_iNumTracks; c++ )
|
||||
sLineString += pND->m_TapNotes[c][i];
|
||||
fprintf( fp, "%s", sLineString );
|
||||
if( i == iMeasureLastIndex )
|
||||
fprintf( fp, ",\n" );
|
||||
else
|
||||
fprintf( fp, "\n" );
|
||||
}
|
||||
}
|
||||
|
||||
m_DifficultyClass = DifficultyClassFromDescriptionAndMeter( m_sDescription, m_iMeter );
|
||||
|
||||
return true;
|
||||
fprintf( fp, ";\n" );
|
||||
|
||||
pND->Convert2sAnd3sToHoldNotes();
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Notes::SaveToSMDir( CString sSongDir )
|
||||
DifficultyClass Notes::DifficultyClassFromDescriptionAndMeter( CString sDescription, int iMeter )
|
||||
{
|
||||
LOG->WriteLine( "Notes::Save( '%s' )", sSongDir );
|
||||
|
||||
CString sNewNotesFilePath = sSongDir + ssprintf("%s-%s.notes", NotesTypeToString(m_NotesType), m_sDescription);
|
||||
|
||||
CStdioFile file;
|
||||
if( !file.Open( sNewNotesFilePath, CFile::modeWrite | CFile::modeCreate ) )
|
||||
throw RageException( "Error opening Notes file '%s' for writing.", sNewNotesFilePath );
|
||||
|
||||
file.WriteString( ssprintf("#TYPE:%s;\n", NotesTypeToString(m_NotesType)) );
|
||||
file.WriteString( ssprintf("#DESCRIPTION:%s;\n", m_sDescription) );
|
||||
file.WriteString( ssprintf("#METER:%d;\n", m_iMeter) );
|
||||
file.WriteString( ssprintf("#CREDIT:%s;\n", m_sCredit) );
|
||||
|
||||
|
||||
file.WriteString( "#NOTES:\n" );
|
||||
CStringArray sMeasureStrings;
|
||||
GetNoteData()->GetMeasureStrings( sMeasureStrings );
|
||||
file.WriteString( join(":\n", sMeasureStrings) );
|
||||
file.WriteString( ";" );
|
||||
|
||||
|
||||
file.Close();
|
||||
}
|
||||
|
||||
DifficultyClass Notes::DifficultyClassFromDescriptionAndMeter( CString sDifficulty, int iMeter )
|
||||
{
|
||||
sDifficulty.MakeLower();
|
||||
sDescription.MakeLower();
|
||||
|
||||
const CString sDescriptionParts[NUM_DIFFICULTY_CLASSES][3] = {
|
||||
{
|
||||
@@ -786,7 +789,7 @@ DifficultyClass Notes::DifficultyClassFromDescriptionAndMeter( CString sDifficul
|
||||
|
||||
for( int i=0; i<NUM_DIFFICULTY_CLASSES; i++ )
|
||||
for( int j=0; j<3; j++ )
|
||||
if( sDifficulty.Find(sDescriptionParts[i][j]) != -1 )
|
||||
if( sDescription.Find(sDescriptionParts[i][j]) != -1 )
|
||||
return DifficultyClass(i);
|
||||
|
||||
// guess difficulty class from meter
|
||||
|
||||
+20
-14
@@ -26,22 +26,31 @@ public:
|
||||
// Loading
|
||||
bool LoadFromNotesFile( const CString &sPath );
|
||||
bool LoadFromBMSFile( const CString &sPath );
|
||||
bool LoadFromDWITokens( const CString &sMode, const CString &sDescription,
|
||||
const int &iNumFeet,
|
||||
const CString &sStepData1, const CString &sStepData2 );
|
||||
void ReadFromCacheFile( FILE* file, bool bReadNoteData );
|
||||
|
||||
// for saving
|
||||
void SaveToSMDir( CString sSongDir );
|
||||
void WriteToCacheFile( FILE* file );
|
||||
|
||||
//
|
||||
bool LoadFromDWITokens(
|
||||
const CString &sMode,
|
||||
const CString &sDescription,
|
||||
const int &iNumFeet,
|
||||
const CString &sStepData1, const CString &sStepData2
|
||||
);
|
||||
void LoadFromSMTokens(
|
||||
const CString &sNotesType,
|
||||
const CString &sDescription,
|
||||
const CString &sCredit,
|
||||
const CString &sDifficultyClass,
|
||||
const CString &sMeter,
|
||||
const CString &sRadarValues,
|
||||
const CString &sNoteDataOut,
|
||||
const bool bLoadNoteData
|
||||
);
|
||||
void WriteSMNotesTag( FILE* fp );
|
||||
|
||||
public:
|
||||
NotesType m_NotesType;
|
||||
CString m_sDescription; // This text is displayed next to thte number of feet when a song is selected
|
||||
CString m_sCredit; // name of the person who created these Notes
|
||||
DifficultyClass m_DifficultyClass; // this is inferred from m_sDescription
|
||||
int m_iMeter; // difficulty from 1-10
|
||||
float m_fRadarValues[NUM_RADAR_VALUES]; // between 0.0-1.2 starting from 12-o'clock rotating clockwise
|
||||
|
||||
// Color is a function of DifficultyClass and Intended Style
|
||||
D3DXCOLOR GetColor()
|
||||
@@ -57,8 +66,6 @@ public:
|
||||
return DifficultyClassToColor( m_DifficultyClass );
|
||||
}
|
||||
|
||||
int m_iMeter; // difficulty from 1-10
|
||||
float m_fRadarValues[NUM_RADAR_VALUES]; // between 0.0-1.2 starting from 12-o'clock rotating clockwise
|
||||
|
||||
// Statistics
|
||||
Grade m_TopGrade;
|
||||
@@ -72,8 +79,7 @@ public:
|
||||
void DeleteNoteData();
|
||||
|
||||
protected:
|
||||
static DifficultyClass DifficultyClassFromDescriptionAndMeter( CString sDifficulty, int iMeter );
|
||||
|
||||
static DifficultyClass DifficultyClassFromDescriptionAndMeter( CString sDescription, int iMeter );
|
||||
|
||||
NoteData* m_pNoteData;
|
||||
};
|
||||
|
||||
@@ -285,20 +285,20 @@ void GetDirListing( CString sPath, CStringArray &AddTo, bool bOnlyDirs, bool bRe
|
||||
::FindClose( hFind );
|
||||
}
|
||||
|
||||
ULONG GetHashForString( CString s )
|
||||
int GetHashForString( CString s )
|
||||
{
|
||||
ULONG hash = 0;
|
||||
int hash = 0;
|
||||
for( int i=0; i<s.GetLength(); i++ )
|
||||
{
|
||||
hash *= 10;
|
||||
hash += (DWORD)s[i];
|
||||
}
|
||||
return hash;
|
||||
return abs(hash);
|
||||
}
|
||||
|
||||
ULONG GetHashForFile( CString sPath )
|
||||
int GetHashForFile( CString sPath )
|
||||
{
|
||||
ULONG hash = 0;
|
||||
int hash = 0;
|
||||
|
||||
hash += GetHashForString( sPath );
|
||||
|
||||
@@ -308,12 +308,12 @@ ULONG GetHashForFile( CString sPath )
|
||||
if( CFile::GetStatus(sPath, status) )
|
||||
hash += status.m_mtime.GetHour() * 3600 + status.m_mtime.GetMinute() * 60 + status.m_mtime.GetSecond();
|
||||
|
||||
return hash;
|
||||
return abs(hash);
|
||||
}
|
||||
|
||||
ULONG GetHashForDirectory( CString sDir )
|
||||
int GetHashForDirectory( CString sDir )
|
||||
{
|
||||
ULONG hash = 0;
|
||||
int hash = 0;
|
||||
|
||||
hash += GetHashForFile( sDir );
|
||||
|
||||
@@ -325,7 +325,7 @@ ULONG GetHashForDirectory( CString sDir )
|
||||
hash += GetHashForFile( sFilePath );
|
||||
}
|
||||
|
||||
return hash;
|
||||
return abs(hash);
|
||||
}
|
||||
|
||||
DWORD GetFileSizeInBytes( const CString &sFilePath )
|
||||
|
||||
@@ -97,9 +97,9 @@ CString join(
|
||||
);
|
||||
|
||||
void GetDirListing( CString sPath, CStringArray &AddTo, bool bOnlyDirs=false, bool bReturnPathToo=false );
|
||||
ULONG GetHashForString( CString s );
|
||||
ULONG GetHashForFile( CString sPath );
|
||||
ULONG GetHashForDirectory( CString sDir ); // a hash value that remains the same as long as nothing in the directory has changed
|
||||
int GetHashForString( CString s );
|
||||
int GetHashForFile( CString sPath );
|
||||
int GetHashForDirectory( CString sDir ); // a hash value that remains the same as long as nothing in the directory has changed
|
||||
|
||||
bool DoesFileExist( const CString &sPath );
|
||||
DWORD GetFileSizeInBytes( const CString &sFilePath );
|
||||
|
||||
@@ -172,9 +172,10 @@ ScreenEdit::~ScreenEdit()
|
||||
|
||||
void ScreenEdit::Update( float fDeltaTime )
|
||||
{
|
||||
float fSongBeat, fBPS;
|
||||
float fPositionSeconds = m_soundMusic.GetPositionSeconds();
|
||||
m_pSong->GetBeatAndBPSFromElapsedTime( fPositionSeconds, fSongBeat, fBPS );
|
||||
float fSongBeat, fBPS;
|
||||
bool bFreeze;
|
||||
m_pSong->GetBeatAndBPSFromElapsedTime( fPositionSeconds, fSongBeat, fBPS, bFreeze );
|
||||
|
||||
if( m_Mode == MODE_RECORD || m_Mode == MODE_PLAY )
|
||||
{
|
||||
@@ -409,7 +410,7 @@ void ScreenEdit::InputEdit( const DeviceInput& DeviceI, const InputEventType typ
|
||||
}
|
||||
|
||||
pNotes->SetNoteData( (NoteData*)&m_NoteFieldEdit );
|
||||
SONGMAN->GetCurrentSong()->Save();
|
||||
SONGMAN->GetCurrentSong()->SaveToSMFile();
|
||||
}
|
||||
break;
|
||||
case DIK_UP:
|
||||
@@ -762,8 +763,9 @@ void ScreenEdit::InputRecord( const DeviceInput& DeviceI, const InputEventType t
|
||||
const float fHoldStartSeconds = m_soundMusic.GetPositionSeconds() - TIME_BEFORE_SLOW_REPEATS * m_soundMusic.GetPlaybackRate();
|
||||
|
||||
float fStartBeat, fEndBeat, fThrowAway;
|
||||
m_pSong->GetBeatAndBPSFromElapsedTime( fHoldStartSeconds, fStartBeat, fThrowAway );
|
||||
m_pSong->GetBeatAndBPSFromElapsedTime( fHoldEndSeconds, fEndBeat, fThrowAway );
|
||||
bool bFreeze;
|
||||
m_pSong->GetBeatAndBPSFromElapsedTime( fHoldStartSeconds, fStartBeat, fThrowAway, bFreeze );
|
||||
m_pSong->GetBeatAndBPSFromElapsedTime( fHoldEndSeconds, fEndBeat, fThrowAway, bFreeze );
|
||||
|
||||
const int iStartIndex = BeatToNoteRow(fStartBeat) - 1;
|
||||
const int iEndIndex = BeatToNoteRow(fEndBeat);
|
||||
|
||||
@@ -348,13 +348,13 @@ void ScreenGameplay::Update( float fDeltaTime )
|
||||
return;
|
||||
|
||||
|
||||
float fSongBeat, fBPS;
|
||||
float fPositionSeconds = m_soundMusic.GetPositionSeconds();
|
||||
|
||||
m_pCurSong->GetBeatAndBPSFromElapsedTime( fPositionSeconds, fSongBeat, fBPS );
|
||||
float fSongBeat, fBPS;
|
||||
bool bFreeze;
|
||||
m_pCurSong->GetBeatAndBPSFromElapsedTime( fPositionSeconds, fSongBeat, fBPS, bFreeze );
|
||||
|
||||
|
||||
m_Background.SetSongBeat( fSongBeat );
|
||||
m_Background.SetSongBeat( fSongBeat, bFreeze );
|
||||
|
||||
|
||||
//LOG->WriteLine( "m_fOffsetInBeats = %f, m_fBeatsPerSecond = %f, m_Music.GetPositionSeconds = %f", m_fOffsetInBeats, m_fBeatsPerSecond, m_Music.GetPositionSeconds() );
|
||||
@@ -477,7 +477,7 @@ void ScreenGameplay::Update( float fDeltaTime )
|
||||
if( PREFSMAN->m_SongOptions.m_AssistType == SongOptions::ASSIST_TICK )
|
||||
{
|
||||
fPositionSeconds += (SOUND->GetPlayLatency()+0.06f) * m_soundMusic.GetPlaybackRate(); // HACK: Add 0.06 seconds to make them play a tiny bit earlier
|
||||
m_pCurSong->GetBeatAndBPSFromElapsedTime( fPositionSeconds, fSongBeat, fBPS );
|
||||
m_pCurSong->GetBeatAndBPSFromElapsedTime( fPositionSeconds, fSongBeat, fBPS, bFreeze );
|
||||
|
||||
int iRowNow = BeatToNoteRowNotRounded( fSongBeat );
|
||||
static int iRowLastCrossed = 0;
|
||||
@@ -539,7 +539,8 @@ void ScreenGameplay::Input( const DeviceInput& DeviceI, const InputEventType typ
|
||||
//LOG->WriteLine( "ScreenGameplay::Input()" );
|
||||
|
||||
float fSongBeat, fBPS;
|
||||
m_pCurSong->GetBeatAndBPSFromElapsedTime( m_soundMusic.GetPositionSeconds(), fSongBeat, fBPS );
|
||||
bool bFreeze;
|
||||
m_pCurSong->GetBeatAndBPSFromElapsedTime( m_soundMusic.GetPositionSeconds(), fSongBeat, fBPS, bFreeze );
|
||||
|
||||
|
||||
// Handle special keys to adjust the offset
|
||||
|
||||
@@ -329,22 +329,21 @@ void ScreenSelectMusic::HandleScreenMessage( const ScreenMessage SM )
|
||||
case SM_PlaySongSample:
|
||||
PlayMusicSample();
|
||||
break;
|
||||
case SM_SongChanged:
|
||||
AfterMusicChange();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ScreenSelectMusic::MenuLeft( const PlayerNumber p, const InputEventType type )
|
||||
{
|
||||
m_MusicWheel.PrevMusic();
|
||||
|
||||
AfterMusicChange();
|
||||
}
|
||||
|
||||
|
||||
void ScreenSelectMusic::MenuRight( const PlayerNumber p, const InputEventType type )
|
||||
{
|
||||
m_MusicWheel.NextMusic();
|
||||
|
||||
AfterMusicChange();
|
||||
}
|
||||
|
||||
void ScreenSelectMusic::MenuStart( const PlayerNumber p )
|
||||
@@ -471,6 +470,10 @@ void ScreenSelectMusic::AfterMusicChange()
|
||||
{
|
||||
if( !GAMEMAN->IsPlayerEnabled( PlayerNumber(p) ) )
|
||||
continue;
|
||||
for( int i=0; i<m_arrayNotes.GetSize(); i++ )
|
||||
if( m_arrayNotes[i]->m_DifficultyClass == PREFSMAN->m_PreferredDifficultyClass[p] )
|
||||
m_iSelection[p] = i;
|
||||
|
||||
m_iSelection[p] = clamp( m_iSelection[p], 0, m_arrayNotes.GetSize() ) ;
|
||||
}
|
||||
}
|
||||
|
||||
+111
-205
@@ -12,12 +12,13 @@
|
||||
|
||||
#include "Notes.h"
|
||||
#include "RageUtil.h"
|
||||
|
||||
#include "Song.h"
|
||||
#include <math.h> // for fmod
|
||||
#include "RageLog.h"
|
||||
#include "IniFile.h"
|
||||
#include "Song.h"
|
||||
|
||||
|
||||
const int FILE_CACHE_VERSION = 11; // increment this when the cache file format changes
|
||||
|
||||
|
||||
int CompareBPMSegments(const void *arg1, const void *arg2)
|
||||
@@ -101,7 +102,7 @@ void Song::AddFreezeSegment( FreezeSegment seg )
|
||||
}
|
||||
|
||||
|
||||
void Song::GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatOut, float &fBPSOut )
|
||||
void Song::GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatOut, float &fBPSOut, bool &bFreezeOut )
|
||||
{
|
||||
// LOG->WriteLine( "GetBeatAndBPSFromElapsedTime( fElapsedTime = %f )", fElapsedTime );
|
||||
// This function is a nightmare. Don't even try to understand it. :-)
|
||||
@@ -134,7 +135,7 @@ void Song::GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatOut, fl
|
||||
|
||||
if( fElapsedTime > fSecondsInThisSegment )
|
||||
{
|
||||
// this BPMSegement is not the current segment
|
||||
// this BPMSegement is NOT the current segment
|
||||
fElapsedTime -= fSecondsInThisSegment;
|
||||
}
|
||||
else
|
||||
@@ -158,6 +159,7 @@ void Song::GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatOut, fl
|
||||
{
|
||||
fBeatOut = m_FreezeSegments[j].m_fStartBeat;
|
||||
fBPSOut = fBPS;
|
||||
bFreezeOut = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -168,6 +170,7 @@ void Song::GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatOut, fl
|
||||
|
||||
fBeatOut = fBeatEstimate;
|
||||
fBPSOut = fBPS;
|
||||
bFreezeOut = false;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -183,10 +186,11 @@ float Song::GetElapsedTimeFromBeat( float fBeat )
|
||||
float fElapsedTimeBestGuess = 100; // seconds
|
||||
float fSecondsToMove = fElapsedTimeBestGuess/2; // seconds
|
||||
float fBeatOut, fBPSOut;
|
||||
bool bFreezeOut;
|
||||
|
||||
while( fSecondsToMove > 0.1f )
|
||||
{
|
||||
GetBeatAndBPSFromElapsedTime( fElapsedTimeBestGuess, fBeatOut, fBPSOut );
|
||||
GetBeatAndBPSFromElapsedTime( fElapsedTimeBestGuess, fBeatOut, fBPSOut, bFreezeOut );
|
||||
if( fBeatOut > fBeat )
|
||||
fElapsedTimeBestGuess -= fSecondsToMove;
|
||||
else
|
||||
@@ -221,8 +225,7 @@ void Song::GetMainAndSubTitlesFromFullTitle( CString sFullTitle, CString &sMainT
|
||||
|
||||
CString Song::GetCacheFilePath()
|
||||
{
|
||||
ULONG hash = GetHashForString( m_sSongDir );
|
||||
return ssprintf( "Cache\\%u.song", hash );
|
||||
return ssprintf( "Cache\\%d", GetHashForString(m_sSongDir) );
|
||||
}
|
||||
|
||||
bool Song::LoadFromSongDir( CString sDir )
|
||||
@@ -240,10 +243,35 @@ bool Song::LoadFromSongDir( CString sDir )
|
||||
//
|
||||
// First look in the cache for this song (without loading NoteData)
|
||||
//
|
||||
//if( LoadFromCacheFile(false) )
|
||||
// return true;
|
||||
IniFile ini;
|
||||
ini.SetPath( "Cache\\index.cache" );
|
||||
if( !ini.ReadFile() )
|
||||
goto load_without_cache;
|
||||
|
||||
int iCacheVersion;
|
||||
ini.GetValueI( "Cache", "CacheVersion", iCacheVersion );
|
||||
if( iCacheVersion != FILE_CACHE_VERSION )
|
||||
{
|
||||
LOG->WriteLine( "Cache format is out of date. Deleting all cache files" );
|
||||
CStringArray asCacheFileNames;
|
||||
GetDirListing( "Cache\\*.*", asCacheFileNames );
|
||||
for( int i=0; i<asCacheFileNames.GetSize(); i++ )
|
||||
DeleteFile( "Cache\\" + asCacheFileNames[i] );
|
||||
goto load_without_cache;
|
||||
}
|
||||
|
||||
int iDirHash;
|
||||
ini.GetValueI( "Cache", m_sSongDir, iDirHash );
|
||||
if( GetHashForDirectory(m_sSongDir) == iDirHash ) // this cache is up to date
|
||||
{
|
||||
if( !DoesFileExist(GetCacheFilePath()) )
|
||||
goto load_without_cache;
|
||||
LoadFromSMFile( GetCacheFilePath(), false ); // don't load NoteData
|
||||
LOG->WriteLine( "Loading '%s' from cache file '%s'.", m_sSongDir, GetCacheFilePath() );
|
||||
return true;
|
||||
}
|
||||
|
||||
load_without_cache:
|
||||
//
|
||||
// There was no entry in the cache for this song.
|
||||
// Let's load it from a file, then write a cache entry.
|
||||
@@ -256,23 +284,23 @@ bool Song::LoadFromSongDir( CString sDir )
|
||||
GetDirListing( sDir + CString("*.dwi"), arrayDWIFileNames );
|
||||
int iNumDWIFiles = arrayDWIFileNames.GetSize();
|
||||
|
||||
CStringArray arraySongFileNames;
|
||||
GetDirListing( sDir + CString("*.song"), arraySongFileNames );
|
||||
int iNumSongFiles = arraySongFileNames.GetSize();
|
||||
CStringArray arraySMFileNames;
|
||||
GetDirListing( sDir + CString("*.sm"), arraySMFileNames );
|
||||
int iNumSMFiles = arraySMFileNames.GetSize();
|
||||
|
||||
|
||||
if( iNumSongFiles > 1 )
|
||||
throw RageException( "There is more than one .song file in '%s'. There should be only one!", sDir );
|
||||
if( iNumSMFiles > 1 )
|
||||
throw RageException( "There is more than one SM file in '%s'. There should be only one!", sDir );
|
||||
else if( iNumDWIFiles > 1 )
|
||||
throw RageException( "There is more than one DWI file in '%s'. There should be only one!", sDir );
|
||||
else if( iNumSongFiles == 1 )
|
||||
LoadFromSMDir( sDir );
|
||||
else if( iNumSMFiles == 1 )
|
||||
LoadFromSMFile( sDir + arraySMFileNames[0], true ); // do load note data
|
||||
else if( iNumDWIFiles == 1 )
|
||||
LoadFromDWIFile( sDir + arrayDWIFileNames[0] );
|
||||
else if( iNumBMSFiles > 0 )
|
||||
LoadFromBMSDir( sDir );
|
||||
else
|
||||
throw RageException( "Couldn't find any .song, BMS, or DWI files in '%s'. This is not a valid song directory.", sDir );
|
||||
throw RageException( "Couldn't find any SM, BMS, or DWI files in '%s'. This is not a valid song directory.", sDir );
|
||||
|
||||
TidyUpData();
|
||||
|
||||
@@ -280,8 +308,8 @@ bool Song::LoadFromSongDir( CString sDir )
|
||||
// In order to save memory, we're going to save the file back to the cache,
|
||||
// then unload all the large NoteData.
|
||||
//
|
||||
//SaveToCacheFile();
|
||||
//LoadFromCacheFile( false );
|
||||
SaveToCacheFile();
|
||||
LoadFromSMFile( GetCacheFilePath(), false ); // don't load NoteData
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -756,47 +784,19 @@ bool Song::LoadFromDWIFile( CString sPath )
|
||||
}
|
||||
|
||||
|
||||
bool Song::LoadFromSMDir( CString sDir )
|
||||
bool Song::LoadFromSMFile( CString sPath, bool bLoadNoteData )
|
||||
{
|
||||
LOG->WriteLine( "Song::LoadFromSMDir(%s)", sDir );
|
||||
LOG->WriteLine( "Song::LoadFromSMDir(%s, %d)", sPath, bLoadNoteData );
|
||||
|
||||
int i;
|
||||
|
||||
// make sure there is a trailing '\\' at the end of sDir
|
||||
if( sDir.Right(1) != "\\" )
|
||||
sDir += "\\";
|
||||
|
||||
// save song dir
|
||||
m_sSongDir = sDir;
|
||||
|
||||
// get group name
|
||||
CStringArray sDirectoryParts;
|
||||
split( m_sSongDir, "\\", sDirectoryParts, true );
|
||||
m_sGroupName = sDirectoryParts[1];
|
||||
|
||||
|
||||
CStringArray arraySongFileNames;
|
||||
GetDirListing( sDir + "*.song", arraySongFileNames );
|
||||
if( arraySongFileNames.GetSize() == 0 )
|
||||
throw RageException( "Couldn't find any SM Song files in '%s'", sDir );
|
||||
|
||||
|
||||
// Load the Song info from the first BMS file. Silly BMS duplicates the song info in every
|
||||
// file. So, we read the song data from only the first BMS file and assume that the info
|
||||
// is identical for every BMS file in the directory.
|
||||
m_sSongFile = arraySongFileNames[0];
|
||||
|
||||
|
||||
CStringArray arrayNotesFileNames;
|
||||
GetDirListing( sDir + CString("*.notes"), arrayNotesFileNames );
|
||||
|
||||
// load the Notes from the rest of the BMS files
|
||||
for( i=0; i<arrayNotesFileNames.GetSize(); i++ )
|
||||
{
|
||||
Notes* pNewNotes = new Notes;
|
||||
pNewNotes->LoadFromNotesFile( m_sSongDir + arrayNotesFileNames[i] );
|
||||
m_arrayNotes.Add( pNewNotes );
|
||||
}
|
||||
|
||||
m_sSongFile = sPath;
|
||||
|
||||
|
||||
CStdioFile file;
|
||||
@@ -846,7 +846,7 @@ bool Song::LoadFromSMDir( CString sDir )
|
||||
if( sValueName == "#TITLE" )
|
||||
GetMainAndSubTitlesFromFullTitle( arrayValueTokens[1], m_sMainTitle, m_sSubTitle );
|
||||
|
||||
if( sValueName == "#MAINTITLE" )
|
||||
if( sValueName == "#TITLE" )
|
||||
m_sMainTitle = arrayValueTokens[1];
|
||||
|
||||
if( sValueName == "#SUBTITLE" )
|
||||
@@ -930,6 +930,24 @@ bool Song::LoadFromSMDir( CString sDir )
|
||||
}
|
||||
}
|
||||
|
||||
else if( sValueName == "#NOTES" )
|
||||
{
|
||||
Notes* pNewNotes = new Notes;
|
||||
if( arrayValueTokens.GetSize() != 7 )
|
||||
throw RageException( "The song file '%s' is has an incorrect number of parameters in a #NOTES tag.", GetSongFilePath() );
|
||||
|
||||
pNewNotes->LoadFromSMTokens(
|
||||
arrayValueTokens[0],
|
||||
arrayValueTokens[1],
|
||||
arrayValueTokens[2],
|
||||
arrayValueTokens[3],
|
||||
arrayValueTokens[4],
|
||||
arrayValueTokens[5],
|
||||
arrayValueTokens[6],
|
||||
bLoadNoteData );
|
||||
m_arrayNotes.Add( pNewNotes );
|
||||
}
|
||||
|
||||
else
|
||||
LOG->WriteLine( "Unexpected value named '%s'", sValueName );
|
||||
}
|
||||
@@ -1068,139 +1086,30 @@ void Song::GetNotesThatMatch( NotesType nt, CArray<Notes*, Notes*>& arrayAddTo )
|
||||
arrayAddTo.Add( m_arrayNotes[i] );
|
||||
}
|
||||
|
||||
|
||||
const int FILE_CACHE_VERSION = 10; // increment this when the cache file format changes
|
||||
|
||||
void Song::SaveToCacheFile()
|
||||
{
|
||||
LOG->WriteLine( "Song::SaveToCacheFile()" );
|
||||
|
||||
int i;
|
||||
CString sCacheFilePath = GetCacheFilePath();
|
||||
//
|
||||
// First look in the cache for this song (without loading NoteData)
|
||||
//
|
||||
IniFile ini;
|
||||
ini.SetPath( "Cache\\index.cache" );
|
||||
ini.ReadFile(); // don't care if this fails
|
||||
|
||||
FILE* file = fopen( sCacheFilePath, "w" );
|
||||
ASSERT( file != NULL );
|
||||
if( file == NULL )
|
||||
return;
|
||||
|
||||
fprintf( file, "%d\n", FILE_CACHE_VERSION );
|
||||
fprintf( file, "%u\n", GetHashForDirectory(m_sSongDir) );
|
||||
WriteStringToFile( file, m_sSongDir );
|
||||
WriteStringToFile( file, m_sSongFile );
|
||||
WriteStringToFile( file, m_sGroupName );
|
||||
|
||||
WriteStringToFile( file, m_sMainTitle );
|
||||
WriteStringToFile( file, m_sSubTitle );
|
||||
WriteStringToFile( file, m_sArtist );
|
||||
WriteStringToFile( file, m_sCredit );
|
||||
fprintf( file, "%f\n", m_fOffsetInSeconds );
|
||||
|
||||
WriteStringToFile( file, m_sMusicFile );
|
||||
fprintf( file, "%d\n", m_iMusicBytes );
|
||||
fprintf( file, "%f\n", m_fMusicLengthSeconds );
|
||||
fprintf( file, "%f\n", m_fMusicSampleStartSeconds );
|
||||
WriteStringToFile( file, m_sBannerFile );
|
||||
WriteStringToFile( file, m_sBackgroundFile );
|
||||
WriteStringToFile( file, m_sBackgroundMovieFile );
|
||||
WriteStringToFile( file, m_sCDTitleFile );
|
||||
|
||||
fprintf( file, "%d\n", m_BPMSegments.GetSize() );
|
||||
for( i=0; i<m_BPMSegments.GetSize(); i++ )
|
||||
fprintf( file, "%f,%f\n", m_BPMSegments[i].m_fStartBeat, m_BPMSegments[i].m_fBPM );
|
||||
|
||||
fprintf( file, "%d\n", m_FreezeSegments.GetSize() );
|
||||
for( i=0; i<m_FreezeSegments.GetSize(); i++ )
|
||||
fprintf( file, "%f,%f\n", m_FreezeSegments[i].m_fStartBeat, m_FreezeSegments[i].m_fFreezeSeconds );
|
||||
|
||||
fprintf( file, "%d\n", m_arrayNotes.GetSize() );
|
||||
for( i=0; i<m_arrayNotes.GetSize(); i++ )
|
||||
m_arrayNotes[i]->WriteToCacheFile( file );
|
||||
|
||||
fclose( file );
|
||||
}
|
||||
|
||||
bool Song::LoadFromCacheFile( bool bLoadNoteData )
|
||||
{
|
||||
LOG->WriteLine( "Song::LoadFromCacheFile( %i )", bLoadNoteData );
|
||||
|
||||
int i;
|
||||
CString sCacheFilePath = GetCacheFilePath();
|
||||
|
||||
LOG->WriteLine( "cache file is '%s'.", sCacheFilePath );
|
||||
|
||||
FILE* file = fopen( sCacheFilePath, "r" );
|
||||
if( file == NULL )
|
||||
return false;
|
||||
|
||||
int iCacheVersion;
|
||||
fscanf( file, "%d\n", &iCacheVersion );
|
||||
if( iCacheVersion != FILE_CACHE_VERSION )
|
||||
{
|
||||
LOG->WriteLine( "Cache file versions don't match '%s'.", sCacheFilePath );
|
||||
fclose( file );
|
||||
DeleteCacheFile();
|
||||
return false;
|
||||
}
|
||||
|
||||
ULONG hash;
|
||||
fscanf( file, "%u\n", &hash );
|
||||
if( hash != GetHashForDirectory(m_sSongDir) )
|
||||
{
|
||||
LOG->WriteLine( "Cache file is out of date.", sCacheFilePath );
|
||||
fclose( file );
|
||||
return false;
|
||||
}
|
||||
|
||||
ReadStringFromFile( file, m_sSongDir );
|
||||
ReadStringFromFile( file, m_sSongFile );
|
||||
ReadStringFromFile( file, m_sGroupName );
|
||||
|
||||
ReadStringFromFile( file, m_sMainTitle );
|
||||
ReadStringFromFile( file, m_sSubTitle );
|
||||
ReadStringFromFile( file, m_sArtist );
|
||||
ReadStringFromFile( file, m_sCredit );
|
||||
fscanf( file, "%f\n", &m_fOffsetInSeconds );
|
||||
|
||||
ReadStringFromFile( file, m_sMusicFile );
|
||||
fscanf( file, "%d\n", &m_iMusicBytes );
|
||||
fscanf( file, "%f\n", &m_fMusicLengthSeconds );
|
||||
fscanf( file, "%f\n", &m_fMusicSampleStartSeconds );
|
||||
ReadStringFromFile( file, m_sBannerFile );
|
||||
ReadStringFromFile( file, m_sBackgroundFile );
|
||||
ReadStringFromFile( file, m_sBackgroundMovieFile );
|
||||
ReadStringFromFile( file, m_sCDTitleFile );
|
||||
|
||||
int iNumBPMSegments;
|
||||
fscanf( file, "%d\n", &iNumBPMSegments );
|
||||
m_BPMSegments.SetSize( iNumBPMSegments );
|
||||
for( i=0; i<iNumBPMSegments; i++ )
|
||||
fscanf( file, "%f,%f\n", &m_BPMSegments[i].m_fStartBeat, &m_BPMSegments[i].m_fBPM );
|
||||
|
||||
int iNumFreezeSegments;
|
||||
fscanf( file, "%d\n", &iNumFreezeSegments );
|
||||
m_FreezeSegments.SetSize( iNumFreezeSegments );
|
||||
for( i=0; i<iNumFreezeSegments; i++ )
|
||||
fscanf( file, "%f,%f\n", &m_FreezeSegments[i].m_fStartBeat, &m_FreezeSegments[i].m_fFreezeSeconds );
|
||||
|
||||
int iNumNotes;
|
||||
fscanf( file, "%d\n", &iNumNotes );
|
||||
m_arrayNotes.SetSize( iNumNotes );
|
||||
for( i=0; i<iNumNotes; i++ )
|
||||
m_arrayNotes[i]->ReadFromCacheFile( file, bLoadNoteData );
|
||||
|
||||
fclose( file );
|
||||
return true;
|
||||
}
|
||||
|
||||
void Song::DeleteCacheFile()
|
||||
{
|
||||
DeleteFile( GetCacheFilePath() );
|
||||
ini.SetValueI( "Cache", "CacheVersion", FILE_CACHE_VERSION );
|
||||
ini.SetValueI( "Cache", m_sSongDir, GetHashForDirectory(m_sSongDir) );
|
||||
ini.WriteFile();
|
||||
SaveToSMFile( GetCacheFilePath() );
|
||||
}
|
||||
|
||||
|
||||
void Song::SaveToSMDir()
|
||||
void Song::SaveToSMFile( CString sPath )
|
||||
{
|
||||
LOG->WriteLine( "Song::SaveToSMDir()" );
|
||||
if( sPath == "" )
|
||||
sPath = GetSongFilePath();
|
||||
|
||||
LOG->WriteLine( "Song::SaveToSMDir('%s')", sPath );
|
||||
|
||||
int i;
|
||||
//
|
||||
@@ -1217,56 +1126,53 @@ void Song::SaveToSMDir()
|
||||
MoveFile( sOldPath, sNewPath );
|
||||
}
|
||||
|
||||
CStdioFile file;
|
||||
if( !file.Open( GetSongFilePath(), CFile::modeWrite | CFile::modeCreate ) )
|
||||
throw RageException( "Error opening song file '%s' for writing.", GetSongFilePath() );
|
||||
FILE* fp = fopen( sPath, "w" );
|
||||
if( fp == NULL )
|
||||
throw RageException( "Error opening song file '%s' for writing.", sPath );
|
||||
|
||||
file.WriteString( ssprintf("#MAINTITLE:%s;\n", m_sMainTitle) );
|
||||
file.WriteString( ssprintf("#SUBTITLE:%s;\n", m_sSubTitle) );
|
||||
file.WriteString( ssprintf("#ARTIST:%s;\n", m_sArtist) );
|
||||
file.WriteString( ssprintf("#CREDIT:%s;\n", m_sCredit) );
|
||||
file.WriteString( ssprintf("#BANNER:%s;\n", m_sBannerFile) );
|
||||
file.WriteString( ssprintf("#BACKGROUND:%s;\n", m_sBackgroundFile) );
|
||||
file.WriteString( ssprintf("#BACKGROUNDMOVIE:%s;\n", m_sBackgroundMovieFile) );
|
||||
file.WriteString( ssprintf("#CDTITLE:%s;\n", m_sCDTitleFile) );
|
||||
file.WriteString( ssprintf("#MUSIC:%s;\n", m_sMusicFile) );
|
||||
file.WriteString( ssprintf("#MUSICBYTES:%u;\n", m_iMusicBytes) );
|
||||
file.WriteString( ssprintf("#OFFSET:%f;\n", m_fOffsetInSeconds) );
|
||||
file.WriteString( ssprintf("#SAMPLESTART:%f;\n", m_fMusicSampleStartSeconds) );
|
||||
file.WriteString( ssprintf("#SAMPLELENGTH:%f;\n", m_fMusicSampleLengthSeconds) );
|
||||
fprintf( fp, "#TITLE:%s;\n", m_sMainTitle );
|
||||
fprintf( fp, "#SUBTITLE:%s;\n", m_sSubTitle );
|
||||
fprintf( fp, "#ARTIST:%s;\n", m_sArtist );
|
||||
fprintf( fp, "#CREDIT:%s;\n", m_sCredit );
|
||||
fprintf( fp, "#BANNER:%s;\n", m_sBannerFile );
|
||||
fprintf( fp, "#BACKGROUND:%s;\n", m_sBackgroundFile );
|
||||
fprintf( fp, "#BACKGROUNDMOVIE:%s;\n", m_sBackgroundMovieFile );
|
||||
fprintf( fp, "#CDTITLE:%s;\n", m_sCDTitleFile );
|
||||
fprintf( fp, "#MUSIC:%s;\n", m_sMusicFile );
|
||||
fprintf( fp, "#MUSICBYTES:%u;\n", m_iMusicBytes );
|
||||
fprintf( fp, "#OFFSET:%.2f;\n", m_fOffsetInSeconds );
|
||||
fprintf( fp, "#SAMPLESTART:%.2f;\n", m_fMusicSampleStartSeconds );
|
||||
fprintf( fp, "#SAMPLELENGTH:%.2f;\n", m_fMusicSampleLengthSeconds );
|
||||
|
||||
file.WriteString( "#FREEZES:" );
|
||||
fprintf( fp, "#FREEZES:" );
|
||||
for( i=0; i<m_FreezeSegments.GetSize(); i++ )
|
||||
{
|
||||
FreezeSegment &fs = m_FreezeSegments[i];
|
||||
|
||||
file.WriteString( ssprintf("%f=%f", fs.m_fStartBeat, fs.m_fFreezeSeconds) );
|
||||
fprintf( fp, "%.2f=%.2f", fs.m_fStartBeat, fs.m_fFreezeSeconds );
|
||||
if( i != m_FreezeSegments.GetSize()-1 )
|
||||
file.WriteString( "," );
|
||||
fprintf( fp, "," );
|
||||
}
|
||||
file.WriteString( ";\n" );
|
||||
fprintf( fp, ";\n" );
|
||||
|
||||
file.WriteString( "#BPMS:" );
|
||||
fprintf( fp, "#BPMS:" );
|
||||
for( i=0; i<m_BPMSegments.GetSize(); i++ )
|
||||
{
|
||||
BPMSegment &bs = m_BPMSegments[i];
|
||||
|
||||
file.WriteString( ssprintf("%f=%f", bs.m_fStartBeat, bs.m_fBPM) );
|
||||
fprintf( fp, "%.2f=%.2f", bs.m_fStartBeat, bs.m_fBPM );
|
||||
if( i != m_BPMSegments.GetSize()-1 )
|
||||
file.WriteString( "," );
|
||||
fprintf( fp, "," );
|
||||
}
|
||||
file.WriteString( ";\n" );
|
||||
fprintf( fp, ";\n" );
|
||||
|
||||
file.Close();
|
||||
|
||||
//
|
||||
// Save all Notes for this file
|
||||
//
|
||||
for( i=0; i<m_arrayNotes.GetSize(); i++ )
|
||||
{
|
||||
m_arrayNotes[i]->SaveToSMDir( m_sSongDir );
|
||||
}
|
||||
m_arrayNotes[i]->WriteSMNotesTag( fp );
|
||||
|
||||
fclose( fp );
|
||||
}
|
||||
|
||||
Grade Song::GetGradeForDifficultyClass( NotesType nt, DifficultyClass dc )
|
||||
|
||||
+7
-15
@@ -3,20 +3,17 @@
|
||||
-----------------------------------------------------------------------------
|
||||
Class: Song
|
||||
|
||||
Desc: Holds data about a piece of music that can be played by one or more
|
||||
Games.
|
||||
Desc: Holds data about a song that is common to several Notes.
|
||||
|
||||
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
|
||||
Chris Danford
|
||||
-----------------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
|
||||
#include "Notes.h"
|
||||
|
||||
#include "GameConstantsAndTypes.h"
|
||||
#include "RageUtil.h"
|
||||
//enum DanceStyle; // why is this needed?
|
||||
|
||||
|
||||
struct BPMSegment
|
||||
@@ -43,21 +40,17 @@ public:
|
||||
~Song();
|
||||
|
||||
bool LoadFromSongDir( CString sDir ); // calls one of the loads below
|
||||
void Save() { SaveToSMDir(); SaveToCacheFile(); };
|
||||
void SetChangedSinceLastSave() { m_bChangedSinceSave = true; }
|
||||
|
||||
bool LoadFromCacheFile( bool bLoadNoteData );
|
||||
|
||||
protected:
|
||||
bool LoadFromDWIFile( CString sPath );
|
||||
bool LoadFromBMSDir( CString sDir );
|
||||
bool LoadFromSMDir( CString sDir );
|
||||
bool LoadFromSMFile( CString sPath, bool bLoadNoteData );
|
||||
|
||||
void TidyUpData(); // call after loading to clean up invalid data
|
||||
|
||||
void SaveToSMDir(); // saves to StepMania song and notes files
|
||||
void SaveToCacheFile(); // saves to cache file
|
||||
void SaveToSMFile( CString sPath = "" ); // no path means save in Song dir
|
||||
|
||||
void DeleteCacheFile();
|
||||
CString GetCacheFilePath();
|
||||
void SaveToCacheFile();
|
||||
|
||||
public:
|
||||
|
||||
@@ -66,7 +59,6 @@ public:
|
||||
CString m_sGroupName;
|
||||
|
||||
CString GetSongFilePath() {return m_sSongDir+m_sSongFile; };
|
||||
CString GetCacheFilePath();
|
||||
|
||||
bool m_bChangedSinceSave;
|
||||
|
||||
@@ -127,7 +119,7 @@ public:
|
||||
break;
|
||||
return m_BPMSegments[i].m_fBPM;
|
||||
};
|
||||
void GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatOut, float &fBPSOut );
|
||||
void GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatOut, float &fBPSOut, bool &bFreezeOut );
|
||||
float GetElapsedTimeFromBeat( float fBeat );
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user