various changes from sm4 and sm-ssc (svn); see updated changelog for the full information

This commit is contained in:
AJ Kelly
2010-02-18 23:17:24 -06:00
parent f9bfc80fa9
commit 5c5ef54a48
26 changed files with 436 additions and 260 deletions
-4
View File
@@ -16,10 +16,7 @@
#include "RageFileManager.h"
#include "CourseWriterCRS.h"
//
// Sorting stuff
//
static bool CompareCoursePointersByName( const Course* pCourse1, const Course* pCourse2 )
{
RString sName1 = pCourse1->GetDisplayFullTitle();
@@ -187,7 +184,6 @@ void CourseUtil::SortCoursePointerArrayByAvgDifficulty( vector<Course*> &vpCours
stable_sort( vpCoursesInOut.begin(), vpCoursesInOut.end(), MovePlayersBestToEnd );
}
void CourseUtil::SortCoursePointerArrayByNumPlays( vector<Course*> &vpCoursesInOut, ProfileSlot slot, bool bDescending )
{
+37
View File
@@ -116,6 +116,43 @@ void LuaHelpers::ReadArrayFromTableB( Lua *L, vector<bool> &aOut )
}
}
namespace
{
/* Creates a table from an XNode and leaves it on the stack. */
void CreateTableFromXNodeRecursive( Lua *L, const XNode *pNode )
{
// create our base table
lua_newtable( L );
FOREACH_CONST_Attr( pNode, pAttr )
{
lua_pushstring( L, pAttr->first ); // push key
pNode->PushAttrValue( L, pAttr->first ); // push value
//add key-value pair to our table
lua_settable( L, -3 );
}
FOREACH_CONST_Child( pNode, c )
{
const XNode *pChild = c;
lua_pushstring( L, pChild->m_sName ); // push key
// push value (more correctly, build this child's table and leave it there
CreateTableFromXNodeRecursive( L, pChild );
// add key-value pair to the table
lua_settable( L, -3 );
}
}
}
void LuaHelpers::CreateTableFromXNode( Lua *L, const XNode *pNode )
{
// This creates our table and leaves it on the stack.
CreateTableFromXNodeRecursive( L, pNode );
}
static int GetLuaStack( lua_State *L )
{
+11 -8
View File
@@ -30,12 +30,12 @@ public:
Lua *Get();
void Release( Lua *&p );
/* Explicitly lock and unlock Lua access. This is done automatically by Get() and
* Release(). */
/* Explicitly lock and unlock Lua access. This is done automatically by
* Get() and Release(). */
void YieldLua();
void UnyieldLua();
/* Register all subscribing types. There's no harm in registering when already registered. */
// Register all subscribing types. There's no harm in registering when already registered.
void RegisterTypes();
void SetGlobal( const RString &sName, int val );
@@ -60,12 +60,12 @@ namespace LuaHelpers
* false is returned. */
bool RunScriptOnStack( Lua *L, RString &sError, int iArgs = 0, int iReturnValues = 0 );
/* LoadScript the given script, and RunScriptOnStack it. iArgs arguments are
/* LoadScript the given script, and RunScriptOnStack it. iArgs arguments are
* at the top of the stack. */
bool RunScript( Lua *L, const RString &sScript, const RString &sName, RString &sError, int iArgs = 0, int iReturnValues = 0 );
/* Run the given expression, returning a single value, and leave the return value on the
* stack. On error, push nil. */
/* Run the given expression, returning a single value, and leave the return
* value on the stack. On error, push nil. */
bool RunExpression( Lua *L, const RString &sExpression, const RString &sName = "" );
bool RunScriptFile( const RString &sFile );
@@ -73,12 +73,15 @@ namespace LuaHelpers
/* Create a Lua array (a table with indices starting at 1) of the given vector,
* and push it on the stack. */
void CreateTableFromArrayB( Lua *L, const vector<bool> &aIn );
// Create a Lua table with contents set from this XNode, then push it on the stack.
void CreateTableFromXNode( Lua *L, const XNode *pNode );
/* Recursively copy elements from the table at stack element -2 into the table
* at stack -1. Pop both elements from the stack. */
void DeepCopy( lua_State *L );
/* Read the table at the top of the stack back into a vector. */
// Read the table at the top of the stack back into a vector.
void ReadArrayFromTableB( Lua *L, vector<bool> &aOut );
void ParseCommandList( lua_State *L, const RString &sCommands, const RString &sName );
+3 -1
View File
@@ -365,6 +365,7 @@ void MusicWheel::GetSongList( vector<Song*> &arraySongs, SortOrder so )
if( (so!=SORT_ROULETTE || !RANDOM_PICKS_LOCKED_SONGS) && iLocked )
continue;
if( PREFSMAN->m_bOnlyPreferredDifficulties )
{
// if the song has steps that fit the preferred difficulty of the default player
@@ -378,6 +379,7 @@ void MusicWheel::GetSongList( vector<Song*> &arraySongs, SortOrder so )
arraySongs.push_back( pSong );
}
}
/* Hack: Add extra stage item if it was eliminated for any reason (eg. it's a long
@@ -437,7 +439,7 @@ void MusicWheel::BuildWheelItemDatas( vector<MusicWheelItemData *> &arrayWheelIt
// Make an array of Song*, then sort them
vector<Song*> arraySongs;
GetSongList(arraySongs, so);
GetSongList( arraySongs, so );
bool bUseSections = true;
+1 -1
View File
@@ -36,7 +36,7 @@ NoteField::NoteField()
m_pNoteData = NULL;
m_pCurDisplay = NULL;
m_textMeasureNumber.LoadFromFont( THEME->GetPathF("Common","normal") );
m_textMeasureNumber.LoadFromFont( THEME->GetPathF("NoteField","MeasureNumber") );
m_textMeasureNumber.SetZoom( 1.0f );
m_textMeasureNumber.SetShadowLength( 2 );
m_textMeasureNumber.SetWrapWidthPixels( 300 );
+2 -2
View File
@@ -71,7 +71,7 @@ public:
// Called when a fret, step, or strum type button changes
void Fret( int col, int row, const RageTimer &tm, bool bHeld, bool bRelease );
// Called when the strum bar is pressed down
void Strum( int col, int row, const RageTimer &tm, bool bHeld, bool bRelease );
@@ -86,7 +86,7 @@ public:
// called by Fret for Hammer-ons and Pull-offs
void Hopo( int col, int row, const RageTimer &tm, bool bHeld, bool bRelease ) { StepStrumHopo(col, row, tm, bHeld, bRelease, ButtonType_Hopo); }
void RandomizeNotes( int iNoteRow );
void FadeToFail();
void CacheAllUsedNoteSkins();
+67 -48
View File
@@ -147,6 +147,8 @@ void Profile::InitGeneralData()
m_iNumTotalSongsPlayed = 0;
ZERO( m_iNumStagesPassedByPlayMode );
ZERO( m_iNumStagesPassedByGrade );
m_UserData.Unset();
}
void Profile::InitSongScores()
@@ -328,50 +330,50 @@ float Profile::GetSongsPossible( StepsType st, Difficulty dc ) const
float Profile::GetSongsActual( StepsType st, Difficulty dc ) const
{
CHECKPOINT_M( ssprintf("Profile::GetSongsActual(%d,%d)",st,dc) );
float fTotalPercents = 0;
// add steps high scores
FOREACHM_CONST( SongID, HighScoresForASong, m_SongHighScores, i )
{
const SongID &id = i->first;
Song* pSong = id.ToSong();
CHECKPOINT_M( ssprintf("Profile::GetSongsActual: %p", pSong) );
// If the Song isn't loaded on the current machine, then we can't
// get radar values to compute dance points.
if( pSong == NULL )
continue;
if( !pSong->NormallyDisplayed() )
continue; // skip
CHECKPOINT_M( ssprintf("Profile::GetSongsActual: song %s", pSong->GetSongDir().c_str()) );
const HighScoresForASong &hsfas = i->second;
FOREACHM_CONST( StepsID, HighScoresForASteps, hsfas.m_StepsHighScores, j )
{
const StepsID &id = j->first;
Steps* pSteps = id.ToSteps( pSong, true );
CHECKPOINT_M( ssprintf("Profile::GetSongsActual: song %p, steps %p", pSong, pSteps) );
// If the Steps isn't loaded on the current machine, then we can't
// get radar values to compute dance points.
if( pSteps == NULL )
continue;
if( pSteps->m_StepsType != st )
continue;
CHECKPOINT_M( ssprintf("Profile::GetSongsActual: n %s = %p", id.ToString().c_str(), pSteps) );
if( pSteps->GetDifficulty() != dc )
continue; // skip
CHECKPOINT;
const HighScoresForASteps& h = j->second;
const HighScoreList& hsl = h.hsl;
fTotalPercents += hsl.GetTopScore().GetPercentDP();
}
CHECKPOINT;
@@ -418,11 +420,11 @@ float Profile::GetCoursesPossible( StepsType st, CourseDifficulty cd ) const
return (float) iTotalTrails;
}
float Profile::GetCoursesActual( StepsType st, CourseDifficulty cd ) const
{
float fTotalPercents = 0;
vector<Course*> vpCourses;
GetHighScoreCourses( vpCourses );
FOREACH_CONST( Course*, vpCourses, c )
@@ -550,9 +552,7 @@ Course *Profile::GetMostPopularCourse() const
return id.ToCourse();
}
//
// Steps high scores
//
void Profile::AddStepsHighScore( const Song* pSong, const Steps* pSteps, HighScore hs, int &iIndexOut )
{
GetStepsHighScoreList(pSong,pSteps).AddHighScore( hs, iIndexOut, IsMachine() );
@@ -567,10 +567,10 @@ HighScoreList& Profile::GetStepsHighScoreList( const Song* pSong, const Steps* p
{
SongID songID;
songID.FromSong( pSong );
StepsID stepsID;
stepsID.FromSteps( pSteps );
HighScoresForASong &hsSong = m_SongHighScores[songID]; // operator[] inserts into map
HighScoresForASteps &hsSteps = hsSong.m_StepsHighScores[stepsID]; // operator[] inserts into map
@@ -639,7 +639,6 @@ void Profile::GetGrades( const Song* pSong, StepsType st, int iCounts[NUM_Grade]
SongID songID;
songID.FromSong( pSong );
memset( iCounts, 0, sizeof(int)*NUM_Grade );
const HighScoresForASong *hsSong = GetHighScoresForASong( songID );
if( hsSong == NULL )
@@ -660,9 +659,7 @@ void Profile::GetGrades( const Song* pSong, StepsType st, int iCounts[NUM_Grade]
}
}
//
// Course high scores
//
void Profile::AddCourseHighScore( const Course* pCourse, const Trail* pTrail, HighScore hs, int &iIndexOut )
{
GetCourseHighScoreList(pCourse,pTrail).AddHighScore( hs, iIndexOut, IsMachine() );
@@ -739,9 +736,7 @@ void Profile::IncrementCoursePlayCount( const Course* pCourse, const Trail* pTra
GetCourseHighScoreList(pCourse,pTrail).IncrementPlayCount( now );
}
//
// Category high scores
//
void Profile::AddCategoryHighScore( StepsType st, RankingCategory rc, HighScore hs, int &iIndexOut )
{
m_CategoryHighScores[st][rc].AddHighScore( hs, iIndexOut, IsMachine() );
@@ -772,10 +767,7 @@ void Profile::IncrementCategoryPlayCount( StepsType st, RankingCategory rc )
}
//
// Loading and saving
//
#define WARN_PARSER ShowWarningOrTrace( __FILE__, __LINE__, "Error parsing file.", true )
#define WARN_AND_RETURN { WARN_PARSER; return; }
#define WARN_AND_CONTINUE { WARN_PARSER; continue; }
@@ -801,7 +793,7 @@ ProfileLoadResult Profile::LoadAllFromDir( RString sDir, bool bRequireSignature
// Not critical if this fails
LoadEditableDataFromDir( sDir );
// Check for the existance of stats.xml
RString fn = sDir + STATS_XML;
bool bCompressed = false;
@@ -836,9 +828,7 @@ ProfileLoadResult Profile::LoadAllFromDir( RString sDir, bool bRequireSignature
pFile.reset( pInflate );
}
//
// Don't unreasonably large stats.xml files.
//
// Don't load unreasonably large stats.xml files.
if( !IsMachine() ) // only check stats coming from the player
{
int iBytes = pFile->GetFileSize();
@@ -884,8 +874,8 @@ ProfileLoadResult Profile::LoadAllFromDir( RString sDir, bool bRequireSignature
ProfileLoadResult Profile::LoadStatsXmlFromNode( const XNode *xml, bool bIgnoreEditable )
{
/* The placeholder stats.xml file has an <html> tag. Don't load it, but don't
* warn about it. */
/* The placeholder stats.xml file has an <html> tag. Don't load it,
* but don't warn about it. */
if( xml->GetName() == "html" )
return ProfileLoadResult_FailedNoProfile;
@@ -895,8 +885,7 @@ ProfileLoadResult Profile::LoadStatsXmlFromNode( const XNode *xml, bool bIgnoreE
return ProfileLoadResult_FailedTampered;
}
/* These are loaded from Editable, so we usually want to ignore them
* here. */
// These are loaded from Editable, so we usually want to ignore them here.
RString sName = m_sDisplayName;
RString sCharacterID = m_sCharacterID;
RString sLastUsedHighScoreName = m_sLastUsedHighScoreName;
@@ -929,7 +918,7 @@ bool Profile::SaveAllToDir( RString sDir, bool bSignData ) const
SaveEditableDataToDir( sDir );
bool bSaved = SaveStatsXmlToDir( sDir, bSignData );
SaveStatsWebPageToDir( sDir );
// Empty directories if none exist.
@@ -963,7 +952,7 @@ bool Profile::SaveStatsXmlToDir( RString sDir, bool bSignData ) const
{
LOG->Trace( "SaveStatsXmlToDir: %s", sDir.c_str() );
auto_ptr<XNode> xml( SaveStatsXmlCreateNode() );
// Save stats.xml
RString fn = sDir + (g_bProfileDataCompress? STATS_XML_GZ:STATS_XML);
@@ -975,7 +964,7 @@ bool Profile::SaveStatsXmlToDir( RString sDir, bool bSignData ) const
LOG->Warn( "Couldn't open %s for writing: %s", fn.c_str(), f.GetError().c_str() );
return false;
}
if( g_bProfileDataCompress )
{
RageFileObjGzip gzip( &f );
@@ -1097,7 +1086,7 @@ XNode* Profile::SaveGeneralDataCreateNode() const
XNode* pNumSongsPlayedByPlayMode = pGeneralDataNode->AppendChild("NumSongsPlayedByPlayMode");
FOREACH_ENUM( PlayMode, pm )
{
/* Don't save unplayed PlayModes. */
// Don't save unplayed PlayModes.
if( !m_iNumSongsPlayedByPlayMode[pm] )
continue;
pNumSongsPlayedByPlayMode->AppendChild( PlayModeToString(pm), m_iNumSongsPlayedByPlayMode[pm] );
@@ -1144,7 +1133,7 @@ XNode* Profile::SaveGeneralDataCreateNode() const
XNode* pNumStagesPassedByPlayMode = pGeneralDataNode->AppendChild("NumStagesPassedByPlayMode");
FOREACH_ENUM( PlayMode, pm )
{
/* Don't save unplayed PlayModes. */
// Don't save unplayed PlayModes.
if( !m_iNumStagesPassedByPlayMode[pm] )
continue;
pNumStagesPassedByPlayMode->AppendChild( PlayModeToString(pm), m_iNumStagesPassedByPlayMode[pm] );
@@ -1161,6 +1150,19 @@ XNode* Profile::SaveGeneralDataCreateNode() const
}
}
// Load Lua UserData from profile
if( !IsMachine() && m_UserData.IsSet() )
{
Lua *L = LUA->Get();
m_UserData.PushSelf( L );
XNode* pUserTable = XmlFileUtil::XNodeFromTable( L );
LUA->Release( L );
// XXX: XNodeFromTable returns a root node with the name "Layer".
pUserTable->m_sName = "UserData";
pGeneralDataNode->AppendChild( pUserTable );
}
return pGeneralDataNode;
}
@@ -1168,13 +1170,11 @@ ProfileLoadResult Profile::LoadEditableDataFromDir( RString sDir )
{
RString fn = sDir + EDITABLE_INI;
//
// Don't load unreasonably large editable.xml files.
//
int iBytes = FILEMAN->GetFileSizeInBytes( fn );
if( iBytes > MAX_EDITABLE_INI_SIZE_BYTES )
{
LOG->Warn( "The file '%s' is unreasonably large. It won't be loaded.", fn.c_str() );
LOG->Warn( "The file '%s' is unreasonably large. It won't be loaded.", fn.c_str() );
return ProfileLoadResult_FailedTampered;
}
@@ -1331,7 +1331,24 @@ void Profile::LoadGeneralDataFromNode( const XNode* pNode )
if( pNumStagesPassedByPlayMode )
FOREACH_ENUM( PlayMode, pm )
pNumStagesPassedByPlayMode->GetChildValue( PlayModeToString(pm), m_iNumStagesPassedByPlayMode[pm] );
}
// Build the custom data table from the existing XNode.
if( !IsMachine() )
{
const XNode *pUserData = pNode->GetChild( "UserData" );
Lua *L = LUA->Get();
// If we have custom data, load it. Otherwise, make a blank table.
if( pUserData )
LuaHelpers::CreateTableFromXNode( L, pUserData );
else
lua_newtable( L );
m_UserData.SetFromStack( L );
LUA->Release( L );
}
}
@@ -1361,7 +1378,7 @@ XNode* Profile::SaveSongScoresCreateNode() const
XNode* pNode = new XNode( "SongScores" );
FOREACHM_CONST( SongID, HighScoresForASong, m_SongHighScores, i )
{
{
const SongID &songID = i->first;
const HighScoresForASong &hsSong = i->second;
@@ -1374,7 +1391,7 @@ XNode* Profile::SaveSongScoresCreateNode() const
int jCheck2 = hsSong.m_StepsHighScores.size();
int jCheck1 = 0;
FOREACHM_CONST( StepsID, HighScoresForASteps, hsSong.m_StepsHighScores, j )
{
{
jCheck1++;
ASSERT( jCheck1 <= jCheck2 );
const StepsID &stepsID = j->first;
@@ -1391,7 +1408,7 @@ XNode* Profile::SaveSongScoresCreateNode() const
pStepsNode->AppendChild( hsl.CreateNode() );
}
}
return pNode;
}
@@ -1440,7 +1457,7 @@ XNode* Profile::SaveCourseScoresCreateNode() const
ASSERT( pProfile );
XNode* pNode = new XNode( "CourseScores" );
FOREACHM_CONST( CourseID, HighScoresForACourse, m_CourseHighScores, i )
{
const CourseID &courseID = i->first;
@@ -1490,7 +1507,7 @@ void Profile::LoadCourseScoresFromNode( const XNode* pCourseScores )
courseID.LoadFromNode( pCourse );
if( !courseID.IsValid() )
WARN_AND_CONTINUE;
// Backward compatability hack to fix importing scores of old style
// courses that weren't in group folder but have now been moved into
@@ -2001,6 +2018,7 @@ public:
static int GetTotalRolls( T* p, lua_State *L ) { lua_pushnumber(L, p->m_iTotalRolls ); return 1; }
static int GetTotalMines( T* p, lua_State *L ) { lua_pushnumber(L, p->m_iTotalMines ); return 1; }
static int GetTotalHands( T* p, lua_State *L ) { lua_pushnumber(L, p->m_iTotalHands ); return 1; }
static int GetUserData( T* p, lua_State *L ) { p->m_UserData.PushSelf(L); return 1; }
LunaProfile()
{
@@ -2044,6 +2062,7 @@ public:
ADD_METHOD( GetTotalRolls );
ADD_METHOD( GetTotalMines );
ADD_METHOD( GetTotalHands );
ADD_METHOD( GetUserData );
}
};
+2 -20
View File
@@ -15,6 +15,7 @@
#include "CourseUtil.h" // for CourseID
#include "TrailUtil.h" // for TrailID
#include "StyleUtil.h" // for StyleID
#include "LuaReference.h"
class XNode;
struct lua_State;
@@ -63,9 +64,7 @@ public:
InitAll();
}
//
// smart accessors
//
RString GetDisplayNameOrHighScoreName() const;
Character *GetCharacter() const;
RString GetDisplayTotalCaloriesBurned() const; // remove me and use Lua instead
@@ -92,17 +91,13 @@ public:
bool IsMachine() const;
//
// Editable data
//
RString m_sDisplayName;
RString m_sCharacterID;
RString m_sLastUsedHighScoreName; // this doesn't really belong in "editable", but we need it in the smaller editable file so that it can be ready quickly.
int m_iWeightPounds; // 0 == not set
//
// General data
//
static RString MakeGuid();
RString m_sGuid;
@@ -143,10 +138,9 @@ public:
int m_iNumTotalSongsPlayed;
int m_iNumStagesPassedByPlayMode[NUM_PlayMode];
int m_iNumStagesPassedByGrade[NUM_Grade];
LuaReference m_UserData;
//
// Song high scores
//
struct HighScoresForASteps
{
HighScoreList hsl;
@@ -170,9 +164,7 @@ public:
bool HasPassedSteps( const Song* pSong, const Steps* pSteps ) const;
bool HasPassedAnyStepsInSong( const Song* pSong ) const;
//
// Course high scores
//
// struct was a typedef'd array of HighScores, but VC6 freaks out
// in processing the templates for map::operator[].
struct HighScoresForATrail
@@ -195,9 +187,7 @@ public:
void IncrementCoursePlayCount( const Course* pCourse, const Trail* pTrail );
//
// Category high scores
//
HighScoreList m_CategoryHighScores[NUM_StepsType][NUM_RankingCategory];
void AddCategoryHighScore( StepsType st, RankingCategory rc, HighScore hs, int &iIndexOut );
@@ -207,17 +197,13 @@ public:
void IncrementCategoryPlayCount( StepsType st, RankingCategory rc );
//
// Screenshot Data
//
vector<Screenshot> m_vScreenshots;
void AddScreenshot( const Screenshot &screenshot );
int GetNextScreenshotIndex() { return m_vScreenshots.size(); }
//
// Calorie Data
//
// Why track calories in a map, and not in a static sized array like
// Bookkeeping? The machine's clock is not guaranteed to be set correctly.
// If calorie array is in a static sized array, playing on a machine with
@@ -263,9 +249,7 @@ public:
void SaveCourseRecentScore( const Course* pCourse, const Trail* pTrail, HighScore hs );
*/
//
// Init'ing
//
void InitAll()
{
InitEditableData();
@@ -285,9 +269,7 @@ public:
void InitCalorieData();
void ClearStats();
//
// Loading and saving
//
ProfileLoadResult LoadAllFromDir( RString sDir, bool bRequireSignature );
bool SaveAllToDir( RString sDir, bool bSignData ) const;
+2 -10
View File
@@ -35,7 +35,7 @@ public:
Profile *GetLocalProfile( const RString &sProfileID ) { return (Profile*) ((const ProfileManager *) this)->GetLocalProfile(sProfileID); }
Profile *GetLocalProfileFromIndex( int iIndex );
RString GetLocalProfileIDFromIndex( int iIndex );
bool CreateLocalProfile( RString sName, RString &sProfileIDOut );
void AddLocalProfileByID( Profile *pProfile, RString sProfileID ); // transfers ownership of pProfile
bool RenameLocalProfile( RString sProfileID, RString sNewName );
@@ -82,24 +82,17 @@ public:
bool LastLoadWasTamperedOrCorrupt( PlayerNumber pn ) const;
bool LastLoadWasFromLastGood( PlayerNumber pn ) const;
//
// Song stats
//
int GetSongNumTimesPlayed( const Song* pSong, ProfileSlot card ) const;
bool IsSongNew( const Song* pSong ) const { return GetSongNumTimesPlayed(pSong,ProfileSlot_Machine)==0; }
void AddStepsScore( const Song* pSong, const Steps* pSteps , PlayerNumber pn, const HighScore &hs, int &iPersonalIndexOut, int &iMachineIndexOut );
void IncrementStepsPlayCount( const Song* pSong, const Steps* pSteps, PlayerNumber pn );
//
// Course stats
//
void AddCourseScore( const Course* pCourse, const Trail* pTrail, PlayerNumber pn, const HighScore &hs, int &iPersonalIndexOut, int &iMachineIndexOut );
void IncrementCoursePlayCount( const Course* pCourse, const Trail* pTrail, PlayerNumber pn );
//
// Category stats
//
void AddCategoryScore( StepsType st, RankingCategory rc, PlayerNumber pn, const HighScore &hs, int &iPersonalIndexOut, int &iMachineIndexOut );
void IncrementCategoryPlayCount( StepsType st, RankingCategory rc, PlayerNumber pn );
@@ -126,12 +119,11 @@ private:
bool m_bLastLoadWasTamperedOrCorrupt[NUM_PLAYERS]; // true if Stats.xml was present, but failed to load (probably because of a signature failure)
bool m_bLastLoadWasFromLastGood[NUM_PLAYERS]; // if true, then m_bLastLoadWasTamperedOrCorrupt is also true
mutable bool m_bNeedToBackUpLastLoad[NUM_PLAYERS]; // if true, back up profile on next save
Profile *m_pMemoryCardProfile[NUM_PLAYERS]; // holds Profile for the currently inserted card
Profile *m_pMachineProfile;
};
extern ProfileManager* PROFILEMAN; // global and accessable from anywhere in our program
#endif
+1 -2
View File
@@ -19,7 +19,6 @@ static void GetResolutionFromFileName( RString sPath, int &iWidth, int &iHeight
* Foo (res 512x128).png
* Also allow, eg:
* Foo (dither, res 512x128).png
*
* Be careful that this doesn't get mixed up with frame dimensions. */
static Regex re( "\\([^\\)]*res ([0-9]+)x([0-9]+).*\\)" );
@@ -202,7 +201,7 @@ void RageBitmapTexture::Create()
case 1:
pixfmt = PixelFormat_RGB5A1;
break;
default:
default:
pixfmt = PixelFormat_RGBA4;
break;
}
+5 -8
View File
@@ -15,9 +15,7 @@
#include "DisplayResolutions.h"
#include "arch/ArchHooks/ArchHooks.h"
//
// Statistics stuff
//
RageTimer g_LastCheckTimer;
int g_iNumVerts;
int g_iFPS, g_iVPF, g_iCFPS;
@@ -145,7 +143,7 @@ void RageDisplay::ResetStats()
RString RageDisplay::GetStats() const
{
RString s;
/* If FPS == 0, we don't have stats yet. */
// If FPS == 0, we don't have stats yet.
if( !GetFPS() )
s = "-- FPS\n-- av FPS\n-- VPF";
@@ -182,7 +180,7 @@ void RageDisplay::StatsAddVerts( int iNumVertsRendered ) { g_iVertsRenderedSince
* angle of the line. */
void RageDisplay::DrawPolyLine(const RageSpriteVertex &p1, const RageSpriteVertex &p2, float LineWidth )
{
/* soh cah toa strikes strikes again! */
// soh cah toa strikes strikes again!
float opp = p2.p.x - p1.p.x;
float adj = p2.p.y - p1.p.y;
float hyp = powf(opp*opp + adj*adj, 0.5f);
@@ -197,7 +195,7 @@ void RageDisplay::DrawPolyLine(const RageSpriteVertex &p1, const RageSpriteVerte
float ydist = lsin * LineWidth/2;
float xdist = lcos * LineWidth/2;
v[0].p.x += xdist;
v[0].p.y -= ydist;
v[1].p.x -= xdist;
@@ -221,7 +219,7 @@ void RageDisplay::DrawLineStripInternal( const RageSpriteVertex v[], int iNumVer
for( int i = 0; i < iNumVerts-1; ++i )
DrawPolyLine(v[i], v[i+1], LineWidth);
/* Join the lines with circles so we get rounded corners. */
// Join the lines with circles so we get rounded corners.
for( int i = 0; i < iNumVerts; ++i )
DrawCircle( v[i], LineWidth/2 );
}
@@ -253,6 +251,7 @@ void RageDisplay::SetDefaultRenderStates()
SetCullMode( CULL_NONE );
SetZWrite( false );
SetZTestMode( ZTEST_OFF );
SetStencilTestMode( STENCILTEST_OFF );
SetAlphaTest( true );
SetBlendMode( BLEND_NORMAL );
SetTextureFiltering( TextureUnit_1, true );
@@ -261,9 +260,7 @@ void RageDisplay::SetDefaultRenderStates()
}
//
// Matrix stuff
//
class MatrixStack
{
vector<RageMatrix> stack;
+25 -20
View File
@@ -65,7 +65,6 @@ RageFileDriverReadAhead::RageFileDriverReadAhead( RageFileBasic *pFile, int iCac
m_pFile = pFile;
m_iFilePos = pFile->Tell();
m_bFileOwned = false;
m_bReadAheadNeeded = true;
m_iPostBufferReadAhead = iPostBufferReadAhead;
FillBuffer( iCacheBytes );
@@ -79,7 +78,6 @@ RageFileDriverReadAhead::RageFileDriverReadAhead( const RageFileDriverReadAhead
m_iFilePos = cpy.m_iFilePos;
m_bFileOwned = true;
m_iPostBufferReadAhead = cpy.m_iPostBufferReadAhead;
m_bReadAheadNeeded = cpy.m_bReadAheadNeeded;
RageFileManagerReadAhead::CacheHintStreaming( m_pFile );
}
@@ -117,32 +115,39 @@ void RageFileDriverReadAhead::FillBuffer( int iBytes )
int RageFileDriverReadAhead::ReadInternal( void *pBuffer, size_t iBytes )
{
/* If we're in the buffered area, and we havn't already done read-ahead, start it. */
int iRet = -1;
if( m_bReadAheadNeeded && m_iFilePos < (int) m_sBuffer.size() )
{
RageFileManagerReadAhead::ReadAhead( m_pFile, m_iPostBufferReadAhead );
m_bReadAheadNeeded = false;
// If we can serve data out of the buffer, use it.
iRet = min( iBytes, m_sBuffer.size() - m_iFilePos );
memcpy( pBuffer, m_sBuffer.data() + m_iFilePos, iRet );
}
else if( !m_bReadAheadNeeded && m_iFilePos >= (int) m_sBuffer.size() )
else
{
/* Reset, so next time we rewind we'll read-ahead again. */
m_bReadAheadNeeded = true;
// Read out of the underlying file.
iRet = m_pFile->Read( pBuffer, iBytes );
}
/* If we can serve data out of the buffer, use it. */
if( m_iFilePos < (int) m_sBuffer.size() )
{
size_t iFromBuffer = min( iBytes, m_sBuffer.size() - m_iFilePos );
memcpy( pBuffer, m_sBuffer.data() + m_iFilePos, iFromBuffer );
m_iFilePos += iFromBuffer;
return iFromBuffer;
}
/* Read out of the underlying file. */
int iRet = m_pFile->Read( pBuffer, iBytes );
if( iRet != -1 )
m_iFilePos += iRet;
/*
* Hint the read-ahead. We only strictly need to do this when reading data from
* m_sBuffer, so the kernel knows to start reading data ahead of it. Always
* doing it is simpler, and reduces some skips when under I/O load.
*/
RageFileManagerReadAhead::ReadAhead( m_pFile, m_iPostBufferReadAhead );
/*
* We're streaming the file, so we don't need data that we've already read in cache.
* Hint the OS to discard it, so it doesn't push more useful data out of cache.
*
* Keep the previous 32k of data in cache. This prevents an issue in Linux: if we're at
* the end of the file, flush the cache, then try to read (resulting in 0 bytes), it'll
* hit the disk if we've flushed.
*/
RageFileManagerReadAhead::DiscardCache( m_pFile, -m_iPostBufferReadAhead - 1024*32, m_iPostBufferReadAhead );
return iRet;
}
+22
View File
@@ -22,6 +22,26 @@ void RageFileManagerReadAhead::ReadAhead( RageFileBasic *pFile, int iBytes )
posix_fadvise( iFD, iStart, iBytes, POSIX_FADV_WILLNEED );
}
void RageFileManagerReadAhead::DiscardCache( RageFileBasic *pFile, int iRelativePosition, int iBytes )
{
int iFD = pFile->GetFD();
if( iFD == -1 )
return;
int iStart = lseek( iFD, 0, SEEK_CUR );
iStart += iRelativePosition;
if( iStart < 0 )
{
iBytes -= iStart;
iStart = 0;
}
if( iBytes == 0 )
return;
posix_fadvise( iFD, iStart, iBytes, POSIX_FADV_DONTNEED );
}
#else
#if 0
/* This doesn't currently work, because dup() locks the file position of the new FD with the old
@@ -123,10 +143,12 @@ void RageFileManagerReadAhead::ReadAhead( RageFileBasic *pFile, int iBytes )
}
}
}
void RageFileManagerReadAhead::DiscardCache( RageFileBasic *pFile, int iRelativePosition, int iBytes ) { }
#else
void RageFileManagerReadAhead::Init() { }
void RageFileManagerReadAhead::Shutdown() { }
void RageFileManagerReadAhead::ReadAhead( RageFileBasic *pFile, int iBytes ) { }
void RageFileManagerReadAhead::DiscardCache( RageFileBasic *pFile, int iRelativePosition, int iBytes ) { }
#endif
#endif
+5 -1
View File
@@ -8,9 +8,13 @@ namespace RageFileManagerReadAhead
void Init();
void Shutdown();
/* Nonblockingly read bytes from a file. */
// Nonblockingly read ahead iBytes in pFile, starting at the current file position.
void ReadAhead( RageFileBasic *pFile, int iBytes );
/* Discard iBytes of kernel cache, starting at the current file position plus
* iRelativePosition (which may be negative). */
void DiscardCache( RageFileBasic *pFile, int iRelativePosition, int iBytes );
void CacheHintStreaming( RageFileBasic *pFile );
};
-2
View File
@@ -60,9 +60,7 @@ public:
bool AllowOperatorMenuButton() const { return ALLOW_OPERATOR_MENU_BUTTON; }
virtual bool AllowLateJoin() const { return false; }
//
// Lua
//
virtual void PushSelf( lua_State *L );
protected:
+10 -6
View File
@@ -34,7 +34,7 @@
#include "LightsManager.h"
#include "ProfileManager.h"
#include "StatsManager.h"
#include "PlayerAI.h" // for NUM_SKILL_LEVELS
#include "PlayerAI.h" // for NUM_SKILL_LEVELS
#include "NetworkSyncManager.h"
#include "Foreach.h"
#include "DancingCharacters.h"
@@ -58,6 +58,7 @@
#include "SongUtil.h"
#include "Song.h"
#include "XmlFileUtil.h"
#include "Profile.h" // for replay data stuff
// Defines
#define SHOW_LIFE_METER_FOR_DISABLED_PLAYERS THEME->GetMetricB(m_sName,"ShowLifeMeterForDisabledPlayers")
@@ -671,7 +672,7 @@ void ScreenGameplay::Init()
m_Failed.SetDrawOrder( DRAW_ORDER_TRANSITIONS-1 ); // on top of everything else
this->AddChild( &m_Failed );
m_textDebug.LoadFromFont( THEME->GetPathF("Common","normal") );
m_textDebug.LoadFromFont( THEME->GetPathF(m_sName,"debug") );
m_textDebug.SetName( "Debug" );
LOAD_ALL_COMMANDS_AND_SET_XY( m_textDebug );
m_textDebug.SetDrawOrder( DRAW_ORDER_TRANSITIONS-1 ); // just under transitions, over the foreground
@@ -2760,14 +2761,16 @@ void ScreenGameplay::SaveReplay()
* Add proper steps hash?
* Add modifiers used
* Add date played, machine played on, etc.
* Add/use player GUID
*/
FOREACH_HumanPlayer( pn )
{
FOREACH_EnabledPlayerInfo( m_vPlayerInfo, pi )
{
Profile *pTempProfile = PROFILEMAN->GetProfile(pn);
XNode *p = new XNode("ReplayData");
// todo: add version number, since this will change in the future -aj
// append version number (in case the format changes)
p->AppendAttr("Version",0);
// song information node
SongID songID;
@@ -2787,7 +2790,8 @@ void ScreenGameplay::SaveReplay()
// player information node (rival data sup)
XNode *pPlayerInfoNode = new XNode("Player");
pPlayerInfoNode->AppendChild("Name", PROFILEMAN->GetPlayerName(pn));
pPlayerInfoNode->AppendChild("DisplayName", pTempProfile->m_sDisplayName);
pPlayerInfoNode->AppendChild("Guid", pTempProfile->m_sGuid);
p->AppendChild(pPlayerInfoNode);
// the timings.
@@ -2825,7 +2829,7 @@ void ScreenGameplay::SaveReplay()
/*
bool ScreenGameplay::LoadReplay()
{
// Load
// Load replay which was selected via options
}
*/
-2
View File
@@ -119,9 +119,7 @@ public:
bool Center1Player() const;
//
// Lua
//
virtual void PushSelf( lua_State *L );
Song *GetNextCourseSong() const;
LifeMeter *GetLifeMeter( PlayerNumber pn );
+1 -1
View File
@@ -41,7 +41,7 @@ void ScreenGameplaySyncMachine::Init()
m_DancingState = STATE_DANCING;
m_textSyncInfo.SetName( "SyncInfo" );
m_textSyncInfo.LoadFromFont( THEME->GetPathF("Common","normal") );
m_textSyncInfo.LoadFromFont( THEME->GetPathF(m_sName,"SyncInfo") );
ActorUtil::LoadAllCommands( m_textSyncInfo, m_sName );
this->AddChild( &m_textSyncInfo );
+1 -3
View File
@@ -43,12 +43,10 @@ void ScreenPrompt::SetPromptSettings( const RString &sText, PromptType type, Pro
void ScreenPrompt::Prompt( ScreenMessage smSendOnPop, const RString &sText, PromptType type, PromptAnswer defaultAnswer, void(*OnYes)(void*), void(*OnNo)(void*), void* pCallbackData )
{
SetPromptSettings( sText, type, defaultAnswer, OnYes, OnNo, pCallbackData );
SCREENMAN->AddNewScreenToTop( "ScreenPrompt", smSendOnPop );
}
REGISTER_SCREEN_CLASS( ScreenPrompt );
void ScreenPrompt::Init()
+5 -4
View File
@@ -29,8 +29,8 @@ public:
void Paint()
{
/* We load songs much faster than we draw frames. Cap the draw rate, so we don't
* slow down the reload. */
/* We load songs much faster than we draw frames. Cap the draw rate,
* so we don't slow down the reload. */
if( m_LastDraw.PeekDeltaTime() < 1.0f/DrawFrameRate )
return;
m_LastDraw.GetDeltaTime();
@@ -51,7 +51,8 @@ void ScreenReloadSongs::Init()
m_iUpdates = 0;
m_Loading.LoadFromFont( THEME->GetPathF("Common", "normal") );
m_Loading.SetName("LoadingText");
m_Loading.LoadFromFont( THEME->GetPathF(m_sName, "LoadingText") );
m_Loading.SetXY( SCREEN_CENTER_X, SCREEN_CENTER_Y );
this->AddChild( &m_Loading );
@@ -68,7 +69,7 @@ void ScreenReloadSongs::Update( float fDeltaTime )
{
Screen::Update( fDeltaTime );
/* Start the reload on the second update. On the first, 0, SCREENMAN->Draw won't draw. */
/* Start the reload on the second update. On the first (0), SCREENMAN->Draw won't draw. */
++m_iUpdates;
if( m_iUpdates != 2 )
return;
+38 -52
View File
@@ -67,7 +67,7 @@ void ScreenSelectMaster::Init()
OPTION_ORDER2.Load( m_sName, OPTION_ORDER_NAME_LIST2, NUM_MenuDir );
DO_SWITCH_ANYWAYS.Load( m_sName, "DoSwitchAnyways" );
WRAP_CURSOR.Load( m_sName, "WrapCursor" );
WRAP_SCROLLER.Load( m_sName, "WrapScroller" );
LOOP_SCROLLER.Load( m_sName, "LoopScroller" );
@@ -90,7 +90,6 @@ void ScreenSelectMaster::Init()
#define PLAYER_APPEND_NO_SPACE(p) (SHARED_SELECTION ? RString() : ssprintf("P%d",(p)+1))
this->SubscribeToMessage( SM_MenuTimer );
// init cursor
if( SHOW_CURSOR )
{
@@ -415,11 +414,9 @@ void ScreenSelectMaster::HandleScreenMessage( const ScreenMessage SM )
{
ScreenSelect::HandleScreenMessage( SM );
vector<PlayerNumber> vpns;
GetActiveElementPlayerNumbers( vpns );
if( SM == SM_PlayPostSwitchPage )
{
int iNewChoice = m_iChoice[ GAMESTATE->m_MasterPlayerNumber ];
@@ -441,8 +438,6 @@ void ScreenSelectMaster::HandleScreenMessage( const ScreenMessage SM )
int iChoice = m_iChoice[*p];
m_vsprScroll[*p][iChoice]->HandleMessage( msg );
}
}
m_fLockInputSecs = POST_SWITCH_PAGE_SECONDS;
@@ -458,10 +453,9 @@ void ScreenSelectMaster::HandleScreenMessage( const ScreenMessage SM )
InputEventPlus iep;
iep.pn = p;
MenuStart( iep );
}
}
}
}
}
int ScreenSelectMaster::GetSelectionIndex( PlayerNumber pn )
@@ -532,17 +526,15 @@ void ScreenSelectMaster::UpdateSelectableChoices()
}
}
/*
* If no options are playable at all, just wait. Some external
/* If no options are playable at all, just wait. Some external
* stimulus may make options available (such as coin insertion).
*
* If any options are playable, make sure one is selected.
*/
* If any options are playable, make sure one is selected. */
FOREACH_HumanPlayer( p )
{
if(m_bUsingTwoLists && m_iSelectedList == 1)
{
m_iChoice[p] = 0; // reset their choice position since we are moving to the new list
// reset their choice position since we are moving to the new list:
m_iChoice[p] = 0;
if( !m_aGameCommandsB[m_iChoice[p]].IsPlayable() )
Move( p, MenuDir_Auto );
}
@@ -556,19 +548,19 @@ void ScreenSelectMaster::UpdateSelectableChoices()
bool ScreenSelectMaster::AnyOptionsArePlayable() const
{
// if they're using the second list
if(m_bUsingTwoLists && m_iSelectedList == 1)
{
for( unsigned i = 0; i < m_aGameCommandsB.size(); ++i )
if( m_aGameCommandsB[i].IsPlayable() )
return true;
}
else
{
for( unsigned i = 0; i < m_aGameCommands.size(); ++i )
if( m_aGameCommands[i].IsPlayable() )
return true;
}
// if they're using the second list
if(m_bUsingTwoLists && m_iSelectedList == 1)
{
for( unsigned i = 0; i < m_aGameCommandsB.size(); ++i )
if( m_aGameCommandsB[i].IsPlayable() )
return true;
}
else
{
for( unsigned i = 0; i < m_aGameCommands.size(); ++i )
if( m_aGameCommands[i].IsPlayable() )
return true;
}
return false;
}
@@ -695,14 +687,12 @@ void ScreenSelectMaster::MenuUp( const InputEventPlus &input )
m_soundChange.Play();
MESSAGEMAN->Broadcast( (MessageID)(Message_MenuUpP1+pn) );
MESSAGEMAN->Broadcast( (MessageID)(Message_MenuSelectionChanged) );
// if they use double select
if(DOUBLE_PRESS_TO_SELECT)
{
m_bDoubleChoice[pn] = false; // player has cancelled their selection
}
}
}
@@ -732,7 +722,6 @@ void ScreenSelectMaster::MenuDown( const InputEventPlus &input )
{
m_bDoubleChoice[pn] = false; // player has cancelled their selection
}
}
}
@@ -756,7 +745,7 @@ bool ScreenSelectMaster::ChangePage( int iNewChoice )
if( SHOW_ICON )
for( unsigned c = 0; c < m_aGameCommands.size(); ++c )
m_vsprIcon[c]->PlayCommand( sIconAndExplanationCommand );
FOREACH_ENUM( Page, page )
{
m_sprExplanation[page]->PlayCommand( sIconAndExplanationCommand );
@@ -786,7 +775,7 @@ bool ScreenSelectMaster::ChangePage( int iNewChoice )
{
// XXX: only play this once (I thought we already did that?)
// Play it on every change to page 2. -Chris
/* That sounds ugly if you go back and forth quickly. -g */
// That sounds ugly if you go back and forth quickly. -g
// Should we lock input while it's scrolling? -Chris
m_soundDifficult.Stop();
m_soundDifficult.PlayRandom();
@@ -1057,7 +1046,7 @@ void ScreenSelectMaster::MenuStart( const InputEventPlus &input )
if( input.type != IET_FIRST_PRESS )
return;
PlayerNumber pn = input.pn;
if( m_fLockInputSecs > 0 )
return;
if( m_bChosen[pn] )
@@ -1070,7 +1059,7 @@ void ScreenSelectMaster::MenuStart( const InputEventPlus &input )
if(DOUBLE_PRESS_TO_SELECT && !m_bDoubleChoice[pn])
{
m_soundStart.PlayCopy();
m_bDoubleChoice[pn] = true;
m_bDoubleChoice[pn] = true;
if(SHOW_SCROLLER)
{
@@ -1096,10 +1085,10 @@ void ScreenSelectMaster::MenuStart( const InputEventPlus &input )
* If any options are playable, then the selection must be playable. */
if( !AnyOptionsArePlayable() )
return;
SOUND->PlayOnceFromDir( ANNOUNCER->GetPathTo(ssprintf("%s comment %s",m_sName.c_str(), mc.m_sName.c_str())) );
/* Play a copy of the sound, so it'll finish playing even if we leave the screen immediately. */
// Play a copy of the sound, so it'll finish playing even if we leave the screen immediately.
if( mc.m_sSoundPath.empty() && !m_bDoubleChoiceNoSound )
m_soundStart.PlayCopy();
@@ -1108,12 +1097,12 @@ void ScreenSelectMaster::MenuStart( const InputEventPlus &input )
mc.ApplyToAllPlayers();
return;
}
float fSecs = 0;
bool bAllDone = true;
if( (bool)SHARED_SELECTION || GetCurrentPage() == PAGE_2 )
{
/* Only one player has to pick. Choose this for all the other players, too. */
// Only one player has to pick. Choose this for all the other players, too.
FOREACH_PlayerNumber( p )
{
ASSERT( !m_bChosen[p] );
@@ -1132,18 +1121,15 @@ void ScreenSelectMaster::MenuStart( const InputEventPlus &input )
this->PostScreenMessage( SM_BeginFadingOut, fSecs );// tell our owner it's time to move on
}
/*
* We want all items to always run OnCommand and either GainFocus or LoseFocus on
/* We want all items to always run OnCommand and either GainFocus or LoseFocus on
* tween-in. If we only run OnCommand, then it has to contain a copy of either
* GainFocus or LoseFocus, which implies that the default setting is hard-coded in
* the theme. Always run both.
*
* GainFocus or LoseFocus, which implies that the default setting is hard-coded
* in the theme. Always run both.
* However, the actual tween-in is OnCommand; we don't always want to actually run
* through the Gain/LoseFocus tweens during initial tween-in. So, we run the focus
* command first, do a FinishTweening to pop it in place, and then run OnCommand.
* This means that the focus command should be position neutral; eg. only use "addx",
* not "x".
*/
* not "x". */
void ScreenSelectMaster::TweenOnScreen()
{
vector<PlayerNumber> vpns;
@@ -1175,8 +1161,8 @@ void ScreenSelectMaster::TweenOnScreen()
{
FOREACH( PlayerNumber, vpns, p )
{
// Play Gain/LoseFocus before playing the on command. Gain/Lose will
// often stop tweening, which ruins the OnCommand.
// Play Gain/LoseFocus before playing the on command.
// Gain/Lose will often stop tweening, which ruins the OnCommand.
for( unsigned c=0; c<m_aGameCommands.size(); c++ )
{
m_vsprScrollB[*p][c]->PlayCommand( int(c) == m_iChoice[*p]? "GainFocus":"LoseFocus" );
@@ -1190,8 +1176,8 @@ void ScreenSelectMaster::TweenOnScreen()
{
FOREACH( PlayerNumber, vpns, p )
{
// Play Gain/LoseFocus before playing the on command. Gain/Lose will
// often stop tweening, which ruins the OnCommand.
// Play Gain/LoseFocus before playing the on command.
// Gain/Lose will often stop tweening, which ruins the OnCommand.
for( unsigned c=0; c<m_aGameCommands.size(); c++ )
{
m_vsprScroll[*p][c]->PlayCommand( int(c) == m_iChoice[*p]? "GainFocus":"LoseFocus" );
@@ -1223,7 +1209,7 @@ void ScreenSelectMaster::TweenOffScreen()
GetActiveElementPlayerNumbers( vpns );
// using two lists -- may need to consider throwing a wider range of commands
// for themers if tweening out with one/two lists/focussed/not focussed etc?
// for themers if tweening out with one/two lists/focused/not focused etc?
if(m_bUsingTwoLists && m_iSelectedList == 1)
{
for( unsigned c=0; c<m_aGameCommandsB.size(); c++ )
+47 -54
View File
@@ -192,10 +192,8 @@ void ScreenSelectMusic::Init()
this->SortByDrawOrder();
}
//#include "RageTimer.h"
void ScreenSelectMusic::BeginScreen()
{
//RageTimer tm;
g_ScreenStartedLoadingAt.Touch();
if( CommonMetrics::AUTO_SET_STYLE )
@@ -215,7 +213,6 @@ void ScreenSelectMusic::BeginScreen()
GAMESTATE->m_PlayMode.Set( PLAY_MODE_REGULAR );
LOG->Trace( "PlayMode not set, setting as regular." );
}
//LOG->Trace("XXX 1 %f", tm.GetDeltaTime());
FOREACH_ENUM( PlayerNumber, pn )
{
if( GAMESTATE->IsHumanPlayer(pn) )
@@ -226,30 +223,23 @@ void ScreenSelectMusic::BeginScreen()
OPTIONS_MENU_AVAILABLE.Load( m_sName, "OptionsMenuAvailable" );
PlayCommand( "Mods" );
//LOG->Trace("XXX 2a %f", tm.GetDeltaTime());
m_MusicWheel.BeginScreen();
//LOG->Trace("XXX 2b %f", tm.GetDeltaTime());
m_SelectionState = SelectionState_SelectingSong;
ZERO( m_bStepsChosen );
m_bGoToOptions = false;
m_bAllowOptionsMenu = m_bAllowOptionsMenuRepeat = false;
ZERO( m_iSelection );
//LOG->Trace("XXX 3 %f", tm.GetDeltaTime());
if( USE_OPTIONS_LIST )
FOREACH_PlayerNumber( pn )
m_OptionsList[pn].Reset();
//LOG->Trace("XXX 4a %f", tm.GetDeltaTime());
AfterMusicChange();
//LOG->Trace("XXX 4b %f", tm.GetDeltaTime());
SOUND->PlayOnceFromAnnouncer( "select music intro" );
//LOG->Trace("XXX 4c %f", tm.GetDeltaTime());
ScreenWithMenuElements::BeginScreen();
//LOG->Trace("XXX 5 %f", tm.GetDeltaTime());
}
ScreenSelectMusic::~ScreenSelectMusic()
@@ -1010,61 +1000,64 @@ void ScreenSelectMusic::MenuStart( const InputEventPlus &input )
* (Right now, we bump them to Beginner...can we come up with something better?)
*/
bool bSelectedRoutineSteps[NUM_PLAYERS], bAnySelectedRoutine = false;
bool bSelectedSameSteps = GAMESTATE->m_pCurSteps[PLAYER_1] == GAMESTATE->m_pCurSteps[PLAYER_2];
FOREACH_HumanPlayer( p )
if( !GAMESTATE->IsCourseMode() && GAMESTATE->GetNumSidesJoined() == 2 )
{
const Steps *pSteps = GAMESTATE->m_pCurSteps[p];
const StepsTypeInfo &sti = GAMEMAN->GetStepsTypeInfo( pSteps->m_StepsType );
bool bSelectedRoutineSteps[NUM_PLAYERS], bAnySelectedRoutine = false;
bool bSelectedSameSteps = GAMESTATE->m_pCurSteps[PLAYER_1] == GAMESTATE->m_pCurSteps[PLAYER_2];
bSelectedRoutineSteps[p] = sti.m_StepsTypeCategory == StepsTypeCategory_Routine;
bAnySelectedRoutine |= bSelectedRoutineSteps[p];
}
if( bAnySelectedRoutine )
{
/* Timer ran out. If we haven't agreed on steps, move players with Routine steps down
* to Beginner. I'll admit that's annoying, but at least they won't lose more stages. */
if( bInitiatedByMenuTimer && !bSelectedSameSteps )
FOREACH_HumanPlayer( p )
{
// Since m_vpSteps is sorted by Difficulty, the first entry should be the easiest.
ASSERT( m_vpSteps.size() );
Steps *pSteps = m_vpSteps[0];
const Steps *pSteps = GAMESTATE->m_pCurSteps[p];
const StepsTypeInfo &sti = GAMEMAN->GetStepsTypeInfo( pSteps->m_StepsType );
FOREACH_PlayerNumber( p )
{
if( bSelectedRoutineSteps[p] )
GAMESTATE->m_pCurSteps[p].Set( pSteps );
}
break;
bSelectedRoutineSteps[p] = sti.m_StepsTypeCategory == StepsTypeCategory_Routine;
bAnySelectedRoutine |= bSelectedRoutineSteps[p];
}
// If the steps don't match up, we need to check some more conditions...
if( !bSelectedSameSteps )
if( bAnySelectedRoutine )
{
const PlayerNumber other = OPPOSITE_PLAYER[pn];
if( m_bStepsChosen[other] )
/* Timer ran out. If we haven't agreed on steps, move players with Routine steps down
* to Beginner. I'll admit that's annoying, but at least they won't lose more stages. */
if( bInitiatedByMenuTimer && !bSelectedSameSteps )
{
/* Unready the other player if they selected Routine steps, but we didn't. */
if( bSelectedRoutineSteps[other] )
/* Since m_vpSteps is sorted by Difficulty, the first entry should be the easiest. */
ASSERT( m_vpSteps.size() );
Steps *pSteps = m_vpSteps[0];
FOREACH_PlayerNumber( p )
{
m_bStepsChosen[other] = false;
bAllPlayersDoneSelectingSteps = false; // if the timer ran out, we handled it earlier
// HACK: send an event to Input to tell it to unready.
InputEventPlus event;
event.MenuI = GAME_BUTTON_SELECT;
event.pn = other;
this->Input( event );
if( bSelectedRoutineSteps[p] )
GAMESTATE->m_pCurSteps[p].Set( pSteps );
}
else if( bSelectedRoutineSteps[pn] )
break;
}
/* If the steps don't match up, we need to check some more conditions... */
if( !bSelectedSameSteps )
{
const PlayerNumber other = OPPOSITE_PLAYER[pn];
if( m_bStepsChosen[other] )
{
// They selected non-Routine steps, so we can't select Routine steps.
return;
/* Unready the other player if they selected Routine steps, but we didn't. */
if( bSelectedRoutineSteps[other] )
{
m_bStepsChosen[other] = false;
bAllPlayersDoneSelectingSteps = false; // if the timer ran out, we handled it earlier
// HACK: send an event to Input to tell it to unready.
InputEventPlus event;
event.MenuI = GAME_BUTTON_SELECT;
event.pn = other;
this->Input( event );
}
else if( bSelectedRoutineSteps[pn] )
{
/* They selected non-Routine steps, so we can't select Routine steps. */
return;
}
}
}
}
-6
View File
@@ -540,9 +540,7 @@ void Sprite::DrawTexture( const TweenState *state )
{
DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Modulate );
//////////////////////
// render the shadow
//////////////////////
if( m_fShadowLengthX != 0 || m_fShadowLengthY != 0 )
{
DISPLAY->PushMatrix();
@@ -554,9 +552,7 @@ void Sprite::DrawTexture( const TweenState *state )
DISPLAY->PopMatrix();
}
//////////////////////
// render the diffuse pass
//////////////////////
v[0].c = state->diffuse[0]; // top left
v[1].c = state->diffuse[2]; // bottom left
v[2].c = state->diffuse[3]; // bottom right
@@ -564,9 +560,7 @@ void Sprite::DrawTexture( const TweenState *state )
DISPLAY->DrawQuad( v );
}
//////////////////////
// render the glow pass
//////////////////////
if( state->glow.a > 0.0001f )
{
DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Glow );