Files
itgmania212121/stepmania/src/song.h
T

281 lines
8.8 KiB
C++
Raw Normal View History

#ifndef SONG_H
#define SONG_H
/*
-----------------------------------------------------------------------------
Class: Song
2002-07-02 00:27:58 +00:00
Desc: See header.
2002-05-19 01:59:48 +00:00
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
Chris Danford
-----------------------------------------------------------------------------
*/
2001-11-03 10:52:42 +00:00
#include "PlayerNumber.h"
2002-05-01 19:14:55 +00:00
#include "GameConstantsAndTypes.h"
2002-09-07 11:45:15 +00:00
#include "Grade.h"
2003-08-03 00:13:55 +00:00
class Steps;
2002-09-07 11:45:15 +00:00
class StyleDef;
2002-09-11 05:15:46 +00:00
class NotesLoader;
class LyricsLoader;
2001-11-30 09:38:35 +00:00
extern const int FILE_CACHE_VERSION;
2001-12-28 10:15:59 +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 BackgroundChange
2002-07-11 19:02:26 +00:00
{
BackgroundChange() { m_fStartBeat=-1; m_fRate=1; m_bFadeLast=false; m_bRewindMovie=false; m_bLoop=true; };
BackgroundChange( float s, CString n, float r=1.f, bool f=false, bool m=false, bool l=true ) { m_fStartBeat=s; m_sBGName=n; m_fRate=r; m_bFadeLast=f; m_bRewindMovie=m; m_bLoop=l; };
2002-07-11 19:02:26 +00:00
float m_fStartBeat;
CString m_sBGName;
float m_fRate;
bool m_bFadeLast;
bool m_bRewindMovie;
bool m_bLoop;
2001-12-19 01:50:57 +00:00
};
void SortBackgroundChangesArray( vector<BackgroundChange> &arrayBackgroundChanges );
struct LyricSegment
{
float m_fStartTime;
CString m_sLyric;
2003-03-19 21:30:12 +00:00
RageColor m_Color;
};
2001-11-03 10:52:42 +00:00
class Song
{
2002-12-13 23:41:46 +00:00
CString m_sSongDir;
2002-09-06 23:36:04 +00:00
public:
2002-08-30 04:28:12 +00:00
/* Set when this song should be displayed in the music wheel: */
enum { SHOW_ALWAYS, /* all the time */
SHOW_ROULETTE, /* only when rouletting */
SHOW_NEVER } /* never (unless song hiding is turned off) */
m_SelectionDisplay;
2002-09-06 23:36:04 +00:00
Song();
2002-06-14 22:25:22 +00:00
~Song();
2003-06-24 20:04:35 +00:00
void Reset();
bool LoadWithoutCache( CString sDir );
2002-09-11 05:15:46 +00:00
NotesLoader *MakeLoader( CString sDir ) const;
2002-09-06 23:36:04 +00:00
bool LoadFromSongDir( CString sDir );
2003-06-24 20:04:35 +00:00
void RevertFromDisk();
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
void ReCalculateRadarValuesAndLastBeat(); // called by TidyUpData, and after saving
void TranslateTitles(); // called by TidyUpData
2001-11-03 10:52:42 +00:00
void SaveToSMFile( CString sPath, bool bSavingCache );
2002-09-11 04:49:07 +00:00
void Save(); // saves SM and DWI
2002-06-30 23:19:33 +00:00
void SaveToCacheFile();
2002-09-11 04:49:07 +00:00
void SaveToDWIFile();
2002-05-19 01:59:48 +00:00
const CString &GetSongFilePath() const;
CString GetCacheFilePath() const;
2002-06-29 11:59:09 +00:00
void AddAutoGenNotes();
2003-08-03 00:13:55 +00:00
void AutoGen( NotesType ntTo, NotesType ntFrom ); // create Steps of type ntTo from Steps of type ntFrom
2003-01-30 07:18:33 +00:00
void RemoveAutoGenNotes();
/* Directory this song data came from: */
2002-12-13 23:41:46 +00:00
const CString &GetSongDir() const { return m_sSongDir; }
/* Filename associated with this file. This will always have
* an .SM extension. If we loaded an .SM, this will point to
* it, but if we loaded any other type, this will point to a
* generated .SM filename. */
CString m_sSongFileName;
2002-06-29 11:59:09 +00:00
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
2003-02-11 23:52:18 +00:00
CString m_sMainTitle, m_sSubTitle, m_sArtist;
CString m_sMainTitleTranslit, m_sSubTitleTranslit, m_sArtistTranslit;
2003-05-20 04:41:47 +00:00
/* If PREFSMAN->m_bShowNative is off, these are the same as GetTranslit* below.
2003-02-11 23:52:18 +00:00
* Otherwise, they return the main titles. */
CString GetDisplayMainTitle() const;
CString GetDisplaySubTitle() const;
CString GetDisplayArtist() const;
/* Returns the transliterated titles, if any; otherwise returns the main titles. */
CString GetTranslitMainTitle() const { return m_sMainTitleTranslit.size()? m_sMainTitleTranslit: m_sMainTitle; }
CString GetTranslitSubTitle() const { return m_sSubTitleTranslit.size()? m_sSubTitleTranslit: m_sSubTitle; }
CString GetTranslitArtist() const { return m_sArtistTranslit.size()? m_sArtistTranslit:m_sArtist; }
/* "title subtitle" */
CString GetFullDisplayTitle() const;
CString GetFullTranslitTitle() const;
/* This is read and saved, but never actually used. */
2002-06-29 11:59:09 +00:00
CString m_sCredit;
2001-12-19 14:56:22 +00:00
2002-06-29 11:59:09 +00:00
CString m_sMusicFile;
2002-11-16 20:19:35 +00:00
unsigned 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-10-31 01:59:08 +00:00
float GetFirstBeat() const;
float GetLastBeat() const;
2002-06-29 11:59:09 +00:00
float m_fMusicSampleStartSeconds;
float m_fMusicSampleLengthSeconds;
enum { DISPLAY_ACTUAL, DISPLAY_SPECIFIED, DISPLAY_RANDOM } m_DisplayBPMType;
2003-06-16 17:28:58 +00:00
float m_fSpecifiedBPMMin;
float m_fSpecifiedBPMMax; // if a range, then Min != Max
2002-08-18 23:20:18 +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_sLyricsFile;
2002-06-29 11:59:09 +00:00
CString m_sBackgroundFile;
CString m_sCDTitleFile;
2002-09-10 08:39:58 +00:00
CString GetMusicPath() const;
CString GetBannerPath() const;
CString GetLyricsPath() const;
2002-09-10 08:39:58 +00:00
CString GetBackgroundPath() const;
CString GetCDTitlePath() const;
2002-06-29 11:59:09 +00:00
2002-09-07 11:45:15 +00:00
bool HasMusic() const;
bool HasBanner() const;
bool HasBackground() const;
bool HasCDTitle() const;
bool HasMovieBackground() const;
bool HasBGChanges() const;
bool HasLyrics() const;
2002-06-29 11:59:09 +00:00
2003-07-09 04:09:35 +00:00
bool Matches(CString sGroup, CString sSong) const;
vector<BPMSegment> m_BPMSegments; // this must be sorted before gameplay
vector<StopSegment> m_StopSegments; // this must be sorted before gameplay
vector<BackgroundChange> m_BackgroundChanges; // this must be sorted before gameplay
vector<LyricSegment> m_LyricSegments; // same
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 AddBackgroundChange( BackgroundChange seg );
void AddLyricSegment( LyricSegment seg );
2002-07-11 19:02:26 +00:00
2003-06-16 17:28:58 +00:00
void GetDisplayBPM( float &fMinBPMOut, float &fMaxBPMOut ) const
{
if( m_DisplayBPMType == DISPLAY_SPECIFIED )
{
fMinBPMOut = m_fSpecifiedBPMMin;
fMaxBPMOut = m_fSpecifiedBPMMax;
}
else
{
GetActualBPM( fMinBPMOut, fMaxBPMOut );
}
}
void GetActualBPM( float &fMinBPMOut, float &fMaxBPMOut ) const
{
fMaxBPMOut = 0;
fMinBPMOut = 100000; // inf
2002-10-31 01:59:08 +00:00
for( unsigned i=0; i<m_BPMSegments.size(); i++ )
2001-12-28 10:15:59 +00:00
{
2002-08-22 09:31:32 +00:00
const BPMSegment &seg = m_BPMSegments[i];
fMaxBPMOut = max( seg.m_fBPM, fMaxBPMOut );
fMinBPMOut = min( seg.m_fBPM, fMinBPMOut );
}
}
2002-08-21 00:48:41 +00:00
float GetBPMAtBeat( float fBeat ) const
2002-06-29 11:59:09 +00:00
{
2002-11-16 07:31:30 +00:00
unsigned i;
for( i=0; i<m_BPMSegments.size()-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 )
{
2002-11-16 07:31:30 +00:00
unsigned i;
for( i=0; i<m_BPMSegments.size()-1; i++ )
2002-07-27 19:29:51 +00:00
if( m_BPMSegments[i+1].m_fStartBeat > fBeat )
break;
return m_BPMSegments[i];
};
CString GetBackgroundAtBeat( float fBeat )
2002-07-11 19:02:26 +00:00
{
2002-11-16 07:31:30 +00:00
unsigned i;
for( i=0; i<m_BackgroundChanges.size()-1; i++ )
if( m_BackgroundChanges[i+1].m_fStartBeat > fBeat )
2002-07-11 19:02:26 +00:00
break;
return m_BackgroundChanges[i].m_sBGName;
}
void GetBeatAndBPSFromElapsedTime( float fElapsedTime, float &fBeatOut, float &fBPSOut, bool &bFreezeOut ) const;
2002-10-18 19:01:32 +00:00
float GetBeatFromElapsedTime( float fElapsedTime ) const // shortcut for places that care only about the beat
{
float fBeat, fThrowAway;
bool bThrowAway;
GetBeatAndBPSFromElapsedTime( fElapsedTime, fBeat, fThrowAway, bThrowAway );
return fBeat;
}
float GetElapsedTimeFromBeat( float fBeat ) const;
2002-06-29 11:59:09 +00:00
2003-08-03 00:13:55 +00:00
vector<Steps*> m_apNotes;
2002-01-20 23:29:03 +00:00
bool SongCompleteForStyle( const StyleDef *st ) const;
bool SongHasNotesType( NotesType nt ) const;
2002-09-29 05:06:18 +00:00
bool SongHasNotesTypeAndDifficulty( NotesType nt, Difficulty dc ) const;
2003-08-03 00:13:55 +00:00
void GetNotes( vector<Steps*>& arrayAddTo, NotesType nt, Difficulty dc = DIFFICULTY_INVALID, int iMeterLow = -1, int iMeterHigh = -1, CString sDescription = "", bool bIncludeAutoGen = true ) const;
Steps* GetNotes( NotesType nt, Difficulty dc, bool bIncludeAutoGen = true ) const;
Steps* GetNotes( NotesType nt, int iMeterLow, int iMeterHigh, bool bIncludeAutoGen = true ) const;
Steps* GetNotes( NotesType nt, CString sDescription, bool bIncludeAutoGen = true ) const;
Steps* GetClosestNotes( NotesType nt, Difficulty dc, bool bIncludeAutoGen = true ) const;
void GetEdits( vector<Steps*>& arrayAddTo, NotesType nt, bool bIncludeAutoGen = true ) const;
2002-09-07 11:45:15 +00:00
int GetNumTimesPlayed() const;
bool IsNew() const;
bool IsEasy( NotesType nt ) const;
bool HasEdits( NotesType nt ) const;
2003-01-22 05:29:27 +00:00
Grade GetGradeForDifficulty( const StyleDef *s, PlayerNumber pn, Difficulty dc ) const;
2002-08-30 04:28:12 +00:00
bool NormallyDisplayed() const;
bool RouletteDisplayed() const;
2003-06-16 20:23:07 +00:00
int GetNumNotesWithGrade( Grade g ) const;
2003-01-30 07:18:33 +00:00
2003-08-03 00:13:55 +00:00
void AddNotes( Steps* pNotes ); // we are responsible for deleting the memory pointed to by pNotes!
void RemoveNotes( Steps* pNotes );
2001-11-03 10:52:42 +00:00
};
2003-06-16 20:23:07 +00:00
CString MakeSortString( CString s );
2003-01-03 05:56:28 +00:00
void SortSongPointerArrayByDifficulty( vector<Song*> &arraySongPointers );
void SortSongPointerArrayByTitle( vector<Song*> &arraySongPointers );
void SortSongPointerArrayByBPM( vector<Song*> &arraySongPointers );
2003-06-16 20:23:07 +00:00
void SortSongPointerArrayByGrade( vector<Song*> &arraySongPointers );
2003-01-03 05:56:28 +00:00
void SortSongPointerArrayByArtist( vector<Song*> &arraySongPointers );
void SortSongPointerArrayByGroupAndDifficulty( vector<Song*> &arraySongPointers );
void SortSongPointerArrayByGroupAndTitle( vector<Song*> &arraySongPointers );
2003-01-03 05:56:28 +00:00
void SortSongPointerArrayByMostPlayed( vector<Song*> &arraySongPointers );
2003-06-27 08:06:22 +00:00
void SortSongPointerArrayByMeter( vector<Song*> &arraySongPointers, Difficulty dc );
2002-01-16 10:01:32 +00:00
#endif