diff --git a/Docs/Changelog_sm-ssc.txt b/Docs/Changelog_sm-ssc.txt
index 264cd0e836..963eba7d32 100644
--- a/Docs/Changelog_sm-ssc.txt
+++ b/Docs/Changelog_sm-ssc.txt
@@ -9,6 +9,138 @@ Not all changes are documented, for various reasons.
supported but exist anyways.)
_____________________________________________________________________________
+20100218
+--------
+* Added Fonts/ScreenReloadSongs LoadingText, making the text on
+ ScreenReloadSongs themeable.
+* Added Fonts/NoteField MeasureNumber, ScreenGameplay debug,
+ ScreenGameplaySyncMachine SyncInfo.
+
+20100216
+--------
+sm4svn r28309: Fix crash in course mode, another (and, from the looks of it,
+ the last) dumb bug this block o' hack caused [vyhd]
+
+20100215
+--------
+Some more sm4svn commits:
+* r28304: read-ahead tweaks; support os read cache flushing [Glenn Maynard]
+* r28306: experimental code for storing Lua data in Profiles and
+ converting between XML and Lua data. [vyhd]
+
+20100214
+--------
+sm4svn catchup... Noticing a pattern?
+* r28293: add RageFile::GetFD for specialized file handling [Glenn Maynard]
+ (FD meaning File Descriptor -aj)
+* r28294: "remove absolutely pointless revision tags that cause [aclocal.m4 and
+ ltmain.sh in libmad] to constantly show up as modified" [Glenn Maynard]
+* r28295: [fix] copy and paste error [Glenn Maynard]
+* r28296: Experimental: hint the OS caching to avoid skips when starting/looping
+ movies [Glenn Maynard]
+* r28297: fix a bug, then disable the whole thing for now due to dup()
+ braindamage; Linux version works fine (posix_fadvise) [Glenn Maynard]
+* r28299: fix m_iFilePos updating on seek [Glenn Maynard]
+* r28300: Added theme metric for Routine noteskins (to enforce separate noteskins
+ per player, or at least conscious thought toward that issue), added fix for
+ ScreenEdit only handling switching players on dance-routine [vyhd]
+ (editor's note: the new metrics are RoutineNoteSkinP1 and RoutineNoteSkinP2 -aj)
+* r28303: make sure routine always writes as two charts, even if only one has
+ steps; DEBUG_ASSERT -> ASSERT [Glenn Maynard]
+
+20100213
+--------
+Even more sm4svn catchup:
+* r28277: remove preferred group filtering (leaving the setting in for later use) [Glenn Maynard]
+* r28279: simplify SongUtil::GetStepsTypeAndDifficultyFromSortOrder [Glenn Maynard]
+* r28281: fix SSM crashes when selecting a song with only one
+ player enabled [Glenn Maynard]
+* r28284: add Style::GetUsesCenteredArrows (doubles + routine)
+* r28285: sanity check (on ScreenGameplay) [Glenn Maynard]
+* various commits related to routine mode [Glenn Maynard]
+ (specifically, r28282,r28286,r28287,r28289,r28290)
+* r28291: fix pump routine right side DownLeft not drawn [Chris Danford]
+* r28292: easier debug stepping [Chris Danford]
+
+20100211
+--------
+sm-ssc:
+* Fix a crash with AutoKeysounds.
+
+Playing catch-up with sm4svn. This happens a lot.
+* r28273: "Added more logical handling of Routine mode selection
+ (see source code comments); hopefully, we can write up a more standard
+ solution to this later, since this is kind of a hack" [vyhd]
+* r28274: course type param to GetCustomDifficulty is optional [Glenn Maynard]
+* r28276: Lua binding for MeterDisplay. Allow setting and changing the
+ width dynamically. Phase out the "StreamWidth" node property; set it with
+ SetStreamWidth instead. [Glenn Maynard]
+
+20100210
+--------
+* Possible fix for handling of delays in autoplay. May also fix things
+ elsewhere (editor?), but that is untested. Autoplay seemed to work well
+ with Uprock (the song), so I have no complaints. -aj
+* Glenn started to revert some of Frieza's code in sm4:
+ * "Personally, there is an assert for checking if the noteskin is not empty.
+ Based on other code, it seems like the noteskin would have to be set
+ somewhere else. If this is a problem somewhere else, find where it's a
+ problem and don't patch this function." -aj re: NoteSkinManager.cpp r2098
+ * r28076 "Adds metric options to flash the lifebar when a note is hit"
+ My comment on why I did this: "Any competent themer can make a lifebar
+ flash when a note is hit. Just hook something up to a JudgmentMesageCommand,
+ read the params, and go from there. If it doesn't work on
+ StreamDisplay/LifeMeterBar, then GO CODE YOUR OWN LIFE METER IN LUA!!
+ Seriously there are enough publicly available references (moonlight,
+ optical, NCEvo if you want to go back in time to see a different type
+ of life meter) that claiming 'oh I don't know how to' isn't an excuse.
+ Please actually put in effort and seek examples when you try stuff
+ kthx i told you this would be ranty" -aj
+
+20100209
+--------
+* sm4svn r28266: Fix GAMESTATE:GetCurrentSteps() only returns single-player
+ steps for any difficulty [vyhd]
+
+20100207
+--------
+* sm4svn r28264: subtractive blend (OpenGL only for now) [Glenn Maynard]
+ (D3D version untested, I'm unsure of the behavior -aj)
+
+20100204
+--------
+* [MusicWheel] add RecentSongsToShow metric.
+
+20100203
+--------
+* "First pass of toasty message, hopefully this doesn't break!" [Midiman]
+
+20100202
+--------
+* [Course.cpp] HasTimedMods() now actually checks for timed mods
+ (technically non-global) instead of being a clone of HasMods().
+* [Player.cpp] add MAX_HOLD_LIFE/[Player] MaxHoldLife metric
+
+20100130
+--------
+* "various commits from wolfman from the hg repo; mostly cleanup aside from
+ rev. 79071b3442, which adds a new metric. (that change is forthcoming)"
+
+20100128
+--------
+* Add DELAYS to list of known .sm tags [Wolfman; sm-ssc hg ebb2bda5b4]
+* fix Windows icons for compiling on VS2003 and VS2005
+* add ScoreKeeperShared.cpp/.h to VS2k3 project
+
+20100127
+--------
+* sm4svn r28259: Change OptionsList behavior to pop menu on Select and
+ default to Exit only on SELECT_ONE [vyhd]
+
+20100126
+--------
+* Add ScreenGameplayShared, ScoreKeeperShared to Makefile.am
+
sm-ssc Private Beta Wave 1.4 | 20100125
---------------------------------------
diff --git a/Docs/Luadoc/Lua.xml b/Docs/Luadoc/Lua.xml
index 8a6e034b73..413ae0bc04 100644
--- a/Docs/Luadoc/Lua.xml
+++ b/Docs/Luadoc/Lua.xml
@@ -14,6 +14,8 @@
+
+
@@ -1489,6 +1491,17 @@
+
+
+
+
+
+
+
+
+
+
+
@@ -1758,8 +1771,9 @@
+
sm-ssc private beta 1.4
- 2010-01-25
+ 2010-02-08
diff --git a/Docs/Luadoc/LuaDocumentation.xml b/Docs/Luadoc/LuaDocumentation.xml
index dd15021700..a97f1e91ca 100644
--- a/Docs/Luadoc/LuaDocumentation.xml
+++ b/Docs/Luadoc/LuaDocumentation.xml
@@ -1071,7 +1071,7 @@
- Return the first of the corresponding to game.
+ Return the first for the specified game.
Returns true if any noteskins exist for the specified Game g.
@@ -2097,13 +2097,13 @@
Returns the displayed subtitle of the song.
-
+
Returns the elapsed time from fBeat.
-
+
Returns the first beat of the song.
-
+
Returns the last beat of the song.
diff --git a/src/CourseUtil.cpp b/src/CourseUtil.cpp
index 486aefc030..ae1603ef16 100644
--- a/src/CourseUtil.cpp
+++ b/src/CourseUtil.cpp
@@ -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 &vpCours
stable_sort( vpCoursesInOut.begin(), vpCoursesInOut.end(), MovePlayersBestToEnd );
}
-
void CourseUtil::SortCoursePointerArrayByNumPlays( vector &vpCoursesInOut, ProfileSlot slot, bool bDescending )
{
diff --git a/src/LuaManager.cpp b/src/LuaManager.cpp
index 903e411c63..fd031a10c0 100644
--- a/src/LuaManager.cpp
+++ b/src/LuaManager.cpp
@@ -116,6 +116,43 @@ void LuaHelpers::ReadArrayFromTableB( Lua *L, vector &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 )
{
diff --git a/src/LuaManager.h b/src/LuaManager.h
index 1ecea2bc84..a29ce779f0 100644
--- a/src/LuaManager.h
+++ b/src/LuaManager.h
@@ -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 &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 &aOut );
void ParseCommandList( lua_State *L, const RString &sCommands, const RString &sName );
diff --git a/src/MusicWheel.cpp b/src/MusicWheel.cpp
index e11ee1621f..1b0b5add16 100644
--- a/src/MusicWheel.cpp
+++ b/src/MusicWheel.cpp
@@ -365,6 +365,7 @@ void MusicWheel::GetSongList( vector &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 &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 &arrayWheelIt
// Make an array of Song*, then sort them
vector arraySongs;
- GetSongList(arraySongs, so);
+ GetSongList( arraySongs, so );
bool bUseSections = true;
diff --git a/src/NoteField.cpp b/src/NoteField.cpp
index b28a265ac2..22dda7d111 100644
--- a/src/NoteField.cpp
+++ b/src/NoteField.cpp
@@ -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 );
diff --git a/src/Player.h b/src/Player.h
index 365ef8aa37..a611081135 100644
--- a/src/Player.h
+++ b/src/Player.h
@@ -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();
diff --git a/src/Profile.cpp b/src/Profile.cpp
index ae82fa603f..82be153b8b 100644
--- a/src/Profile.cpp
+++ b/src/Profile.cpp
@@ -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 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 tag. Don't load it, but don't
- * warn about it. */
+ /* The placeholder stats.xml file has an 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 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 );
}
};
diff --git a/src/Profile.h b/src/Profile.h
index c97baaec75..2dce403afe 100644
--- a/src/Profile.h
+++ b/src/Profile.h
@@ -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 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;
diff --git a/src/ProfileManager.h b/src/ProfileManager.h
index 6fdbf2554d..26607f52b1 100644
--- a/src/ProfileManager.h
+++ b/src/ProfileManager.h
@@ -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
diff --git a/src/RageBitmapTexture.cpp b/src/RageBitmapTexture.cpp
index 46fc5dd987..038880d494 100644
--- a/src/RageBitmapTexture.cpp
+++ b/src/RageBitmapTexture.cpp
@@ -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;
}
diff --git a/src/RageDisplay.cpp b/src/RageDisplay.cpp
index 8c837679a7..c43302cd28 100644
--- a/src/RageDisplay.cpp
+++ b/src/RageDisplay.cpp
@@ -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 stack;
diff --git a/src/RageFileDriverReadAhead.cpp b/src/RageFileDriverReadAhead.cpp
index 37e1f0dfc5..d4088fcd0e 100644
--- a/src/RageFileDriverReadAhead.cpp
+++ b/src/RageFileDriverReadAhead.cpp
@@ -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;
}
diff --git a/src/RageFileManager_ReadAhead.cpp b/src/RageFileManager_ReadAhead.cpp
index e78fa26d4a..dcbb84daba 100644
--- a/src/RageFileManager_ReadAhead.cpp
+++ b/src/RageFileManager_ReadAhead.cpp
@@ -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
diff --git a/src/RageFileManager_ReadAhead.h b/src/RageFileManager_ReadAhead.h
index 9bbc9cdc9f..a5091ca089 100644
--- a/src/RageFileManager_ReadAhead.h
+++ b/src/RageFileManager_ReadAhead.h
@@ -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 );
};
diff --git a/src/Screen.h b/src/Screen.h
index 8b86a8416c..33af0c8bba 100644
--- a/src/Screen.h
+++ b/src/Screen.h
@@ -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:
diff --git a/src/ScreenGameplay.cpp b/src/ScreenGameplay.cpp
index 2ea693082b..b6670392d3 100644
--- a/src/ScreenGameplay.cpp
+++ b/src/ScreenGameplay.cpp
@@ -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
}
*/
diff --git a/src/ScreenGameplay.h b/src/ScreenGameplay.h
index e02146d2e4..fdf75f40c8 100644
--- a/src/ScreenGameplay.h
+++ b/src/ScreenGameplay.h
@@ -119,9 +119,7 @@ public:
bool Center1Player() const;
- //
// Lua
- //
virtual void PushSelf( lua_State *L );
Song *GetNextCourseSong() const;
LifeMeter *GetLifeMeter( PlayerNumber pn );
diff --git a/src/ScreenGameplaySyncMachine.cpp b/src/ScreenGameplaySyncMachine.cpp
index 59764229e3..eecdbc7eef 100644
--- a/src/ScreenGameplaySyncMachine.cpp
+++ b/src/ScreenGameplaySyncMachine.cpp
@@ -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 );
diff --git a/src/ScreenPrompt.cpp b/src/ScreenPrompt.cpp
index 9863f770fb..23b2c695c2 100644
--- a/src/ScreenPrompt.cpp
+++ b/src/ScreenPrompt.cpp
@@ -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()
diff --git a/src/ScreenReloadSongs.cpp b/src/ScreenReloadSongs.cpp
index 9848f97280..e7626dc51c 100644
--- a/src/ScreenReloadSongs.cpp
+++ b/src/ScreenReloadSongs.cpp
@@ -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;
diff --git a/src/ScreenSelectMaster.cpp b/src/ScreenSelectMaster.cpp
index 4991d6a653..9cfe182ae6 100644
--- a/src/ScreenSelectMaster.cpp
+++ b/src/ScreenSelectMaster.cpp
@@ -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 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 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; cPlayCommand( 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; cPlayCommand( 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; cSortByDrawOrder();
}
-//#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;
+ }
}
}
}
diff --git a/src/Sprite.cpp b/src/Sprite.cpp
index c75c61872c..5c88b6cfc6 100644
--- a/src/Sprite.cpp
+++ b/src/Sprite.cpp
@@ -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 );