Changed Notes difficulty/description in preparation for edit selection system

This commit is contained in:
Chris Danford
2003-01-21 22:23:01 +00:00
parent 779f1b829c
commit ac391552fd
22 changed files with 292 additions and 206 deletions
+7 -17
View File
@@ -186,29 +186,19 @@ Notes* Course::GetNotesForStage( int iStage )
{ {
Song* pSong = GetSong(iStage); Song* pSong = GetSong(iStage);
CString sDescription = entries[iStage].description; CString sDescription = entries[iStage].description;
unsigned i;
for( i=0; i<pSong->m_apNotes.size(); i++ ) for( unsigned i=0; i<pSong->m_apNotes.size(); i++ )
{ {
Notes* pNotes = pSong->m_apNotes[i]; Notes* pNotes = pSong->m_apNotes[i];
if( 0==stricmp(pNotes->GetDescription(), sDescription) &&
GAMESTATE->GetCurrentStyleDef()->MatchesNotesType(pNotes->m_NotesType) ) if( !GAMESTATE->GetCurrentStyleDef()->MatchesNotesType(pNotes->m_NotesType) )
continue;
if( pNotes->GetDescription().CompareNoCase(sDescription) ||
DifficultyToString(pNotes->GetDifficulty()).CompareNoCase(sDescription) )
return pNotes; return pNotes;
} }
// Didn't find a matching description. Try to match the Difficulty instead.
Difficulty dc = Notes::DifficultyFromDescriptionAndMeter( sDescription, 5 );
for( i=0; i<pSong->m_apNotes.size(); i++ )
{
Notes* pNotes = pSong->m_apNotes[i];
if( pNotes->GetDifficulty() == dc &&
GAMESTATE->GetCurrentStyleDef()->MatchesNotesType(pNotes->m_NotesType) )
return pNotes;
}
return NULL; return NULL;
} }
+5 -5
View File
@@ -22,8 +22,8 @@
bool DifficultyIcon::Load( CString sPath ) bool DifficultyIcon::Load( CString sPath )
{ {
Sprite::Load( sPath ); Sprite::Load( sPath );
if( GetNumStates() != 6 && GetNumStates() != 12 ) if( GetNumStates() != 5 && GetNumStates() != 10 )
RageException::Throw( "The difficulty icon graphic '%s' must have 6 or 12 states.", sPath.GetString() ); RageException::Throw( "The difficulty icon graphic '%s' must have 5 or 10 frames.", sPath.GetString() );
StopAnimating(); StopAnimating();
return true; return true;
} }
@@ -39,12 +39,12 @@ void DifficultyIcon::SetFromNotes( PlayerNumber pn, Notes* pNotes )
{ {
SetDiffuse( RageColor(1,1,1,1) ); SetDiffuse( RageColor(1,1,1,1) );
int iStateNo = pNotes->GetNotesDisplayType(); int iStateNo = pNotes->GetDifficulty();
switch( GetNumStates() ) switch( GetNumStates() )
{ {
case 6: SetState( iStateNo ); break; case 5: SetState( iStateNo ); break;
case 12: SetState( iStateNo*2+pn ); break; case 10: SetState( iStateNo*2+pn ); break;
default: ASSERT(0); default: ASSERT(0);
} }
} }
+7 -5
View File
@@ -21,10 +21,12 @@ CString DifficultyToString( Difficulty dc )
{ {
switch( dc ) switch( dc )
{ {
case DIFFICULTY_EASY: return "easy"; case DIFFICULTY_BEGINNER: return "beginner";
case DIFFICULTY_MEDIUM: return "medium"; case DIFFICULTY_EASY: return "easy";
case DIFFICULTY_HARD: return "hard"; case DIFFICULTY_MEDIUM: return "medium";
default: ASSERT(0); return ""; // invalid Difficulty case DIFFICULTY_HARD: return "hard";
case DIFFICULTY_CHALLENGE: return "challenge";
default: ASSERT(0); return ""; // invalid Difficulty
} }
} }
@@ -36,7 +38,7 @@ Difficulty StringToDifficulty( CString sDC )
if( sDC == DifficultyToString(dc) ) if( sDC == DifficultyToString(dc) )
return dc; return dc;
} }
return CLASS_INVALID; return DIFFICULTY_INVALID;
} }
RageColor PlayerToColor( PlayerNumber pn ) RageColor PlayerToColor( PlayerNumber pn )
+6 -4
View File
@@ -50,11 +50,13 @@ enum RadarCategory // starting from 12-o'clock rotating clockwise
enum Difficulty enum Difficulty
{ {
DIFFICULTY_EASY, // corresponds to Basic, Easy DIFFICULTY_BEGINNER, // corresponds to DDREX Beginner
DIFFICULTY_MEDIUM, // corresponds to Trick, Another, Standard, Normal DIFFICULTY_EASY, // corresponds to Basic, Easy
DIFFICULTY_HARD, // corresponds to Maniac, SSR, Heavy, Crazy DIFFICULTY_MEDIUM, // corresponds to Trick, Another, Standard, Normal
DIFFICULTY_HARD, // corresponds to Maniac, SSR, Heavy, Crazy
DIFFICULTY_CHALLENGE, // corresponds to 5th SMANIAC, MAX2 Challenge, EX Challenge
NUM_DIFFICULTIES, NUM_DIFFICULTIES,
CLASS_INVALID DIFFICULTY_INVALID
}; };
CString DifficultyToString( Difficulty dc ); CString DifficultyToString( Difficulty dc );
+1 -1
View File
@@ -60,7 +60,7 @@ void GameState::Reset()
m_MasterPlayerNumber = PLAYER_INVALID; m_MasterPlayerNumber = PLAYER_INVALID;
m_sPreferredGroup = ""; m_sPreferredGroup = "";
for( p=0; p<NUM_PLAYERS; p++ ) for( p=0; p<NUM_PLAYERS; p++ )
m_PreferredDifficulty[p] = CLASS_INVALID; m_PreferredDifficulty[p] = DIFFICULTY_INVALID;
m_SongSortOrder = SORT_GROUP; m_SongSortOrder = SORT_GROUP;
m_PlayMode = PLAY_MODE_INVALID; m_PlayMode = PLAY_MODE_INVALID;
m_bEditing = false; m_bEditing = false;
+2 -2
View File
@@ -22,13 +22,13 @@
MusicStatusDisplay::MusicStatusDisplay() MusicStatusDisplay::MusicStatusDisplay()
{ {
Load( THEME->GetPathTo("Graphics","music status icons 1x4") ); Load( THEME->GetPathTo("Graphics","music status icons 1x5") );
StopAnimating(); StopAnimating();
SetType( none ); SetType( none );
} }
void MusicStatusDisplay::SetType( IconType type ) void MusicStatusDisplay::SetType( Type type )
{ {
m_type = type; m_type = type;
+3 -3
View File
@@ -21,14 +21,14 @@ class MusicStatusDisplay : public Sprite
public: public:
MusicStatusDisplay(); MusicStatusDisplay();
enum IconType { none, easy, crown1, crown2, crown3 }; enum Type { none, easy, crown1, crown2, crown3, edits };
void SetType( IconType type ); void SetType( Type type );
virtual void Update( float fDeltaTime ); virtual void Update( float fDeltaTime );
virtual void DrawPrimitives(); virtual void DrawPrimitives();
protected: protected:
IconType m_type; Type m_type;
}; };
#endif #endif
+46 -75
View File
@@ -26,12 +26,11 @@
#include "ThemeManager.h" #include "ThemeManager.h"
#define COLOR_BEGINNER THEME->GetMetricC("Notes","ColorBeginner")
#define COLOR_EASY THEME->GetMetricC("Notes","ColorEasy") #define COLOR_EASY THEME->GetMetricC("Notes","ColorEasy")
#define COLOR_MEDIUM THEME->GetMetricC("Notes","ColorMedium") #define COLOR_MEDIUM THEME->GetMetricC("Notes","ColorMedium")
#define COLOR_HARD THEME->GetMetricC("Notes","ColorHard") #define COLOR_HARD THEME->GetMetricC("Notes","ColorHard")
#define COLOR_S_HARD THEME->GetMetricC("Notes","ColorSHard")
#define COLOR_CHALLENGE THEME->GetMetricC("Notes","ColorChallenge") #define COLOR_CHALLENGE THEME->GetMetricC("Notes","ColorChallenge")
#define COLOR_BATTLE THEME->GetMetricC("Notes","ColorBattle")
Notes::Notes() Notes::Notes()
{ {
@@ -40,7 +39,7 @@ Notes::Notes()
* it'd trip obscure asserts all over the place, so I'll wait * it'd trip obscure asserts all over the place, so I'll wait
* until after b6 to do this. -glenn */ * until after b6 to do this. -glenn */
m_NotesType = NOTES_TYPE_DANCE_SINGLE; m_NotesType = NOTES_TYPE_DANCE_SINGLE;
m_Difficulty = CLASS_INVALID; m_Difficulty = DIFFICULTY_INVALID;
m_iMeter = 0; m_iMeter = 0;
for(int i = 0; i < NUM_RADAR_VALUES; ++i) for(int i = 0; i < NUM_RADAR_VALUES; ++i)
m_fRadarValues[i] = -1; /* unknown */ m_fRadarValues[i] = -1; /* unknown */
@@ -104,94 +103,66 @@ CString Notes::GetSMNoteData() const
return *notes_comp; return *notes_comp;
} }
// Color is a function of Difficulty and Intended Style
NotesDisplayType Notes::GetNotesDisplayType() const
{
CString sDescription = GetDescription();
sDescription.MakeLower();
if( -1 != sDescription.Find("battle") ) return NOTES_DISPLAY_BATTLE;
else if( -1 != sDescription.Find("couple") ) return NOTES_DISPLAY_BATTLE;
else if( -1 != sDescription.Find("smaniac") ) return NOTES_DISPLAY_S_HARD;
else if( -1 != sDescription.Find("challenge") ) return NOTES_DISPLAY_CHALLENGE;
switch( GetDifficulty() )
{
case DIFFICULTY_EASY: return NOTES_DISPLAY_EASY;
case DIFFICULTY_MEDIUM: return NOTES_DISPLAY_MEDIUM;
case DIFFICULTY_HARD: return NOTES_DISPLAY_HARD;
default: ASSERT(0); return NOTES_DISPLAY_EASY;
}
}
RageColor Notes::GetColor() const RageColor Notes::GetColor() const
{ {
switch( GetNotesDisplayType() ) switch( m_Difficulty )
{ {
case NOTES_DISPLAY_EASY: return COLOR_EASY; case DIFFICULTY_BEGINNER: return COLOR_BEGINNER;
case NOTES_DISPLAY_MEDIUM: return COLOR_MEDIUM; case DIFFICULTY_EASY: return COLOR_EASY;
case NOTES_DISPLAY_HARD: return COLOR_HARD; case DIFFICULTY_MEDIUM: return COLOR_MEDIUM;
case NOTES_DISPLAY_S_HARD: return COLOR_S_HARD; case DIFFICULTY_HARD: return COLOR_HARD;
case NOTES_DISPLAY_CHALLENGE: return COLOR_CHALLENGE; case DIFFICULTY_CHALLENGE: return COLOR_CHALLENGE;
case NOTES_DISPLAY_BATTLE: return COLOR_BATTLE; default: ASSERT(0); return COLOR_BEGINNER;
default: return COLOR_EASY;
} }
} }
void Notes::TidyUpData() void Notes::TidyUpData()
{ {
if( GetDifficulty() == CLASS_INVALID ) if( GetDifficulty() == DIFFICULTY_INVALID )
SetDifficulty(DifficultyFromDescriptionAndMeter( GetDescription(), GetMeter() ));
if( GetMeter() < 1 || GetMeter() > 10 )
{ {
CString sDescription = GetDescription();
sDescription.MakeLower();
if( sDescription == "beginner" ) SetDifficulty(DIFFICULTY_BEGINNER);
else if( sDescription == "easy" ) SetDifficulty(DIFFICULTY_EASY);
else if( sDescription == "basic" ) SetDifficulty(DIFFICULTY_EASY);
else if( sDescription == "light" ) SetDifficulty(DIFFICULTY_EASY);
else if( sDescription == "medium" ) SetDifficulty(DIFFICULTY_MEDIUM);
else if( sDescription == "another" ) SetDifficulty(DIFFICULTY_MEDIUM);
else if( sDescription == "trick" ) SetDifficulty(DIFFICULTY_MEDIUM);
else if( sDescription == "standard" ) SetDifficulty(DIFFICULTY_MEDIUM);
else if( sDescription == "hard" ) SetDifficulty(DIFFICULTY_HARD);
else if( sDescription == "ssr" ) SetDifficulty(DIFFICULTY_HARD);
else if( sDescription == "maniac" ) SetDifficulty(DIFFICULTY_HARD);
else if( sDescription == "heavy" ) SetDifficulty(DIFFICULTY_HARD);
else if( sDescription == "smaniac" ) SetDifficulty(DIFFICULTY_CHALLENGE);
else if( sDescription == "challenge" ) SetDifficulty(DIFFICULTY_CHALLENGE);
}
if( GetDifficulty() == DIFFICULTY_INVALID )
{
if( GetMeter() == 1 ) SetDifficulty(DIFFICULTY_BEGINNER);
else if( GetMeter() <= 3 ) SetDifficulty(DIFFICULTY_EASY);
else if( GetMeter() <= 6 ) SetDifficulty(DIFFICULTY_MEDIUM);
else SetDifficulty(DIFFICULTY_HARD);
}
if( GetMeter() < 1 || GetMeter() > 10 ) // meter is invalid
{
// guess meter from difficulty class
switch( GetDifficulty() ) switch( GetDifficulty() )
{ {
case DIFFICULTY_EASY: SetMeter(3); break; case DIFFICULTY_BEGINNER: SetMeter(1); break;
case DIFFICULTY_MEDIUM: SetMeter(5); break; case DIFFICULTY_EASY: SetMeter(3); break;
case DIFFICULTY_HARD: SetMeter(8); break; case DIFFICULTY_MEDIUM: SetMeter(5); break;
case DIFFICULTY_HARD: SetMeter(8); break;
case DIFFICULTY_CHALLENGE: SetMeter(8); break;
case DIFFICULTY_INVALID: SetMeter(5); break;
default: ASSERT(0); default: ASSERT(0);
} }
} }
} }
Difficulty Notes::DifficultyFromDescriptionAndMeter( CString sDescription, int iMeter )
{
sDescription.MakeLower();
const int DESCRIPTIONS_PER_CLASS = 4;
const CString sDescriptionParts[NUM_DIFFICULTIES][DESCRIPTIONS_PER_CLASS] = {
{
"easy",
"basic",
"light",
"GARBAGE", // don't worry - this will never match because the compare string is all lowercase
},
{
"medium",
"another",
"trick",
"standard",
},
{
"hard",
"ssr",
"maniac",
"heavy",
},
};
for( int i=0; i<NUM_DIFFICULTIES; i++ )
for( int j=0; j<DESCRIPTIONS_PER_CLASS; j++ )
if( sDescription.Find(sDescriptionParts[i][j]) != -1 )
return (Difficulty)i;
// guess difficulty class from meter
if( iMeter <= 3 ) return DIFFICULTY_EASY;
else if( iMeter <= 6 ) return DIFFICULTY_MEDIUM;
else return DIFFICULTY_HARD;
}
////////////////////////////////////////////// //////////////////////////////////////////////
// //
+1 -15
View File
@@ -17,16 +17,6 @@
#include "Grade.h" #include "Grade.h"
class NoteData; class NoteData;
enum NotesDisplayType
{
NOTES_DISPLAY_EASY,
NOTES_DISPLAY_MEDIUM,
NOTES_DISPLAY_HARD,
NOTES_DISPLAY_S_HARD,
NOTES_DISPLAY_CHALLENGE,
NOTES_DISPLAY_BATTLE
};
struct Notes struct Notes
{ {
public: public:
@@ -56,9 +46,7 @@ public:
void SetSMNoteData( const CString &out ); void SetSMNoteData( const CString &out );
CString GetSMNoteData() const; CString GetSMNoteData() const;
void AutogenFrom( Notes *parent, NotesType ntTo ); void AutogenFrom( Notes *parent, NotesType ntTo );
RageColor GetColor() const; // a function of difficulty
NotesDisplayType GetNotesDisplayType() const;
RageColor GetColor() const;
// Statistics // Statistics
Grade m_TopGrade; Grade m_TopGrade;
@@ -66,8 +54,6 @@ public:
int m_iMaxCombo; int m_iMaxCombo;
int m_iNumTimesPlayed; int m_iNumTimesPlayed;
static Difficulty DifficultyFromDescriptionAndMeter( CString sDescription, int iMeter );
void TidyUpData(); void TidyUpData();
protected: protected:
+6 -4
View File
@@ -120,11 +120,13 @@ bool DWILoader::LoadFromDWITokens(
ASSERT(0); ASSERT(0);
} }
int iNumFeet = atoi(sNumFeet);
out.SetDescription(sDescription); out.SetDescription(sDescription);
out.SetMeter(iNumFeet);
out.SetMeter(atoi(sNumFeet)); if( sDescription.CompareNoCase("basic")==0 ) out.SetDifficulty( DIFFICULTY_EASY );
else if( sDescription.CompareNoCase("trick")==0 ) out.SetDifficulty( DIFFICULTY_MEDIUM );
//SetDifficulty(DifficultyFromDescriptionAndMeter( GetDescription(), GetMeter() )); else if( sDescription.CompareNoCase("maniac")==0 ) out.SetDifficulty( DIFFICULTY_HARD );
else if( sDescription.CompareNoCase("smaniac")==0 ) out.SetDifficulty( DIFFICULTY_CHALLENGE );
NoteData* pNoteData = new NoteData; NoteData* pNoteData = new NoteData;
ASSERT( pNoteData ); ASSERT( pNoteData );
+7 -12
View File
@@ -199,19 +199,14 @@ bool NotesWriterDWI::WriteDWINotesTag( FILE* fp, const Notes &out )
default: return false; // not a type supported by DWI default: return false; // not a type supported by DWI
} }
if( 0==out.GetDescription().CompareNoCase("challenge") ) switch( out.GetDifficulty() )
fprintf( fp, "SMANIAC:" );
else if( 0==out.GetDescription().CompareNoCase("smaniac") )
fprintf( fp, "SMANIAC:" );
else
{ {
switch( out.GetDifficulty() ) case DIFFICULTY_BEGINNER:
{ case DIFFICULTY_EASY: fprintf( fp, "BASIC:" ); break;
case DIFFICULTY_EASY: fprintf( fp, "BASIC:" ); break; case DIFFICULTY_MEDIUM: fprintf( fp, "ANOTHER:" ); break;
case DIFFICULTY_MEDIUM: fprintf( fp, "ANOTHER:" ); break; case DIFFICULTY_HARD: fprintf( fp, "MANIAC:" ); break;
case DIFFICULTY_HARD: fprintf( fp, "MANIAC:" ); break; case DIFFICULTY_CHALLENGE: fprintf( fp, "SMANIAC:" ); break;
default: ASSERT(0); return false; default: ASSERT(0); return false;
}
} }
fprintf( fp, "%d:\n", out.GetMeter() ); fprintf( fp, "%d:\n", out.GetMeter() );
+1 -1
View File
@@ -341,7 +341,7 @@ ScreenGameplay::ScreenGameplay( bool bDemonstration )
if( !GAMESTATE->IsPlayerEnabled(PlayerNumber(p)) ) if( !GAMESTATE->IsPlayerEnabled(PlayerNumber(p)) )
continue; continue;
m_DifficultyIcon[p].Load( THEME->GetPathTo("graphics","gameplay difficulty icons 2x6") ); m_DifficultyIcon[p].Load( THEME->GetPathTo("graphics","gameplay difficulty icons 2x5") );
m_DifficultyIcon[p].SetXY( DIFFICULTY_X(p), DIFFICULTY_Y(p,bExtra,bReverse[p]) ); m_DifficultyIcon[p].SetXY( DIFFICULTY_X(p), DIFFICULTY_Y(p,bExtra,bReverse[p]) );
this->AddChild( &m_DifficultyIcon[p] ); this->AddChild( &m_DifficultyIcon[p] );
} }
+18
View File
@@ -86,11 +86,29 @@ ScreenGraphicOptions::ScreenGraphicOptions() :
g_GraphicOptionsLines, g_GraphicOptionsLines,
NUM_GRAPHIC_OPTIONS_LINES, NUM_GRAPHIC_OPTIONS_LINES,
false ); false );
UpdateRefreshRates();
m_Menu.StopTimer(); m_Menu.StopTimer();
SOUNDMAN->PlayMusic( THEME->GetPathTo("Sounds","graphic options music") ); SOUNDMAN->PlayMusic( THEME->GetPathTo("Sounds","graphic options music") );
} }
void ScreenGraphicOptions::UpdateRefreshRates()
{
/* If we're windowed, leave all refresh rates dimmed, but don't
* change the actual selection. */
if(m_iSelectedOption[0][GO_WINDOWED])
return;
// PositionUnderlines();
}
void ScreenGraphicOptions::OnChange()
{
ScreenOptions::OnChange();
UpdateRefreshRates();
}
void ScreenGraphicOptions::ImportOptions() void ScreenGraphicOptions::ImportOptions()
{ {
m_iSelectedOption[0][GO_WINDOWED] = PREFSMAN->m_bWindowed ? 1:0; m_iSelectedOption[0][GO_WINDOWED] = PREFSMAN->m_bWindowed ? 1:0;
+2
View File
@@ -19,7 +19,9 @@ public:
ScreenGraphicOptions(); ScreenGraphicOptions();
private: private:
void UpdateRefreshRates();
void OnChange();
void ImportOptions(); void ImportOptions();
void ExportOptions(); void ExportOptions();
+78
View File
@@ -85,6 +85,7 @@ ScreenOptions::ScreenOptions( CString sBackgroundPath, CString sPagePath, CStrin
m_framePage.SetX( SCREEN_LEFT-SCREEN_WIDTH ); m_framePage.SetX( SCREEN_LEFT-SCREEN_WIDTH );
m_framePage.BeginTweening( 0.3f, Actor::TWEEN_BIAS_BEGIN ); m_framePage.BeginTweening( 0.3f, Actor::TWEEN_BIAS_BEGIN );
m_framePage.SetTweenX( 0 ); m_framePage.SetTweenX( 0 );
ZeroMemory(&m_OptionDim, sizeof(m_OptionDim));
} }
void ScreenOptions::Init( InputMode im, OptionRowData OptionRowData[], int iNumOptionLines, bool bUseIcons ) void ScreenOptions::Init( InputMode im, OptionRowData OptionRowData[], int iNumOptionLines, bool bUseIcons )
@@ -231,6 +232,36 @@ void ScreenOptions::InitOptionsText()
option.SetXY( CENTER_X, fY ); option.SetXY( CENTER_X, fY );
} }
void ScreenOptions::DimOption(int line, int option, bool dim)
{
if(m_OptionDim[line][option] == dim)
return;
m_OptionDim[line][option] = dim;
m_textOptions[line][option].StopTweening();
m_textOptions[line][option].BeginTweening(.250);
if(m_OptionDim[line][option])
m_textOptions[line][option].SetTweenDiffuse( RageColor(.5,.5,.5,1) );
else
m_textOptions[line][option].SetTweenDiffuse( RageColor(1,1,1,1) );
/* Don't know if I like this ...-glenn
m_textOptionLineTitles[line].BeginTweening(.250);
if(RowCompletelyDimmed(line))
m_textOptionLineTitles[line].SetTweenZoom( 0.6f );
else
m_textOptionLineTitles[line].SetTweenZoom( 0.7f );
*/
}
bool ScreenOptions::RowCompletelyDimmed(int line) const
{
for(unsigned i = 0; i < m_OptionRowData[line].iNumOptions; ++i)
if(!m_OptionDim[line][i]) return false;
return true;
}
void ScreenOptions::PositionUnderlines() void ScreenOptions::PositionUnderlines()
{ {
// Set the position of the underscores showing the current choice for each option line. // Set the position of the underscores showing the current choice for each option line.
@@ -459,6 +490,17 @@ void ScreenOptions::MenuLeft( PlayerNumber pn )
const int iNumOptions = m_OptionRowData[iCurRow].iNumOptions; const int iNumOptions = m_OptionRowData[iCurRow].iNumOptions;
m_iSelectedOption[p][iCurRow] = (m_iSelectedOption[p][iCurRow]-1+iNumOptions) % iNumOptions; m_iSelectedOption[p][iCurRow] = (m_iSelectedOption[p][iCurRow]-1+iNumOptions) % iNumOptions;
// Chris: I commented this out because it made wrapping a pain. Is it used anyway? If so, please
// let me know and I'll fix it.
// do {
// new_opt--;
// } while(new_opt >= 0 && m_OptionDim[iCurRow][new_opt]);
//
// if( new_opt < 0 ) // can't go left any more
// return;
//
// m_iSelectedOption[p][iCurRow] = new_opt;
TweenCursor( (PlayerNumber)p ); TweenCursor( (PlayerNumber)p );
} }
m_SoundChangeCol.Play(); m_SoundChangeCol.Play();
@@ -479,6 +521,19 @@ void ScreenOptions::MenuRight( PlayerNumber pn )
const int iNumOptions = m_OptionRowData[iCurRow].iNumOptions; const int iNumOptions = m_OptionRowData[iCurRow].iNumOptions;
m_iSelectedOption[p][iCurRow] = (m_iSelectedOption[p][iCurRow]+1) % iNumOptions; m_iSelectedOption[p][iCurRow] = (m_iSelectedOption[p][iCurRow]+1) % iNumOptions;
// Chris: I commented this out because it made wrapping a pain. Is it used anyway? If so, please
// let me know and I'll fix it.
// int new_opt = m_iSelectedOption[p][iCurRow];
// do {
// new_opt++;
// } while(new_opt < m_OptionRowData[iCurRow].iNumOptions &&
// m_OptionDim[iCurRow][new_opt]);
//
// if( new_opt == m_OptionRowData[iCurRow].iNumOptions ) // can't go right any more
// return;
//
// m_iSelectedOption[p][iCurRow] = new_opt;
TweenCursor( (PlayerNumber)p ); TweenCursor( (PlayerNumber)p );
} }
m_SoundChangeCol.Play(); m_SoundChangeCol.Play();
@@ -496,6 +551,18 @@ void ScreenOptions::MenuUp( PlayerNumber pn )
return; // can't go up any more return; // can't go up any more
m_iCurrentRow[p]--; m_iCurrentRow[p]--;
// Chris: Will add back in later
// /* Find the prev row with any un-dimmed entries. */
// int new_row = m_iCurrentRow[p];
// do {
/// if(--new_row < 0)
// new_row = m_iNumOptionRows-1; // wrap around
// if(!RowCompletelyDimmed(new_row)) break;
// } while(new_row != m_iCurrentRow[p]);
// m_iCurrentRow[p] = new_row;
TweenCursor( (PlayerNumber)p ); TweenCursor( (PlayerNumber)p );
} }
m_SoundPrevRow.Play(); m_SoundPrevRow.Play();
@@ -514,6 +581,17 @@ void ScreenOptions::MenuDown( PlayerNumber pn )
return; // can't go down any more return; // can't go down any more
m_iCurrentRow[p]++; m_iCurrentRow[p]++;
// Chris: Commented this out, but will add back in later.
// /* Find the next row with any un-dimmed entries. */
// int new_row = m_iCurrentRow[p];
// do {
// if( ++new_row == m_iNumOptionRows )
// new_row = 0; // wrap around
// if(!RowCompletelyDimmed(new_row)) break;
// } while(new_row != m_iCurrentRow[p]);
// m_iCurrentRow[p] = new_row;
TweenCursor( (PlayerNumber)p ); TweenCursor( (PlayerNumber)p );
} }
m_SoundNextRow.Play(); m_SoundNextRow.Play();
+2
View File
@@ -91,6 +91,8 @@ protected:
BitmapText m_textOptionLineTitles[MAX_OPTION_LINES]; BitmapText m_textOptionLineTitles[MAX_OPTION_LINES];
BitmapText m_textOptions[MAX_OPTION_LINES][MAX_OPTIONS_PER_LINE]; // this array has to be big enough to hold all of the options BitmapText m_textOptions[MAX_OPTION_LINES][MAX_OPTIONS_PER_LINE]; // this array has to be big enough to hold all of the options
bool m_OptionDim[MAX_OPTION_LINES][MAX_OPTIONS_PER_LINE]; bool m_OptionDim[MAX_OPTION_LINES][MAX_OPTIONS_PER_LINE];
void DimOption(int line, int option, bool dim);
bool RowCompletelyDimmed(int line) const;
int m_iSelectedOption[NUM_PLAYERS][MAX_OPTION_LINES]; int m_iSelectedOption[NUM_PLAYERS][MAX_OPTION_LINES];
int m_iCurrentRow[NUM_PLAYERS]; int m_iCurrentRow[NUM_PLAYERS];
+84 -27
View File
@@ -28,8 +28,20 @@ const float LOCK_INPUT_TIME = 0.30f; // lock input while waiting for tweening to
#define MORE_Y( page ) THEME->GetMetricF("ScreenSelectDifficulty",ssprintf("MorePage%dY",page+1)) #define MORE_Y( page ) THEME->GetMetricF("ScreenSelectDifficulty",ssprintf("MorePage%dY",page+1))
#define EXPLANATION_X( page ) THEME->GetMetricF("ScreenSelectDifficulty",ssprintf("ExplanationPage%dX",page+1)) #define EXPLANATION_X( page ) THEME->GetMetricF("ScreenSelectDifficulty",ssprintf("ExplanationPage%dX",page+1))
#define EXPLANATION_Y( page ) THEME->GetMetricF("ScreenSelectDifficulty",ssprintf("ExplanationPage%dY",page+1)) #define EXPLANATION_Y( page ) THEME->GetMetricF("ScreenSelectDifficulty",ssprintf("ExplanationPage%dY",page+1))
#define CHOICE_X( i ) THEME->GetMetricF("ScreenSelectDifficulty",ssprintf("Choice%dX",i+1)) #define BEGINNER_X() THEME->GetMetricF("ScreenSelectDifficulty","BeginnerX")
#define CHOICE_Y( i ) THEME->GetMetricF("ScreenSelectDifficulty",ssprintf("Choice%dY",i+1)) #define BEGINNER_Y() THEME->GetMetricF("ScreenSelectDifficulty","BeginnerY")
#define EASY_X() THEME->GetMetricF("ScreenSelectDifficulty","EasyX")
#define EASY_Y() THEME->GetMetricF("ScreenSelectDifficulty","EasyY")
#define MEDIUM_X() THEME->GetMetricF("ScreenSelectDifficulty","MediumX")
#define MEDIUM_Y() THEME->GetMetricF("ScreenSelectDifficulty","MediumY")
#define HARD_X() THEME->GetMetricF("ScreenSelectDifficulty","HardX")
#define HARD_Y() THEME->GetMetricF("ScreenSelectDifficulty","HardY")
#define NONSTOP_X() THEME->GetMetricF("ScreenSelectDifficulty","NonstopX")
#define NONSTOP_Y() THEME->GetMetricF("ScreenSelectDifficulty","NonstopY")
#define ONI_X() THEME->GetMetricF("ScreenSelectDifficulty","OniX")
#define ONI_Y() THEME->GetMetricF("ScreenSelectDifficulty","OniY")
#define ENDLESS_X() THEME->GetMetricF("ScreenSelectDifficulty","EndlessX")
#define ENDLESS_Y() THEME->GetMetricF("ScreenSelectDifficulty","EndlessY")
#define CURSOR_OFFSET_X( p ) THEME->GetMetricF("ScreenSelectDifficulty",ssprintf("CursorOffsetP%dX",p+1)) #define CURSOR_OFFSET_X( p ) THEME->GetMetricF("ScreenSelectDifficulty",ssprintf("CursorOffsetP%dX",p+1))
#define CURSOR_OFFSET_Y( i ) THEME->GetMetricF("ScreenSelectDifficulty",ssprintf("CursorOffsetP%dY",i+1)) #define CURSOR_OFFSET_Y( i ) THEME->GetMetricF("ScreenSelectDifficulty",ssprintf("CursorOffsetP%dY",i+1))
#define CURSOR_SHADOW_LENGTH_X THEME->GetMetricF("ScreenSelectDifficulty","CursorShadowLengthX") #define CURSOR_SHADOW_LENGTH_X THEME->GetMetricF("ScreenSelectDifficulty","CursorShadowLengthX")
@@ -40,10 +52,52 @@ const float LOCK_INPUT_TIME = 0.30f; // lock input while waiting for tweening to
#define NEXT_SCREEN_ARCADE THEME->GetMetric("ScreenSelectDifficulty","NextScreenArcade") #define NEXT_SCREEN_ARCADE THEME->GetMetric("ScreenSelectDifficulty","NextScreenArcade")
#define NEXT_SCREEN_ONI THEME->GetMetric("ScreenSelectDifficulty","NextScreenOni") #define NEXT_SCREEN_ONI THEME->GetMetric("ScreenSelectDifficulty","NextScreenOni")
float CHOICE_X( int choice )
{
switch( choice )
{
case 0: return BEGINNER_X();
case 1: return EASY_X();
case 2: return MEDIUM_X();
case 3: return HARD_X();
case 4: return NONSTOP_X();
case 5: return ONI_X();
case 6: return ENDLESS_X();
default: ASSERT(0); return 0;
}
}
float CHOICE_Y( int choice )
{
switch( choice )
{
case 0: return BEGINNER_Y();
case 1: return EASY_Y();
case 2: return MEDIUM_Y();
case 3: return HARD_Y();
case 4: return NONSTOP_Y();
case 5: return ONI_Y();
case 6: return ENDLESS_Y();
default: ASSERT(0); return 0;
}
}
const CString CHOICE_TEXT[ScreenSelectDifficulty::NUM_CHOICES] =
{
"beginner",
"easy",
"medium",
"hard",
"nonstop",
"oni",
"endless"
};
float CURSOR_X( int choice, int p ) { return CHOICE_X(choice) + CURSOR_OFFSET_X(p); } float CURSOR_X( int choice, int p ) { return CHOICE_X(choice) + CURSOR_OFFSET_X(p); }
float CURSOR_Y( int choice, int p ) { return CHOICE_Y(choice) + CURSOR_OFFSET_Y(p); } float CURSOR_Y( int choice, int p ) { return CHOICE_Y(choice) + CURSOR_OFFSET_Y(p); }
const ScreenMessage SM_GoToPrevScreen = ScreenMessage(SM_User + 1); const ScreenMessage SM_GoToPrevScreen = ScreenMessage(SM_User + 1);
const ScreenMessage SM_GoToNextScreen = ScreenMessage(SM_User + 2); const ScreenMessage SM_GoToNextScreen = ScreenMessage(SM_User + 2);
const ScreenMessage SM_StartTweeningOffScreen = ScreenMessage(SM_User + 3); const ScreenMessage SM_StartTweeningOffScreen = ScreenMessage(SM_User + 3);
@@ -70,8 +124,8 @@ ScreenSelectDifficulty::ScreenSelectDifficulty()
for( unsigned c=0; c<NUM_CHOICES; c++ ) for( unsigned c=0; c<NUM_CHOICES; c++ )
{ {
CString sHeaderFile = ssprintf( "select difficulty header %d", c+1 ); CString sHeaderFile = ssprintf( "select difficulty header %s", CHOICE_TEXT[c].c_str() );
CString sPictureFile = ssprintf( "select difficulty picture %d", c+1 ); CString sPictureFile = ssprintf( "select difficulty picture %s", CHOICE_TEXT[c].c_str() );
m_sprPicture[c].Load( THEME->GetPathTo("Graphics",sPictureFile) ); m_sprPicture[c].Load( THEME->GetPathTo("Graphics",sPictureFile) );
m_sprPicture[c].SetXY( CHOICE_X(c), CHOICE_Y(c) ); m_sprPicture[c].SetXY( CHOICE_X(c), CHOICE_Y(c) );
@@ -197,23 +251,26 @@ void ScreenSelectDifficulty::HandleScreenMessage( const ScreenMessage SM )
{ {
switch( m_Choice[p] ) switch( m_Choice[p] )
{ {
case 3: // need to set preferred difficulty even for courses case CHOICE_BEGINNER: GAMESTATE->m_PreferredDifficulty[p] = DIFFICULTY_BEGINNER; break;
case 4: case CHOICE_EASY: GAMESTATE->m_PreferredDifficulty[p] = DIFFICULTY_EASY; break;
case 5: case CHOICE_NONSTOP: // need to set preferred difficulty even for courses
case 0: GAMESTATE->m_PreferredDifficulty[p] = DIFFICULTY_EASY; break; case CHOICE_ONI:
case 1: GAMESTATE->m_PreferredDifficulty[p] = DIFFICULTY_MEDIUM; break; case CHOICE_ENDLESS:
case 2: GAMESTATE->m_PreferredDifficulty[p] = DIFFICULTY_HARD; break; case CHOICE_MEDIUM: GAMESTATE->m_PreferredDifficulty[p] = DIFFICULTY_MEDIUM; break;
case CHOICE_HARD: GAMESTATE->m_PreferredDifficulty[p] = DIFFICULTY_HARD; break;
default: ASSERT(0);
} }
} }
switch( m_Choice[GAMESTATE->m_MasterPlayerNumber] ) switch( m_Choice[GAMESTATE->m_MasterPlayerNumber] )
{ {
case 0: case CHOICE_BEGINNER:
case 1: case CHOICE_EASY:
case 2: GAMESTATE->m_PlayMode = PLAY_MODE_ARCADE; break; case CHOICE_MEDIUM:
case 3: GAMESTATE->m_PlayMode = PLAY_MODE_NONSTOP; break; case CHOICE_HARD: GAMESTATE->m_PlayMode = PLAY_MODE_ARCADE; break;
case 4: GAMESTATE->m_PlayMode = PLAY_MODE_ONI; break; case CHOICE_NONSTOP: GAMESTATE->m_PlayMode = PLAY_MODE_NONSTOP; break;
case 5: GAMESTATE->m_PlayMode = PLAY_MODE_ENDLESS; break; case CHOICE_ONI: GAMESTATE->m_PlayMode = PLAY_MODE_ONI; break;
case CHOICE_ENDLESS: GAMESTATE->m_PlayMode = PLAY_MODE_ENDLESS; break;
default: ASSERT(0); // bad selection default: ASSERT(0); // bad selection
} }
@@ -257,7 +314,7 @@ void ScreenSelectDifficulty::MenuRight( PlayerNumber pn )
ChangeTo( pn, m_Choice[pn], m_Choice[pn]+1 ); ChangeTo( pn, m_Choice[pn], m_Choice[pn]+1 );
} }
bool ScreenSelectDifficulty::IsItemOnPage2( int iItemIndex ) bool ScreenSelectDifficulty::IsOnPage2( int iItemIndex )
{ {
ASSERT( iItemIndex >= 0 && iItemIndex < NUM_CHOICES ); ASSERT( iItemIndex >= 0 && iItemIndex < NUM_CHOICES );
@@ -268,19 +325,19 @@ bool ScreenSelectDifficulty::SelectedSomethingOnPage2()
{ {
for( int p=0; p<NUM_PLAYERS; p++ ) for( int p=0; p<NUM_PLAYERS; p++ )
{ {
if( GAMESTATE->IsPlayerEnabled(p) && IsItemOnPage2(m_Choice[p]) ) if( GAMESTATE->IsPlayerEnabled(p) && IsOnPage2(m_Choice[p]) )
return true; return true;
} }
return false; return false;
} }
void ScreenSelectDifficulty::ChangeTo( PlayerNumber pn, int iSelectionWas, int iSelectionIs ) void ScreenSelectDifficulty::ChangeTo( PlayerNumber pn, int iOldChoice, int iNewChoice )
{ {
bool bChangedPagesFrom1To2 = iSelectionWas < 3 && iSelectionIs >= 3; bool bChangedPagesFrom1To2 = !IsOnPage2(iOldChoice) && IsOnPage2(iNewChoice);
bool bChangedPagesFrom2To1 = iSelectionWas >= 3 && iSelectionIs < 3; bool bChangedPagesFrom2To1 = IsOnPage2(iOldChoice) && !IsOnPage2(iNewChoice);
bool bChangedPages = bChangedPagesFrom1To2 || bChangedPagesFrom2To1; bool bChangedPages = bChangedPagesFrom1To2 || bChangedPagesFrom2To1;
bool bSelectedSomethingOnPage1 = iSelectionIs < 3; bool bSelectedSomethingOnPage1 = !IsOnPage2(iNewChoice);
bool bSelectedSomethingOnPage2 = iSelectionIs >= 3; bool bSelectedSomethingOnPage2 = IsOnPage2(iNewChoice);
bool bSomeoneMadeAChoice = false; bool bSomeoneMadeAChoice = false;
int p; int p;
@@ -295,12 +352,12 @@ void ScreenSelectDifficulty::ChangeTo( PlayerNumber pn, int iSelectionWas, int i
{ {
// change both players // change both players
for( int p=0; p<NUM_PLAYERS; p++ ) for( int p=0; p<NUM_PLAYERS; p++ )
m_Choice[p] = (Choice)iSelectionIs; m_Choice[p] = (Choice)iNewChoice;
} }
else // moving around in page 1 else // moving around in page 1
{ {
// change only the player who pressed the button // change only the player who pressed the button
m_Choice[pn] = (Choice)iSelectionIs; m_Choice[pn] = (Choice)iNewChoice;
} }
@@ -442,7 +499,7 @@ void ScreenSelectDifficulty::TweenOffScreen()
for( unsigned c=0; c<NUM_CHOICES; c++ ) for( unsigned c=0; c<NUM_CHOICES; c++ )
{ {
if( SelectedSomethingOnPage2() != IsItemOnPage2(c) ) // item isn't on selected page if( SelectedSomethingOnPage2() != IsOnPage2(c) ) // item isn't on selected page
continue; // don't tween continue; // don't tween
const float fPauseTime = c*0.2f; const float fPauseTime = c*0.2f;
@@ -512,7 +569,7 @@ void ScreenSelectDifficulty::TweenOnScreen()
{ {
const float fPauseTime = d*0.2f; const float fPauseTime = d*0.2f;
if( SelectedSomethingOnPage2() != IsItemOnPage2(d) ) // item isn't on the current page if( SelectedSomethingOnPage2() != IsOnPage2(d) ) // item isn't on the current page
continue; // don't tween continue; // don't tween
// set off screen // set off screen
+6 -5
View File
@@ -20,9 +20,11 @@
class ScreenSelectDifficulty : public Screen class ScreenSelectDifficulty : public Screen
{ {
public:
enum Choice enum Choice
{ {
CHOICE_EASY, // page 1 CHOICE_BEGINNER = 0, // page 1
CHOICE_EASY,
CHOICE_MEDIUM, CHOICE_MEDIUM,
CHOICE_HARD, CHOICE_HARD,
CHOICE_NONSTOP, // page 2 CHOICE_NONSTOP, // page 2
@@ -31,11 +33,10 @@ class ScreenSelectDifficulty : public Screen
NUM_CHOICES NUM_CHOICES
}; };
#define NUM_CHOICES_ON_PAGE_1 3 // easy, medium, hard, #define NUM_CHOICES_ON_PAGE_1 4 // beginner, easy, medium, hard,
#define NUM_CHOICES_ON_PAGE_2 3 // Nonstop, Oni, Endless #define NUM_CHOICES_ON_PAGE_2 3 // Nonstop, Oni, Endless
#define NUM_PAGES 2 #define NUM_PAGES 2
public:
ScreenSelectDifficulty(); ScreenSelectDifficulty();
virtual ~ScreenSelectDifficulty(); virtual ~ScreenSelectDifficulty();
@@ -53,9 +54,9 @@ public:
void TweenOnScreen(); void TweenOnScreen();
private: private:
void ChangeTo( PlayerNumber pn, int iSelectionWas, int iSelectionIs ); void ChangeTo( PlayerNumber pn, int iOldChoice, int iNewChoice );
bool IsItemOnPage2( int iItemIndex ); bool IsOnPage2( int iChoice );
bool SelectedSomethingOnPage2(); // checks selection of players bool SelectedSomethingOnPage2(); // checks selection of players
MenuElements m_Menu; MenuElements m_Menu;
+1
View File
@@ -60,6 +60,7 @@ ScreenSelectGame::ScreenSelectGame() :
g_SelectGameLines, g_SelectGameLines,
NUM_SELECT_GAME_LINES, NUM_SELECT_GAME_LINES,
false ); false );
m_Menu.SetTimer( 99 );
m_Menu.StopTimer(); m_Menu.StopTimer();
SOUNDMAN->PlayMusic( THEME->GetPathTo("Sounds","select game music") ); SOUNDMAN->PlayMusic( THEME->GetPathTo("Sounds","select game music") );
+1 -1
View File
@@ -136,7 +136,7 @@ ScreenSelectMusic::ScreenSelectMusic()
m_sprDifficultyFrame[p].SetState( p ); m_sprDifficultyFrame[p].SetState( p );
this->AddChild( &m_sprDifficultyFrame[p] ); this->AddChild( &m_sprDifficultyFrame[p] );
m_DifficultyIcon[p].Load( THEME->GetPathTo("graphics","select music difficulty icons 1x6") ); m_DifficultyIcon[p].Load( THEME->GetPathTo("graphics","select music difficulty icons 1x5") );
m_DifficultyIcon[p].SetXY( DIFFICULTY_ICON_X(p), DIFFICULTY_ICON_Y(p) ); m_DifficultyIcon[p].SetXY( DIFFICULTY_ICON_X(p), DIFFICULTY_ICON_Y(p) );
this->AddChild( &m_DifficultyIcon[p] ); this->AddChild( &m_DifficultyIcon[p] );
+1 -19
View File
@@ -556,22 +556,6 @@ void Song::TidyUpData()
} }
} }
// challenge notes are encoded as smaniac. If there is only one Notes for
// a NotesType and it's "smaniac", then convert it to "Challenge"
for( NotesType nt=(NotesType)0; nt<NUM_NOTES_TYPES; nt=(NotesType)(nt+1) )
{
vector<Notes*> apNotes;
GetNotesThatMatch( nt, apNotes );
if( apNotes.size() == 1 )
{
if( 0 == apNotes[0]->GetDescription().CompareNoCase("smaniac") )
{
apNotes[0]->SetDescription("Challenge");
apNotes[0]->SetDifficulty(DIFFICULTY_HARD);
}
}
}
for( i=0; i<m_apNotes.size(); i++ ) for( i=0; i<m_apNotes.size(); i++ )
m_apNotes[i]->Compress(); m_apNotes[i]->Compress();
} }
@@ -707,9 +691,7 @@ void Song::ReCalulateRadarValuesAndLastBeat()
/* 桜 */ /* 桜 */
ttab.push_back(TitleTrans("^Sakura$", "", "", "&sakura;", "", "") ); ttab.push_back(TitleTrans("^Sakura$", "", "", "&sakura;", "", "") );
/* XXX: "door of magic" (mahou no tobira) -> 魔法の扉 */ /* XXX: "door of magic" (tobira no mahou) -> 魔法の扉 */
ttab.push_back(TitleTrans("^Door of Magic$", "", "", "&mahou1;&mahou2;&hno;&tobira;", "", "") );
ttab.push_back(TitleTrans("^mahou no tobira$", "", "", "&mahou1;&mahou2;&hno;&tobira;", "", "") );
/* XXX スペース★マコのテーマ (space? special? * "mako"?'s team) (title or subtitle, not sure) */ /* XXX スペース★マコのテーマ (space? special? * "mako"?'s team) (title or subtitle, not sure) */
/* Subtitles: */ /* Subtitles: */
+7 -10
View File
@@ -320,30 +320,27 @@ try_element_again:
#ifdef _DEBUG #ifdef _DEBUG
CString sMessage = ssprintf("The theme element %s/%s is missing.",sAssetCategory.GetString(),sFileName.GetString()); CString sMessage = ssprintf("The theme element %s/%s is missing.",sAssetCategory.GetString(),sFileName.GetString());
switch( MessageBox(NULL, sMessage, "ThemeManager", MB_ABORTRETRYIGNORE ) ) switch( MessageBox(NULL, sMessage, "ThemeManager", MB_RETRYCANCEL ) )
{ {
case IDRETRY: case IDRETRY:
goto try_element_again; goto try_element_again;
case IDABORT: case IDCANCEL:
break; RageException::Throw( "Theme element '%s/%s' could not be found in '%s' or '%s'.",
case IDIGNORE:
LOG->Warn(
"Theme element '%s/%s' could not be found in '%s' or '%s'.",
sAssetCategory.GetString(), sAssetCategory.GetString(),
sFileName.GetString(), sFileName.GetString(),
GetThemeDirFromName(m_sCurThemeName).GetString(), GetThemeDirFromName(m_sCurThemeName).GetString(),
GetThemeDirFromName(BASE_THEME_NAME).GetString() ); GetThemeDirFromName(BASE_THEME_NAME).GetString() );
return GetPathTo( sAssetCategory, "_missing" ); break;
} }
#endif #endif
RageException::Throw( "Theme element '%s/%s' could not be found in '%s' or '%s'.", LOG->Warn(
"Theme element '%s/%s' could not be found in '%s' or '%s'.",
sAssetCategory.GetString(), sAssetCategory.GetString(),
sFileName.GetString(), sFileName.GetString(),
GetThemeDirFromName(m_sCurThemeName).GetString(), GetThemeDirFromName(m_sCurThemeName).GetString(),
GetThemeDirFromName(BASE_THEME_NAME).GetString() ); GetThemeDirFromName(BASE_THEME_NAME).GetString() );
return GetPathTo( sAssetCategory, "_missing" );
return ""; // shut VC6 up
} }