Abstracted wheel and items from WheelBase and WheelBaseItems
This commit is contained in:
+46
-361
@@ -91,36 +91,8 @@ void MusicWheel::Load( CString sType )
|
||||
{
|
||||
LOG->Trace( "MusicWheel::Load('%s')", sType.c_str() );
|
||||
|
||||
SWITCH_SECONDS .Load(sType,"SwitchSeconds");
|
||||
ROULETTE_SWITCH_SECONDS .Load(sType,"RouletteSwitchSeconds");
|
||||
ROULETTE_SLOW_DOWN_SWITCHES .Load(sType,"RouletteSlowDownSwitches");
|
||||
LOCKED_INITIAL_VELOCITY .Load(sType,"LockedInitialVelocity");
|
||||
SCROLL_BAR_X .Load(sType,"ScrollBarX");
|
||||
SCROLL_BAR_HEIGHT .Load(sType,"ScrollBarHeight");
|
||||
ITEM_CURVE_X .Load(sType,"ItemCurveX");
|
||||
USE_LINEAR_WHEEL .Load(sType,"NoCurving");
|
||||
ITEM_SPACING_Y .Load(sType,"ItemSpacingY");
|
||||
WHEEL_3D_RADIUS .Load(sType,"Wheel3DRadius");
|
||||
CIRCLE_PERCENT .Load(sType,"CirclePercent");
|
||||
NUM_SECTION_COLORS .Load(sType,"NumSectionColors");
|
||||
SONG_REAL_EXTRA_COLOR .Load(sType,"SongRealExtraColor");
|
||||
SORT_MENU_COLOR .Load(sType,"SortMenuColor");
|
||||
SHOW_ROULETTE .Load(sType,"ShowRoulette");
|
||||
SHOW_RANDOM .Load(sType,"ShowRandom");
|
||||
SHOW_PORTAL .Load(sType,"ShowPortal");
|
||||
USE_3D .Load(sType,"Use3D");
|
||||
NUM_WHEEL_ITEMS_TO_DRAW .Load(sType,"NumWheelItems");
|
||||
MOST_PLAYED_SONGS_TO_SHOW .Load(sType,"MostPlayedSongsToShow");
|
||||
MODE_MENU_CHOICE_NAMES .Load(sType,"ModeMenuChoiceNames");
|
||||
vector<CString> vsModeChoiceNames;
|
||||
split( MODE_MENU_CHOICE_NAMES, ",", vsModeChoiceNames );
|
||||
CHOICE .Load(sType,CHOICE_NAME,vsModeChoiceNames);
|
||||
WHEEL_ITEM_ON_DELAY_CENTER .Load(sType,"WheelItemOnDelayCenter");
|
||||
WHEEL_ITEM_ON_DELAY_OFFSET .Load(sType,"WheelItemOnDelayOffset");
|
||||
WHEEL_ITEM_OFF_DELAY_CENTER .Load(sType,"WheelItemOffDelayCenter");
|
||||
WHEEL_ITEM_OFF_DELAY_OFFSET .Load(sType,"WheelItemOffDelayOffset");
|
||||
SECTION_COLORS .Load(sType,SECTION_COLORS_NAME,NUM_SECTION_COLORS);
|
||||
|
||||
LoadFromMetrics( sType );
|
||||
LoadVariables();
|
||||
|
||||
FOREACH( MusicWheelItem*, m_MusicWheelItems, i )
|
||||
SAFE_DELETE( *i );
|
||||
@@ -143,31 +115,12 @@ void MusicWheel::Load( CString sType )
|
||||
if( GAMESTATE->m_CurStyle == NULL )
|
||||
GAMESTATE->m_CurStyle = GAMEMAN->STYLE_DANCE_SINGLE;
|
||||
*/
|
||||
|
||||
m_sprHighlight.Load( THEME->GetPathG(sType,"highlight") );
|
||||
m_sprHighlight->SetName( "Highlight" );
|
||||
this->AddChild( m_sprHighlight );
|
||||
ActorUtil::OnCommand( m_sprHighlight, sType );
|
||||
|
||||
m_ScrollBar.SetX( SCROLL_BAR_X );
|
||||
m_ScrollBar.SetBarHeight( SCROLL_BAR_HEIGHT );
|
||||
this->AddChild( &m_ScrollBar );
|
||||
|
||||
/* We play a lot of this one, so precache it. */
|
||||
m_soundChangeMusic.Load( THEME->GetPathS(sType,"change"), true );
|
||||
m_soundChangeSort.Load( THEME->GetPathS(sType,"sort") );
|
||||
m_soundExpand.Load( THEME->GetPathS(sType,"expand"), true );
|
||||
m_soundLocked.Load( THEME->GetPathS(sType,"locked"), true );
|
||||
|
||||
|
||||
m_iSelection = 0;
|
||||
|
||||
m_WheelState = STATE_SELECTING_MUSIC;
|
||||
m_fTimeLeftInState = 0;
|
||||
m_fPositionOffsetFromSelection = 0;
|
||||
|
||||
m_iSwitchesLeftInSpinDown = 0;
|
||||
m_Moving = 0;
|
||||
|
||||
if( GAMESTATE->IsExtraStage() || GAMESTATE->IsExtraStage2() )
|
||||
{
|
||||
@@ -265,6 +218,26 @@ void MusicWheel::Load( CString sType )
|
||||
RebuildAllMusicWheelItems();
|
||||
}
|
||||
|
||||
void MusicWheel::LoadFromMetrics( CString sType )
|
||||
{
|
||||
WheelBase::LoadFromMetrics(sType);
|
||||
|
||||
ROULETTE_SWITCH_SECONDS .Load(sType,"RouletteSwitchSeconds");
|
||||
ROULETTE_SLOW_DOWN_SWITCHES .Load(sType,"RouletteSlowDownSwitches");
|
||||
NUM_SECTION_COLORS .Load(sType,"NumSectionColors");
|
||||
SONG_REAL_EXTRA_COLOR .Load(sType,"SongRealExtraColor");
|
||||
SORT_MENU_COLOR .Load(sType,"SortMenuColor");
|
||||
SHOW_ROULETTE .Load(sType,"ShowRoulette");
|
||||
SHOW_RANDOM .Load(sType,"ShowRandom");
|
||||
SHOW_PORTAL .Load(sType,"ShowPortal");
|
||||
MOST_PLAYED_SONGS_TO_SHOW .Load(sType,"MostPlayedSongsToShow");
|
||||
MODE_MENU_CHOICE_NAMES .Load(sType,"ModeMenuChoiceNames");
|
||||
vector<CString> vsModeChoiceNames;
|
||||
split( MODE_MENU_CHOICE_NAMES, ",", vsModeChoiceNames );
|
||||
CHOICE .Load(sType,CHOICE_NAME,vsModeChoiceNames);
|
||||
SECTION_COLORS .Load(sType,SECTION_COLORS_NAME,NUM_SECTION_COLORS);
|
||||
}
|
||||
|
||||
MusicWheel::~MusicWheel()
|
||||
{
|
||||
FOREACH( MusicWheelItem*, m_MusicWheelItems, i )
|
||||
@@ -305,7 +278,7 @@ bool MusicWheel::SelectSection( const CString & SectionName )
|
||||
unsigned int i;
|
||||
for( i=0; i<m_CurWheelItemData.size(); i++ )
|
||||
{
|
||||
if( m_CurWheelItemData[i]->m_sSectionName == SectionName )
|
||||
if( m_CurWheelItemData[i]->m_sText == SectionName )
|
||||
{
|
||||
m_iSelection = i; // select it
|
||||
break;
|
||||
@@ -328,7 +301,7 @@ bool MusicWheel::SelectSong( Song *p )
|
||||
if( from[i].m_pSong == p )
|
||||
{
|
||||
// make its group the currently expanded group
|
||||
SetOpenGroup(from[i].m_sSectionName);
|
||||
SetOpenGroup(from[i].m_sText);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -358,7 +331,7 @@ bool MusicWheel::SelectCourse( Course *p )
|
||||
if( from[i].m_pCourse == p )
|
||||
{
|
||||
// make its group the currently expanded group
|
||||
SetOpenGroup(from[i].m_sSectionName);
|
||||
SetOpenGroup(from[i].m_sText);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -390,7 +363,7 @@ bool MusicWheel::SelectModeMenuItem()
|
||||
return false;
|
||||
|
||||
// make its group the currently expanded group
|
||||
SetOpenGroup( from[i].m_sSectionName );
|
||||
SetOpenGroup( from[i].m_sText );
|
||||
|
||||
for( i=0; i<m_CurWheelItemData.size(); i++ )
|
||||
{
|
||||
@@ -402,21 +375,7 @@ bool MusicWheel::SelectModeMenuItem()
|
||||
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
bool MusicWheel::ScrollToItem( CString Item )
|
||||
{
|
||||
for ( int i=0;i<m_CurWheelItemData.length();i++ )
|
||||
if ( m_CurWheelItemData[i].m_sSectionName == Item )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if ( i == m_CurWheelItemData.length() )
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
void MusicWheel::GetSongList(vector<Song*> &arraySongs, SortOrder so, CString sPreferredGroup )
|
||||
{
|
||||
vector<Song*> apAllSongs;
|
||||
@@ -792,52 +751,6 @@ void MusicWheel::BuildWheelItemDatas( vector<WheelItemData> &arrayWheelItemDatas
|
||||
}
|
||||
}
|
||||
|
||||
void MusicWheel::GetItemPosition( float fPosOffsetsFromMiddle, float& fX_out, float& fY_out, float& fZ_out, float& fRotationX_out )
|
||||
{
|
||||
if( USE_3D )
|
||||
{
|
||||
const float curve = CIRCLE_PERCENT*2*PI;
|
||||
fRotationX_out = SCALE(fPosOffsetsFromMiddle,-NUM_WHEEL_ITEMS/2.0f,+NUM_WHEEL_ITEMS/2.0f,-curve/2.f,+curve/2.f);
|
||||
fX_out = (1-RageFastCos(fPosOffsetsFromMiddle/PI))*ITEM_CURVE_X;
|
||||
fY_out = WHEEL_3D_RADIUS*RageFastSin(fRotationX_out);
|
||||
fZ_out = -100+WHEEL_3D_RADIUS*RageFastCos(fRotationX_out);
|
||||
fRotationX_out *= 180.f/PI; // to degrees
|
||||
|
||||
// printf( "fRotationX_out = %f\n", fRotationX_out );
|
||||
}
|
||||
else if(!USE_LINEAR_WHEEL)
|
||||
{
|
||||
fX_out = (1-RageFastCos(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 );
|
||||
}
|
||||
else
|
||||
{
|
||||
fX_out = fPosOffsetsFromMiddle*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 );
|
||||
}
|
||||
}
|
||||
|
||||
void MusicWheel::SetItemPosition( Actor &item, float fPosOffsetsFromMiddle )
|
||||
{
|
||||
float fX, fY, fZ, fRotationX;
|
||||
GetItemPosition( fPosOffsetsFromMiddle, fX, fY, fZ, fRotationX );
|
||||
item.SetXY( fX, fY );
|
||||
item.SetZ( fZ );
|
||||
item.SetRotationX( fRotationX );
|
||||
}
|
||||
|
||||
void MusicWheel::RebuildAllMusicWheelItems()
|
||||
{
|
||||
RebuildMusicWheelItems( INT_MAX );
|
||||
@@ -869,7 +782,7 @@ void MusicWheel::RebuildMusicWheelItems( int dist )
|
||||
WheelItemData *data = m_CurWheelItemData[iIndex];
|
||||
MusicWheelItem *display = m_MusicWheelItems[i];
|
||||
|
||||
bool bExpanded = (data->m_Type == TYPE_SECTION) ? (data->m_sSectionName == m_sExpandedSectionName) : false;
|
||||
bool bExpanded = (data->m_Type == TYPE_SECTION) ? (data->m_sText == m_sExpandedSectionName) : false;
|
||||
display->LoadFromWheelItemData( data, bExpanded );
|
||||
}
|
||||
}
|
||||
@@ -887,7 +800,7 @@ void MusicWheel::RebuildMusicWheelItems( int dist )
|
||||
WheelItemData *data = m_CurWheelItemData[iIndex];
|
||||
MusicWheelItem *display = m_MusicWheelItems[i];
|
||||
|
||||
bool bExpanded = (data->m_Type == TYPE_SECTION) ? (data->m_sSectionName == m_sExpandedSectionName) : false;
|
||||
bool bExpanded = (data->m_Type == TYPE_SECTION) ? (data->m_sText == m_sExpandedSectionName) : false;
|
||||
display->LoadFromWheelItemData( data, bExpanded );
|
||||
}
|
||||
}
|
||||
@@ -901,7 +814,7 @@ void MusicWheel::RebuildMusicWheelItems( int dist )
|
||||
WheelItemData *data = m_CurWheelItemData[iIndex];
|
||||
MusicWheelItem *display = m_MusicWheelItems[i];
|
||||
|
||||
bool bExpanded = (data->m_Type == TYPE_SECTION) ? (data->m_sSectionName == m_sExpandedSectionName) : false;
|
||||
bool bExpanded = (data->m_Type == TYPE_SECTION) ? (data->m_sText == m_sExpandedSectionName) : false;
|
||||
display->LoadFromWheelItemData( data, bExpanded );
|
||||
}
|
||||
}
|
||||
@@ -917,40 +830,6 @@ void MusicWheel::NotesOrTrailChanged( PlayerNumber pn ) // update grade graphics
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void MusicWheel::DrawPrimitives()
|
||||
{
|
||||
if( USE_3D )
|
||||
{
|
||||
// DISPLAY->PushMatrix();
|
||||
// DISPLAY->EnterPerspective(45, false);
|
||||
|
||||
// construct view and project matrix
|
||||
// RageVector3 Up( 0.0f, 1.0f, 0.0f );
|
||||
// RageVector3 Eye( SCREEN_CENTER_X, SCREEN_CENTER_Y, 550 );
|
||||
// RageVector3 At( SCREEN_CENTER_X, SCREEN_CENTER_Y, 0 );
|
||||
|
||||
// DISPLAY->LookAt(Eye, At, Up);
|
||||
}
|
||||
|
||||
// draw outside->inside
|
||||
for( int i=0; i<NUM_WHEEL_ITEMS/2; i++ )
|
||||
DrawItem( i );
|
||||
for( int i=NUM_WHEEL_ITEMS-1; i>=NUM_WHEEL_ITEMS/2; i-- )
|
||||
DrawItem( i );
|
||||
|
||||
|
||||
ActorFrame::DrawPrimitives();
|
||||
|
||||
if( USE_3D )
|
||||
{
|
||||
// DISPLAY->ExitPerspective();
|
||||
// DISPLAY->PopMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MusicWheel::DrawItem( int i )
|
||||
{
|
||||
MusicWheelItem *display = m_MusicWheelItems[i];
|
||||
@@ -965,36 +844,13 @@ void MusicWheel::DrawItem( int i )
|
||||
case STATE_ROULETTE_SPINNING:
|
||||
case STATE_ROULETTE_SLOWING_DOWN:
|
||||
case STATE_RANDOM_SPINNING:
|
||||
case STATE_LOCKED:
|
||||
{
|
||||
SetItemPosition( *display, fThisBannerPositionOffsetFromSelection );
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if( m_WheelState == STATE_LOCKED && i != NUM_WHEEL_ITEMS/2 )
|
||||
display->m_fPercentGray = 0.5f;
|
||||
else
|
||||
display->m_fPercentGray = 0;
|
||||
|
||||
display->Draw();
|
||||
}
|
||||
|
||||
|
||||
void MusicWheel::UpdateScrollbar()
|
||||
{
|
||||
int total_num_items = m_CurWheelItemData.size();
|
||||
float item_at=m_iSelection - m_fPositionOffsetFromSelection;
|
||||
|
||||
if(NUM_WHEEL_ITEMS >= total_num_items) {
|
||||
m_ScrollBar.SetPercentage( 0, 1 );
|
||||
} else {
|
||||
float size = float(NUM_WHEEL_ITEMS) / total_num_items;
|
||||
float center = item_at / total_num_items;
|
||||
size *= 0.5f;
|
||||
|
||||
m_ScrollBar.SetPercentage( center - size, center + size );
|
||||
}
|
||||
WheelBase::DrawItem(i, display, fThisBannerPositionOffsetFromSelection);
|
||||
}
|
||||
|
||||
bool MusicWheel::IsSettled() const
|
||||
@@ -1009,30 +865,17 @@ bool MusicWheel::IsSettled() const
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void MusicWheel::Update( float fDeltaTime )
|
||||
void MusicWheel::UpdateItems(float fDeltaTime )
|
||||
{
|
||||
ActorFrame::Update( fDeltaTime );
|
||||
|
||||
for( unsigned i=0; i<unsigned(NUM_WHEEL_ITEMS); i++ )
|
||||
{
|
||||
MusicWheelItem *display = m_MusicWheelItems[i];
|
||||
|
||||
display->Update( fDeltaTime );
|
||||
}
|
||||
}
|
||||
|
||||
UpdateScrollbar();
|
||||
|
||||
if( m_Moving )
|
||||
{
|
||||
m_TimeBeforeMovingBegins -= fDeltaTime;
|
||||
m_TimeBeforeMovingBegins = max(m_TimeBeforeMovingBegins, 0);
|
||||
}
|
||||
|
||||
// update wheel state
|
||||
m_fTimeLeftInState -= fDeltaTime;
|
||||
if( m_fTimeLeftInState <= 0 ) // time to go to a new state
|
||||
{
|
||||
void MusicWheel::UpdateSwitch() {
|
||||
switch( m_WheelState )
|
||||
{
|
||||
case STATE_FLYING_OFF_BEFORE_NEXT_SORT:
|
||||
@@ -1147,85 +990,8 @@ void MusicWheel::Update( float fDeltaTime )
|
||||
ASSERT(0); // all state changes should be handled explicitly
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( m_WheelState == STATE_LOCKED )
|
||||
{
|
||||
/* 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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
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();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// "rotate" wheel toward selected song
|
||||
float fSpinSpeed = 0.2f + fabsf(m_fPositionOffsetFromSelection)/SWITCH_SECONDS;
|
||||
|
||||
if( m_fPositionOffsetFromSelection > 0 )
|
||||
{
|
||||
m_fPositionOffsetFromSelection -= fSpinSpeed*fDeltaTime;
|
||||
if( m_fPositionOffsetFromSelection < 0 )
|
||||
m_fPositionOffsetFromSelection = 0;
|
||||
}
|
||||
else if( m_fPositionOffsetFromSelection < 0 )
|
||||
{
|
||||
m_fPositionOffsetFromSelection += fSpinSpeed*fDeltaTime;
|
||||
if( m_fPositionOffsetFromSelection > 0 )
|
||||
m_fPositionOffsetFromSelection = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MusicWheel::ChangeMusic(int dist)
|
||||
{
|
||||
m_iSelection += dist;
|
||||
@@ -1237,11 +1003,12 @@ void MusicWheel::ChangeMusic(int dist)
|
||||
|
||||
SCREENMAN->PostMessageToTopScreen( SM_SongChanged, 0 );
|
||||
|
||||
/* If we're moving automatically, don't play this; it'll be called in Update. */
|
||||
/* If we're moving automatically, don't play this; it'll be called in Update.*/
|
||||
if(!IsMoving())
|
||||
m_soundChangeMusic.Play();
|
||||
}
|
||||
|
||||
|
||||
bool MusicWheel::ChangeSort( SortOrder new_so ) // return true if change successful
|
||||
{
|
||||
ASSERT( new_so < NUM_SORT_ORDERS );
|
||||
@@ -1334,7 +1101,7 @@ bool MusicWheel::Select() // return true if this selection ends the screen
|
||||
{
|
||||
case TYPE_SECTION:
|
||||
{
|
||||
CString sThisItemSectionName = m_CurWheelItemData[m_iSelection]->m_sSectionName;
|
||||
CString sThisItemSectionName = m_CurWheelItemData[m_iSelection]->m_sText;
|
||||
if( m_sExpandedSectionName == sThisItemSectionName ) // already expanded
|
||||
m_sExpandedSectionName = ""; // collapse it
|
||||
else // already collapsed
|
||||
@@ -1420,8 +1187,8 @@ void MusicWheel::SetOpenGroup(CString group, SortOrder so)
|
||||
{
|
||||
WheelItemData &d = from[i];
|
||||
if( (d.m_Type == TYPE_SONG || d.m_Type == TYPE_COURSE) &&
|
||||
!d.m_sSectionName.empty() &&
|
||||
d.m_sSectionName != group )
|
||||
!d.m_sText.empty() &&
|
||||
d.m_sText != group )
|
||||
continue;
|
||||
|
||||
/* Only show tutorial songs in arcade */
|
||||
@@ -1457,37 +1224,8 @@ bool MusicWheel::IsRouletting() const
|
||||
m_WheelState == STATE_RANDOM_SPINNING;
|
||||
}
|
||||
|
||||
int MusicWheel::IsMoving() const
|
||||
{
|
||||
return m_Moving && m_TimeBeforeMovingBegins == 0;
|
||||
}
|
||||
|
||||
void MusicWheel::TweenOnScreen(bool changing_sort)
|
||||
{
|
||||
m_WheelState = STATE_TWEENING_ON_SCREEN;
|
||||
|
||||
SetItemPosition( *m_sprHighlight, 0 );
|
||||
|
||||
COMMAND( m_sprHighlight, "StartOn");
|
||||
if( changing_sort )
|
||||
{
|
||||
const float delay = fabsf(NUM_WHEEL_ITEMS/2-WHEEL_ITEM_ON_DELAY_CENTER) * WHEEL_ITEM_ON_DELAY_OFFSET;
|
||||
m_sprHighlight->BeginTweening( delay ); // sleep
|
||||
COMMAND( m_sprHighlight, "FinishOnSort");
|
||||
} else {
|
||||
COMMAND( m_sprHighlight, "FinishOn");
|
||||
}
|
||||
|
||||
m_ScrollBar.SetX( SCROLL_BAR_X );
|
||||
m_ScrollBar.AddX( 30 );
|
||||
if(changing_sort)
|
||||
m_ScrollBar.BeginTweening( 0.2f ); // sleep
|
||||
else
|
||||
m_ScrollBar.BeginTweening( 0.7f ); // sleep
|
||||
m_ScrollBar.BeginTweening( 0.2f , Actor::TWEEN_ACCELERATE );
|
||||
m_ScrollBar.AddX( -30 );
|
||||
|
||||
for( int i=0; i<NUM_WHEEL_ITEMS; i++ )
|
||||
void MusicWheel::TweenOnScreenUpdateItems(bool changing_sort) {
|
||||
for( int i=0; i<NUM_WHEEL_ITEMS; i++ )
|
||||
{
|
||||
MusicWheelItem *display = m_MusicWheelItems[i];
|
||||
float fThisBannerPositionOffsetFromSelection = i - NUM_WHEEL_ITEMS/2 + m_fPositionOffsetFromSelection;
|
||||
@@ -1500,36 +1238,9 @@ void MusicWheel::TweenOnScreen(bool changing_sort)
|
||||
if( changing_sort )
|
||||
display->HurryTweening( 0.25f );
|
||||
}
|
||||
|
||||
if( changing_sort )
|
||||
HurryTweening( 0.25f );
|
||||
|
||||
m_fTimeLeftInState = GetTweenTimeLeft() + 0.100f;
|
||||
}
|
||||
|
||||
void MusicWheel::TweenOffScreen(bool changing_sort)
|
||||
{
|
||||
m_WheelState = STATE_TWEENING_OFF_SCREEN;
|
||||
|
||||
SetItemPosition( *m_sprHighlight, 0 );
|
||||
|
||||
COMMAND( m_sprHighlight, "StartOff");
|
||||
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. */
|
||||
const float delay = fabsf(NUM_WHEEL_ITEMS/2-WHEEL_ITEM_ON_DELAY_CENTER) * WHEEL_ITEM_ON_DELAY_OFFSET;
|
||||
m_sprHighlight->BeginTweening( delay ); // sleep
|
||||
COMMAND( m_sprHighlight, "FinishOffSort");
|
||||
} else {
|
||||
COMMAND( m_sprHighlight, "FinishOff");
|
||||
}
|
||||
COMMAND( m_sprHighlight, "FinishOff");
|
||||
|
||||
m_ScrollBar.BeginTweening( 0 );
|
||||
m_ScrollBar.BeginTweening( 0.2f, Actor::TWEEN_ACCELERATE );
|
||||
m_ScrollBar.SetX( SCROLL_BAR_X+30 );
|
||||
|
||||
void MusicWheel::TweenOffScreenUpdateItems(bool changing_sort) {
|
||||
for( int i=0; i<NUM_WHEEL_ITEMS; i++ )
|
||||
{
|
||||
MusicWheelItem *display = m_MusicWheelItems[i];
|
||||
@@ -1543,29 +1254,9 @@ void MusicWheel::TweenOffScreen(bool changing_sort)
|
||||
if( changing_sort )
|
||||
display->HurryTweening( 0.25f );
|
||||
}
|
||||
|
||||
if( changing_sort )
|
||||
HurryTweening( 0.25f );
|
||||
|
||||
m_fTimeLeftInState = GetTweenTimeLeft() + 0.100f;
|
||||
}
|
||||
|
||||
void MusicWheel::Move(int n)
|
||||
{
|
||||
if(n == m_Moving)
|
||||
return;
|
||||
|
||||
if( m_WheelState == STATE_LOCKED )
|
||||
{
|
||||
if(n)
|
||||
{
|
||||
int iSign = n/abs(n);
|
||||
m_fLockedWheelVelocity = iSign*LOCKED_INITIAL_VELOCITY;
|
||||
m_soundLocked.Play();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool MusicWheel::MoveSpecific(int n) {
|
||||
/* If we're not selecting, discard this. We won't ignore it; we'll
|
||||
* get called again every time the key is repeated. */
|
||||
/* Still process Move(0) so we sometimes continue moving immediate
|
||||
@@ -1578,10 +1269,10 @@ void MusicWheel::Move(int n)
|
||||
case STATE_FLYING_OFF_BEFORE_NEXT_SORT:
|
||||
case STATE_FLYING_ON_AFTER_NEXT_SORT:
|
||||
if( n!= 0 )
|
||||
return;
|
||||
return false;
|
||||
break;
|
||||
default:
|
||||
return; // don't continue
|
||||
return false; // don't continue
|
||||
}
|
||||
|
||||
if(m_Moving != 0 && n == 0 && m_TimeBeforeMovingBegins == 0)
|
||||
@@ -1596,13 +1287,7 @@ void MusicWheel::Move(int n)
|
||||
* Moving() is 0, so the final banner, etc. always gets set. */
|
||||
SCREENMAN->PostMessageToTopScreen( SM_SongChanged, 0 );
|
||||
}
|
||||
|
||||
m_TimeBeforeMovingBegins = 1/4.0f;
|
||||
m_SpinSpeed = float(PREFSMAN->m_iMusicWheelSwitchSpeed);
|
||||
m_Moving = n;
|
||||
|
||||
if(m_Moving)
|
||||
ChangeMusic(m_Moving);
|
||||
return true;
|
||||
}
|
||||
|
||||
Song* MusicWheel::GetSelectedSong()
|
||||
@@ -1663,7 +1348,7 @@ Song *MusicWheel::GetPreferredSelectionForRandomOrPortal()
|
||||
|
||||
Song* pSong = wid[iSelection].m_pSong;
|
||||
|
||||
if( !sPreferredGroup.empty() && wid[iSelection].m_sSectionName != sPreferredGroup )
|
||||
if( !sPreferredGroup.empty() && wid[iSelection].m_sText != sPreferredGroup )
|
||||
continue;
|
||||
|
||||
// There's an off possibility that somebody might have only one song with only beginner steps.
|
||||
|
||||
+20
-68
@@ -15,51 +15,40 @@
|
||||
#include "RageTimer.h"
|
||||
#include "MusicWheelItem.h"
|
||||
#include "ThemeMetric.h"
|
||||
#include "WheelBase.h"
|
||||
|
||||
class Course;
|
||||
class Song;
|
||||
|
||||
struct CompareSongPointerArrayBySectionName;
|
||||
|
||||
class MusicWheel : public ActorFrame
|
||||
class MusicWheel : public WheelBase
|
||||
{
|
||||
friend struct CompareSongPointerArrayBySectionName;
|
||||
|
||||
public:
|
||||
MusicWheel();
|
||||
~MusicWheel();
|
||||
void Load( CString sType );
|
||||
virtual void Load( CString sType );
|
||||
|
||||
virtual void Update( float fDeltaTime );
|
||||
virtual void DrawPrimitives();
|
||||
void DrawItem( int index );
|
||||
virtual void DrawItem( int index );
|
||||
|
||||
virtual void TweenOnScreen(bool changing_sort);
|
||||
virtual void TweenOffScreen(bool changing_sort);
|
||||
virtual void TweenOnScreen() { TweenOnScreen(false); }
|
||||
virtual void TweenOffScreen() { TweenOffScreen(false); }
|
||||
|
||||
void Move(int n);
|
||||
bool ChangeSort( SortOrder new_so ); // return true if change successful
|
||||
bool NextSort(); // return true if change successful
|
||||
void StartRoulette();
|
||||
void StartRandom();
|
||||
bool IsRouletting() const;
|
||||
/* Return true if we're moving fast automatically. */
|
||||
int IsMoving() const;
|
||||
bool IsSettled() const;
|
||||
|
||||
virtual bool IsSettled() const;
|
||||
|
||||
void NotesOrTrailChanged( PlayerNumber pn ); // update grade graphics and top score
|
||||
|
||||
void GetItemPosition( float fPosOffsetsFromMiddle, float& fX_out, float& fY_out, float& fZ_out, float& fRotationX_out );
|
||||
void SetItemPosition( Actor &item, float fPosOffsetsFromMiddle );
|
||||
|
||||
bool Select(); // return true if this selection ends the screen
|
||||
virtual bool Select(); // return true if this selection ends the screen
|
||||
WheelItemType GetSelectedType() { return m_CurWheelItemData[m_iSelection]->m_Type; }
|
||||
Song* GetSelectedSong();
|
||||
Course* GetSelectedCourse() { return m_CurWheelItemData[m_iSelection]->m_pCourse; }
|
||||
CString GetSelectedSection(){ return m_CurWheelItemData[m_iSelection]->m_sSectionName; }
|
||||
CString GetSelectedSection(){ return m_CurWheelItemData[m_iSelection]->m_sText; }
|
||||
|
||||
bool WheelIsLocked() { return (m_WheelState == STATE_LOCKED ? true : false); }
|
||||
void RebuildAllMusicWheelItems();
|
||||
void RebuildMusicWheelItems( int dist );
|
||||
|
||||
@@ -68,84 +57,47 @@ public:
|
||||
bool SelectSong( Song *p );
|
||||
bool SelectSection( const CString & SectionName );
|
||||
void SetOpenGroup(CString group, SortOrder so = SORT_INVALID);
|
||||
SortOrder GetSortOrder() const { return m_SortOrder; }
|
||||
virtual void ChangeMusic(int dist); /* +1 or -1 */ //CHECK THIS
|
||||
|
||||
protected:
|
||||
virtual void LoadFromMetrics( CString sType );
|
||||
virtual bool MoveSpecific(int n);
|
||||
void GetSongList(vector<Song*> &arraySongs, SortOrder so, CString sPreferredGroup );
|
||||
void BuildWheelItemDatas( vector<WheelItemData> &arrayWheelItems, SortOrder so );
|
||||
bool SelectSongOrCourse();
|
||||
bool SelectCourse( Course *p );
|
||||
bool SelectModeMenuItem();
|
||||
void ChangeMusic(int dist); /* +1 or -1 */
|
||||
virtual void TweenOnScreenUpdateItems(bool changing_sort);
|
||||
virtual void TweenOffScreenUpdateItems(bool changing_sort);
|
||||
|
||||
ScrollBar m_ScrollBar;
|
||||
AutoActor m_sprHighlight;
|
||||
virtual void UpdateItems(float fDeltaTime );
|
||||
virtual void UpdateSwitch();
|
||||
|
||||
virtual inline void UpdateScrollbar() { WheelBase::UpdateScrollbar(m_CurWheelItemData.size()); }
|
||||
|
||||
vector<WheelItemData> m_WheelItemDatas[NUM_SORT_ORDERS];
|
||||
vector<WheelItemData *> m_CurWheelItemData;
|
||||
vector<MusicWheelItem *> m_MusicWheelItems;
|
||||
|
||||
int m_iSelection; // index into m_CurWheelItemData
|
||||
CString m_sExpandedSectionName;
|
||||
CString m_sLastModeMenuItem;
|
||||
SortOrder m_SortOrder;
|
||||
|
||||
int m_iSwitchesLeftInSpinDown;
|
||||
float m_fLockedWheelVelocity;
|
||||
/* 0 = none; -1 or 1 = up/down */
|
||||
int m_Moving;
|
||||
RageTimer m_MovingSoundTimer;
|
||||
float m_TimeBeforeMovingBegins;
|
||||
float m_SpinSpeed;
|
||||
enum WheelState {
|
||||
STATE_SELECTING_MUSIC,
|
||||
STATE_FLYING_OFF_BEFORE_NEXT_SORT,
|
||||
STATE_FLYING_ON_AFTER_NEXT_SORT,
|
||||
STATE_TWEENING_ON_SCREEN,
|
||||
STATE_TWEENING_OFF_SCREEN,
|
||||
STATE_WAITING_OFF_SCREEN,
|
||||
STATE_ROULETTE_SPINNING,
|
||||
STATE_ROULETTE_SLOWING_DOWN,
|
||||
STATE_RANDOM_SPINNING,
|
||||
STATE_LOCKED,
|
||||
};
|
||||
WheelState m_WheelState;
|
||||
float m_fTimeLeftInState;
|
||||
float m_fPositionOffsetFromSelection;
|
||||
|
||||
RageSound m_soundChangeMusic;
|
||||
RageSound m_soundChangeSort;
|
||||
RageSound m_soundExpand;
|
||||
RageSound m_soundLocked;
|
||||
|
||||
bool WheelItemIsVisible(int n);
|
||||
void UpdateScrollbar();
|
||||
|
||||
|
||||
ThemeMetric<float> SWITCH_SECONDS;
|
||||
ThemeMetric<float> ROULETTE_SWITCH_SECONDS;
|
||||
ThemeMetric<int> ROULETTE_SLOW_DOWN_SWITCHES;
|
||||
ThemeMetric<float> LOCKED_INITIAL_VELOCITY;
|
||||
ThemeMetric<float> SCROLL_BAR_X;
|
||||
ThemeMetric<int> SCROLL_BAR_HEIGHT;
|
||||
ThemeMetric<float> ITEM_CURVE_X;
|
||||
ThemeMetric<bool> USE_LINEAR_WHEEL;
|
||||
ThemeMetric<float> ITEM_SPACING_Y;
|
||||
ThemeMetric<float> WHEEL_3D_RADIUS;
|
||||
ThemeMetric<float> CIRCLE_PERCENT;
|
||||
ThemeMetric<int> NUM_SECTION_COLORS;
|
||||
ThemeMetric<RageColor> SONG_REAL_EXTRA_COLOR;
|
||||
ThemeMetric<RageColor> SORT_MENU_COLOR;
|
||||
ThemeMetric<bool> SHOW_ROULETTE;
|
||||
ThemeMetric<bool> SHOW_RANDOM;
|
||||
ThemeMetric<bool> SHOW_PORTAL;
|
||||
ThemeMetric<bool> USE_3D;
|
||||
ThemeMetric<float> NUM_WHEEL_ITEMS_TO_DRAW;
|
||||
ThemeMetric<int> MOST_PLAYED_SONGS_TO_SHOW;
|
||||
ThemeMetric<CString> MODE_MENU_CHOICE_NAMES;
|
||||
ThemeMetricMap<CString> CHOICE;
|
||||
ThemeMetric<float> WHEEL_ITEM_ON_DELAY_CENTER;
|
||||
ThemeMetric<float> WHEEL_ITEM_ON_DELAY_OFFSET;
|
||||
ThemeMetric<float> WHEEL_ITEM_OFF_DELAY_CENTER;
|
||||
ThemeMetric<float> WHEEL_ITEM_OFF_DELAY_OFFSET;
|
||||
ThemeMetric1D<RageColor> SECTION_COLORS;
|
||||
};
|
||||
|
||||
|
||||
@@ -36,13 +36,10 @@ ThemeMetric1D<float> GRADE_Y ("MusicWheelItem",GRADE_Y_NAME,NUM_PLAYERS);
|
||||
|
||||
|
||||
WheelItemData::WheelItemData( WheelItemType wit, Song* pSong, CString sSectionName, Course* pCourse, RageColor color )
|
||||
:WheelItemBaseData(wit, sSectionName, color)
|
||||
{
|
||||
m_Type = wit;
|
||||
m_pSong = pSong;
|
||||
m_sSectionName = sSectionName;
|
||||
m_pCourse = pCourse;
|
||||
m_color = color;
|
||||
m_Flags = WheelNotifyIcon::Flags();
|
||||
}
|
||||
|
||||
|
||||
@@ -52,9 +49,9 @@ MusicWheelItem::MusicWheelItem()
|
||||
|
||||
SetName( "MusicWheelItem" );
|
||||
|
||||
m_sprSongBar.Load( THEME->GetPathG("MusicWheelItem","song") );
|
||||
m_sprSongBar.SetXY( 0, 0 );
|
||||
this->AddChild( &m_sprSongBar );
|
||||
m_sprBar.Load( THEME->GetPathG("MusicWheelItem","song") );
|
||||
m_sprBar.SetXY( 0, 0 );
|
||||
this->AddChild( &m_sprBar );
|
||||
|
||||
m_sprSectionBar.Load( THEME->GetPathG("MusicWheelItem","section") );
|
||||
m_sprSectionBar.SetXY( 0, 0 );
|
||||
@@ -74,11 +71,11 @@ MusicWheelItem::MusicWheelItem()
|
||||
m_TextBanner.RunCommands( SONG_NAME_ON_COMMAND );
|
||||
this->AddChild( &m_TextBanner );
|
||||
|
||||
m_textSectionName.LoadFromFont( THEME->GetPathF("MusicWheelItem","section") );
|
||||
m_textSectionName.SetShadowLength( 0 );
|
||||
m_textSectionName.SetXY( SECTION_X, SECTION_Y );
|
||||
m_textSectionName.RunCommands( SECTION_ON_COMMAND );
|
||||
this->AddChild( &m_textSectionName );
|
||||
m_text.LoadFromFont( THEME->GetPathF("MusicWheelItem","section") );
|
||||
m_text.SetShadowLength( 0 );
|
||||
m_text.SetXY( SECTION_X, SECTION_Y );
|
||||
m_text.RunCommands( SECTION_ON_COMMAND );
|
||||
this->AddChild( &m_text );
|
||||
|
||||
m_textRoulette.LoadFromFont( THEME->GetPathF("MusicWheelItem","roulette") );
|
||||
m_textRoulette.SetShadowLength( 0 );
|
||||
@@ -116,10 +113,10 @@ void MusicWheelItem::LoadFromWheelItemData( WheelItemData* pWID, bool bExpanded
|
||||
// hide all
|
||||
m_WheelNotifyIcon.SetHidden( true );
|
||||
m_TextBanner.SetHidden( true );
|
||||
m_sprSongBar.SetHidden( true );
|
||||
m_sprBar.SetHidden( true );
|
||||
m_sprSectionBar.SetHidden( true );
|
||||
m_sprExpandedBar.SetHidden( true );
|
||||
m_textSectionName.SetHidden( true );
|
||||
m_text.SetHidden( true );
|
||||
m_textRoulette.SetHidden( true );
|
||||
FOREACH_PlayerNumber( p )
|
||||
m_GradeDisplay[p].SetHidden( true );
|
||||
@@ -139,8 +136,8 @@ void MusicWheelItem::LoadFromWheelItemData( WheelItemData* pWID, bool bExpanded
|
||||
switch( pWID->m_Type )
|
||||
{
|
||||
case TYPE_SECTION:
|
||||
sDisplayName = SONGMAN->ShortenGroupName(data->m_sSectionName);
|
||||
bt = &m_textSectionName;
|
||||
sDisplayName = SONGMAN->ShortenGroupName(data->m_sText);
|
||||
bt = &m_text;
|
||||
break;
|
||||
case TYPE_COURSE:
|
||||
sDisplayName = data->m_pCourse->GetFullDisplayTitle();
|
||||
@@ -202,7 +199,7 @@ void MusicWheelItem::LoadFromWheelItemData( WheelItemData* pWID, bool bExpanded
|
||||
break;
|
||||
case TYPE_SONG:
|
||||
case TYPE_COURSE:
|
||||
m_sprSongBar.SetHidden( false );
|
||||
m_sprBar.SetHidden( false );
|
||||
break;
|
||||
default: ASSERT(0);
|
||||
}
|
||||
@@ -236,28 +233,6 @@ void MusicWheelItem::RefreshGrades()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void MusicWheelItem::Update( float fDeltaTime )
|
||||
{
|
||||
ActorFrame::Update( fDeltaTime );
|
||||
}
|
||||
|
||||
void MusicWheelItem::DrawPrimitives()
|
||||
{
|
||||
ActorFrame::DrawPrimitives();
|
||||
|
||||
if( m_fPercentGray > 0 )
|
||||
{
|
||||
Sprite &bar = m_sprSongBar.GetVisible() ? m_sprSongBar : (m_sprSectionBar.GetVisible() ? m_sprSectionBar : m_sprExpandedBar);
|
||||
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) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (c) 2001-2004 Chris Danford, Chris Gomez, Glenn Maynard
|
||||
* All rights reserved.
|
||||
|
||||
@@ -10,59 +10,42 @@
|
||||
#include "TextBanner.h"
|
||||
#include "GameConstantsAndTypes.h"
|
||||
#include "GameCommand.h"
|
||||
#include "WheelItemBase.h"
|
||||
|
||||
class Course;
|
||||
class Song;
|
||||
|
||||
struct WheelItemData;
|
||||
|
||||
class MusicWheelItem : public ActorFrame
|
||||
class MusicWheelItem : public WheelItemBase
|
||||
{
|
||||
public:
|
||||
MusicWheelItem();
|
||||
|
||||
virtual void Update( float fDeltaTime );
|
||||
virtual void DrawPrimitives();
|
||||
|
||||
void LoadFromWheelItemData( WheelItemData* pWID, bool bExpanded );
|
||||
virtual void LoadFromWheelItemData( WheelItemData* pWID, bool bExpanded );
|
||||
void RefreshGrades();
|
||||
|
||||
WheelItemData *data;
|
||||
float m_fPercentGray;
|
||||
|
||||
Sprite m_sprSongBar;
|
||||
Sprite m_sprSectionBar;
|
||||
Sprite m_sprExpandedBar;
|
||||
WheelNotifyIcon m_WheelNotifyIcon;
|
||||
TextBanner m_TextBanner;
|
||||
BitmapText m_textSectionName;
|
||||
BitmapText m_textRoulette;
|
||||
BitmapText m_textCourse;
|
||||
BitmapText m_textSort;
|
||||
GradeDisplay m_GradeDisplay[NUM_PLAYERS];
|
||||
|
||||
void DrawPrimitives() { WheelItemBase::DrawPrimitives(m_sprBar.GetVisible() ? m_sprBar : (m_sprSectionBar.GetVisible() ? m_sprSectionBar : m_sprExpandedBar)); }
|
||||
};
|
||||
|
||||
enum WheelItemType
|
||||
{
|
||||
TYPE_SECTION,
|
||||
TYPE_SONG,
|
||||
TYPE_ROULETTE,
|
||||
TYPE_RANDOM,
|
||||
TYPE_PORTAL,
|
||||
TYPE_COURSE,
|
||||
TYPE_SORT
|
||||
};
|
||||
|
||||
struct WheelItemData
|
||||
struct WheelItemData : public WheelItemBaseData
|
||||
{
|
||||
WheelItemData() {}
|
||||
WheelItemData( WheelItemType wit, Song* pSong, CString sSectionName, Course* pCourse, RageColor color );
|
||||
|
||||
WheelItemType m_Type;
|
||||
CString m_sSectionName;
|
||||
Course* m_pCourse;
|
||||
Song* m_pSong;
|
||||
RageColor m_color; // either text color or section background color
|
||||
WheelNotifyIcon::Flags m_Flags;
|
||||
|
||||
// for TYPE_SORT
|
||||
CString m_sLabel;
|
||||
|
||||
Reference in New Issue
Block a user