2002-01-16 10:01:32 +00:00
#include "stdafx.h"
/*
-----------------------------------------------------------------------------
2002-05-01 19:14:55 +00:00
Class: MusicWheel
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
2002-05-19 01:59:48 +00:00
Copyright (c) 2001-2002 by the person(s) listed below. All rights reserved.
2002-05-01 19:14:55 +00:00
Chris Danford
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"
2002-11-11 04:53:31 +00:00
#include <math.h>
#include "ThemeManager.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
// WheelItem stuff
2002-08-27 03:59:22 +00:00
#define ICON_X THEME->GetMetricF("WheelItemDisplay","IconX")
#define SONG_NAME_X THEME->GetMetricF("WheelItemDisplay","SongNameX")
#define SECTION_NAME_X THEME->GetMetricF("WheelItemDisplay","SectionNameX")
#define SECTION_ZOOM THEME->GetMetricF("WheelItemDisplay","SectionZoom")
#define ROULETTE_X THEME->GetMetricF("WheelItemDisplay","RouletteX")
#define ROULETTE_ZOOM THEME->GetMetricF("WheelItemDisplay","RouletteZoom")
#define COURSE_X THEME->GetMetricF("WheelItemDisplay","CourseX")
#define COURSE_ZOOM THEME->GetMetricF("WheelItemDisplay","CourseZoom")
2002-09-03 06:33:08 +00:00
#define GRADE_X( p ) THEME->GetMetricF("WheelItemDisplay",ssprintf("GradeP%dX",p+1))
2003-01-01 17:20:36 +00:00
#define DEFAULT_SCROLL_DIRECTION THEME->GetMetricI("Notes","DefaultScrollDirection")
2002-01-16 10:01:32 +00:00
2002-08-13 23:26:46 +00:00
// MusicWheel stuff
#define FADE_SECONDS THEME->GetMetricF("MusicWheel","FadeSeconds")
#define SWITCH_SECONDS THEME->GetMetricF("MusicWheel","SwitchSeconds")
#define ROULETTE_SWITCH_SECONDS THEME->GetMetricF("MusicWheel","RouletteSwitchSeconds")
2003-01-02 02:59:25 +00:00
#define FAST_SPIN_SWITCH_SECONDS 0.05 // THEME->GetMetricF("MusicWheel","RouletteSwitchSeconds")
2002-08-13 23:26:46 +00:00
#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")
2002-09-03 06:33:08 +00:00
#define ITEM_SPACING_Y THEME->GetMetricF("MusicWheel","ItemSpacingY")
#define NUM_SECTION_COLORS THEME->GetMetricI("MusicWheel","NumSectionColors")
#define SECTION_COLORS( i ) THEME->GetMetricC("MusicWheel",ssprintf("SectionColor%d",i+1))
float g_fItemSpacingY ; // cache
2002-01-16 10:01:32 +00:00
2002-10-28 05:30:45 +00:00
inline RageColor GetNextSectionColor () {
2002-05-19 01:59:48 +00:00
static int i = 0 ;
i = i % NUM_SECTION_COLORS ;
2002-08-13 23:26:46 +00:00
return SECTION_COLORS ( i ++ );
2002-05-19 01:59:48 +00:00
}
2002-02-05 05:33:33 +00:00
2002-10-28 05:30:45 +00:00
WheelItemData :: WheelItemData ( WheelItemType wit , Song * pSong , const CString & sSectionName , Course * pCourse , const RageColor color )
2002-01-16 10:01:32 +00:00
{
2002-05-19 01:59:48 +00:00
m_WheelItemType = wit ;
2002-02-09 04:30:27 +00:00
m_pSong = pSong ;
2002-05-19 01:59:48 +00:00
m_sSectionName = sSectionName ;
2002-06-14 22:25:22 +00:00
m_pCourse = pCourse ;
2002-05-19 01:59:48 +00:00
m_color = color ;
2002-08-20 21:00:56 +00:00
m_IconType = MusicStatusDisplay :: none ;
2002-02-09 04:30:27 +00:00
}
2003-01-03 03:24:00 +00:00
2002-02-09 04:30:27 +00:00
WheelItemDisplay :: WheelItemDisplay ()
{
2003-01-03 03:24:00 +00:00
data = NULL ;
2002-06-30 23:19:33 +00:00
2003-01-03 03:24:00 +00:00
m_fPercentGray = 0 ;
2002-08-13 23:26:46 +00:00
m_MusicStatusDisplay . SetXY ( ICON_X , 0 );
2002-02-09 04:30:27 +00:00
2002-05-19 01:59:48 +00:00
m_TextBanner . SetHorizAlign ( align_left );
2002-08-13 23:26:46 +00:00
m_TextBanner . SetXY ( SONG_NAME_X , 0 );
2002-01-16 10:01:32 +00:00
2002-08-13 23:26:46 +00:00
m_sprSongBar . Load ( THEME -> GetPathTo ( "Graphics" , "select music song bar" ) );
2002-04-16 17:31:00 +00:00
m_sprSongBar . SetXY ( 0 , 0 );
2002-08-13 23:26:46 +00:00
m_sprSectionBar . Load ( THEME -> GetPathTo ( "Graphics" , "select music section bar" ) );
2002-05-19 01:59:48 +00:00
m_sprSectionBar . SetXY ( 0 , 0 );
2002-01-16 10:01:32 +00:00
2002-09-03 22:31:06 +00:00
m_textSectionName . LoadFromFont ( THEME -> GetPathTo ( "Fonts" , "musicwheel section" ) );
2002-01-16 10:01:32 +00:00
m_textSectionName . TurnShadowOff ();
2002-03-06 08:25:09 +00:00
m_textSectionName . SetVertAlign ( align_middle );
2002-08-13 23:26:46 +00:00
m_textSectionName . SetXY ( SECTION_NAME_X , 0 );
m_textSectionName . SetZoom ( SECTION_ZOOM );
2002-05-19 01:59:48 +00:00
2002-09-03 22:31:06 +00:00
m_textRoulette . LoadFromFont ( THEME -> GetPathTo ( "Fonts" , "musicwheel roulette" ) );
2002-05-19 01:59:48 +00:00
m_textRoulette . TurnShadowOff ();
m_textRoulette . TurnRainbowOn ();
2002-08-13 23:26:46 +00:00
m_textRoulette . SetZoom ( ROULETTE_ZOOM );
m_textRoulette . SetXY ( ROULETTE_X , 0 );
2002-04-16 17:31:00 +00:00
for ( int p = 0 ; p < NUM_PLAYERS ; p ++ )
{
2002-08-22 09:31:32 +00:00
m_GradeDisplay [ p ]. Load ( THEME -> GetPathTo ( "Graphics" , "select music small grades 2x8" ) );
2002-05-01 19:14:55 +00:00
m_GradeDisplay [ p ]. SetZoom ( 1.0f );
2002-09-03 06:33:08 +00:00
m_GradeDisplay [ p ]. SetXY ( GRADE_X ( p ), 0 );
2002-04-16 17:31:00 +00:00
}
2002-06-14 22:25:22 +00:00
2002-09-03 22:31:06 +00:00
m_textCourse . LoadFromFont ( THEME -> GetPathTo ( "Fonts" , "musicwheel course" ) );
2002-06-14 22:25:22 +00:00
m_textCourse . TurnShadowOff ();
2002-08-13 23:26:46 +00:00
m_textCourse . SetZoom ( COURSE_ZOOM );
2002-06-14 22:25:22 +00:00
m_textCourse . SetHorizAlign ( align_left );
2002-08-13 23:26:46 +00:00
m_textCourse . SetXY ( COURSE_X , 0 );
2002-02-05 05:33:33 +00:00
}
2002-01-16 10:01:32 +00:00
2002-02-09 04:30:27 +00:00
void WheelItemDisplay :: LoadFromWheelItemData ( WheelItemData * pWID )
2002-01-16 10:01:32 +00:00
{
2002-02-09 04:30:27 +00:00
ASSERT ( pWID != NULL );
2003-01-03 03:24:00 +00:00
data = pWID ;
/*
2002-02-09 04:30:27 +00:00
// copy all data items
2002-06-14 22:25:22 +00:00
this->m_WheelItemType = pWID->m_WheelItemType;
this->m_sSectionName = pWID->m_sSectionName;
this->m_pCourse = pWID->m_pCourse;
this->m_pSong = pWID->m_pSong;
this->m_color = pWID->m_color;
2003-01-03 03:24:00 +00:00
this->m_IconType = pWID->m_IconType; */
2002-01-16 10:01:32 +00:00
2002-02-09 04:30:27 +00:00
// init type specific stuff
switch ( pWID -> m_WheelItemType )
{
case TYPE_SECTION :
2003-01-02 02:59:25 +00:00
case TYPE_COURSE :
2002-03-06 08:25:09 +00:00
{
2003-01-02 02:59:25 +00:00
CString sDisplayName ;
BitmapText * bt ;
if ( pWID -> m_WheelItemType == TYPE_SECTION )
{
2003-01-03 03:24:00 +00:00
sDisplayName = SONGMAN -> ShortenGroupName ( data -> m_sSectionName );
2003-01-02 02:59:25 +00:00
bt = & m_textSectionName ;
}
else
{
2003-01-03 03:24:00 +00:00
sDisplayName = data -> m_pCourse -> m_sName ;
2003-01-02 02:59:25 +00:00
bt = & m_textCourse ;
}
bt -> SetZoom ( 1 );
bt -> SetText ( sDisplayName );
2003-01-03 03:24:00 +00:00
bt -> SetDiffuse ( data -> m_color );
2003-01-02 02:59:25 +00:00
bt -> TurnRainbowOff ();
2002-03-06 08:25:09 +00:00
2003-01-02 02:59:25 +00:00
float fSourcePixelWidth = ( float ) bt -> GetWidestLineWidthInSourcePixels ();
2002-06-14 22:25:22 +00:00
float fMaxTextWidth = 200 ;
if ( fSourcePixelWidth > fMaxTextWidth )
2003-01-02 02:59:25 +00:00
bt -> SetZoomX ( fMaxTextWidth / fSourcePixelWidth );
2002-04-16 17:31:00 +00:00
}
2002-02-09 04:30:27 +00:00
break ;
2002-04-16 17:31:00 +00:00
case TYPE_SONG :
{
2003-01-03 03:24:00 +00:00
m_TextBanner . LoadFromSong ( data -> m_pSong );
m_TextBanner . SetDiffuse ( data -> m_color );
m_MusicStatusDisplay . SetType ( data -> m_IconType );
2002-05-29 09:47:24 +00:00
RefreshGrades ();
2002-04-16 17:31:00 +00:00
}
2002-02-09 04:30:27 +00:00
break ;
2002-05-19 01:59:48 +00:00
case TYPE_ROULETTE :
2003-01-03 03:24:00 +00:00
m_textRoulette . SetText ( "ROULETTE" );
2002-06-14 22:25:22 +00:00
break ;
2003-01-03 03:24:00 +00:00
case TYPE_RANDOM :
m_textRoulette . SetText ( "RANDOM" );
break ;
2002-02-09 04:30:27 +00:00
default :
2002-02-11 04:46:31 +00:00
ASSERT ( false ); // invalid type
2002-02-09 04:30:27 +00:00
}
}
2002-04-28 20:42:32 +00:00
void WheelItemDisplay :: RefreshGrades ()
{
2002-05-29 09:47:24 +00:00
// Refresh Grades
2002-04-28 20:42:32 +00:00
for ( int p = 0 ; p < NUM_PLAYERS ; p ++ )
{
2002-07-23 01:41:40 +00:00
if ( ! GAMESTATE -> IsPlayerEnabled ( ( PlayerNumber ) p ) )
2002-05-19 01:59:48 +00:00
{
2002-10-28 05:30:45 +00:00
m_GradeDisplay [ p ]. SetDiffuse ( RageColor ( 1 , 1 , 1 , 0 ) );
2002-05-19 01:59:48 +00:00
continue ;
}
2003-01-03 03:24:00 +00:00
if ( data -> m_pSong ) // this is a song display
2002-04-28 20:42:32 +00:00
{
2003-01-03 03:24:00 +00:00
if ( data -> m_pSong == GAMESTATE -> m_pCurSong )
2002-10-07 05:45:59 +00:00
{
Notes * pNotes = GAMESTATE -> m_pCurNotes [ p ];
2002-10-07 07:16:40 +00:00
m_GradeDisplay [ p ]. SetGrade ( ( PlayerNumber ) p , pNotes ? pNotes -> m_TopGrade : GRADE_NO_DATA );
2002-10-07 05:45:59 +00:00
}
else
{
const Difficulty dc = GAMESTATE -> m_PreferredDifficulty [ p ];
2003-01-03 03:24:00 +00:00
const Grade grade = data -> m_pSong -> GetGradeForDifficulty ( GAMESTATE -> GetCurrentStyleDef (), p , dc );
2002-10-07 05:45:59 +00:00
m_GradeDisplay [ p ]. SetGrade ( ( PlayerNumber ) p , grade );
}
2002-04-28 20:42:32 +00:00
}
2002-05-19 01:59:48 +00:00
else // this is a section display
2002-04-28 20:42:32 +00:00
{
2002-08-22 09:31:32 +00:00
m_GradeDisplay [ p ]. SetGrade ( ( PlayerNumber ) p , GRADE_NO_DATA );
2002-04-28 20:42:32 +00:00
}
}
2002-05-29 09:47:24 +00:00
2002-04-28 20:42:32 +00:00
}
2002-02-09 04:30:27 +00:00
2002-05-29 09:47:24 +00:00
2002-02-09 04:30:27 +00:00
void WheelItemDisplay :: Update ( float fDeltaTime )
2002-02-05 05:33:33 +00:00
{
2002-05-28 20:01:22 +00:00
Actor :: Update ( fDeltaTime );
2003-01-03 03:24:00 +00:00
switch ( data -> m_WheelItemType )
2002-02-05 05:33:33 +00:00
{
case TYPE_SECTION :
2002-04-16 17:31:00 +00:00
m_sprSectionBar . Update ( fDeltaTime );
2002-02-05 05:33:33 +00:00
m_textSectionName . Update ( fDeltaTime );
break ;
2002-05-19 01:59:48 +00:00
case TYPE_ROULETTE :
2003-01-03 03:24:00 +00:00
case TYPE_RANDOM :
2002-05-19 01:59:48 +00:00
m_sprSectionBar . Update ( fDeltaTime );
m_textRoulette . Update ( fDeltaTime );
break ;
2002-04-16 17:31:00 +00:00
case TYPE_SONG :
2002-06-14 22:25:22 +00:00
{
m_sprSongBar . Update ( fDeltaTime );
m_MusicStatusDisplay . Update ( fDeltaTime );
m_TextBanner . Update ( fDeltaTime );
for ( int p = 0 ; p < NUM_PLAYERS ; p ++ )
m_GradeDisplay [ p ]. Update ( fDeltaTime );
}
2002-02-05 05:33:33 +00:00
break ;
2002-06-14 22:25:22 +00:00
case TYPE_COURSE :
m_sprSongBar . Update ( fDeltaTime );
m_textCourse . Update ( fDeltaTime );
break ;
default :
ASSERT ( 0 );
2002-02-05 05:33:33 +00:00
}
}
2002-05-19 01:59:48 +00:00
void WheelItemDisplay :: DrawPrimitives ()
2002-02-05 05:33:33 +00:00
{
2003-01-03 03:24:00 +00:00
Sprite * bar = NULL ;
switch ( data -> m_WheelItemType )
{
case TYPE_SECTION :
case TYPE_ROULETTE :
case TYPE_RANDOM : bar = & m_sprSectionBar ; break ;
case TYPE_SONG :
case TYPE_COURSE : bar = & m_sprSongBar ; break ;
default : ASSERT ( 0 );
}
bar -> Draw ();
switch ( data -> m_WheelItemType )
2002-02-05 05:33:33 +00:00
{
case TYPE_SECTION :
2002-08-19 20:02:30 +00:00
m_textSectionName . Draw ();
break ;
case TYPE_ROULETTE :
2003-01-03 03:24:00 +00:00
case TYPE_RANDOM :
2002-08-19 20:02:30 +00:00
m_textRoulette . Draw ();
break ;
2002-08-20 21:00:56 +00:00
case TYPE_SONG :
2002-08-19 20:02:30 +00:00
m_TextBanner . Draw ();
2002-08-20 21:00:56 +00:00
m_MusicStatusDisplay . Draw ();
int p ;
for ( p = 0 ; p < NUM_PLAYERS ; p ++ )
m_GradeDisplay [ p ]. Draw ();
2002-08-19 20:02:30 +00:00
break ;
case TYPE_COURSE :
2002-06-14 22:25:22 +00:00
m_textCourse . Draw ();
break ;
default :
ASSERT ( 0 );
2002-02-05 05:33:33 +00:00
}
2003-01-03 03:24:00 +00:00
if ( m_fPercentGray > 0 )
{
bar -> SetGlow ( RageColor ( 0 , 0 , 0 , m_fPercentGray ) );
bar -> SetDiffuse ( RageColor ( 0 , 0 , 0 , 0 ) );
bar -> Draw ();
bar -> SetDiffuse ( RageColor ( 0 , 0 , 0 , 1 ) );
bar -> SetGlow ( RageColor ( 0 , 0 , 0 , 0 ) );
}
2002-02-05 05:33:33 +00:00
}
2002-01-16 10:01:32 +00:00
MusicWheel :: MusicWheel ()
{
2002-07-31 19:40:40 +00:00
LOG -> Trace ( "MusicWheel::MusicWheel()" );
2002-01-16 10:01:32 +00:00
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 ++ )
GAMESTATE -> m_PlayerOptions [ i ]. m_bReverseScroll = true ;
}
2002-09-03 06:33:08 +00:00
// update theme metric cache
g_fItemSpacingY = ITEM_SPACING_Y ;
2002-05-28 20:01:22 +00:00
// for debugging
2002-07-23 01:41:40 +00:00
if ( GAMESTATE -> m_CurStyle == STYLE_NONE )
GAMESTATE -> m_CurStyle = STYLE_DANCE_SINGLE ;
2002-05-28 20:01:22 +00:00
2002-08-13 23:26:46 +00:00
m_sprSelectionOverlay . Load ( THEME -> GetPathTo ( "Graphics" , "select music song 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 ) );
m_sprSelectionOverlay . SetEffectGlowing ( 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-01-16 10:01:32 +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-02 22:10:51 +00:00
m_soundChangeMusic . Load ( THEME -> GetPathTo ( "Sounds" , "select music change music" ) );
2002-08-13 23:26:46 +00:00
m_soundChangeSort . Load ( THEME -> GetPathTo ( "Sounds" , "select music change sort" ) );
m_soundExpand . Load ( THEME -> GetPathTo ( "Sounds" , "select music section expand" ) );
m_soundStart . Load ( THEME -> GetPathTo ( "Sounds" , "menu start" ) );
m_soundLocked . Load ( THEME -> GetPathTo ( "Sounds" , "select music wheel locked" ) );
2002-01-16 10:01:32 +00:00
// init m_mapGroupNameToBannerColor
2002-10-24 19:53:13 +00:00
CArray < Song * , Song *> arraySongs = SONGMAN -> m_pSongs ;
2002-01-16 10:01:32 +00:00
SortSongPointerArrayByGroup ( arraySongs );
m_iSelection = 0 ;
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-01-02 02:59:25 +00:00
2002-08-01 13:42:56 +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.
if ( GAMESTATE -> m_sPreferredGroup == "ALL MUSIC" )
GAMESTATE -> m_sPreferredGroup = GAMESTATE -> m_pCurSong -> m_sGroupName ;
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
{
2002-08-01 13:42:56 +00:00
if ( GAMESTATE -> IsPlayerEnabled ( 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 ;
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
}
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 ) );
2003-01-03 03:24:00 +00:00
BuildWheelItemDatas ( m_WheelItemDatas [ SORT_ROULETTE ], SongSortOrder ( SORT_ROULETTE ) );
2002-08-30 21:51:40 +00:00
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
{
2002-08-01 13:42:56 +00:00
CStringArray asGroupNames ;
SONGMAN -> GetGroupNames ( asGroupNames );
2002-10-31 02:46:42 +00:00
if ( ! asGroupNames . empty () )
2002-08-01 13:42:56 +00:00
{
2002-08-30 21:51:40 +00:00
/* XXX: Do groups get added if they're empty?
* This will select songs we can't use; we want the first song
2002-09-06 10:13:46 +00:00
* that's actually visible. Should we select out of wheel data?
2002-08-30 21:51:40 +00:00
* -glenn */
2002-08-01 13:42:56 +00:00
CArray < Song * , Song *> arraySongs ;
SONGMAN -> GetSongsInGroup ( asGroupNames [ 0 ], arraySongs );
2002-10-31 02:46:42 +00:00
if ( ! arraySongs . empty () ) // still nothing selected
2002-08-01 13:42:56 +00:00
GAMESTATE -> m_pCurSong = arraySongs [ 0 ]; // select the first song
}
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 );
2002-08-01 05:11:11 +00:00
// Select the the previously selected course (if any)
2003-01-02 02:59:25 +00:00
if ( ! selected ) selected = SelectCourse ( GAMESTATE -> m_pCurCourse );
if ( ! selected ) SetOpenGroup ( "" );
2002-08-01 05:11:11 +00:00
2002-02-09 18:53:47 +00:00
// rebuild the WheelItems that appear on screen
2002-02-09 04:30:27 +00:00
RebuildWheelItemDisplays ();
2002-01-16 10:01:32 +00:00
}
2002-02-06 05:13:39 +00:00
MusicWheel ::~ MusicWheel ()
{
2002-08-13 23:26:46 +00:00
}
2003-01-02 02:59:25 +00:00
bool MusicWheel :: SelectSong ( const Song * p )
2002-08-13 23:26:46 +00:00
{
2003-01-02 02:59:25 +00:00
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_pSong == p )
{
// 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_pSong == p )
m_iSelection = i ; // select it
}
return true ;
2002-02-06 05:13:39 +00:00
}
2003-01-02 02:59:25 +00:00
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 )
{
// 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_pCourse == p )
m_iSelection = i ; // select it
}
return true ;
}
2003-01-03 03:24:00 +00:00
void MusicWheel :: GetSongList ( CArray < Song * , Song *> & arraySongs , bool bRoulette )
{
// copy only songs that have at least one Notes for the current GameMode
for ( unsigned i = 0 ; i < SONGMAN -> m_pSongs . size (); i ++ )
{
Song * pSong = SONGMAN -> m_pSongs [ i ];
/* 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. */
if ( ! bRoulette && ! pSong -> NormallyDisplayed () )
continue ;
if ( bRoulette && ! pSong -> RouletteDisplayed () )
continue ;
}
CArray < Notes * , Notes *> arraySteps ;
pSong -> GetNotesThatMatch ( GAMESTATE -> GetCurrentStyleDef () -> m_NotesType , arraySteps );
if ( ! arraySteps . empty () )
arraySongs . push_back ( pSong );
}
}
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
2003-01-03 03:24:00 +00:00
if ( so == SongSortOrder ( SORT_ROULETTE ) && GAMESTATE -> m_PlayMode != PLAY_MODE_ARCADE )
return ; /* only used in arcade */
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 :
{
///////////////////////////////////
// Make an array of Song*, then sort them
///////////////////////////////////
CArray < Song * , Song *> arraySongs ;
2003-01-03 03:24:00 +00:00
GetSongList ( arraySongs , so == SORT_ROULETTE );
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 )
{
case SORT_GROUP :
2003-01-03 03:24:00 +00:00
case SORT_ROULETTE :
2002-06-14 22:25:22 +00:00
SortSongPointerArrayByGroup ( arraySongs );
break ;
case SORT_TITLE :
SortSongPointerArrayByTitle ( arraySongs );
break ;
case SORT_BPM :
SortSongPointerArrayByBPM ( arraySongs );
break ;
// case SORT_ARTIST:
// SortSongPointerArrayByArtist( 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 ;
default :
2002-08-20 21:00:56 +00:00
ASSERT ( 0 ); // unhandled SortOrder
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-06-14 22:25:22 +00:00
2002-09-07 10:15:27 +00:00
bool bUseSections = false ;
2002-06-14 22:25:22 +00:00
switch ( so )
{
case SORT_MOST_PLAYED : bUseSections = false ; break ;
case SORT_BPM : bUseSections = false ; break ;
2002-07-28 16:20:46 +00:00
case SORT_GROUP : bUseSections = GAMESTATE -> m_sPreferredGroup == "ALL MUSIC" ; break ;
2002-06-14 22:25:22 +00:00
case SORT_TITLE : bUseSections = true ; break ;
2003-01-03 03:24:00 +00:00
case SORT_ROULETTE : bUseSections = false ; break ;
2002-06-14 22:25:22 +00:00
default : ASSERT ( false );
}
2002-06-30 23:19:33 +00:00
2002-12-30 21:42:14 +00:00
if ( ! PREFSMAN -> m_bMusicWheelUsesSections )
bUseSections = false ;
2002-06-14 22:25:22 +00:00
if ( bUseSections )
{
// 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 ( GAMESTATE -> m_sPreferredGroup != "ALL MUSIC" && pSong -> m_sGroupName != GAMESTATE -> m_sPreferredGroup )
continue ;
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 ;
2002-10-31 04:23:39 +00:00
arrayWheelItemDatas . push_back ( WheelItemData ( TYPE_SECTION , NULL , sThisSection , NULL , colorSection ) );
2002-06-14 22:25:22 +00:00
sLastSection = sThisSection ;
}
2002-10-31 04:23:39 +00:00
arrayWheelItemDatas . push_back ( WheelItemData ( TYPE_SONG , pSong , sThisSection , NULL , SONGMAN -> GetSongColor ( pSong )) );
2002-06-14 22:25:22 +00:00
}
}
else
{
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 ];
2002-07-28 16:20:46 +00:00
if ( GAMESTATE -> m_sPreferredGroup != "ALL MUSIC" && pSong -> m_sGroupName != GAMESTATE -> m_sPreferredGroup )
2002-07-27 19:29:51 +00:00
continue ; // skip
2002-10-31 04:23:39 +00:00
arrayWheelItemDatas . push_back ( WheelItemData ( TYPE_SONG , pSong , "" , NULL , SONGMAN -> GetSongColor ( pSong )) );
2002-06-14 22:25:22 +00:00
}
}
}
2002-10-09 06:57:37 +00:00
2003-01-03 03:24:00 +00:00
if ( so != SORT_ROULETTE )
2002-10-09 06:57:37 +00:00
{
2002-10-31 04:23:39 +00:00
arrayWheelItemDatas . push_back ( WheelItemData ( TYPE_ROULETTE , NULL , "" , NULL , RageColor ( 1 , 0 , 0 , 1 )) );
2003-01-03 03:24:00 +00:00
arrayWheelItemDatas . push_back ( WheelItemData ( TYPE_RANDOM , NULL , "" , NULL , RageColor ( 1 , 0 , 0 , 1 )) );
2002-10-09 06:57:37 +00:00
}
2002-10-10 04:11:30 +00:00
// HACK: Add extra stage item if it isn't already present on the music wheel
2002-10-09 06:57:37 +00:00
if ( GAMESTATE -> IsExtraStage () || GAMESTATE -> IsExtraStage2 () )
{
Song * pSong ;
Notes * pNotes ;
PlayerOptions po ;
SongOptions so ;
SONGMAN -> GetExtraStageInfo ( GAMESTATE -> IsExtraStage2 (), GAMESTATE -> m_pCurSong -> m_sGroupName , GAMESTATE -> GetCurrentStyleDef (), pSong , pNotes , po , so );
2002-10-10 04:11:30 +00:00
bool bFoundExtraSong = false ;
2002-10-31 02:46:42 +00:00
for ( unsigned i = 0 ; i < arrayWheelItemDatas . size (); i ++ )
2002-10-10 04:11:30 +00:00
{
if ( arrayWheelItemDatas [ i ]. m_pSong == pSong )
{
bFoundExtraSong = true ;
break ;
}
}
if ( ! bFoundExtraSong )
2002-10-31 04:23:39 +00:00
arrayWheelItemDatas . push_back ( WheelItemData ( TYPE_SONG , pSong , "" , NULL , GAMESTATE -> GetStageColor ()) );
2002-10-09 06:57:37 +00:00
}
2002-01-16 10:01:32 +00:00
break ;
2002-06-14 22:25:22 +00:00
case PLAY_MODE_ONI :
2002-07-29 03:06:55 +00:00
case PLAY_MODE_ENDLESS :
{
2002-10-31 02:46:42 +00:00
unsigned i ;
2002-08-02 09:31:06 +00:00
2002-07-29 03:06:55 +00:00
CArray < Course * , Course *> apCourses ;
2002-08-01 20:30:40 +00:00
switch ( GAMESTATE -> m_PlayMode )
{
case PLAY_MODE_ONI :
2002-10-31 02:46:42 +00:00
for ( i = 0 ; i < SONGMAN -> m_aOniCourses . size (); i ++ )
2002-10-31 04:23:39 +00:00
apCourses . push_back ( & SONGMAN -> m_aOniCourses [ i ] );
2002-08-01 20:30:40 +00:00
SortCoursePointerArrayByDifficulty ( apCourses );
break ;
case PLAY_MODE_ENDLESS :
2002-10-31 02:46:42 +00:00
for ( i = 0 ; i < SONGMAN -> m_aEndlessCourses . size (); i ++ )
2002-10-31 04:23:39 +00:00
apCourses . push_back ( & SONGMAN -> m_aEndlessCourses [ i ] );
2002-08-01 20:30:40 +00:00
break ;
}
2002-07-29 03:06:55 +00:00
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
CArray < Song * , Song *> apSongs ;
CArray < Notes * , Notes *> apNotes ;
CStringArray asModifiers ;
2002-09-04 03:29:42 +00:00
pCourse -> GetSongAndNotesForCurrentStyle ( apSongs , apNotes , asModifiers , false );
2002-08-01 20:30:40 +00:00
2002-10-31 02:46:42 +00:00
if ( ! apNotes . empty () )
2002-10-31 04:23:39 +00:00
arrayWheelItemDatas . push_back ( WheelItemData ( TYPE_COURSE , NULL , "" , pCourse , pCourse -> GetColor ()) );
2002-07-29 03:06:55 +00:00
}
}
break ;
2002-01-16 10:01:32 +00:00
default :
2002-06-14 22:25:22 +00:00
ASSERT ( 0 ); // invalid PlayMode
2002-01-16 10:01:32 +00:00
}
2002-02-10 06:25:12 +00:00
// init crowns
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-10-14 00:28:27 +00:00
bool bIsEasy = pSong -> IsEasy ( GAMESTATE -> GetCurrentStyleDef () -> m_NotesType );
2002-09-06 10:13:46 +00:00
WheelItemData & WID = arrayWheelItemDatas [ i ];
2002-08-20 21:00:56 +00:00
WID . m_IconType = bIsEasy ? MusicStatusDisplay :: easy : MusicStatusDisplay :: none ;
2002-02-10 06:25:12 +00:00
}
2002-01-16 10:01:32 +00:00
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 ];
WID . m_IconType = MusicStatusDisplay :: IconType ( MusicStatusDisplay :: crown1 + i );
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
{
2002-10-31 04:23:39 +00:00
arrayWheelItemDatas . push_back ( WheelItemData ( TYPE_SECTION , NULL , "- EMPTY -" , NULL , RageColor ( 1 , 0 , 0 , 1 )) );
2002-05-19 01:59:48 +00:00
}
2002-01-16 10:01:32 +00:00
}
float MusicWheel :: GetBannerY ( float fPosOffsetsFromMiddle )
{
2002-09-09 02:59:48 +00:00
return roundf ( fPosOffsetsFromMiddle * g_fItemSpacingY );
2002-01-16 10:01:32 +00:00
}
float MusicWheel :: GetBannerX ( float fPosOffsetsFromMiddle )
{
2002-02-24 01:43:11 +00:00
float fX = ( 1 - cosf (( fPosOffsetsFromMiddle ) / 3 )) * 95.0f ;
2002-04-16 17:31:00 +00:00
2002-09-09 02:59:48 +00:00
return roundf ( fX );
2002-01-16 10:01:32 +00:00
}
2002-02-09 04:30:27 +00:00
void MusicWheel :: RebuildWheelItemDisplays ()
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-01-02 02:59:25 +00:00
iIndex -= NUM_WHEEL_ITEMS_TO_DRAW / 2 ;
while ( iIndex < 0 )
iIndex += m_CurWheelItemData . size ();
2002-01-16 10:01:32 +00:00
// iIndex is now the index of the lowest WheelItem to draw
2003-01-02 02:59:25 +00:00
for ( int i = 0 ; i < NUM_WHEEL_ITEMS_TO_DRAW ; i ++ )
2002-01-16 10:01:32 +00:00
{
2003-01-02 02:59:25 +00:00
WheelItemData * data = m_CurWheelItemData [ iIndex ];
2002-02-09 04:30:27 +00:00
WheelItemDisplay & display = m_WheelItemDisplays [ i ];
2002-01-16 10:01:32 +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-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
{
for ( int i = 0 ; i < NUM_WHEEL_ITEMS_TO_DRAW ; i ++ )
{
WheelItemDisplay & display = m_WheelItemDisplays [ i ];
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
{
for ( int i = 0 ; i < NUM_WHEEL_ITEMS_TO_DRAW ; i ++ )
{
WheelItemDisplay & display = m_WheelItemDisplays [ i ];
2002-05-28 20:01:22 +00:00
switch ( m_WheelState )
{
2002-06-24 22:04:31 +00:00
case STATE_SELECTING_MUSIC :
case STATE_ROULETTE_SPINNING :
case STATE_ROULETTE_SLOWING_DOWN :
2003-01-03 03:24:00 +00:00
case STATE_RANDOM_SPINNING :
2002-06-24 22:04:31 +00:00
case STATE_LOCKED :
2002-05-28 20:01:22 +00:00
{
float fThisBannerPositionOffsetFromSelection = i - NUM_WHEEL_ITEMS_TO_DRAW / 2 + m_fPositionOffsetFromSelection ;
2002-01-16 10:01:32 +00:00
2002-05-28 20:01:22 +00:00
float fY = GetBannerY ( fThisBannerPositionOffsetFromSelection );
if ( fY < - SCREEN_HEIGHT / 2 || fY > SCREEN_HEIGHT / 2 )
continue ; // skip
2002-05-01 19:14:55 +00:00
2002-05-28 20:01:22 +00:00
float fX = GetBannerX ( fThisBannerPositionOffsetFromSelection );
display . SetXY ( fX , fY );
}
break ;
2003-01-02 02:59:25 +00:00
}
2002-01-16 10:01:32 +00:00
2002-06-30 23:19:33 +00:00
if ( m_WheelState == STATE_LOCKED && i != NUM_WHEEL_ITEMS_TO_DRAW / 2 )
display . m_fPercentGray = 0.5f ;
else
display . m_fPercentGray = 0 ;
2002-02-09 04:30:27 +00:00
display . Draw ();
2002-01-16 10:01:32 +00:00
}
2002-05-19 01:59:48 +00:00
ActorFrame :: DrawPrimitives ();
2002-01-16 10:01:32 +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 ;
if ( NUM_WHEEL_ITEMS_TO_DRAW > total_num_items ) {
m_ScrollBar . SetPercentage ( 0 , 1 );
} else {
float size = float ( NUM_WHEEL_ITEMS_TO_DRAW ) / total_num_items ;
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 ;
2002-11-16 08:55:46 +00:00
for ( i = 0 ; i < int ( NUM_WHEEL_ITEMS_TO_DRAW ); i ++ )
2002-01-16 10:01:32 +00:00
{
2002-02-09 04:30:27 +00:00
WheelItemDisplay & display = m_WheelItemDisplays [ i ];
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 );
2003-01-03 03:24:00 +00:00
if ( m_TimeBeforeMovingBegins == 0 && m_WheelState != STATE_LOCKED &&
fabsf ( m_fPositionOffsetFromSelection ) < 0.5f )
2003-01-02 02:59:25 +00:00
{
2003-01-03 03:24:00 +00:00
if ( m_WheelState == STATE_RANDOM_SPINNING && ! m_iSwitchesLeftInSpinDown )
{
// m_fPositionOffsetFromSelection = max(m_fPositionOffsetFromSelection, 0.3f);
m_Moving = 0 ;
m_WheelState = STATE_LOCKED ;
m_soundStart . Play ();
m_fLockedWheelVelocity = 0 ;
SCREENMAN -> SendMessageToTopScreen ( SM_SongChanged , 0 );
}
else {
// spin as fast as possible
if ( m_Moving == 1 ) NextMusic ();
else PrevMusic ();
if ( m_WheelState == STATE_RANDOM_SPINNING )
m_iSwitchesLeftInSpinDown -- ;
}
2003-01-02 02:59:25 +00:00
}
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 ;
CString sPrevSelectedSection = m_CurWheelItemData [ m_iSelection ] -> m_sSectionName ;
2002-01-16 10:01:32 +00:00
2002-06-14 22:25:22 +00:00
// change the sort order
2002-08-13 23:26:46 +00:00
GAMESTATE -> m_SongSortOrder = SongSortOrder ( ( GAMESTATE -> m_SongSortOrder + 1 ) % NUM_SORT_ORDERS );
2002-08-20 21:00:56 +00:00
SCREENMAN -> SendMessageToTopScreen ( SM_SortOrderChanged , 0 );
2003-01-02 02:59:25 +00:00
SetOpenGroup ( GetSectionNameFromSongAndSort ( pPrevSelectedSong , GAMESTATE -> m_SongSortOrder ));
2002-06-14 22:25:22 +00:00
//RebuildWheelItems();
2002-01-16 10:01:32 +00:00
2002-06-14 22:25:22 +00:00
m_iSelection = 0 ;
2002-02-24 01:43:11 +00:00
2002-06-14 22:25:22 +00:00
if ( pPrevSelectedSong != NULL ) // the previous selected item was a song
2003-01-02 02:59:25 +00:00
SelectSong ( pPrevSelectedSong );
2002-06-14 22:25:22 +00:00
else // the previously selected item was a section
2002-02-24 01:43:11 +00:00
{
2002-06-14 22:25:22 +00:00
// find the previously selected song, and select it
2003-01-02 02:59:25 +00:00
for ( i = 0 ; i < m_CurWheelItemData . size (); i ++ )
2002-02-24 01:43:11 +00:00
{
2003-01-02 02:59:25 +00:00
if ( m_CurWheelItemData [ i ] -> m_sSectionName == sPrevSelectedSection )
2002-06-14 22:25:22 +00:00
{
m_iSelection = i ;
break ;
}
2002-02-24 01:43:11 +00:00
}
}
2002-02-09 04:30:27 +00:00
2002-08-28 22:42:40 +00:00
// If changed sort to "BEST", put selection on most popular song
if ( GAMESTATE -> m_SongSortOrder == SORT_MOST_PLAYED )
{
2003-01-02 02:59:25 +00:00
for ( i = 0 ; i < m_CurWheelItemData . size (); i ++ )
2002-08-28 22:42:40 +00:00
{
2003-01-02 02:59:25 +00:00
if ( m_CurWheelItemData [ i ] -> m_pSong != NULL )
2002-08-28 22:42:40 +00:00
{
m_iSelection = i ;
break ;
}
}
}
SCREENMAN -> SendMessageToTopScreen ( SM_SongChanged , 0 );
2002-06-14 22:25:22 +00:00
RebuildWheelItemDisplays ();
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 ;
2002-07-31 04:06:34 +00:00
if ( GAMESTATE -> IsExtraStage () || GAMESTATE -> IsExtraStage2 () )
{
2002-08-01 13:42:56 +00:00
// if ( m_bUseRandomExtra )
// {
2003-01-02 07:45:05 +00:00
// SOUNDMAN->music->StopPlaying();
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. */
SCREENMAN -> SendMessageToTopScreen ( 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 )
randomf ( 0 , 1 ) >= 0.5f ? NextMusic () : PrevMusic ();
else
NextMusic ();
}
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-01-20 08:59:38 +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 )
2002-06-24 22:04:31 +00:00
{
2003-01-03 03:24:00 +00:00
float t = min ( tm , 0.1f );
tm -= t ;
m_fPositionOffsetFromSelection = clamp ( m_fPositionOffsetFromSelection , - 0.3f , + 0.3f );
float fSpringForce = - m_fPositionOffsetFromSelection * LOCKED_INITIAL_VELOCITY ;
m_fLockedWheelVelocity += fSpringForce ;
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
}
}
2002-01-20 08:59:38 +00:00
else
{
2002-06-24 22:04:31 +00:00
// "rotate" wheel toward selected song
float fSpinSpeed ;
2003-01-02 02:59:25 +00:00
if ( m_Moving && m_TimeBeforeMovingBegins == 0 )
fSpinSpeed = m_SpinSpeed ;
2002-06-24 22:04:31 +00:00
else
2002-08-26 05:53:48 +00:00
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-02 02:59:25 +00:00
void MusicWheel :: PrevMusic ()
2002-01-16 10:01:32 +00:00
{
2002-06-24 22:04:31 +00:00
if ( m_WheelState == STATE_LOCKED )
{
2002-08-13 23:26:46 +00:00
m_fLockedWheelVelocity = LOCKED_INITIAL_VELOCITY ;
2002-06-24 22:04:31 +00:00
m_soundLocked . Play ();
return ;
}
if ( fabsf ( m_fPositionOffsetFromSelection ) > 0.5f ) // wheel is busy spinning
return ;
2002-01-20 07:51:09 +00:00
switch ( m_WheelState )
{
2002-06-24 22:04:31 +00:00
case STATE_SELECTING_MUSIC :
2002-06-14 22:25:22 +00:00
case STATE_ROULETTE_SPINNING :
case STATE_ROULETTE_SLOWING_DOWN :
2003-01-03 03:24:00 +00:00
case STATE_RANDOM_SPINNING :
2002-01-20 07:51:09 +00:00
break ; // fall through
default :
return ; // don't fall through
}
2002-01-16 10:01:32 +00:00
2002-02-09 04:30:27 +00:00
// decrement m_iSelection
2003-01-02 02:59:25 +00:00
m_iSelection -- ;
if ( m_iSelection < 0 )
m_iSelection = m_CurWheelItemData . size () - 1 ;
2002-02-06 05:13:39 +00:00
2002-02-09 04:30:27 +00:00
RebuildWheelItemDisplays ();
2002-01-16 10:01:32 +00:00
2002-01-20 08:59:38 +00:00
m_fPositionOffsetFromSelection -= 1 ;
2002-04-28 20:42:32 +00:00
m_soundChangeMusic . Play ();
2002-06-30 23:19:33 +00:00
2003-01-02 02:59:25 +00:00
SCREENMAN -> SendMessageToTopScreen ( SM_SongChanged , 0 );
2002-01-16 10:01:32 +00:00
}
2003-01-02 02:59:25 +00:00
void MusicWheel :: NextMusic ()
2002-01-16 10:01:32 +00:00
{
2002-06-24 22:04:31 +00:00
if ( m_WheelState == STATE_LOCKED )
{
2002-08-13 23:26:46 +00:00
m_fLockedWheelVelocity = - LOCKED_INITIAL_VELOCITY ;
2002-06-24 22:04:31 +00:00
m_soundLocked . Play ();
return ;
}
2002-07-11 19:02:26 +00:00
if ( fabsf ( m_fPositionOffsetFromSelection ) > 0.5f ) // wheel is very busy spinning
2002-06-24 22:04:31 +00:00
return ;
2002-01-18 22:18:41 +00:00
switch ( m_WheelState )
{
2002-06-24 22:04:31 +00:00
case STATE_SELECTING_MUSIC :
2002-06-14 22:25:22 +00:00
case STATE_ROULETTE_SPINNING :
case STATE_ROULETTE_SLOWING_DOWN :
2003-01-03 03:24:00 +00:00
case STATE_RANDOM_SPINNING :
2002-09-06 21:25:07 +00:00
break ;
2002-01-18 22:18:41 +00:00
default :
2002-07-31 19:40:40 +00:00
LOG -> Trace ( "NextMusic() ignored" );
2002-01-18 22:18:41 +00:00
return ; // don't continue
}
2002-01-16 10:01:32 +00:00
2002-02-09 04:30:27 +00:00
// increment m_iSelection
2003-01-02 02:59:25 +00:00
m_iSelection ++ ;
if ( m_iSelection > int ( m_CurWheelItemData . size () - 1 ) )
m_iSelection = 0 ;
2002-02-09 04:30:27 +00:00
RebuildWheelItemDisplays ();
2002-01-16 10:01:32 +00:00
2002-01-20 08:59:38 +00:00
m_fPositionOffsetFromSelection += 1 ;
2003-01-02 02:59:25 +00:00
2002-04-28 20:42:32 +00:00
m_soundChangeMusic . Play ();
2002-06-30 23:19:33 +00:00
2003-01-02 02:59:25 +00:00
SCREENMAN -> SendMessageToTopScreen ( SM_SongChanged , 0 );
2002-01-16 10:01:32 +00:00
}
2002-08-20 21:00:56 +00:00
bool MusicWheel :: PrevSort ()
2002-05-19 01:59:48 +00:00
{
2002-08-20 21:00:56 +00:00
return NextSort ();
2002-05-19 01:59:48 +00:00
}
2002-08-20 21:00:56 +00:00
bool MusicWheel :: NextSort ()
2002-01-16 10:01:32 +00:00
{
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
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
}
2002-06-14 22:25:22 +00:00
bool MusicWheel :: Select () // return true of a playable item was chosen
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 ;
2002-06-14 22:25:22 +00:00
if ( m_WheelState == STATE_ROULETTE_SPINNING )
{
m_WheelState = STATE_ROULETTE_SLOWING_DOWN ;
2003-01-02 02:59:25 +00:00
m_Moving = 0 ;
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-02 02:59:25 +00:00
switch ( m_CurWheelItemData [ m_iSelection ] -> m_WheelItemType )
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-01-02 02:59:25 +00:00
CString sThisItemSectionName = m_CurWheelItemData [ m_iSelection ] -> m_sSectionName ;
2002-01-16 10:01:32 +00:00
if ( m_sExpandedSectionName == sThisItemSectionName ) // already expanded
m_sExpandedSectionName = "" ; // collapse it
else // already collapsed
m_sExpandedSectionName = sThisItemSectionName ; // expand it
2003-01-02 02:59:25 +00:00
SetOpenGroup ( m_sExpandedSectionName );
2002-02-09 04:30:27 +00:00
RebuildWheelItemDisplays ();
2002-01-16 10:01:32 +00:00
2002-04-28 20:42:32 +00:00
m_soundExpand . Play ();
2002-01-16 10:01:32 +00:00
m_iSelection = 0 ; // reset in case we can't find the last selected song
// find the section header and select it
2003-01-02 02:59:25 +00:00
for ( unsigned i = 0 ; i < m_CurWheelItemData . size (); i ++ )
2002-01-16 10:01:32 +00:00
{
2003-01-02 02:59:25 +00:00
if ( m_CurWheelItemData [ i ] -> m_WheelItemType == TYPE_SECTION
&& m_CurWheelItemData [ i ] -> m_sSectionName == sThisItemSectionName )
2002-01-16 10:01:32 +00:00
{
m_iSelection = i ;
break ;
}
}
}
return false ;
2002-05-19 01:59:48 +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 :
{
const RANDOM_SPINS = 5 ;
/* Grab all of the currently-visible data. */
vector < WheelItemData *> & newData = m_CurWheelItemData ;
newData . clear ();
int i ;
/* Add RANDOM_SPINS * 2 worth of random items. */
int total = int ( m_WheelItemDatas [ SORT_ROULETTE ]. size ());
for ( i = 0 ; i < total ; ++ i )
swap ( m_WheelItemDatas [ SORT_ROULETTE ][ i ], m_WheelItemDatas [ SORT_ROULETTE ][ rand () % total ]);
for ( i = 0 ; i < RANDOM_SPINS * 2 ; ++ i )
newData . push_back ( & m_WheelItemDatas [ SORT_ROULETTE ][ i ] );
/* The cursor is on m_WheelItemDisplays[NUM_WHEEL_ITEMS_TO_DRAW/2].
* Fill from 0 to NUM_WHEEL_ITEMS_TO_DRAW, so all of the items
* that were on the screen stay there. However, skip some from
* the beginning to make sure we don't actually *land* on one. */
int fillstart = max ( NUM_WHEEL_ITEMS_TO_DRAW / 2 - RANDOM_SPINS + 1 , 0 );
for ( i = fillstart ; i < NUM_WHEEL_ITEMS_TO_DRAW ; i ++ )
newData . push_back ( m_WheelItemDisplays [ i ]. data );
m_iSelection = newData . size () - NUM_WHEEL_ITEMS_TO_DRAW / 2 - 1 ;
m_Moving = - 1 ;
m_TimeBeforeMovingBegins = 0 ;
m_SpinSpeed = 1.0f / ROULETTE_SWITCH_SECONDS ;
m_iSwitchesLeftInSpinDown = RANDOM_SPINS ;
m_WheelState = STATE_RANDOM_SPINNING ;
RebuildWheelItemDisplays ();
}
return false ;
2002-01-16 10:01:32 +00:00
2002-04-16 17:31:00 +00:00
case TYPE_SONG :
2002-01-16 10:01:32 +00:00
default :
return true ;
}
}
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 ));
2002-08-20 21:00:56 +00:00
}
2003-01-03 03:24:00 +00:00
void MusicWheel :: SetOpenGroup ( CString group , SongSortOrder so )
2002-08-20 21:00:56 +00:00
{
2003-01-03 03:24:00 +00:00
if ( so == NUM_SORT_ORDERS )
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 )
{
if (( from [ i ]. m_WheelItemType == TYPE_SONG ||
from [ i ]. m_WheelItemType == TYPE_COURSE ) &&
! from [ i ]. m_sSectionName . empty () &&
from [ i ]. m_sSectionName != group )
continue ;
m_CurWheelItemData . push_back ( & from [ i ]);
}
m_iSelection = 0 ;
for ( i = 0 ; i < m_CurWheelItemData . size (); ++ i )
{
if ( m_CurWheelItemData [ i ] == old )
m_iSelection = i ;
}
2003-01-03 03:24:00 +00:00
RebuildWheelItemDisplays ();
2002-08-20 21:00:56 +00:00
}
2003-01-02 02:59:25 +00:00
bool MusicWheel :: IsRouletting () const
2002-02-09 04:30:27 +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 ;
2003-01-02 02:59:25 +00:00
}
int MusicWheel :: IsMoving () const
{
if ( ! m_Moving ) return false ;
return m_TimeBeforeMovingBegins == 0 ;
}
void MusicWheel :: TweenOnScreen ( bool changing_sort )
{
float factor = 1.0f ;
if ( changing_sort ) factor = 0.25 ;
2002-02-07 02:16:14 +00:00
m_WheelState = STATE_TWEENING_ON_SCREEN ;
2002-05-28 20:01:22 +00:00
2003-01-02 02:59:25 +00:00
float fX = GetBannerX ( 0 ), fY = GetBannerY ( 0 );
2002-05-29 09:47:24 +00:00
2002-08-13 23:26:46 +00:00
m_sprSelectionOverlay . SetXY ( fX + 320 , fY );
2003-01-02 02:59:25 +00:00
if ( changing_sort ) {
m_sprSelectionOverlay . BeginTweening ( 0.04f * NUM_WHEEL_ITEMS_TO_DRAW / 2 * factor ); // sleep
m_sprSelectionOverlay . BeginTweening ( 0.2f * factor , Actor :: TWEEN_BIAS_BEGIN );
} else {
m_sprSelectionOverlay . BeginTweening ( 0.05f * factor ); // sleep
m_sprSelectionOverlay . BeginTweening ( 0.4f * factor , Actor :: TWEEN_BIAS_BEGIN );
}
2002-08-13 23:26:46 +00:00
m_sprSelectionOverlay . SetTweenX ( 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
m_ScrollBar . BeginTweening ( 0.2f * factor , Actor :: TWEEN_BIAS_BEGIN );
2002-08-31 06:43:28 +00:00
m_ScrollBar . SetTweenX ( SCROLL_BAR_X );
2002-05-28 20:01:22 +00:00
for ( int i = 0 ; i < NUM_WHEEL_ITEMS_TO_DRAW ; i ++ )
{
WheelItemDisplay & display = m_WheelItemDisplays [ i ];
float fThisBannerPositionOffsetFromSelection = i - NUM_WHEEL_ITEMS_TO_DRAW / 2 + m_fPositionOffsetFromSelection ;
float fX = GetBannerX ( fThisBannerPositionOffsetFromSelection );
float fY = GetBannerY ( fThisBannerPositionOffsetFromSelection );
display . SetXY ( fX + 320 , fY );
2003-01-02 02:59:25 +00:00
display . BeginTweening ( 0.04f * i * factor ); // sleep
display . BeginTweening ( 0.2f * factor , Actor :: TWEEN_BIAS_BEGIN );
2002-05-28 20:01:22 +00:00
display . SetTweenX ( fX );
}
2003-01-02 02:59:25 +00:00
m_fTimeLeftInState = TweenTime () + 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
2002-05-29 09:47:24 +00:00
float fX , fY ;
fX = GetBannerX ( 0 );
fY = GetBannerY ( 0 );
2002-08-13 23:26:46 +00:00
m_sprSelectionOverlay . SetXY ( fX , fY );
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. */
m_sprSelectionOverlay . BeginTweening ( 0.04f * NUM_WHEEL_ITEMS_TO_DRAW / 2 * factor ); // sleep
m_sprSelectionOverlay . BeginTweening ( 0.2f * factor , Actor :: TWEEN_BIAS_END );
} else {
m_sprSelectionOverlay . BeginTweening ( 0 ); // sleep
m_sprSelectionOverlay . BeginTweening ( 0.2f * factor , Actor :: TWEEN_BIAS_END );
}
2002-08-13 23:26:46 +00:00
m_sprSelectionOverlay . SetTweenX ( fX + 320 );
2002-05-29 09:47:24 +00:00
2002-09-02 21:59:58 +00:00
m_ScrollBar . BeginTweening ( 0 );
2003-01-02 02:59:25 +00:00
m_ScrollBar . BeginTweening ( 0.2f * factor , Actor :: TWEEN_BIAS_BEGIN );
2002-08-31 06:43:28 +00:00
m_ScrollBar . SetTweenX ( SCROLL_BAR_X + 30 );
2002-05-28 20:01:22 +00:00
for ( int i = 0 ; i < NUM_WHEEL_ITEMS_TO_DRAW ; i ++ )
{
WheelItemDisplay & display = m_WheelItemDisplays [ i ];
float fThisBannerPositionOffsetFromSelection = i - NUM_WHEEL_ITEMS_TO_DRAW / 2 + m_fPositionOffsetFromSelection ;
float fX = GetBannerX ( fThisBannerPositionOffsetFromSelection );
float fY = GetBannerY ( fThisBannerPositionOffsetFromSelection );
display . SetXY ( fX , fY );
2003-01-02 02:59:25 +00:00
display . BeginTweening ( 0.04f * i * factor ); // sleep
display . BeginTweening ( 0.2f * factor , Actor :: TWEEN_BIAS_END );
2002-05-28 20:01:22 +00:00
display . SetTweenX ( fX + 320 );
}
2003-01-02 02:59:25 +00:00
m_fTimeLeftInState = TweenTime () + 0.100f ;
2002-06-24 22:04:31 +00:00
}
2002-12-30 21:57:54 +00:00
CString MusicWheel :: GetSectionNameFromSongAndSort ( Song * pSong , SongSortOrder so )
{
if ( pSong == NULL )
return "" ;
CString sTemp ;
switch ( so )
{
case SORT_GROUP :
sTemp = pSong -> m_sGroupName ;
return sTemp ;
// case SORT_ARTIST:
// sTemp = pSong->m_sArtist;
// sTemp.MakeUpper();
// sTemp = (sTemp.GetLength() > 0) ? sTemp.Left(1) : "";
// if( IsAnInt(sTemp) )
// sTemp = "NUM";
// return sTemp;
case SORT_TITLE :
sTemp = pSong -> GetSortTitle ();
sTemp . MakeUpper ();
sTemp = ( sTemp . GetLength () > 0 ) ? sTemp . Left ( 1 ) : "" ;
if ( IsAnInt ( sTemp ) )
sTemp = "NUM" ;
return sTemp ;
case SORT_BPM :
case SORT_MOST_PLAYED :
default :
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-02 02:59:25 +00:00
/* Give us one last chance to move. This will ensure that we're at least
* 0.5f from the selection, so we have a chance to spin down smoothly. */
Update ( 0 );
2002-12-30 22:40:34 +00:00
2003-01-02 02:59:25 +00:00
bool Stopping = ( m_Moving != 0 && n == 0 && m_TimeBeforeMovingBegins == 0 );
m_TimeBeforeMovingBegins = TIME_BEFORE_SLOW_REPEATS ;
m_SpinSpeed = 1.0f / FAST_SPIN_SWITCH_SECONDS ;
m_Moving = n ;
if ( Stopping )
{
/* Make sure the user always gets an SM_SongChanged when
* Moving() is 0, so the final banner, etc. always get set. */
SCREENMAN -> SendMessageToTopScreen ( SM_SongChanged , 0 );
} else {
if ( n == 1 )
NextMusic ();
else if ( n == - 1 )
PrevMusic ();
}
2002-12-30 22:40:34 +00:00
}