2003-02-16 04:01:45 +00:00
# include "global.h"
2002-01-16 10:01:32 +00:00
/*
-----------------------------------------------------------------------------
2003-02-10 05:30:12 +00:00
Class: MusicWheelItem
2002-01-16 10:01:32 +00:00
2002-05-01 19:14:55 +00:00
Desc: See header.
2002-01-16 10:01:32 +00:00
2003-02-03 04:50:37 +00:00
Copyright (c) 2001-2003 by the person(s) listed below. All rights reserved.
2002-05-01 19:14:55 +00:00
Chris Danford
2003-02-03 04:50:37 +00:00
Chris Gomez
2003-02-10 05:30:12 +00:00
Glenn Maynard
2002-01-16 10:01:32 +00:00
-----------------------------------------------------------------------------
*/
# include "MusicWheel.h"
# include "RageUtil.h"
2002-02-28 19:40:40 +00:00
# include "SongManager.h"
2002-03-19 07:09:49 +00:00
# include "GameManager.h"
2002-07-23 01:41:40 +00:00
# include "PrefsManager.h"
2003-01-02 07:54:28 +00:00
# include "RageSoundManager.h"
2002-05-19 01:59:48 +00:00
# include "ScreenManager.h" // for sending SM_PlayMusicSample
2002-05-01 19:14:55 +00:00
# include "RageLog.h"
# include "GameConstantsAndTypes.h"
2002-07-23 01:41:40 +00:00
# include "GameState.h"
2003-07-04 18:03:20 +00:00
# include "RageMath.h"
2002-11-11 04:53:31 +00:00
# include <math.h>
# include "ThemeManager.h"
2003-04-03 21:29:14 +00:00
# include "song.h"
2003-03-31 23:06:15 +00:00
# include "Course.h"
2003-04-02 04:41:49 +00:00
# include "RageDisplay.h"
2003-04-19 18:51:13 +00:00
# include "RageTextureManager.h"
2003-04-19 22:22:31 +00:00
# include "Banner.h"
2003-06-27 08:06:22 +00:00
# include "Notes.h"
2003-07-07 22:21:31 +00:00
# include "UnlockSystem.h"
2002-01-20 08:59:38 +00:00
2002-09-03 06:33:08 +00:00
2002-08-13 23:26:46 +00:00
# define FADE_SECONDS THEME->GetMetricF("MusicWheel","FadeSeconds")
# define SWITCH_SECONDS THEME->GetMetricF("MusicWheel","SwitchSeconds")
# define ROULETTE_SWITCH_SECONDS THEME->GetMetricF("MusicWheel","RouletteSwitchSeconds")
# define ROULETTE_SLOW_DOWN_SWITCHES THEME->GetMetricI("MusicWheel","RouletteSlowDownSwitches")
# define LOCKED_INITIAL_VELOCITY THEME->GetMetricF("MusicWheel","LockedInitialVelocity")
# define SCROLL_BAR_X THEME->GetMetricF("MusicWheel","ScrollBarX")
2002-08-26 05:53:48 +00:00
# define SCROLL_BAR_HEIGHT THEME->GetMetricI("MusicWheel","ScrollBarHeight")
2003-03-26 19:15:38 +00:00
CachedThemeMetricF ITEM_CURVE_X ( " MusicWheel " , " ItemCurveX " ) ;
CachedThemeMetricF ITEM_SPACING_Y ( " MusicWheel " , " ItemSpacingY " ) ;
2002-09-03 06:33:08 +00:00
# define NUM_SECTION_COLORS THEME->GetMetricI("MusicWheel","NumSectionColors")
# define SECTION_COLORS( i ) THEME->GetMetricC("MusicWheel",ssprintf("SectionColor%d",i+1))
2003-02-10 05:30:12 +00:00
# define DEFAULT_SCROLL_DIRECTION THEME->GetMetricI("Notes","DefaultScrollDirection")
2003-02-12 20:55:51 +00:00
# define SONG_REAL_EXTRA_COLOR THEME->GetMetricC("MusicWheel","SongRealExtraColor")
2003-03-13 23:58:30 +00:00
# define SHOW_ROULETTE THEME->GetMetricB("MusicWheel","ShowRoulette")
# define SHOW_RANDOM THEME->GetMetricB("MusicWheel","ShowRandom")
2003-04-02 04:41:49 +00:00
CachedThemeMetricB USE_3D ( " MusicWheel " , " Use3D " ) ;
2003-06-30 00:34:18 +00:00
CachedThemeMetricI NUM_WHEEL_ITEMS_METRIC ( " MusicWheel " , " NumWheelItems " ) ;
# define NUM_WHEEL_ITEMS min( MAX_WHEEL_ITEMS, (int) NUM_WHEEL_ITEMS_METRIC )
2002-09-03 06:33:08 +00:00
2003-01-21 07:04:53 +00:00
const int MAX_WHEEL_SOUND_SPEED = 15 ;
2002-09-03 06:33:08 +00:00
2003-02-17 20:38:57 +00:00
2003-06-30 07:09:13 +00:00
static const SongSortOrder SortOrder [ ] =
{
SORT_GROUP ,
SORT_TITLE ,
SORT_BPM ,
SORT_MOST_PLAYED ,
SORT_ARTIST ,
SORT_INVALID
} ;
2003-05-17 23:04:14 +00:00
2002-01-16 10:01:32 +00:00
MusicWheel : : MusicWheel ( )
{
2002-07-31 19:40:40 +00:00
LOG - > Trace ( " MusicWheel::MusicWheel() " ) ;
2003-01-27 07:25:29 +00:00
if ( GAMESTATE - > m_pCurSong ! = NULL )
2003-04-25 00:27:30 +00:00
LOG - > Trace ( " Current Song: %s " , GAMESTATE - > m_pCurSong - > GetSongDir ( ) . c_str ( ) ) ;
2003-01-27 07:25:29 +00:00
else
LOG - > Trace ( " Current Song: NULL " ) ;
2002-09-03 06:33:08 +00:00
2003-01-01 17:20:36 +00:00
if ( DEFAULT_SCROLL_DIRECTION & & GAMESTATE - > m_pCurSong = = NULL ) /* check the song is null... incase they have just come back from a song and changed their PlayerOptions */
{
for ( int i = 0 ; i < NUM_PLAYERS ; i + + )
2003-02-26 23:26:57 +00:00
GAMESTATE - > m_PlayerOptions [ i ] . m_fReverseScroll = 1 ;
2003-01-01 17:20:36 +00:00
}
2002-09-03 06:33:08 +00:00
// update theme metric cache
2003-03-26 19:15:38 +00:00
ITEM_CURVE_X . Refresh ( ) ;
ITEM_SPACING_Y . Refresh ( ) ;
2003-04-02 04:41:49 +00:00
USE_3D . Refresh ( ) ;
2003-06-30 00:34:18 +00:00
NUM_WHEEL_ITEMS_METRIC . Refresh ( ) ;
2002-09-03 06:33:08 +00:00
2002-05-28 20:01:22 +00:00
// for debugging
2003-01-30 07:18:33 +00:00
if ( GAMESTATE - > m_CurStyle = = STYLE_INVALID )
2002-07-23 01:41:40 +00:00
GAMESTATE - > m_CurStyle = STYLE_DANCE_SINGLE ;
2002-05-28 20:01:22 +00:00
2003-04-12 17:39:27 +00:00
m_sprSelectionOverlay . Load ( THEME - > GetPathToG ( " MusicWheel highlight " ) ) ;
2002-01-16 10:01:32 +00:00
m_sprSelectionOverlay . SetXY ( 0 , 0 ) ;
2002-10-28 05:30:45 +00:00
m_sprSelectionOverlay . SetDiffuse ( RageColor ( 1 , 1 , 1 , 1 ) ) ;
2003-02-18 23:15:38 +00:00
m_sprSelectionOverlay . SetEffectGlowShift ( 1.0f , RageColor ( 1 , 1 , 1 , 0.4f ) , RageColor ( 1 , 1 , 1 , 1 ) ) ;
2002-09-02 21:59:58 +00:00
AddChild ( & m_sprSelectionOverlay ) ;
2002-05-29 09:47:24 +00:00
2002-08-13 23:26:46 +00:00
m_ScrollBar . SetX ( SCROLL_BAR_X ) ;
2002-08-26 05:53:48 +00:00
m_ScrollBar . SetBarHeight ( SCROLL_BAR_HEIGHT ) ;
2002-09-02 21:59:58 +00:00
this - > AddChild ( & m_ScrollBar ) ;
2002-05-01 19:14:55 +00:00
2003-01-21 02:45:35 +00:00
/* We play a lot of this one, so precache it. */
2003-04-12 17:39:27 +00:00
m_soundChangeMusic . Load ( THEME - > GetPathToS ( " MusicWheel change " ) , true ) ;
m_soundChangeSort . Load ( THEME - > GetPathToS ( " MusicWheel sort " ) ) ;
m_soundExpand . Load ( THEME - > GetPathToS ( " MusicWheel expand " ) ) ;
m_soundStart . Load ( THEME - > GetPathToS ( " Common start " ) ) ;
m_soundLocked . Load ( THEME - > GetPathToS ( " MusicWheel locked " ) ) ;
2002-06-24 22:04:31 +00:00
2002-01-16 10:01:32 +00:00
m_iSelection = 0 ;
2003-06-16 17:28:58 +00:00
m_LastSongSortOrder = SORT_INVALID ;
2002-01-16 10:01:32 +00:00
2002-06-24 22:04:31 +00:00
m_WheelState = STATE_SELECTING_MUSIC ;
m_fTimeLeftInState = 0 ;
2002-01-20 08:59:38 +00:00
m_fPositionOffsetFromSelection = 0 ;
2002-01-16 10:01:32 +00:00
2002-06-24 22:04:31 +00:00
m_iSwitchesLeftInSpinDown = 0 ;
2003-02-25 21:10:07 +00:00
m_Moving = 0 ;
2003-02-01 05:39:48 +00:00
if ( GAMESTATE - > IsExtraStage ( ) | | GAMESTATE - > IsExtraStage2 ( ) )
2002-07-31 04:06:34 +00:00
{
2002-08-01 13:42:56 +00:00
// make the preferred group the group of the last song played.
2003-02-25 00:33:42 +00:00
if ( GAMESTATE - > m_sPreferredGroup = = GROUP_ALL_MUSIC & & ! PREFSMAN - > m_bPickExtraStage )
2003-04-23 07:29:03 +00:00
{
ASSERT ( GAMESTATE - > m_pCurSong ) ;
2002-08-01 13:42:56 +00:00
GAMESTATE - > m_sPreferredGroup = GAMESTATE - > m_pCurSong - > m_sGroupName ;
2003-04-23 07:29:03 +00:00
}
2002-08-01 13:42:56 +00:00
Song * pSong ;
Notes * pNotes ;
PlayerOptions po ;
SongOptions so ;
SONGMAN - > GetExtraStageInfo (
GAMESTATE - > IsExtraStage2 ( ) ,
GAMESTATE - > m_sPreferredGroup ,
2002-09-06 08:56:28 +00:00
GAMESTATE - > GetCurrentStyleDef ( ) ,
2002-08-01 13:42:56 +00:00
pSong ,
pNotes ,
po ,
so ) ;
GAMESTATE - > m_pCurSong = pSong ;
for ( int p = 0 ; p < NUM_PLAYERS ; p + + )
2002-07-31 04:06:34 +00:00
{
2003-04-10 05:46:31 +00:00
if ( GAMESTATE - > IsHumanPlayer ( p ) )
2002-07-31 04:06:34 +00:00
{
2002-08-01 13:42:56 +00:00
GAMESTATE - > m_pCurNotes [ p ] = pNotes ;
GAMESTATE - > m_PlayerOptions [ p ] = po ;
2003-07-07 19:19:16 +00:00
GAMESTATE - > m_PreferredDifficulty [ p ] = pNotes - > GetDifficulty ( ) ;
2002-07-31 04:06:34 +00:00
}
}
2002-08-01 13:42:56 +00:00
GAMESTATE - > m_SongOptions = so ;
2002-07-31 04:06:34 +00:00
}
2003-06-30 07:09:13 +00:00
if ( GAMESTATE - > m_SongSortOrder = = SORT_INVALID )
{
if ( GAMESTATE - > IsCourseMode ( ) )
GAMESTATE - > m_SongSortOrder = SORT_PREFERRED ;
else
GAMESTATE - > m_SongSortOrder = SortOrder [ 0 ] ;
}
2003-05-17 23:04:14 +00:00
2002-08-30 21:51:40 +00:00
/* Build all of the wheel item data. Do tihs after selecting
* the extra stage, so it knows to always display it. */
for ( int so = 0 ; so < NUM_SORT_ORDERS ; so + + )
BuildWheelItemDatas ( m_WheelItemDatas [ so ] , SongSortOrder ( so ) ) ;
2002-08-01 13:42:56 +00:00
// If there is no currently selected song, select one.
if ( GAMESTATE - > m_pCurSong = = NULL )
2002-02-24 01:43:11 +00:00
{
2003-01-27 07:25:29 +00:00
//Select the first selectable song based on the sort order...
vector < WheelItemData > & wiWheelItems = m_WheelItemDatas [ GAMESTATE - > m_SongSortOrder ] ;
for ( unsigned i = 0 ; i < wiWheelItems . size ( ) ; i + + )
{
if ( wiWheelItems [ i ] . m_pSong ! = NULL )
{
GAMESTATE - > m_pCurSong = wiWheelItems [ i ] . m_pSong ;
break ;
}
}
if ( GAMESTATE - > m_pCurSong = = NULL )
2002-08-01 13:42:56 +00:00
{
2003-01-27 07:25:29 +00:00
//XXX What to do here?
//No selectable songs from the wheel data...
//Cursor will be on Random/Roulette, but GAMESTATE->m_pCurSong will be NULL
//Should we error out? The user won't have an enjoyable game experience at this point...
//Should we find the pointer to the roulette entry? (the old way did that - maybe not intentional though)
//For now, write out to the debug log...
LOG - > Trace ( " MusicWheel::MusicWheel() - No selectable songs found in WheelData! " ) ;
2002-08-01 13:42:56 +00:00
}
2002-02-24 01:43:11 +00:00
}
2002-08-01 05:11:11 +00:00
// Select the the previously selected song (if any)
2003-01-02 02:59:25 +00:00
bool selected = SelectSong ( GAMESTATE - > m_pCurSong ) ;
// Select the the previously selected course (if any)
if ( ! selected ) selected = SelectCourse ( GAMESTATE - > m_pCurCourse ) ;
if ( ! selected ) SetOpenGroup ( " " ) ;
// rebuild the WheelItems that appear on screen
2003-03-31 23:06:15 +00:00
RebuildMusicWheelItems ( ) ;
2003-01-02 02:59:25 +00:00
}
MusicWheel : : ~ MusicWheel ( )
{
}
bool MusicWheel : : SelectSong ( const Song * p )
{
if ( p = = NULL )
return false ;
unsigned i ;
vector < WheelItemData > & from = m_WheelItemDatas [ GAMESTATE - > m_SongSortOrder ] ;
for ( i = 0 ; i < from . size ( ) ; i + + )
2002-01-20 09:03:37 +00:00
{
2003-01-02 02:59:25 +00:00
if ( from [ i ] . m_pSong = = p )
2002-02-09 18:53:47 +00:00
{
2003-01-02 02:59:25 +00:00
// make its group the currently expanded group
SetOpenGroup ( from [ i ] . m_sSectionName ) ;
break ;
2002-02-09 18:53:47 +00:00
}
2002-01-20 09:03:37 +00:00
}
2002-02-06 05:13:39 +00:00
2003-01-02 02:59:25 +00:00
if ( i = = from . size ( ) )
return false ;
for ( i = 0 ; i < m_CurWheelItemData . size ( ) ; i + + )
2002-08-01 05:11:11 +00:00
{
2003-01-02 02:59:25 +00:00
if ( m_CurWheelItemData [ i ] - > m_pSong = = p )
m_iSelection = i ; // select it
}
return true ;
}
bool MusicWheel : : SelectCourse ( const Course * p )
{
if ( p = = NULL )
return false ;
unsigned i ;
vector < WheelItemData > & from = m_WheelItemDatas [ GAMESTATE - > m_SongSortOrder ] ;
for ( i = 0 ; i < from . size ( ) ; i + + )
{
if ( from [ i ] . m_pCourse = = p )
2002-08-01 05:11:11 +00:00
{
2003-01-02 02:59:25 +00:00
// make its group the currently expanded group
SetOpenGroup ( from [ i ] . m_sSectionName ) ;
break ;
2002-08-01 05:11:11 +00:00
}
}
2003-01-02 02:59:25 +00:00
if ( i = = from . size ( ) )
return false ;
2002-02-06 05:13:39 +00:00
2003-01-02 02:59:25 +00:00
for ( i = 0 ; i < m_CurWheelItemData . size ( ) ; i + + )
{
if ( m_CurWheelItemData [ i ] - > m_pCourse = = p )
m_iSelection = i ; // select it
}
2002-08-13 23:26:46 +00:00
2003-01-02 02:59:25 +00:00
return true ;
2002-01-16 10:01:32 +00:00
}
2003-06-16 17:28:58 +00:00
bool MusicWheel : : SelectSort ( SongSortOrder so )
{
if ( so = = SORT_INVALID )
return false ;
unsigned i ;
vector < WheelItemData > & from = m_WheelItemDatas [ GAMESTATE - > m_SongSortOrder ] ;
for ( i = 0 ; i < from . size ( ) ; i + + )
{
if ( from [ i ] . m_SongSortOrder = = so )
{
// make its group the currently expanded group
SetOpenGroup ( from [ i ] . m_sSectionName ) ;
break ;
}
}
if ( i = = from . size ( ) )
return false ;
for ( i = 0 ; i < m_CurWheelItemData . size ( ) ; i + + )
{
if ( m_CurWheelItemData [ i ] - > m_SongSortOrder = = so )
m_iSelection = i ; // select it
}
return true ;
}
2003-04-19 18:51:13 +00:00
void MusicWheel : : GetSongList ( vector < Song * > & arraySongs , SongSortOrder so , CString sPreferredGroup )
2003-01-03 03:24:00 +00:00
{
2003-02-03 05:53:59 +00:00
vector < Song * > apAllSongs ;
2003-05-17 23:04:14 +00:00
// if( so==SORT_PREFERRED && GAMESTATE->m_sPreferredGroup!=GROUP_ALL_MUSIC)
// SONGMAN->GetSongs( apAllSongs, GAMESTATE->m_sPreferredGroup, GAMESTATE->GetNumStagesLeft() );
// else
// SONGMAN->GetSongs( apAllSongs, GAMESTATE->GetNumStagesLeft() );
SONGMAN - > GetSongs ( apAllSongs , GAMESTATE - > m_sPreferredGroup , GAMESTATE - > GetNumStagesLeft ( ) ) ;
2003-02-03 05:53:59 +00:00
2003-01-03 03:24:00 +00:00
// copy only songs that have at least one Notes for the current GameMode
2003-02-03 05:53:59 +00:00
for ( unsigned i = 0 ; i < apAllSongs . size ( ) ; i + + )
2003-01-03 03:24:00 +00:00
{
2003-02-03 05:53:59 +00:00
Song * pSong = apAllSongs [ i ] ;
2003-01-03 03:24:00 +00:00
/* If we're on an extra stage, and this song is selected, ignore
* #SELECTABLE. */
if ( pSong ! = GAMESTATE - > m_pCurSong | |
( ! GAMESTATE - > IsExtraStage ( ) & & ! GAMESTATE - > IsExtraStage2 ( ) ) ) {
/* Hide songs that asked to be hidden via #SELECTABLE. */
2003-04-19 18:51:13 +00:00
if ( so ! = SORT_ROULETTE & & ! pSong - > NormallyDisplayed ( ) )
2003-01-03 03:24:00 +00:00
continue ;
2003-07-09 11:38:50 +00:00
if ( so = = SORT_ROULETTE & & ! ( pSong - > RouletteDisplayed ( )
| | GAMESTATE - > m_pUnlockingSys - > SongIsRoulette ( pSong ) ) )
2003-07-07 10:22:53 +00:00
continue ;
2003-01-03 03:24:00 +00:00
}
2003-01-03 05:56:28 +00:00
vector < Notes * > arraySteps ;
2003-03-27 01:56:21 +00:00
pSong - > GetNotes ( arraySteps , GAMESTATE - > GetCurrentStyleDef ( ) - > m_NotesType , DIFFICULTY_INVALID , - 1 , - 1 , " " , PREFSMAN - > m_bAutogenMissingTypes ) ;
2003-01-03 03:24:00 +00:00
if ( ! arraySteps . empty ( ) )
2003-05-09 05:56:05 +00:00
{
// If we're using unlocks, check it here to prevent from being shown
2003-07-09 11:38:50 +00:00
if ( PREFSMAN - > m_bUseUnlockSystem & & so ! = SORT_ROULETTE )
2003-05-09 05:56:05 +00:00
{
2003-07-09 04:46:24 +00:00
pSong - > m_bIsLocked = GAMESTATE - > m_pUnlockingSys - > SongIsLocked ( pSong ) ;
2003-05-09 05:56:05 +00:00
if ( pSong - > m_bIsLocked ) { continue ; }
}
2003-01-03 03:24:00 +00:00
arraySongs . push_back ( pSong ) ;
2003-05-09 05:56:05 +00:00
}
2003-01-03 03:24:00 +00:00
}
}
2003-06-19 06:24:41 +00:00
extern map < const Song * , CString > song_sort_val ;
bool CompareSongPointersBySortVal ( const Song * pSong1 , const Song * pSong2 ) ;
void MusicWheel : : SortSongPointerArrayBySectionName ( vector < Song * > & arraySongPointers , SongSortOrder so )
{
for ( unsigned i = 0 ; i < arraySongPointers . size ( ) ; + + i )
{
CString val = MusicWheel : : GetSectionNameFromSongAndSort ( arraySongPointers [ i ] , so ) ;
/* Make sure NUM comes first and OTHER comes last. */
if ( val = = " NUM " ) val = " 0 " ;
else if ( val = = " OTHER " ) val = " 2 " ;
else val = " 1 " + val ;
song_sort_val [ arraySongPointers [ i ] ] = val ;
}
stable_sort ( arraySongPointers . begin ( ) , arraySongPointers . end ( ) , CompareSongPointersBySortVal ) ;
song_sort_val . clear ( ) ;
}
2003-02-11 23:52:18 +00:00
2003-01-03 03:24:00 +00:00
void MusicWheel : : BuildWheelItemDatas ( vector < WheelItemData > & arrayWheelItemDatas , SongSortOrder so )
2002-01-16 10:01:32 +00:00
{
2002-10-31 02:46:42 +00:00
unsigned i ;
2002-02-09 04:30:27 +00:00
2002-07-23 01:41:40 +00:00
switch ( GAMESTATE - > m_PlayMode )
2002-02-09 18:53:47 +00:00
{
2002-06-14 22:25:22 +00:00
case PLAY_MODE_ARCADE :
2003-07-08 19:56:56 +00:00
case PLAY_MODE_HUMAN_BATTLE :
case PLAY_MODE_CPU_BATTLE :
2003-04-07 05:14:27 +00:00
case PLAY_MODE_RAVE :
2002-06-14 22:25:22 +00:00
{
2003-06-16 17:28:58 +00:00
if ( so = = SORT_SORT )
{
arrayWheelItemDatas . clear ( ) ; // clear out the previous wheel items
for ( i = 0 ; i < MAX_SELECTABLE_SORT ; i + + )
{
RageColor c = RageColor ( 1 , 1 , 0 , 1 ) ;
arrayWheelItemDatas . push_back ( WheelItemData ( TYPE_SORT , NULL , " " , NULL , c , ( SongSortOrder ) i ) ) ;
}
break ;
}
2002-06-14 22:25:22 +00:00
///////////////////////////////////
// Make an array of Song*, then sort them
///////////////////////////////////
2003-01-03 05:56:28 +00:00
vector < Song * > arraySongs ;
2002-06-14 22:25:22 +00:00
2003-04-19 18:51:13 +00:00
GetSongList ( arraySongs , so , GAMESTATE - > m_sPreferredGroup ) ;
2002-02-09 18:53:47 +00:00
2002-07-27 19:29:51 +00:00
// sort the songs
2002-06-14 22:25:22 +00:00
switch ( so )
{
2003-04-19 18:51:13 +00:00
case SORT_PREFERRED :
2003-01-03 03:24:00 +00:00
case SORT_ROULETTE :
2003-04-19 18:51:13 +00:00
SortSongPointerArrayByGroupAndDifficulty ( arraySongs ) ;
break ;
case SORT_GROUP :
2003-06-15 01:06:40 +00:00
SortSongPointerArrayByGroupAndTitle ( arraySongs ) ;
2002-06-14 22:25:22 +00:00
break ;
case SORT_TITLE :
SortSongPointerArrayByTitle ( arraySongs ) ;
break ;
case SORT_BPM :
SortSongPointerArrayByBPM ( arraySongs ) ;
break ;
case SORT_MOST_PLAYED :
SortSongPointerArrayByMostPlayed ( arraySongs ) ;
2002-10-31 02:46:42 +00:00
if ( arraySongs . size ( ) > 30 )
2002-10-24 20:16:46 +00:00
arraySongs . erase ( arraySongs . begin ( ) + 30 , arraySongs . end ( ) ) ;
2002-06-14 22:25:22 +00:00
break ;
2003-06-16 20:23:07 +00:00
case SORT_GRADE :
SortSongPointerArrayByGrade ( arraySongs ) ;
break ;
case SORT_ARTIST :
SortSongPointerArrayByArtist ( arraySongs ) ;
break ;
2003-06-27 08:06:22 +00:00
case SORT_EASY_METER :
SortSongPointerArrayByMeter ( arraySongs , DIFFICULTY_EASY ) ;
break ;
case SORT_MEDIUM_METER :
SortSongPointerArrayByMeter ( arraySongs , DIFFICULTY_MEDIUM ) ;
break ;
case SORT_HARD_METER :
SortSongPointerArrayByMeter ( arraySongs , DIFFICULTY_HARD ) ;
break ;
2002-06-14 22:25:22 +00:00
default :
2002-08-20 21:00:56 +00:00
ASSERT ( 0 ) ; // unhandled SortOrder
2002-06-14 22:25:22 +00:00
}
2002-01-16 10:01:32 +00:00
2002-02-09 04:30:27 +00:00
2002-06-14 22:25:22 +00:00
///////////////////////////////////
2002-10-24 20:16:46 +00:00
// Build an array of WheelItemDatas from the sorted list of Song*'s
2002-06-14 22:25:22 +00:00
///////////////////////////////////
2002-10-24 20:16:46 +00:00
arrayWheelItemDatas . clear ( ) ; // clear out the previous wheel items
2002-04-16 17:31:00 +00:00
2002-09-07 10:15:27 +00:00
bool bUseSections = false ;
2002-06-14 22:25:22 +00:00
switch ( so )
{
2003-04-19 18:51:13 +00:00
case SORT_PREFERRED : bUseSections = false ; break ;
2003-05-17 23:04:14 +00:00
case SORT_GROUP : bUseSections = GAMESTATE - > m_sPreferredGroup = = GROUP_ALL_MUSIC ; break ;
2002-06-14 22:25:22 +00:00
case SORT_TITLE : bUseSections = true ; break ;
2003-06-16 20:23:07 +00:00
case SORT_BPM : bUseSections = true ; break ;
case SORT_MOST_PLAYED : bUseSections = false ; break ;
case SORT_GRADE : bUseSections = true ; break ;
case SORT_ARTIST : bUseSections = true ; break ;
2003-06-27 08:06:22 +00:00
case SORT_EASY_METER : bUseSections = true ; break ;
case SORT_MEDIUM_METER : bUseSections = true ; break ;
case SORT_HARD_METER : bUseSections = true ; break ;
2003-01-03 03:24:00 +00:00
case SORT_ROULETTE : bUseSections = false ; break ;
2003-03-13 23:58:30 +00:00
default : ASSERT ( 0 ) ;
2002-06-14 22:25:22 +00:00
}
2002-06-30 23:19:33 +00:00
2003-02-04 03:03:43 +00:00
if ( PREFSMAN - > m_MusicWheelUsesSections = = PrefsManager : : NEVER | | ( so ! = SORT_TITLE & & PREFSMAN - > m_MusicWheelUsesSections = = PrefsManager : : ABC_ONLY ) )
2002-12-30 21:42:14 +00:00
bUseSections = false ;
2002-01-16 10:01:32 +00:00
2002-06-14 22:25:22 +00:00
if ( bUseSections )
{
2003-06-16 20:23:07 +00:00
// Sorting twice isn't necessary. Instead, modify the compatator functions
// in Song.cpp to have the desired effect. -Chris
2003-06-19 06:24:41 +00:00
/* Keeping groups together with the sorts is tricky and brittle; we
* keep getting OTHER split up without this. However, it puts the
* Grade and BPM sorts in the wrong order, and they're already correct,
* so don't re-sort for them. */
2003-06-16 20:23:07 +00:00
// /* We're using sections, so use the section name as the top-level
// * sort. */
2003-06-19 06:24:41 +00:00
if ( so ! = SORT_GRADE & & so ! = SORT_BPM )
SortSongPointerArrayBySectionName ( arraySongs , so ) ;
2003-02-11 23:52:18 +00:00
2002-06-14 22:25:22 +00:00
// make WheelItemDatas with sections
CString sLastSection = " " ;
2002-10-28 05:30:45 +00:00
RageColor colorSection ;
2002-10-31 02:46:42 +00:00
for ( unsigned i = 0 ; i < arraySongs . size ( ) ; i + + )
2002-06-14 22:25:22 +00:00
{
Song * pSong = arraySongs [ i ] ;
CString sThisSection = GetSectionNameFromSongAndSort ( pSong , so ) ;
int iSectionColorIndex = 0 ;
2002-07-28 16:20:46 +00:00
if ( sThisSection ! = sLastSection ) // new section, make a section item
2002-06-14 22:25:22 +00:00
{
2002-08-13 23:26:46 +00:00
colorSection = ( so = = SORT_GROUP ) ? SONGMAN - > GetGroupColor ( pSong - > m_sGroupName ) : SECTION_COLORS ( iSectionColorIndex ) ;
2002-06-14 22:25:22 +00:00
iSectionColorIndex = ( iSectionColorIndex + 1 ) % NUM_SECTION_COLORS ;
2003-06-16 17:28:58 +00:00
arrayWheelItemDatas . push_back ( WheelItemData ( TYPE_SECTION , NULL , sThisSection , NULL , colorSection , SORT_INVALID ) ) ;
2002-06-14 22:25:22 +00:00
sLastSection = sThisSection ;
}
2003-06-16 17:28:58 +00:00
arrayWheelItemDatas . push_back ( WheelItemData ( TYPE_SONG , pSong , sThisSection , NULL , SONGMAN - > GetSongColor ( pSong ) , SORT_INVALID ) ) ;
2002-06-14 22:25:22 +00:00
}
}
else
2002-01-16 10:01:32 +00:00
{
2002-10-31 02:46:42 +00:00
for ( unsigned i = 0 ; i < arraySongs . size ( ) ; i + + )
2002-06-14 22:25:22 +00:00
{
2002-07-27 19:29:51 +00:00
Song * pSong = arraySongs [ i ] ;
2003-06-16 17:28:58 +00:00
arrayWheelItemDatas . push_back ( WheelItemData ( TYPE_SONG , pSong , " " , NULL , SONGMAN - > GetSongColor ( pSong ) , SORT_INVALID ) ) ;
2002-06-14 22:25:22 +00:00
}
2002-01-16 10:01:32 +00:00
}
2002-10-09 06:57:37 +00:00
2003-02-25 00:33:42 +00:00
if ( so ! = SORT_ROULETTE )
{
2003-03-13 23:58:30 +00:00
if ( SHOW_ROULETTE )
2003-06-16 17:28:58 +00:00
arrayWheelItemDatas . push_back ( WheelItemData ( TYPE_ROULETTE , NULL , " " , NULL , RageColor ( 1 , 0 , 0 , 1 ) , SORT_INVALID ) ) ;
2003-03-13 23:58:30 +00:00
if ( SHOW_RANDOM )
2003-06-16 17:28:58 +00:00
arrayWheelItemDatas . push_back ( WheelItemData ( TYPE_RANDOM , NULL , " " , NULL , RageColor ( 1 , 0 , 0 , 1 ) , SORT_INVALID ) ) ;
2003-02-25 00:33:42 +00:00
}
2002-10-10 04:11:30 +00:00
2003-02-25 00:33:42 +00:00
// HACK: Add extra stage item if it isn't already present on the music wheel
if ( GAMESTATE - > IsExtraStage ( ) | | GAMESTATE - > IsExtraStage2 ( ) )
2002-10-10 04:11:30 +00:00
{
2003-02-25 00:33:42 +00:00
Song * pSong ;
Notes * pNotes ;
PlayerOptions po ;
SongOptions so ;
SONGMAN - > GetExtraStageInfo ( GAMESTATE - > IsExtraStage2 ( ) , GAMESTATE - > m_pCurSong - > m_sGroupName , GAMESTATE - > GetCurrentStyleDef ( ) , pSong , pNotes , po , so ) ;
bool bFoundExtraSong = false ;
for ( unsigned i = 0 ; i < arrayWheelItemDatas . size ( ) ; i + + )
2002-10-10 04:11:30 +00:00
{
2003-02-25 00:33:42 +00:00
if ( arrayWheelItemDatas [ i ] . m_pSong = = pSong )
{
/* Change the song color. */
arrayWheelItemDatas [ i ] . m_color = SONG_REAL_EXTRA_COLOR ;
bFoundExtraSong = true ;
break ;
}
2002-10-10 04:11:30 +00:00
}
2003-02-11 19:55:37 +00:00
2003-02-25 00:33:42 +00:00
if ( ! bFoundExtraSong )
2003-06-16 17:28:58 +00:00
arrayWheelItemDatas . push_back ( WheelItemData ( TYPE_SONG , pSong , " " , NULL , SONG_REAL_EXTRA_COLOR , SORT_INVALID ) ) ;
2003-02-25 00:33:42 +00:00
}
2002-10-09 06:57:37 +00:00
}
2002-06-14 22:25:22 +00:00
break ;
2003-01-21 05:14:59 +00:00
case PLAY_MODE_NONSTOP :
2002-06-14 22:25:22 +00:00
case PLAY_MODE_ONI :
2002-08-01 20:30:40 +00:00
case PLAY_MODE_ENDLESS :
2002-04-16 17:31:00 +00:00
{
2003-06-16 17:28:58 +00:00
// We only use SORT_PREFERRED when selecting a course
2003-06-30 07:09:13 +00:00
if ( so ! = SongSortOrder ( SORT_PREFERRED ) )
2003-06-16 17:28:58 +00:00
break ;
2003-01-03 05:56:28 +00:00
vector < Course * > apCourses ;
2002-08-01 20:30:40 +00:00
switch ( GAMESTATE - > m_PlayMode )
2002-04-16 17:31:00 +00:00
{
2003-03-27 01:56:21 +00:00
case PLAY_MODE_NONSTOP : SONGMAN - > GetNonstopCourses ( apCourses , PREFSMAN - > m_bAutogenGroupCourses ) ; break ;
case PLAY_MODE_ONI : SONGMAN - > GetOniCourses ( apCourses , PREFSMAN - > m_bAutogenGroupCourses ) ; break ;
case PLAY_MODE_ENDLESS : SONGMAN - > GetEndlessCourses ( apCourses , PREFSMAN - > m_bAutogenGroupCourses ) ; break ;
2003-01-21 05:14:59 +00:00
default : ASSERT ( 0 ) ;
2002-04-16 17:31:00 +00:00
}
2002-07-29 03:06:55 +00:00
2003-02-16 23:54:30 +00:00
SortCoursePointerArrayByDifficulty ( apCourses ) ;
2002-10-31 02:46:42 +00:00
for ( unsigned c = 0 ; c < apCourses . size ( ) ; c + + ) // foreach course
2002-07-29 03:06:55 +00:00
{
Course * pCourse = apCourses [ c ] ;
2002-08-01 20:30:40 +00:00
// check that this course has at least one song playable in the current style
2003-02-16 10:12:03 +00:00
if ( pCourse - > IsPlayableIn ( GAMESTATE - > GetCurrentStyleDef ( ) - > m_NotesType ) )
2003-06-16 17:28:58 +00:00
arrayWheelItemDatas . push_back ( WheelItemData ( TYPE_COURSE , NULL , " " , pCourse , pCourse - > GetColor ( ) , SORT_INVALID ) ) ;
2002-07-29 03:06:55 +00:00
}
}
break ;
2002-06-14 22:25:22 +00:00
default :
ASSERT ( 0 ) ; // invalid PlayMode
2002-01-16 10:01:32 +00:00
}
2003-02-10 05:30:12 +00:00
// init music status icons
2002-10-31 02:46:42 +00:00
for ( i = 0 ; i < arrayWheelItemDatas . size ( ) ; i + + )
2002-02-10 06:25:12 +00:00
{
Song * pSong = arrayWheelItemDatas [ i ] . m_pSong ;
2002-08-20 21:00:56 +00:00
if ( pSong = = NULL )
continue ;
2002-09-06 10:13:46 +00:00
WheelItemData & WID = arrayWheelItemDatas [ i ] ;
2003-02-10 05:30:12 +00:00
WID . m_Flags . bHasBeginnerOr1Meter = pSong - > IsEasy ( NOTES_TYPE_DANCE_SINGLE ) ;
WID . m_Flags . bEdits = pSong - > HasEdits ( NOTES_TYPE_DANCE_SINGLE ) ;
WID . m_Flags . iStagesForSong = SongManager : : GetNumStagesForSong ( pSong ) ;
2002-02-10 06:25:12 +00:00
}
2002-01-16 10:01:32 +00:00
2003-02-10 05:30:12 +00:00
// init crowns
2002-02-06 05:13:39 +00:00
if ( so = = SORT_MOST_PLAYED )
2002-01-16 10:01:32 +00:00
{
// init crown icons
2002-10-31 02:46:42 +00:00
for ( i = 0 ; i < min ( 3u , arrayWheelItemDatas . size ( ) ) ; i + + )
2002-01-16 10:01:32 +00:00
{
2002-08-20 21:00:56 +00:00
WheelItemData & WID = arrayWheelItemDatas [ i ] ;
2003-02-10 05:30:12 +00:00
WID . m_Flags . iPlayersBestNumber = i + 1 ;
2002-01-16 10:01:32 +00:00
}
}
2002-10-31 02:46:42 +00:00
if ( arrayWheelItemDatas . empty ( ) )
2002-01-16 10:01:32 +00:00
{
2003-06-16 17:28:58 +00:00
arrayWheelItemDatas . push_back ( WheelItemData ( TYPE_SECTION , NULL , " - EMPTY - " , NULL , RageColor ( 1 , 0 , 0 , 1 ) , SORT_INVALID ) ) ;
2002-05-19 01:59:48 +00:00
}
2002-01-16 10:01:32 +00:00
}
2003-04-02 04:41:49 +00:00
void MusicWheel : : GetItemPosition ( float fPosOffsetsFromMiddle , float & fX_out , float & fY_out , float & fZ_out , float & fRotationX_out )
2002-01-16 10:01:32 +00:00
{
2003-04-02 04:41:49 +00:00
if ( USE_3D )
{
2003-04-02 07:04:57 +00:00
fRotationX_out = SCALE ( fPosOffsetsFromMiddle , - 7 , + 7 , + PI / 2.f , - PI / 2.f ) ;
2002-01-16 10:01:32 +00:00
2003-07-05 05:34:16 +00:00
// printf( "fRotationX_out = %f\n", fRotationX_out );
2003-04-02 04:41:49 +00:00
float radius = 200 ;
fX_out = 0 ;
fY_out = - radius * sinf ( fRotationX_out ) ;
fZ_out = - 100 + radius * cosf ( fRotationX_out ) ; // getting werid results with acosf()
2003-04-23 05:54:56 +00:00
fRotationX_out * = 180.f / PI ; // to degrees
2003-04-02 04:41:49 +00:00
}
else
{
fX_out = ( 1 - cosf ( fPosOffsetsFromMiddle / PI ) ) * ITEM_CURVE_X ;
fY_out = fPosOffsetsFromMiddle * ITEM_SPACING_Y ;
fZ_out = 0 ;
fRotationX_out = 0 ;
fX_out = roundf ( fX_out ) ;
fY_out = roundf ( fY_out ) ;
fZ_out = roundf ( fZ_out ) ;
}
2002-01-16 10:01:32 +00:00
}
2003-03-31 23:06:15 +00:00
void MusicWheel : : RebuildMusicWheelItems ( )
2002-01-16 10:01:32 +00:00
{
2002-02-09 04:30:27 +00:00
// rewind to first index that will be displayed;
2002-01-16 10:01:32 +00:00
int iIndex = m_iSelection ;
2003-01-02 02:59:25 +00:00
if ( m_iSelection > int ( m_CurWheelItemData . size ( ) - 1 ) )
2002-02-10 06:25:12 +00:00
m_iSelection = 0 ;
2002-11-16 08:55:46 +00:00
2003-03-26 19:15:38 +00:00
iIndex - = NUM_WHEEL_ITEMS / 2 ;
2003-03-14 22:55:06 +00:00
ASSERT ( m_CurWheelItemData . size ( ) ) ;
2003-01-02 02:59:25 +00:00
while ( iIndex < 0 )
iIndex + = m_CurWheelItemData . size ( ) ;
2002-02-06 05:13:39 +00:00
2002-02-09 04:30:27 +00:00
// iIndex is now the index of the lowest WheelItem to draw
2003-03-26 19:15:38 +00:00
for ( int i = 0 ; i < NUM_WHEEL_ITEMS ; i + + )
2002-02-09 04:30:27 +00:00
{
2003-01-02 02:59:25 +00:00
WheelItemData * data = m_CurWheelItemData [ iIndex ] ;
2003-03-31 23:06:15 +00:00
MusicWheelItem & display = m_MusicWheelItems [ i ] ;
2002-02-06 05:13:39 +00:00
2003-01-02 02:59:25 +00:00
display . LoadFromWheelItemData ( data ) ;
2002-02-09 04:30:27 +00:00
// increment iIndex
2003-01-02 02:59:25 +00:00
iIndex + + ;
if ( iIndex > int ( m_CurWheelItemData . size ( ) - 1 ) )
iIndex = 0 ;
2002-01-16 10:01:32 +00:00
}
2002-02-09 04:30:27 +00:00
}
2002-04-28 20:42:32 +00:00
void MusicWheel : : NotesChanged ( PlayerNumber pn ) // update grade graphics and top score
{
2003-03-26 19:15:38 +00:00
for ( int i = 0 ; i < NUM_WHEEL_ITEMS ; i + + )
2002-04-28 20:42:32 +00:00
{
2003-03-31 23:06:15 +00:00
MusicWheelItem & display = m_MusicWheelItems [ i ] ;
2002-04-28 20:42:32 +00:00
display . RefreshGrades ( ) ;
}
}
2002-02-09 04:30:27 +00:00
2002-05-19 01:59:48 +00:00
void MusicWheel : : DrawPrimitives ( )
2002-02-09 04:30:27 +00:00
{
2003-04-02 04:41:49 +00:00
if ( USE_3D )
{
2003-04-23 05:54:56 +00:00
// DISPLAY->PushMatrix();
// DISPLAY->EnterPerspective(45, false);
2003-04-02 04:41:49 +00:00
// construct view and project matrix
2003-04-23 05:54:56 +00:00
// RageVector3 Up( 0.0f, 1.0f, 0.0f );
// RageVector3 Eye( CENTER_X, CENTER_Y, 550 );
// RageVector3 At( CENTER_X, CENTER_Y, 0 );
2003-04-02 04:41:49 +00:00
2003-04-23 05:54:56 +00:00
// DISPLAY->LookAt(Eye, At, Up);
2003-04-02 04:41:49 +00:00
}
2003-04-23 05:54:56 +00:00
// draw outside->inside
int i ;
for ( i = 0 ; i < NUM_WHEEL_ITEMS / 2 ; i + + )
DrawItem ( i ) ;
for ( i = NUM_WHEEL_ITEMS - 1 ; i > = NUM_WHEEL_ITEMS / 2 ; i - - )
DrawItem ( i ) ;
ActorFrame : : DrawPrimitives ( ) ;
if ( USE_3D )
2002-01-16 10:01:32 +00:00
{
2003-04-23 05:54:56 +00:00
// DISPLAY->ExitPerspective();
// DISPLAY->PopMatrix();
}
}
2002-01-16 10:01:32 +00:00
2002-05-01 19:14:55 +00:00
2003-04-23 05:54:56 +00:00
void MusicWheel : : DrawItem ( int i )
{
MusicWheelItem & display = m_MusicWheelItems [ i ] ;
2003-04-02 04:41:49 +00:00
2003-04-23 05:54:56 +00:00
switch ( m_WheelState )
{
case STATE_SELECTING_MUSIC :
case STATE_ROULETTE_SPINNING :
case STATE_ROULETTE_SLOWING_DOWN :
case STATE_RANDOM_SPINNING :
case STATE_LOCKED :
{
float fThisBannerPositionOffsetFromSelection = i - NUM_WHEEL_ITEMS / 2 + m_fPositionOffsetFromSelection ;
2002-01-16 10:01:32 +00:00
2003-04-23 05:54:56 +00:00
float fX , fY , fZ , fRotationX ;
GetItemPosition ( fThisBannerPositionOffsetFromSelection , fX , fY , fZ , fRotationX ) ;
2002-01-16 10:01:32 +00:00
2003-04-23 05:54:56 +00:00
// if( fY < -SCREEN_HEIGHT/2 || fY > SCREEN_HEIGHT/2 )
// continue; // skip
2002-06-30 23:19:33 +00:00
2003-04-23 05:54:56 +00:00
display . SetXY ( fX , fY ) ;
display . SetZ ( fZ ) ;
display . SetRotationX ( fRotationX ) ;
}
break ;
2002-01-16 10:01:32 +00:00
}
2003-04-23 05:54:56 +00:00
if ( m_WheelState = = STATE_LOCKED & & i ! = NUM_WHEEL_ITEMS / 2 )
display . m_fPercentGray = 0.5f ;
else
display . m_fPercentGray = 0 ;
display . Draw ( ) ;
2002-01-16 10:01:32 +00:00
}
2003-04-23 05:54:56 +00:00
2003-01-02 02:59:25 +00:00
void MusicWheel : : UpdateScrollbar ( )
{
int total_num_items = m_CurWheelItemData . size ( ) ;
float item_at = m_iSelection - m_fPositionOffsetFromSelection ;
2003-04-20 02:02:58 +00:00
if ( NUM_WHEEL_ITEMS > = total_num_items ) {
2003-01-02 02:59:25 +00:00
m_ScrollBar . SetPercentage ( 0 , 1 ) ;
} else {
2003-03-26 19:15:38 +00:00
float size = float ( NUM_WHEEL_ITEMS ) / total_num_items ;
2003-01-02 02:59:25 +00:00
float center = item_at / total_num_items ;
size * = 0.5f ;
m_ScrollBar . SetPercentage ( center - size , center + size ) ;
}
}
2002-01-16 10:01:32 +00:00
void MusicWheel : : Update ( float fDeltaTime )
{
ActorFrame : : Update ( fDeltaTime ) ;
2002-10-31 02:46:42 +00:00
unsigned i ;
2003-03-26 21:32:48 +00:00
for ( i = 0 ; i < unsigned ( NUM_WHEEL_ITEMS ) ; i + + )
2002-01-16 10:01:32 +00:00
{
2003-03-31 23:06:15 +00:00
MusicWheelItem & display = m_MusicWheelItems [ i ] ;
2002-02-09 04:30:27 +00:00
display . Update ( fDeltaTime ) ;
2002-01-16 10:01:32 +00:00
}
2003-01-02 02:59:25 +00:00
UpdateScrollbar ( ) ;
2002-01-16 10:01:32 +00:00
2003-01-02 02:59:25 +00:00
if ( m_Moving )
2002-06-14 22:25:22 +00:00
{
2003-01-02 02:59:25 +00:00
m_TimeBeforeMovingBegins - = fDeltaTime ;
m_TimeBeforeMovingBegins = max ( m_TimeBeforeMovingBegins , 0 ) ;
2002-06-24 22:04:31 +00:00
}
2002-01-16 10:01:32 +00:00
// update wheel state
m_fTimeLeftInState - = fDeltaTime ;
if ( m_fTimeLeftInState < = 0 ) // time to go to a new state
{
switch ( m_WheelState )
{
2002-01-18 21:19:05 +00:00
case STATE_FLYING_OFF_BEFORE_NEXT_SORT :
2002-01-16 10:01:32 +00:00
{
2003-01-02 02:59:25 +00:00
Song * pPrevSelectedSong = m_CurWheelItemData [ m_iSelection ] - > m_pSong ;
2003-02-03 04:50:37 +00:00
2003-03-25 21:17:29 +00:00
SCREENMAN - > PostMessageToTopScreen ( SM_SortOrderChanged , 0 ) ;
2003-06-16 17:28:58 +00:00
2003-01-02 02:59:25 +00:00
SetOpenGroup ( GetSectionNameFromSongAndSort ( pPrevSelectedSong , GAMESTATE - > m_SongSortOrder ) ) ;
2002-06-14 22:25:22 +00:00
m_iSelection = 0 ;
2002-02-24 01:43:11 +00:00
2003-06-16 17:28:58 +00:00
switch ( GAMESTATE - > m_SongSortOrder )
2002-02-24 01:43:11 +00:00
{
2003-06-16 17:28:58 +00:00
case SORT_PREFERRED :
case SORT_GROUP :
case SORT_TITLE :
case SORT_BPM :
2003-06-16 20:23:07 +00:00
case SORT_GRADE :
case SORT_ARTIST :
2003-06-16 17:28:58 +00:00
case SORT_MOST_PLAYED :
case SORT_ROULETTE :
2003-06-27 08:06:22 +00:00
case SORT_EASY_METER :
case SORT_MEDIUM_METER :
case SORT_HARD_METER :
2003-06-16 17:28:58 +00:00
// Look for the last selected song or course
if ( GAMESTATE - > m_pCurCourse )
SelectCourse ( GAMESTATE - > m_pCurCourse ) ;
if ( GAMESTATE - > m_pCurSong )
SelectSong ( GAMESTATE - > m_pCurSong ) ;
break ;
case SORT_SORT :
SelectSort ( m_LastSongSortOrder ) ;
break ;
default :
ASSERT ( 0 ) ;
2002-08-28 22:42:40 +00:00
}
2003-06-27 08:06:22 +00:00
// Change difficulty for sorts by meter
switch ( GAMESTATE - > m_SongSortOrder )
{
case SORT_EASY_METER :
{
for ( int p = 0 ; p < NUM_PLAYERS ; p + + )
if ( GAMESTATE - > IsPlayerEnabled ( p ) )
GAMESTATE - > m_PreferredDifficulty [ p ] = DIFFICULTY_EASY ;
}
break ;
case SORT_MEDIUM_METER :
{
for ( int p = 0 ; p < NUM_PLAYERS ; p + + )
if ( GAMESTATE - > IsPlayerEnabled ( p ) )
GAMESTATE - > m_PreferredDifficulty [ p ] = DIFFICULTY_MEDIUM ;
}
break ;
case SORT_HARD_METER :
{
for ( int p = 0 ; p < NUM_PLAYERS ; p + + )
if ( GAMESTATE - > IsPlayerEnabled ( p ) )
GAMESTATE - > m_PreferredDifficulty [ p ] = DIFFICULTY_HARD ;
}
break ;
}
2003-03-25 21:17:29 +00:00
SCREENMAN - > PostMessageToTopScreen ( SM_SongChanged , 0 ) ;
2003-03-31 23:06:15 +00:00
RebuildMusicWheelItems ( ) ;
2003-01-02 02:59:25 +00:00
TweenOnScreen ( true ) ;
2003-01-03 03:24:00 +00:00
m_WheelState = STATE_FLYING_ON_AFTER_NEXT_SORT ;
2002-01-16 10:01:32 +00:00
}
break ;
2003-01-03 03:24:00 +00:00
2002-01-18 21:19:05 +00:00
case STATE_FLYING_ON_AFTER_NEXT_SORT :
2002-06-24 22:04:31 +00:00
m_WheelState = STATE_SELECTING_MUSIC ; // now, wait for input
2002-01-16 10:01:32 +00:00
break ;
2003-01-03 03:24:00 +00:00
2002-01-18 21:19:05 +00:00
case STATE_TWEENING_ON_SCREEN :
m_fTimeLeftInState = 0 ;
2003-02-01 05:39:48 +00:00
if ( ( GAMESTATE - > IsExtraStage ( ) & & ! PREFSMAN - > m_bPickExtraStage ) | | GAMESTATE - > IsExtraStage2 ( ) )
2002-07-31 04:06:34 +00:00
{
2002-08-01 13:42:56 +00:00
// if ( m_bUseRandomExtra )
// {
2003-01-21 02:45:35 +00:00
// SOUNDMAN->StopMusic();
2002-08-01 13:42:56 +00:00
// m_soundExpand.Play();
// m_WheelState = STATE_ROULETTE_SPINNING;
// m_SortOrder = SORT_GROUP;
2002-10-28 05:30:45 +00:00
// m_MusicSortDisplay.SetDiffuse( RageColor(1,1,1,0) );
2002-08-01 13:42:56 +00:00
// m_MusicSortDisplay.SetEffectNone();
// BuildWheelItemDatas( m_WheelItemDatas[SORT_GROUP], SORT_GROUP, true );
// }
// else
2002-07-31 04:06:34 +00:00
{
m_WheelState = STATE_LOCKED ;
m_soundStart . Play ( ) ;
m_fLockedWheelVelocity = 0 ;
}
}
else
{
m_WheelState = STATE_SELECTING_MUSIC ;
}
2002-01-18 21:19:05 +00:00
break ;
case STATE_TWEENING_OFF_SCREEN :
m_WheelState = STATE_WAITING_OFF_SCREEN ;
m_fTimeLeftInState = 0 ;
break ;
2002-06-24 22:04:31 +00:00
case STATE_SELECTING_MUSIC :
2002-01-16 10:01:32 +00:00
m_fTimeLeftInState = 0 ;
break ;
2002-06-24 22:04:31 +00:00
case STATE_ROULETTE_SPINNING :
2003-01-03 03:24:00 +00:00
case STATE_RANDOM_SPINNING :
2002-06-24 22:04:31 +00:00
break ;
case STATE_WAITING_OFF_SCREEN :
break ;
case STATE_LOCKED :
break ;
2002-06-14 22:25:22 +00:00
case STATE_ROULETTE_SLOWING_DOWN :
2002-06-24 22:04:31 +00:00
if ( m_iSwitchesLeftInSpinDown = = 0 )
{
m_WheelState = STATE_LOCKED ;
m_fTimeLeftInState = 0 ;
m_soundStart . Play ( ) ;
m_fLockedWheelVelocity = 0 ;
2003-01-02 02:59:25 +00:00
/* Send this again so the screen starts sample music. */
2003-03-25 21:17:29 +00:00
SCREENMAN - > PostMessageToTopScreen ( SM_SongChanged , 0 ) ;
2002-06-24 22:04:31 +00:00
}
else
{
m_iSwitchesLeftInSpinDown - - ;
2002-09-10 02:37:17 +00:00
const float SwitchTimes [ ] = { 0.5f , 1.3f , 0.8f , 0.4f , 0.2f } ;
ASSERT ( m_iSwitchesLeftInSpinDown > = 0 & & m_iSwitchesLeftInSpinDown < = 4 ) ;
m_fTimeLeftInState = SwitchTimes [ m_iSwitchesLeftInSpinDown ] ;
2002-07-31 19:40:40 +00:00
LOG - > Trace ( " m_iSwitchesLeftInSpinDown id %d, m_fTimeLeftInState is %f " , m_iSwitchesLeftInSpinDown , m_fTimeLeftInState ) ;
2002-06-24 22:04:31 +00:00
if ( m_iSwitchesLeftInSpinDown < 2 )
2003-01-21 07:04:53 +00:00
ChangeMusic ( randomf ( 0 , 1 ) > = 0.5f ? 1 : - 1 ) ;
2002-06-24 22:04:31 +00:00
else
2003-01-21 07:04:53 +00:00
ChangeMusic ( 1 ) ;
2002-06-24 22:04:31 +00:00
}
break ;
default :
ASSERT ( 0 ) ; // all state changes should be handled explitily
2002-06-14 22:25:22 +00:00
break ;
2002-01-16 10:01:32 +00:00
}
}
2002-06-24 22:04:31 +00:00
if ( m_WheelState = = STATE_LOCKED )
{
2003-01-03 03:24:00 +00:00
/* Do this in at most .1 sec chunks, so we don't get weird if we
* stop for some reason (and so it behaves the same when being
* single stepped). */
float tm = fDeltaTime ;
while ( tm > 0 )
{
float t = min ( tm , 0.1f ) ;
tm - = t ;
2002-06-24 22:04:31 +00:00
2003-01-03 03:24:00 +00:00
m_fPositionOffsetFromSelection = clamp ( m_fPositionOffsetFromSelection , - 0.3f , + 0.3f ) ;
2002-06-24 22:04:31 +00:00
2003-01-03 03:24:00 +00:00
float fSpringForce = - m_fPositionOffsetFromSelection * LOCKED_INITIAL_VELOCITY ;
m_fLockedWheelVelocity + = fSpringForce ;
2002-06-24 22:04:31 +00:00
2003-01-03 03:24:00 +00:00
float fDrag = - m_fLockedWheelVelocity * t * 4 ;
m_fLockedWheelVelocity + = fDrag ;
m_fPositionOffsetFromSelection + = m_fLockedWheelVelocity * t ;
if ( fabsf ( m_fPositionOffsetFromSelection ) < 0.01f & & fabsf ( m_fLockedWheelVelocity ) < 0.01f )
{
m_fPositionOffsetFromSelection = 0 ;
m_fLockedWheelVelocity = 0 ;
}
2002-06-24 22:04:31 +00:00
}
}
2003-01-21 07:04:53 +00:00
else if ( IsMoving ( ) )
{
/* We're automatically moving. Move linearly, and don't clamp
* to the selection. */
float fSpinSpeed = m_SpinSpeed * m_Moving ;
m_fPositionOffsetFromSelection - = fSpinSpeed * fDeltaTime ;
/* Make sure that we don't go further than 1 away, in case the
* speed is very high or we miss a lot of frames. */
m_fPositionOffsetFromSelection = clamp ( m_fPositionOffsetFromSelection , - 1.0f , 1.0f ) ;
/* If it passed the selection, move again. */
if ( ( m_Moving = = - 1 & & m_fPositionOffsetFromSelection > = 0 ) | |
( m_Moving = = 1 & & m_fPositionOffsetFromSelection < = 0 ) )
{
ChangeMusic ( m_Moving ) ;
if ( PREFSMAN - > m_iMusicWheelSwitchSpeed < MAX_WHEEL_SOUND_SPEED )
m_soundChangeMusic . Play ( ) ;
}
if ( PREFSMAN - > m_iMusicWheelSwitchSpeed > = MAX_WHEEL_SOUND_SPEED & &
m_MovingSoundTimer . PeekDeltaTime ( ) > = 1.0f / MAX_WHEEL_SOUND_SPEED )
{
m_MovingSoundTimer . GetDeltaTime ( ) ;
m_soundChangeMusic . Play ( ) ;
}
}
2002-01-20 08:59:38 +00:00
else
{
2002-06-24 22:04:31 +00:00
// "rotate" wheel toward selected song
2003-01-21 07:04:53 +00:00
float fSpinSpeed = 0.2f + fabsf ( m_fPositionOffsetFromSelection ) / SWITCH_SECONDS ;
2002-06-24 22:04:31 +00:00
if ( m_fPositionOffsetFromSelection > 0 )
2002-06-29 11:59:09 +00:00
{
m_fPositionOffsetFromSelection - = fSpinSpeed * fDeltaTime ;
if ( m_fPositionOffsetFromSelection < 0 )
m_fPositionOffsetFromSelection = 0 ;
}
2002-06-24 22:04:31 +00:00
else if ( m_fPositionOffsetFromSelection < 0 )
2002-06-29 11:59:09 +00:00
{
m_fPositionOffsetFromSelection + = fSpinSpeed * fDeltaTime ;
if ( m_fPositionOffsetFromSelection > 0 )
m_fPositionOffsetFromSelection = 0 ;
}
2002-01-20 08:59:38 +00:00
}
2002-01-16 10:01:32 +00:00
}
2003-01-21 07:04:53 +00:00
void MusicWheel : : ChangeMusic ( int dist )
2002-01-16 10:01:32 +00:00
{
2003-01-21 07:04:53 +00:00
m_iSelection + = dist ;
2003-01-02 02:59:25 +00:00
if ( m_iSelection < 0 )
m_iSelection = m_CurWheelItemData . size ( ) - 1 ;
2003-01-21 07:04:53 +00:00
else if ( m_iSelection > int ( m_CurWheelItemData . size ( ) - 1 ) )
m_iSelection = 0 ;
2002-02-06 05:13:39 +00:00
2003-03-31 23:06:15 +00:00
RebuildMusicWheelItems ( ) ;
2002-01-16 10:01:32 +00:00
2003-01-21 07:04:53 +00:00
m_fPositionOffsetFromSelection + = dist ;
2002-06-30 23:19:33 +00:00
2003-03-25 21:17:29 +00:00
SCREENMAN - > PostMessageToTopScreen ( SM_SongChanged , 0 ) ;
2002-06-24 22:04:31 +00:00
2003-01-21 07:04:53 +00:00
/* If we're moving automatically, don't play this; it'll be called in Update. */
if ( ! IsMoving ( ) )
2003-01-19 00:47:06 +00:00
m_soundChangeMusic . Play ( ) ;
2002-01-16 10:01:32 +00:00
}
2003-06-16 17:28:58 +00:00
bool MusicWheel : : ChangeSort ( SongSortOrder new_so ) // return true if change successful
2002-01-16 10:01:32 +00:00
{
2003-06-19 19:31:46 +00:00
if ( GAMESTATE - > m_SongSortOrder = = new_so )
return false ;
2002-01-18 22:18:41 +00:00
switch ( m_WheelState )
{
2002-06-24 22:04:31 +00:00
case STATE_SELECTING_MUSIC :
2002-01-24 08:01:24 +00:00
case STATE_FLYING_ON_AFTER_NEXT_SORT :
2002-01-18 22:18:41 +00:00
break ; // fall through
default :
2002-08-20 21:00:56 +00:00
return false ; // don't continue
2002-01-18 22:18:41 +00:00
}
2002-01-16 10:01:32 +00:00
2002-04-28 20:42:32 +00:00
m_soundChangeSort . Play ( ) ;
2002-01-16 10:01:32 +00:00
2003-01-02 02:59:25 +00:00
TweenOffScreen ( true ) ;
2002-05-28 20:01:22 +00:00
2003-06-16 17:28:58 +00:00
m_LastSongSortOrder = GAMESTATE - > m_SongSortOrder ;
GAMESTATE - > m_SongSortOrder = new_so ;
2002-01-18 21:19:05 +00:00
m_WheelState = STATE_FLYING_OFF_BEFORE_NEXT_SORT ;
2002-08-20 21:00:56 +00:00
return true ;
2002-01-16 10:01:32 +00:00
}
2003-06-16 17:28:58 +00:00
bool MusicWheel : : NextSort ( ) // return true if change successful
{
2003-06-30 06:53:21 +00:00
/* Is the current sort in the default sort order? */
int cur = 0 ;
while ( SortOrder [ cur ] ! = SORT_INVALID & & SortOrder [ cur ] ! = GAMESTATE - > m_SongSortOrder )
+ + cur ;
2003-06-16 17:28:58 +00:00
2003-06-30 06:53:21 +00:00
SongSortOrder so ;
if ( SortOrder [ cur ] = = SORT_INVALID )
{
/* It isn't, which means we're either in the sort menu or in a sort selected
* from the sort menu. If we're in the sort menu, return to the first sort.
* Otherwise, return to the sort menu. */
if ( GAMESTATE - > m_SongSortOrder = = SORT_SORT )
so = SortOrder [ 0 ] ;
else
so = SORT_SORT ;
} else {
+ + cur ;
if ( SortOrder [ cur ] = = SORT_INVALID )
cur = 0 ;
so = SortOrder [ cur ] ;
}
2003-06-16 17:28:58 +00:00
return ChangeSort ( so ) ;
}
bool MusicWheel : : Select ( ) // return true if this selection ends the screen
2002-01-16 10:01:32 +00:00
{
2002-07-31 19:40:40 +00:00
LOG - > Trace ( " MusicWheel::Select() " ) ;
2002-06-24 22:04:31 +00:00
2003-01-03 03:24:00 +00:00
if ( m_WheelState = = STATE_ROULETTE_SLOWING_DOWN )
return false ;
2003-01-22 01:30:07 +00:00
m_Moving = 0 ;
2002-06-14 22:25:22 +00:00
if ( m_WheelState = = STATE_ROULETTE_SPINNING )
{
m_WheelState = STATE_ROULETTE_SLOWING_DOWN ;
2002-08-13 23:26:46 +00:00
m_iSwitchesLeftInSpinDown = ROULETTE_SLOW_DOWN_SWITCHES / 2 + 1 + rand ( ) % ( ROULETTE_SLOW_DOWN_SWITCHES / 2 ) ;
2002-06-24 22:04:31 +00:00
m_fTimeLeftInState = 0.1f ;
2002-06-14 22:25:22 +00:00
return false ;
}
2003-01-22 01:30:07 +00:00
2003-01-19 00:47:06 +00:00
if ( m_WheelState = = STATE_RANDOM_SPINNING )
{
m_fPositionOffsetFromSelection = max ( m_fPositionOffsetFromSelection , 0.3f ) ;
m_WheelState = STATE_LOCKED ;
m_soundStart . Play ( ) ;
m_fLockedWheelVelocity = 0 ;
2003-03-25 21:17:29 +00:00
SCREENMAN - > PostMessageToTopScreen ( SM_SongChanged , 0 ) ;
2003-01-19 00:47:06 +00:00
return false ;
}
2003-03-31 23:06:15 +00:00
switch ( m_CurWheelItemData [ m_iSelection ] - > m_Type )
2002-01-16 10:01:32 +00:00
{
2002-02-09 04:30:27 +00:00
case TYPE_SECTION :
2002-01-16 10:01:32 +00:00
{
2003-06-16 17:28:58 +00:00
CString sThisItemSectionName = m_CurWheelItemData [ m_iSelection ] - > m_sSectionName ;
if ( m_sExpandedSectionName = = sThisItemSectionName ) // already expanded
m_sExpandedSectionName = " " ; // collapse it
else // already collapsed
m_sExpandedSectionName = sThisItemSectionName ; // expand it
2002-01-16 10:01:32 +00:00
2003-06-16 17:28:58 +00:00
m_soundExpand . Play ( ) ;
2002-01-16 10:01:32 +00:00
2003-06-16 17:28:58 +00:00
SetOpenGroup ( m_sExpandedSectionName ) ;
2002-01-16 10:01:32 +00:00
}
return false ;
2003-07-09 11:38:50 +00:00
case TYPE_ROULETTE :
2002-08-20 21:00:56 +00:00
StartRoulette ( ) ;
2002-05-19 01:59:48 +00:00
return false ;
2003-01-03 03:24:00 +00:00
case TYPE_RANDOM :
2003-01-19 00:47:06 +00:00
StartRandom ( ) ;
2003-01-03 03:24:00 +00:00
return false ;
2002-04-16 17:31:00 +00:00
case TYPE_SONG :
2003-07-09 11:38:50 +00:00
if ( PREFSMAN - > m_bUseUnlockSystem )
GAMESTATE - > m_pUnlockingSys - > RouletteUnlock ( m_CurWheelItemData [ m_iSelection ] - > m_pSong ) ;
// fall-through - we want to check for unlocking only if its a song
2003-06-16 17:28:58 +00:00
case TYPE_COURSE :
2002-01-16 10:01:32 +00:00
return true ;
2003-06-16 17:28:58 +00:00
case TYPE_SORT :
ChangeSort ( m_CurWheelItemData [ m_iSelection ] - > m_SongSortOrder ) ;
return false ;
default :
ASSERT ( 0 ) ;
return false ;
2002-01-16 10:01:32 +00:00
}
}
2002-08-20 21:00:56 +00:00
void MusicWheel : : StartRoulette ( )
{
m_WheelState = STATE_ROULETTE_SPINNING ;
2003-01-02 02:59:25 +00:00
m_Moving = 1 ;
m_TimeBeforeMovingBegins = 0 ;
m_SpinSpeed = 1.0f / ROULETTE_SWITCH_SECONDS ;
2003-01-03 03:24:00 +00:00
SetOpenGroup ( " " , SongSortOrder ( SORT_ROULETTE ) ) ;
2003-01-02 02:59:25 +00:00
}
2003-01-19 00:47:06 +00:00
void MusicWheel : : StartRandom ( )
{
/* Shuffle the roulette wheel. */
unsigned total = m_WheelItemDatas [ SORT_ROULETTE ] . size ( ) ;
for ( unsigned i = 0 ; i < total ; + + i )
swap ( m_WheelItemDatas [ SORT_ROULETTE ] [ i ] , m_WheelItemDatas [ SORT_ROULETTE ] [ rand ( ) % total ] ) ;
SetOpenGroup ( " " , SongSortOrder ( SORT_ROULETTE ) ) ;
m_Moving = - 1 ;
m_TimeBeforeMovingBegins = 0 ;
m_SpinSpeed = 1.0f / ROULETTE_SWITCH_SECONDS ;
2003-02-12 06:25:51 +00:00
m_SpinSpeed * = 20.0f ; /* faster! */
2003-01-19 00:47:06 +00:00
m_WheelState = STATE_RANDOM_SPINNING ;
2003-02-12 06:25:51 +00:00
this - > Select ( ) ;
2003-03-31 23:06:15 +00:00
RebuildMusicWheelItems ( ) ;
2003-01-19 00:47:06 +00:00
}
2003-01-03 03:24:00 +00:00
void MusicWheel : : SetOpenGroup ( CString group , SongSortOrder so )
2003-01-02 02:59:25 +00:00
{
2003-06-16 17:28:58 +00:00
if ( so = = SORT_INVALID )
2003-01-03 03:24:00 +00:00
so = GAMESTATE - > m_SongSortOrder ;
2003-01-02 02:59:25 +00:00
m_sExpandedSectionName = group ;
WheelItemData * old = NULL ;
if ( ! m_CurWheelItemData . empty ( ) )
old = m_CurWheelItemData [ m_iSelection ] ;
m_CurWheelItemData . clear ( ) ;
2003-01-03 03:24:00 +00:00
vector < WheelItemData > & from = m_WheelItemDatas [ so ] ;
2003-01-02 02:59:25 +00:00
unsigned i ;
for ( i = 0 ; i < from . size ( ) ; + + i )
{
2003-03-31 23:06:15 +00:00
if ( ( from [ i ] . m_Type = = TYPE_SONG | |
from [ i ] . m_Type = = TYPE_COURSE ) & &
2003-01-02 02:59:25 +00:00
! from [ i ] . m_sSectionName . empty ( ) & &
from [ i ] . m_sSectionName ! = group )
continue ;
m_CurWheelItemData . push_back ( & from [ i ] ) ;
}
2003-06-16 17:28:58 +00:00
//
// Try to select the item that was selected before chaning groups
//
2003-01-02 02:59:25 +00:00
m_iSelection = 0 ;
2003-06-16 17:28:58 +00:00
for ( i = 0 ; i < m_CurWheelItemData . size ( ) ; i + + )
2003-01-02 02:59:25 +00:00
{
2003-06-16 17:28:58 +00:00
if ( m_CurWheelItemData [ i ] = = old )
{
2003-01-02 02:59:25 +00:00
m_iSelection = i ;
2003-06-16 17:28:58 +00:00
break ;
}
2003-01-02 02:59:25 +00:00
}
2003-01-03 03:24:00 +00:00
2003-03-31 23:06:15 +00:00
RebuildMusicWheelItems ( ) ;
2002-08-20 21:00:56 +00:00
}
2003-01-02 02:59:25 +00:00
bool MusicWheel : : IsRouletting ( ) const
2002-08-20 21:00:56 +00:00
{
2003-01-03 03:24:00 +00:00
return m_WheelState = = STATE_ROULETTE_SPINNING | | m_WheelState = = STATE_ROULETTE_SLOWING_DOWN | |
m_WheelState = = STATE_RANDOM_SPINNING ;
2002-08-20 21:00:56 +00:00
}
2003-01-02 02:59:25 +00:00
int MusicWheel : : IsMoving ( ) const
2002-02-09 04:30:27 +00:00
{
2003-01-21 07:04:53 +00:00
return m_Moving & & m_TimeBeforeMovingBegins = = 0 ;
2003-01-02 02:59:25 +00:00
}
2002-05-28 20:01:22 +00:00
2003-01-02 02:59:25 +00:00
void MusicWheel : : TweenOnScreen ( bool changing_sort )
{
float factor = 1.0f ;
if ( changing_sort ) factor = 0.25 ;
2002-05-28 20:01:22 +00:00
2003-01-02 02:59:25 +00:00
m_WheelState = STATE_TWEENING_ON_SCREEN ;
2003-04-02 04:41:49 +00:00
float fX , fY , fZ , fRotationX ;
GetItemPosition ( 0 , fX , fY , fZ , fRotationX ) ;
2002-05-29 09:47:24 +00:00
2002-08-13 23:26:46 +00:00
m_sprSelectionOverlay . SetXY ( fX + 320 , fY ) ;
2003-04-02 04:41:49 +00:00
m_sprSelectionOverlay . SetZ ( fZ ) ;
m_sprSelectionOverlay . SetRotationX ( fRotationX ) ;
2003-01-02 02:59:25 +00:00
if ( changing_sort ) {
2003-03-26 19:15:38 +00:00
m_sprSelectionOverlay . BeginTweening ( 0.04f * NUM_WHEEL_ITEMS / 2 * factor ) ; // sleep
2003-03-02 01:43:33 +00:00
m_sprSelectionOverlay . BeginTweening ( 0.2f * factor , Actor : : TWEEN_ACCELERATE ) ;
2003-01-02 02:59:25 +00:00
} else {
m_sprSelectionOverlay . BeginTweening ( 0.05f * factor ) ; // sleep
2003-03-02 01:43:33 +00:00
m_sprSelectionOverlay . BeginTweening ( 0.4f * factor , Actor : : TWEEN_ACCELERATE ) ;
2003-01-02 02:59:25 +00:00
}
2003-04-12 06:16:12 +00:00
m_sprSelectionOverlay . SetX ( fX ) ;
2002-05-29 09:47:24 +00:00
2002-08-31 06:43:28 +00:00
m_ScrollBar . SetX ( SCROLL_BAR_X + 30 ) ;
2003-01-02 02:59:25 +00:00
if ( changing_sort )
m_ScrollBar . BeginTweening ( 0.2f * factor ) ; // sleep
else
m_ScrollBar . BeginTweening ( 0.7f * factor ) ; // sleep
2003-03-02 01:43:33 +00:00
m_ScrollBar . BeginTweening ( 0.2f * factor , Actor : : TWEEN_ACCELERATE ) ;
2003-04-12 06:16:12 +00:00
m_ScrollBar . SetX ( SCROLL_BAR_X ) ;
2002-05-28 20:01:22 +00:00
2003-03-26 19:15:38 +00:00
for ( int i = 0 ; i < NUM_WHEEL_ITEMS ; i + + )
2002-05-28 20:01:22 +00:00
{
2003-03-31 23:06:15 +00:00
MusicWheelItem & display = m_MusicWheelItems [ i ] ;
2003-03-26 19:15:38 +00:00
float fThisBannerPositionOffsetFromSelection = i - NUM_WHEEL_ITEMS / 2 + m_fPositionOffsetFromSelection ;
2002-05-28 20:01:22 +00:00
2003-04-02 04:41:49 +00:00
float fX , fY , fZ , fRotationX ;
GetItemPosition ( fThisBannerPositionOffsetFromSelection , fX , fY , fZ , fRotationX ) ;
2002-05-28 20:01:22 +00:00
display . SetXY ( fX + 320 , fY ) ;
2003-04-02 04:41:49 +00:00
display . SetZ ( fZ ) ;
display . SetRotationX ( fRotationX ) ;
2003-01-02 02:59:25 +00:00
display . BeginTweening ( 0.04f * i * factor ) ; // sleep
2003-03-02 01:43:33 +00:00
display . BeginTweening ( 0.2f * factor , Actor : : TWEEN_ACCELERATE ) ;
2003-04-12 06:16:12 +00:00
display . SetX ( fX ) ;
2002-05-28 20:01:22 +00:00
}
2003-01-02 02:59:25 +00:00
2003-03-02 01:43:33 +00:00
m_fTimeLeftInState = GetTweenTimeLeft ( ) + 0.100f ;
2002-02-07 02:16:14 +00:00
}
2003-01-02 02:59:25 +00:00
void MusicWheel : : TweenOffScreen ( bool changing_sort )
2002-02-09 04:30:27 +00:00
{
2003-01-02 02:59:25 +00:00
float factor = 1.0f ;
if ( changing_sort ) factor = 0.25 ;
2002-05-28 20:01:22 +00:00
2003-01-02 02:59:25 +00:00
m_WheelState = STATE_TWEENING_OFF_SCREEN ;
2002-05-28 20:01:22 +00:00
2003-04-02 04:41:49 +00:00
float fX , fY , fZ , fRotationX ;
GetItemPosition ( 0 , fX , fY , fZ , fRotationX ) ;
2002-08-13 23:26:46 +00:00
m_sprSelectionOverlay . SetXY ( fX , fY ) ;
2003-04-02 04:41:49 +00:00
m_sprSelectionOverlay . SetZ ( fZ ) ;
m_sprSelectionOverlay . SetRotationX ( fRotationX ) ;
2003-01-02 02:59:25 +00:00
if ( changing_sort ) {
/* When changing sort, tween the overlay with the item in the center;
* having it separate looks messy when we're moving fast. */
2003-03-26 19:15:38 +00:00
m_sprSelectionOverlay . BeginTweening ( 0.04f * NUM_WHEEL_ITEMS / 2 * factor ) ; // sleep
2003-03-02 01:43:33 +00:00
m_sprSelectionOverlay . BeginTweening ( 0.2f * factor , Actor : : TWEEN_DECELERATE ) ;
2003-01-02 02:59:25 +00:00
} else {
m_sprSelectionOverlay . BeginTweening ( 0 ) ; // sleep
2003-03-02 01:43:33 +00:00
m_sprSelectionOverlay . BeginTweening ( 0.2f * factor , Actor : : TWEEN_DECELERATE ) ;
2003-01-02 02:59:25 +00:00
}
2003-04-12 06:16:12 +00:00
m_sprSelectionOverlay . SetX ( fX + 320 ) ;
2002-05-29 09:47:24 +00:00
2002-09-02 21:59:58 +00:00
m_ScrollBar . BeginTweening ( 0 ) ;
2003-03-02 01:43:33 +00:00
m_ScrollBar . BeginTweening ( 0.2f * factor , Actor : : TWEEN_ACCELERATE ) ;
2003-04-12 06:16:12 +00:00
m_ScrollBar . SetX ( SCROLL_BAR_X + 30 ) ;
2002-05-28 20:01:22 +00:00
2003-03-26 19:15:38 +00:00
for ( int i = 0 ; i < NUM_WHEEL_ITEMS ; i + + )
2002-05-28 20:01:22 +00:00
{
2003-03-31 23:06:15 +00:00
MusicWheelItem & display = m_MusicWheelItems [ i ] ;
2003-03-26 19:15:38 +00:00
float fThisBannerPositionOffsetFromSelection = i - NUM_WHEEL_ITEMS / 2 + m_fPositionOffsetFromSelection ;
2002-05-28 20:01:22 +00:00
2003-04-02 04:41:49 +00:00
float fX , fY , fZ , fRotationX ;
GetItemPosition ( fThisBannerPositionOffsetFromSelection , fX , fY , fZ , fRotationX ) ;
2002-05-28 20:01:22 +00:00
display . SetXY ( fX , fY ) ;
2003-04-02 04:41:49 +00:00
display . SetZ ( fZ ) ;
display . SetRotationX ( fRotationX ) ;
2003-01-02 02:59:25 +00:00
display . BeginTweening ( 0.04f * i * factor ) ; // sleep
2003-03-02 01:43:33 +00:00
display . BeginTweening ( 0.2f * factor , Actor : : TWEEN_DECELERATE ) ;
2003-04-12 06:16:12 +00:00
display . SetX ( fX + 320 ) ;
2002-05-28 20:01:22 +00:00
}
2003-03-02 01:43:33 +00:00
m_fTimeLeftInState = GetTweenTimeLeft ( ) + 0.100f ;
2002-06-24 22:04:31 +00:00
}
2002-12-30 21:57:54 +00:00
2003-02-11 23:52:18 +00:00
CString MusicWheel : : GetSectionNameFromSongAndSort ( const Song * pSong , SongSortOrder so )
2002-12-30 21:57:54 +00:00
{
if ( pSong = = NULL )
return " " ;
switch ( so )
{
2003-06-16 20:23:07 +00:00
case SORT_PREFERRED :
return " " ;
2002-12-30 21:57:54 +00:00
case SORT_GROUP :
2003-06-16 20:23:07 +00:00
return pSong - > m_sGroupName ;
2002-12-30 21:57:54 +00:00
case SORT_TITLE :
2003-06-16 20:23:07 +00:00
case SORT_ARTIST :
{
CString s ;
switch ( so )
{
case SORT_TITLE : s = pSong - > GetTranslitMainTitle ( ) ; break ;
2003-06-19 05:30:01 +00:00
case SORT_ARTIST : s = pSong - > GetTranslitArtist ( ) ; break ;
2003-06-16 20:23:07 +00:00
default : ASSERT ( 0 ) ;
}
s = MakeSortString ( s ) ; // resulting string will be uppercase
if ( s . empty ( ) )
return " " ;
else if ( s [ 0 ] > = ' 0 ' & & s [ 0 ] < = ' 9 ' )
return " NUM " ;
else if ( s [ 0 ] < ' A ' | | s [ 0 ] > ' Z ' )
return " OTHER " ;
else
return s . Left ( 1 ) ;
}
2002-12-30 21:57:54 +00:00
case SORT_BPM :
2003-06-16 17:28:58 +00:00
{
const int iBPMGroupSize = 20 ;
float fMinBPM , fMaxBPM ;
pSong - > GetDisplayBPM ( fMinBPM , fMaxBPM ) ;
int iMaxBPM = ( int ) fMaxBPM ;
2003-06-19 05:30:01 +00:00
iMaxBPM + = iBPMGroupSize - ( iMaxBPM % iBPMGroupSize ) - 1 ;
2003-06-16 17:28:58 +00:00
return ssprintf ( " %03d-%03d " , iMaxBPM - ( iBPMGroupSize - 1 ) , iMaxBPM ) ;
}
2002-12-30 21:57:54 +00:00
case SORT_MOST_PLAYED :
2003-06-16 20:23:07 +00:00
return " " ;
case SORT_GRADE :
{
for ( int i = NUM_GRADES ; i > GRADE_NO_DATA ; i - - )
{
Grade g = ( Grade ) i ;
int iCount = pSong - > GetNumNotesWithGrade ( g ) ;
if ( iCount > 0 )
return ssprintf ( " %4s x %d " , GradeToString ( g ) . c_str ( ) , iCount ) ;
}
return " NO DATA " ;
}
2003-06-27 08:06:22 +00:00
case SORT_EASY_METER :
{
Notes * pNotes = pSong - > GetNotes ( GAMESTATE - > GetCurrentStyleDef ( ) - > m_NotesType , DIFFICULTY_EASY ) ;
if ( pNotes )
return ssprintf ( " %02d " , pNotes - > GetMeter ( ) ) ;
return " N/A " ;
}
case SORT_MEDIUM_METER :
{
Notes * pNotes = pSong - > GetNotes ( GAMESTATE - > GetCurrentStyleDef ( ) - > m_NotesType , DIFFICULTY_MEDIUM ) ;
if ( pNotes )
return ssprintf ( " %02d " , pNotes - > GetMeter ( ) ) ;
return " N/A " ;
}
case SORT_HARD_METER :
{
Notes * pNotes = pSong - > GetNotes ( GAMESTATE - > GetCurrentStyleDef ( ) - > m_NotesType , DIFFICULTY_HARD ) ;
if ( pNotes )
return ssprintf ( " %02d " , pNotes - > GetMeter ( ) ) ;
return " N/A " ;
}
2003-06-16 20:23:07 +00:00
case SORT_SORT :
return " " ;
2002-12-30 21:57:54 +00:00
default :
2003-06-16 20:23:07 +00:00
ASSERT ( 0 ) ;
2002-12-30 21:57:54 +00:00
return " " ;
}
}
2002-12-30 22:40:34 +00:00
2003-01-02 02:59:25 +00:00
void MusicWheel : : Move ( int n )
2002-12-30 22:40:34 +00:00
{
2003-01-02 02:59:25 +00:00
if ( n = = m_Moving )
return ;
2002-12-30 22:40:34 +00:00
2003-01-21 07:04:53 +00:00
if ( m_WheelState = = STATE_LOCKED )
{
if ( n )
{
2003-03-24 21:37:13 +00:00
int iSign = n / abs ( n ) ;
m_fLockedWheelVelocity = iSign * LOCKED_INITIAL_VELOCITY ;
2003-01-21 07:04:53 +00:00
m_soundLocked . Play ( ) ;
}
return ;
}
2003-01-02 02:59:25 +00:00
2003-01-21 07:04:53 +00:00
/* If we're not selecting, discard this. We won't ignore it; we'll
* get called again every time the key is repeated. */
if ( m_WheelState ! = STATE_SELECTING_MUSIC )
return ;
2003-01-02 02:59:25 +00:00
2003-01-21 07:04:53 +00:00
if ( m_Moving ! = 0 & & n = = 0 & & m_TimeBeforeMovingBegins = = 0 )
2003-01-02 02:59:25 +00:00
{
2003-01-21 07:04:53 +00:00
/* We were moving, and now we're stopping. If we're really close to
* the selection, move to the next one, so we have a chance to spin down
* smoothly. */
if ( fabsf ( m_fPositionOffsetFromSelection ) < 0.25f )
ChangeMusic ( m_Moving ) ;
2003-01-02 02:59:25 +00:00
/* Make sure the user always gets an SM_SongChanged when
2003-01-21 07:04:53 +00:00
* Moving() is 0, so the final banner, etc. always gets set. */
2003-03-25 21:17:29 +00:00
SCREENMAN - > PostMessageToTopScreen ( SM_SongChanged , 0 ) ;
2003-01-02 02:59:25 +00:00
}
2003-01-21 07:04:53 +00:00
m_TimeBeforeMovingBegins = TIME_BEFORE_SLOW_REPEATS ;
m_SpinSpeed = float ( PREFSMAN - > m_iMusicWheelSwitchSpeed ) ;
m_Moving = n ;
if ( fabsf ( m_fPositionOffsetFromSelection ) > 0.5f ) // wheel is very busy spinning
return ;
if ( m_Moving )
ChangeMusic ( m_Moving ) ;
2002-12-30 22:40:34 +00:00
}