2002-04-16 17:31:00 +00:00
|
|
|
#pragma once
|
2001-11-04 19:34:28 +00:00
|
|
|
/*
|
|
|
|
|
-----------------------------------------------------------------------------
|
2002-03-19 07:09:49 +00:00
|
|
|
Class: Song
|
2001-11-04 19:34:28 +00:00
|
|
|
|
2002-07-02 00:27:58 +00:00
|
|
|
Desc: See header.
|
2001-11-04 19:34:28 +00:00
|
|
|
|
2002-05-19 01:59:48 +00:00
|
|
|
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
|
2002-03-19 07:09:49 +00:00
|
|
|
Chris Danford
|
2001-11-04 19:34:28 +00:00
|
|
|
-----------------------------------------------------------------------------
|
|
|
|
|
*/
|
2001-11-03 10:52:42 +00:00
|
|
|
|
2002-05-19 01:59:48 +00:00
|
|
|
#include "Notes.h"
|
2001-11-03 10:52:42 +00:00
|
|
|
|
2002-05-01 19:14:55 +00:00
|
|
|
#include "GameConstantsAndTypes.h"
|
2002-03-19 07:09:49 +00:00
|
|
|
#include "RageUtil.h"
|
2001-11-30 09:38:35 +00:00
|
|
|
|
2001-12-28 10:15:59 +00:00
|
|
|
|
|
|
|
|
struct BPMSegment
|
|
|
|
|
{
|
|
|
|
|
BPMSegment() { m_fStartBeat = m_fBPM = -1; };
|
2002-06-24 22:04:31 +00:00
|
|
|
BPMSegment( float s, float b ) { m_fStartBeat = s; m_fBPM = b; };
|
2001-12-28 10:15:59 +00:00
|
|
|
float m_fStartBeat;
|
|
|
|
|
float m_fBPM;
|
|
|
|
|
};
|
|
|
|
|
|
2002-07-11 19:02:26 +00:00
|
|
|
struct StopSegment
|
2001-12-28 10:15:59 +00:00
|
|
|
{
|
2002-07-11 19:02:26 +00:00
|
|
|
StopSegment() { m_fStartBeat = m_fStopSeconds = -1; };
|
|
|
|
|
StopSegment( float s, float f ) { m_fStartBeat = s; m_fStopSeconds = f; };
|
2001-12-28 10:15:59 +00:00
|
|
|
float m_fStartBeat;
|
2002-07-11 19:02:26 +00:00
|
|
|
float m_fStopSeconds;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct AnimationSegment
|
|
|
|
|
{
|
|
|
|
|
AnimationSegment() { m_fStartBeat = -1; };
|
|
|
|
|
AnimationSegment( float s, CString sAnimName ) { m_fStartBeat = s; m_sAnimationName = sAnimName; };
|
|
|
|
|
float m_fStartBeat;
|
|
|
|
|
CString m_sAnimationName;
|
2001-12-19 01:50:57 +00:00
|
|
|
};
|
|
|
|
|
|
2001-11-03 10:52:42 +00:00
|
|
|
|
|
|
|
|
class Song
|
|
|
|
|
{
|
|
|
|
|
public:
|
2001-11-04 19:34:28 +00:00
|
|
|
Song();
|
2002-06-14 22:25:22 +00:00
|
|
|
~Song();
|
2001-11-04 19:34:28 +00:00
|
|
|
|
2002-05-19 01:59:48 +00:00
|
|
|
bool LoadFromSongDir( CString sDir ); // calls one of the loads below
|
|
|
|
|
|
2002-04-16 17:31:00 +00:00
|
|
|
bool LoadFromDWIFile( CString sPath );
|
|
|
|
|
bool LoadFromBMSDir( CString sDir );
|
2002-07-03 03:13:13 +00:00
|
|
|
bool LoadFromSMFile( CString sPath );
|
2002-07-31 19:40:40 +00:00
|
|
|
bool LoadFromKSFDir( CString sDir );
|
2002-06-30 23:19:33 +00:00
|
|
|
|
2002-04-16 17:31:00 +00:00
|
|
|
void TidyUpData(); // call after loading to clean up invalid data
|
2001-11-03 10:52:42 +00:00
|
|
|
|
2002-07-02 00:27:58 +00:00
|
|
|
void SaveToSMFile( CString sPath = "" ); // no path means save to SongFilePath
|
2002-08-17 06:44:04 +00:00
|
|
|
void SaveToSMAndDWIFile(); // saves SM, then saves DWI so that the SM is the master copy and NoteTypes not supported by DWI are not lost
|
2002-06-30 23:19:33 +00:00
|
|
|
void SaveToCacheFile();
|
2002-05-19 01:59:48 +00:00
|
|
|
|
2002-08-21 00:47:29 +00:00
|
|
|
CString GetSongFilePath() const;
|
|
|
|
|
CString GetCacheFilePath() const;
|
2002-06-29 11:59:09 +00:00
|
|
|
|
2002-07-02 00:27:58 +00:00
|
|
|
public:
|
2002-06-29 11:59:09 +00:00
|
|
|
CString m_sSongDir;
|
|
|
|
|
CString m_sGroupName;
|
|
|
|
|
|
2001-11-03 10:52:42 +00:00
|
|
|
|
2002-06-29 11:59:09 +00:00
|
|
|
bool m_bChangedSinceSave;
|
2001-12-28 10:15:59 +00:00
|
|
|
|
2002-06-29 11:59:09 +00:00
|
|
|
CString m_sMainTitle;
|
|
|
|
|
CString m_sSubTitle;
|
|
|
|
|
CString m_sArtist;
|
|
|
|
|
CString m_sCredit;
|
2001-12-19 14:56:22 +00:00
|
|
|
|
2002-08-21 00:47:29 +00:00
|
|
|
CString GetFullTitle() const { return m_sMainTitle + " " + m_sSubTitle; }
|
2002-07-11 19:02:26 +00:00
|
|
|
static void GetMainAndSubTitlesFromFullTitle( const CString sFullTitle, CString &sMainTitleOut, CString &sSubTitleOut );
|
2002-04-28 20:42:32 +00:00
|
|
|
|
2002-06-29 11:59:09 +00:00
|
|
|
|
|
|
|
|
CString m_sMusicFile;
|
|
|
|
|
DWORD m_iMusicBytes;
|
2002-07-03 21:27:26 +00:00
|
|
|
float m_fBeat0OffsetInSeconds;
|
2002-06-29 11:59:09 +00:00
|
|
|
float m_fMusicLengthSeconds;
|
2002-07-11 19:02:26 +00:00
|
|
|
float m_fFirstBeat;
|
|
|
|
|
float m_fLastBeat;
|
2002-06-29 11:59:09 +00:00
|
|
|
float m_fMusicSampleStartSeconds;
|
|
|
|
|
float m_fMusicSampleLengthSeconds;
|
2002-08-18 23:20:18 +00:00
|
|
|
|
2002-08-21 00:47:29 +00:00
|
|
|
float GetMusicStartBeat() const;
|
2002-08-18 23:20:18 +00:00
|
|
|
|
2002-06-29 11:59:09 +00:00
|
|
|
CString m_sBannerFile;
|
|
|
|
|
CString m_sBackgroundFile;
|
|
|
|
|
CString m_sCDTitleFile;
|
2002-07-11 19:02:26 +00:00
|
|
|
CString m_sMovieBackgroundFile;
|
2002-06-29 11:59:09 +00:00
|
|
|
|
2002-07-31 19:40:40 +00:00
|
|
|
CString GetMusicPath() {return m_sMusicFile.Find('.')==0 ? m_sMusicFile : m_sSongDir+m_sMusicFile; };
|
2002-06-29 11:59:09 +00:00
|
|
|
CString GetBannerPath() {return m_sSongDir+m_sBannerFile; };
|
|
|
|
|
CString GetBackgroundPath() {return m_sSongDir+m_sBackgroundFile; };
|
2002-07-11 19:02:26 +00:00
|
|
|
CString GetCDTitlePath() {return m_sCDTitleFile.Find('.')==0 ? m_sCDTitleFile : m_sSongDir+m_sCDTitleFile; };
|
|
|
|
|
CString GetMovieBackgroundPath(){return m_sSongDir+m_sMovieBackgroundFile; };
|
2002-06-29 11:59:09 +00:00
|
|
|
|
|
|
|
|
|
2002-07-11 19:02:26 +00:00
|
|
|
bool HasMusic() {return m_sMusicFile != "" && IsAFile(GetMusicPath()); };
|
|
|
|
|
bool HasBanner() {return m_sBannerFile != "" && IsAFile(GetBannerPath()); };
|
|
|
|
|
bool HasBackground() {return m_sBackgroundFile != "" && IsAFile(GetBackgroundPath()); };
|
|
|
|
|
bool HasCDTitle() {return m_sCDTitleFile != "" && IsAFile(GetCDTitlePath()); };
|
|
|
|
|
bool HasMovieBackground() {return m_sMovieBackgroundFile != ""&& IsAFile(GetMovieBackgroundPath()); };
|
2002-06-29 11:59:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
CArray<BPMSegment, BPMSegment&> m_BPMSegments; // this must be sorted before gameplay
|
2002-07-11 19:02:26 +00:00
|
|
|
CArray<StopSegment, StopSegment&> m_StopSegments; // this must be sorted before gameplay
|
|
|
|
|
CArray<AnimationSegment, AnimationSegment&> m_AnimationSegments; // this must be sorted before gameplay
|
2002-06-29 11:59:09 +00:00
|
|
|
|
|
|
|
|
void AddBPMSegment( BPMSegment seg );
|
2002-07-11 19:02:26 +00:00
|
|
|
void AddStopSegment( StopSegment seg );
|
|
|
|
|
void AddAnimationSegment( AnimationSegment seg );
|
|
|
|
|
|
2002-08-21 00:48:41 +00:00
|
|
|
void GetMinMaxBPM( float &fMinBPM, float &fMaxBPM ) const
|
2001-11-27 22:47:30 +00:00
|
|
|
{
|
2001-12-28 10:15:59 +00:00
|
|
|
fMaxBPM = 0;
|
|
|
|
|
fMinBPM = 100000; // inf
|
|
|
|
|
for( int i=0; i<m_BPMSegments.GetSize(); i++ )
|
|
|
|
|
{
|
|
|
|
|
BPMSegment &seg = m_BPMSegments[i];
|
|
|
|
|
fMaxBPM = max( seg.m_fBPM, fMaxBPM );
|
|
|
|
|
fMinBPM = min( seg.m_fBPM, fMinBPM );
|
2001-11-27 22:47:30 +00:00
|
|
|
}
|
|
|
|
|
};
|
2002-08-21 00:48:41 +00:00
|
|
|
float GetBPMAtBeat( float fBeat ) const
|
2002-06-29 11:59:09 +00:00
|
|
|
{
|
|
|
|
|
for( int i=0; i<m_BPMSegments.GetSize()-1; i++ )
|
2002-07-02 00:27:58 +00:00
|
|
|
if( m_BPMSegments[i+1].m_fStartBeat > fBeat )
|
2002-06-29 11:59:09 +00:00
|
|
|
break;
|
|
|
|
|
return m_BPMSegments[i].m_fBPM;
|
|
|
|
|
};
|
2002-07-27 19:29:51 +00:00
|
|
|
BPMSegment& GetBPMSegmentAtBeat( float fBeat )
|
|
|
|
|
{
|
|
|
|
|
for( int i=0; i<m_BPMSegments.GetSize()-1; i++ )
|
|
|
|
|
if( m_BPMSegments[i+1].m_fStartBeat > fBeat )
|
|
|
|
|
break;
|
|
|
|
|
return m_BPMSegments[i];
|
|
|
|
|
};
|
2002-07-11 19:02:26 +00:00
|
|
|
CString GetAnimationAtBeat( float fBeat )
|
|
|
|
|
{
|
|
|
|
|
for( int i=0; i<m_AnimationSegments.GetSize()-1; i++ )
|
|
|
|
|
if( m_AnimationSegments[i+1].m_fStartBeat > fBeat )
|
|
|
|
|
break;
|
|
|
|
|
return m_AnimationSegments[i].m_sAnimationName;
|
|
|
|
|
};
|
2002-08-21 00:47:29 +00:00
|
|
|
void GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatOut, float &fBPSOut, bool &bFreezeOut ) const;
|
|
|
|
|
float GetElapsedTimeFromBeat( float fBeat ) const;
|
2002-06-29 11:59:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2002-07-11 19:02:26 +00:00
|
|
|
CArray<Notes*, Notes*> m_apNotes;
|
2002-01-20 23:29:03 +00:00
|
|
|
|
2002-08-20 06:47:30 +00:00
|
|
|
bool SongHasNoteType( NotesType nt ) const;
|
2002-08-21 00:47:29 +00:00
|
|
|
void GetNotesThatMatch( NotesType nt, CArray<Notes*, Notes*>& arrayAddTo ) const;
|
|
|
|
|
int GetNumTimesPlayed() const
|
2002-02-02 05:11:12 +00:00
|
|
|
{
|
|
|
|
|
int iTotalNumTimesPlayed = 0;
|
2002-07-11 19:02:26 +00:00
|
|
|
for( int i=0; i<m_apNotes.GetSize(); i++ )
|
2002-02-02 05:11:12 +00:00
|
|
|
{
|
2002-07-11 19:02:26 +00:00
|
|
|
iTotalNumTimesPlayed += m_apNotes[i]->m_iNumTimesPlayed;
|
2002-02-02 05:11:12 +00:00
|
|
|
}
|
|
|
|
|
return iTotalNumTimesPlayed;
|
|
|
|
|
}
|
2002-08-21 00:47:29 +00:00
|
|
|
bool IsNew() const;
|
|
|
|
|
bool IsEasy( NotesType nt ) const;
|
|
|
|
|
Grade GetGradeForDifficultyClass( NotesType nt, DifficultyClass dc ) const;
|
2001-11-03 10:52:42 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
2002-02-11 04:46:31 +00:00
|
|
|
void SortSongPointerArrayByTitle( CArray<Song*, Song*> &arraySongPointers );
|
|
|
|
|
void SortSongPointerArrayByBPM( CArray<Song*, Song*> &arraySongPointers );
|
|
|
|
|
void SortSongPointerArrayByArtist( CArray<Song*, Song*> &arraySongPointers );
|
|
|
|
|
void SortSongPointerArrayByGroup( CArray<Song*, Song*> &arraySongPointers );
|
|
|
|
|
void SortSongPointerArrayByMostPlayed( CArray<Song*, Song*> &arraySongPointers );
|
2002-01-16 10:01:32 +00:00
|
|
|
|
|
|
|
|
|