2011-03-17 01:47:30 -04:00
#ifndef SONGMANAGER_H
#define SONGMANAGER_H
2011-08-06 21:33:49 +00:00
class LoadingWindow ;
2011-03-17 01:47:30 -04:00
class Song ;
class Style ;
class Steps ;
class PlayerOptions ;
struct lua_State ;
#include "RageTypes.h"
#include "GameConstantsAndTypes.h"
#include "SongOptions.h"
#include "PlayerOptions.h"
#include "PlayerNumber.h"
#include "Difficulty.h"
#include "Course.h"
#include "ThemeMetric.h"
#include "RageTexturePreloader.h"
#include "RageUtil.h"
2011-06-12 19:35:24 -04:00
RString SONG_GROUP_COLOR_NAME ( size_t i );
RString COURSE_GROUP_COLOR_NAME ( size_t i );
bool CompareNotesPointersForExtra ( const Steps * n1 , const Steps * n2 );
2011-03-17 01:47:30 -04:00
/** @brief The max number of edit steps a profile can have. */
const int MAX_EDIT_STEPS_PER_PROFILE = 200 ;
/** @brief The max number of edit courses a profile can have. */
const int MAX_EDIT_COURSES_PER_PROFILE = 20 ;
/** @brief The holder for the Songs and its Steps. */
class SongManager
{
public :
SongManager ();
~ SongManager ();
2022-06-09 15:31:29 +02:00
/**
* @brief Initialize all songs from disk
* @param ld the loading window to be updated, or nullptr
* @param onlyAdditions only load songs added after the last
* invocation of this function
*/
void InitSongsFromDisk ( LoadingWindow * ld , bool onlyAdditions );
2011-03-17 01:47:30 -04:00
void FreeSongs ();
2015-03-17 04:20:02 +00:00
void UnlistSong ( Song * song );
2011-03-17 01:47:30 -04:00
void Cleanup ();
void Invalidate ( const Song * pStaleSong );
void RegenerateNonFixedCourses ();
void SetPreferences ();
void SaveEnabledSongsToPref ();
void LoadEnabledSongsFromPref ();
void LoadStepEditsFromProfileDir ( const RString & sProfileDir , ProfileSlot slot );
void LoadCourseEditsFromProfileDir ( const RString & sProfileDir , ProfileSlot slot );
int GetNumStepsLoadedFromProfile ();
void FreeAllLoadedFromProfile ( ProfileSlot slot = ProfileSlot_Invalid );
void LoadGroupSymLinks ( RString sDir , RString sGroupFolder );
2022-06-09 15:31:29 +02:00
/**
* @brief Initialize all courses from disk
* @param ld the loading window to be updated, or nullptr
* @param onlyAdditions only load courses added after the last
* invocation of this function
*/
void InitCoursesFromDisk ( LoadingWindow * ld , bool onlyAdditions );
2011-03-17 01:47:30 -04:00
void InitAutogenCourses ();
void InitRandomAttacks ();
void FreeCourses ();
void AddCourse ( Course * pCourse ); // transfers ownership of pCourse
void DeleteCourse ( Course * pCourse ); // transfers ownership of pCourse
/** @brief Remove all of the auto generated courses. */
void DeleteAutogenCourses ();
void InvalidateCachedTrails ();
2022-06-09 15:31:29 +02:00
/**
* @brief Initialize all songs and courses from disk, and update
* autogenerated courses afterwards
* @param ld the loading window to be updated, or nullptr
* @param onlyAdditions only load songs and courses added after the
* last invocation of this function
*/
void InitAll ( LoadingWindow * ld , bool onlyAdditions );
2022-10-28 17:17:06 +02:00
void Reload ( bool bAllowFastLoad , LoadingWindow * ld = nullptr );
2022-06-09 15:31:29 +02:00
void LoadAdditions ( LoadingWindow * ld = nullptr );
2011-03-17 01:47:30 -04:00
void PreloadSongImages ();
2015-03-31 15:20:37 -06:00
bool IsGroupNeverCached ( const RString & group ) const ;
2011-03-17 01:47:30 -04:00
RString GetSongGroupBannerPath ( RString sSongGroup ) const ;
//RString GetSongGroupBackgroundPath( RString sSongGroup ) const;
2022-07-10 18:28:56 +03:00
void GetSongGroupNames ( std :: vector < RString > & AddTo ) const ;
2011-03-17 01:47:30 -04:00
bool DoesSongGroupExist ( RString sSongGroup ) const ;
RageColor GetSongGroupColor ( const RString & sSongGroupName ) const ;
RageColor GetSongColor ( const Song * pSong ) const ;
RString GetCourseGroupBannerPath ( const RString & sCourseGroup ) const ;
//RString GetCourseGroupBackgroundPath( const RString &sCourseGroup ) const;
2022-07-10 18:28:56 +03:00
void GetCourseGroupNames ( std :: vector < RString > & AddTo ) const ;
2011-03-17 01:47:30 -04:00
bool DoesCourseGroupExist ( const RString & sCourseGroup ) const ;
RageColor GetCourseGroupColor ( const RString & sCourseGroupName ) const ;
RageColor GetCourseColor ( const Course * pCourse ) const ;
2011-08-27 13:18:41 -05:00
void ResetGroupColors ();
2011-03-17 01:47:30 -04:00
static RString ShortenGroupName ( RString sLongGroupName );
// Lookup
2011-05-30 13:57:09 -04:00
/**
* @brief Retrieve all of the songs that belong to a particular group.
* @param sGroupName the name of the group.
* @return the songs that belong in the group. */
2022-07-10 18:28:56 +03:00
const std :: vector < Song *> & GetSongs ( const RString & sGroupName ) const ;
2011-05-30 13:57:09 -04:00
/**
* @brief Retrieve all of the songs in the game.
* @return all of the songs. */
2022-07-10 18:28:56 +03:00
const std :: vector < Song *> & GetAllSongs () const { return GetSongs ( GROUP_ALL ); }
2011-05-30 13:57:09 -04:00
/**
* @brief Retrieve all of the popular songs.
*
* Popularity is determined specifically by the number of times
* a song is chosen.
* @return all of the popular songs. */
2022-07-10 18:28:56 +03:00
const std :: vector < Song *> & GetPopularSongs () const { return m_pPopularSongs ; }
2011-08-27 15:23:20 -05:00
2011-05-30 13:57:09 -04:00
/**
* @brief Retrieve all of the songs in a group that have at least one
* valid step for the current gametype.
* @param sGroupName the name of the group.
* @return the songs within the group that have at least one valid Step. */
2022-07-10 18:28:56 +03:00
const std :: vector < Song *> & GetSongsOfCurrentGame ( const RString & sGroupName ) const ;
2011-05-30 13:57:09 -04:00
/**
* @brief Retrieve all of the songs in the game that have at least one
* valid step for the current gametype.
* @return the songs within the game that have at least one valid Step. */
2022-07-10 18:28:56 +03:00
const std :: vector < Song *> & GetAllSongsOfCurrentGame () const ;
2011-08-27 15:23:20 -05:00
2022-07-10 18:28:56 +03:00
void GetPreferredSortSongs ( std :: vector < Song *> & AddTo ) const ;
2011-03-17 01:47:30 -04:00
RString SongToPreferredSortSectionName ( const Song * pSong ) const ;
2022-07-10 18:28:56 +03:00
const std :: vector < Course *> & GetPopularCourses ( CourseType ct ) const { return m_pPopularCourses [ ct ]; }
2011-03-17 01:47:30 -04:00
Song * FindSong ( RString sPath ) const ;
Song * FindSong ( RString sGroup , RString sSong ) const ;
Course * FindCourse ( RString sPath ) const ;
Course * FindCourse ( RString sGroup , RString sName ) const ;
2011-05-30 13:57:09 -04:00
/**
* @brief Retrieve the number of songs in the game.
* @return the number of songs. */
2011-03-17 01:47:30 -04:00
int GetNumSongs () const ;
2011-09-16 21:52:27 -04:00
int GetNumLockedSongs () const ;
2011-03-17 01:47:30 -04:00
int GetNumUnlockedSongs () const ;
int GetNumSelectableAndUnlockedSongs () const ;
int GetNumSongGroups () const ;
2011-05-30 13:57:09 -04:00
/**
* @brief Retrieve the number of courses in the game.
* @return the number of courses. */
2011-03-17 01:47:30 -04:00
int GetNumCourses () const ;
int GetNumCourseGroups () const ;
Song * GetRandomSong ();
Course * GetRandomCourse ();
// sm-ssc addition:
RString GetSongGroupByIndex ( unsigned index ) { return m_sSongGroupNames [ index ]; }
int GetSongRank ( Song * pSong );
2022-07-10 18:28:56 +03:00
void GetStepsLoadedFromProfile ( std :: vector < Steps *> & AddTo , ProfileSlot slot ) const ;
2011-03-17 01:47:30 -04:00
void DeleteSteps ( Steps * pSteps ); // transfers ownership of pSteps
2022-07-10 18:28:56 +03:00
void GetAllCourses ( std :: vector < Course *> & AddTo , bool bIncludeAutogen ) const ;
void GetCourses ( CourseType ct , std :: vector < Course *> & AddTo , bool bIncludeAutogen ) const ;
void GetCoursesInGroup ( std :: vector < Course *> & AddTo , const RString & sCourseGroup , bool bIncludeAutogen ) const ;
void GetPreferredSortCourses ( CourseType ct , std :: vector < Course *> & AddTo , bool bIncludeAutogen ) const ;
2011-03-17 01:47:30 -04:00
void GetExtraStageInfo ( bool bExtra2 , const Style * s , Song *& pSongOut , Steps *& pStepsOut );
Song * GetSongFromDir ( RString sDir ) const ;
Course * GetCourseFromPath ( RString sPath ) const ; // path to .crs file, or path to song group dir
Course * GetCourseFromName ( RString sName ) const ;
void UpdatePopular ();
void UpdateShuffled (); // re-shuffle songs and courses
2023-03-14 12:02:21 -07:00
void SetPreferredSongs ( RString sPreferredSongs = "PreferredSongs.txt" , bool bIsAbsolute = false );
void SetPreferredCourses ( RString sPreferredCourses = "PreferredCourses.txt" , bool bIsAbsolute = false );
2011-03-17 01:47:30 -04:00
void UpdatePreferredSort ( RString sPreferredSongs = "PreferredSongs.txt" , RString sPreferredCourses = "PreferredCourses.txt" );
void SortSongs (); // sort m_pSongs by CompareSongPointersByTitle
void UpdateRankingCourses (); // courses shown on the ranking screen
void RefreshCourseGroupInfo ();
// Lua
void PushSelf ( lua_State * L );
protected :
2022-06-09 15:31:29 +02:00
/**
* @brief Load all songs from a directory
* @param sDir the directory to be loaded
* @param ld the loading window to be updated, or nullptr
* @param onlyAdditions only load songs added after the last
* invocation of this function
*/
void LoadSongDir ( RString sDir , LoadingWindow * ld , bool onlyAdditions );
2014-12-07 01:53:17 -07:00
bool GetExtraStageInfoFromCourse ( bool bExtra2 , RString sPreferredGroup , Song *& pSongOut , Steps *& pStepsOut , StepsType stype );
2011-03-17 01:47:30 -04:00
void SanityCheckGroupDir ( RString sDir ) const ;
void AddGroup ( RString sDir , RString sGroupDirName );
int GetNumEditsLoadedFromProfile ( ProfileSlot slot ) const ;
2015-03-30 17:45:52 -06:00
void AddSongToList ( Song * new_song );
2011-03-17 01:47:30 -04:00
/** @brief All of the songs that can be played. */
2022-07-10 18:28:56 +03:00
std :: vector < Song *> m_pSongs ;
std :: map < RString , Song *> m_SongsByDir ;
std :: set < RString > m_GroupsToNeverCache ;
2022-06-09 15:31:29 +02:00
2015-03-17 04:20:02 +00:00
/** @brief Hold pointers to all the songs that have been deleted from disk but must at least be kept temporarily alive for smooth audio transitions. */
2022-07-10 18:28:56 +03:00
std :: vector < Song *> m_pDeletedSongs ;
2022-06-09 15:31:29 +02:00
2011-03-17 01:47:30 -04:00
/** @brief The most popular songs ranked by number of plays. */
2022-07-10 18:28:56 +03:00
std :: vector < Song *> m_pPopularSongs ;
std :: vector < Song *> m_pShuffledSongs ; // used by GetRandomSong
2011-03-17 01:47:30 -04:00
struct PreferredSortSection
{
RString sName ;
2022-07-10 18:28:56 +03:00
std :: vector < Song *> vpSongs ;
2011-03-17 01:47:30 -04:00
};
2022-07-10 18:28:56 +03:00
std :: vector < PreferredSortSection > m_vPreferredSongSort ;
std :: vector < RString > m_sSongGroupNames ;
std :: vector < RString > m_sSongGroupBannerPaths ; // each song group may have a banner associated with it
2011-03-17 01:47:30 -04:00
//vector<RString> m_sSongGroupBackgroundPaths; // each song group may have a background associated with it (very rarely)
struct Comp { bool operator ()( const RString & s , const RString & t ) const { return CompareRStringsAsc ( s , t ); } };
2022-07-10 18:28:56 +03:00
typedef std :: vector < Song *> SongPointerVector ;
std :: map < RString , SongPointerVector , Comp > m_mapSongGroupIndex ;
2011-03-17 01:47:30 -04:00
2022-07-10 18:28:56 +03:00
std :: vector < Course *> m_pCourses ;
std :: vector < Course *> m_pPopularCourses [ NUM_CourseType ];
std :: vector < Course *> m_pShuffledCourses ; // used by GetRandomCourse
2011-03-17 01:47:30 -04:00
struct CourseGroupInfo
{
RString m_sBannerPath ;
//RString m_sBackgroundPath;
};
2022-07-10 18:28:56 +03:00
std :: map < RString , CourseGroupInfo > m_mapCourseGroupToInfo ;
typedef std :: vector < Course *> CoursePointerVector ;
std :: vector < CoursePointerVector > m_vPreferredCourseSort ;
2011-03-17 01:47:30 -04:00
RageTexturePreloader m_TexturePreload ;
ThemeMetric < int > NUM_SONG_GROUP_COLORS ;
ThemeMetric1D < RageColor > SONG_GROUP_COLOR ;
ThemeMetric < int > NUM_COURSE_GROUP_COLORS ;
ThemeMetric1D < RageColor > COURSE_GROUP_COLOR ;
2017-06-06 06:30:06 -06:00
ThemeMetric < int > num_profile_song_group_colors ;
ThemeMetric1D < RageColor > profile_song_group_colors ;
2011-03-17 01:47:30 -04:00
};
2013-11-30 09:50:54 -06:00
extern SongManager * SONGMAN ; // global and accessible from anywhere in our program
2011-03-17 01:47:30 -04:00
#endif
/**
* @file
* @author Chris Danford, Glenn Maynard (c) 2001-2004
* @section LICENSE
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, and/or sell copies of the Software, and to permit persons to
* whom the Software is furnished to do so, provided that the above
* copyright notice(s) and this permission notice appear in all copies of
* the Software and that both the above copyright notice(s) and this
* permission notice appear in supporting documentation.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF
* THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS
* INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT
* OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
* OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/