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
+132
View File
@@ -9,6 +9,138 @@ Not all changes are documented, for various reasons.
supported but exist anyways.) 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 sm-ssc Private Beta Wave 1.4 | 20100125
--------------------------------------- ---------------------------------------
+15 -1
View File
@@ -14,6 +14,8 @@
<Function name='ColorMidTone'/> <Function name='ColorMidTone'/>
<Function name='ColorToHSV'/> <Function name='ColorToHSV'/>
<Function name='ColorToHex'/> <Function name='ColorToHex'/>
<Function name='ComboContinue'/>
<Function name='ComboMaintain'/>
<Function name='ComboTransformCommand'/> <Function name='ComboTransformCommand'/>
<Function name='ConnectToServer'/> <Function name='ConnectToServer'/>
<Function name='CourseDifficultyToLocalizedString'/> <Function name='CourseDifficultyToLocalizedString'/>
@@ -1489,6 +1491,17 @@
<EnumValue name='&apos;MusicWheelUsesSections_Always&apos;' value='1'/> <EnumValue name='&apos;MusicWheelUsesSections_Always&apos;' value='1'/>
<EnumValue name='&apos;MusicWheelUsesSections_ABCOnly&apos;' value='2'/> <EnumValue name='&apos;MusicWheelUsesSections_ABCOnly&apos;' value='2'/>
</Enum> </Enum>
<Enum name='NotePart'>
<EnumValue name='&apos;NotePart_TapNote&apos;' value='0'/>
<EnumValue name='&apos;NotePart_TapMine&apos;' value='1'/>
<EnumValue name='&apos;NotePart_TapLift&apos;' value='2'/>
<EnumValue name='&apos;NotePart_TapFake&apos;' value='3'/>
<EnumValue name='&apos;NotePart_HoldHead&apos;' value='4'/>
<EnumValue name='&apos;NotePart_HoldTail&apos;' value='5'/>
<EnumValue name='&apos;NotePart_HoldTopCap&apos;' value='6'/>
<EnumValue name='&apos;NotePart_HoldBody&apos;' value='7'/>
<EnumValue name='&apos;NotePart_HoldBottomCap&apos;' value='8'/>
</Enum>
<Enum name='NoteType'> <Enum name='NoteType'>
<EnumValue name='&apos;NoteType_4th&apos;' value='0'/> <EnumValue name='&apos;NoteType_4th&apos;' value='0'/>
<EnumValue name='&apos;NoteType_8th&apos;' value='1'/> <EnumValue name='&apos;NoteType_8th&apos;' value='1'/>
@@ -1758,8 +1771,9 @@
<Constant name='left' value='&apos;HorizAlign_Left&apos;'/> <Constant name='left' value='&apos;HorizAlign_Left&apos;'/>
<Constant name='middle' value='&apos;VertAlign_Middle&apos;'/> <Constant name='middle' value='&apos;VertAlign_Middle&apos;'/>
<Constant name='right' value='&apos;HorizAlign_Right&apos;'/> <Constant name='right' value='&apos;HorizAlign_Right&apos;'/>
<Constant name='sGame' value='&apos;dance&apos;'/>
<Constant name='top' value='&apos;VertAlign_Top&apos;'/> <Constant name='top' value='&apos;VertAlign_Top&apos;'/>
</Constants> </Constants>
<Version>sm-ssc private beta 1.4</Version> <Version>sm-ssc private beta 1.4</Version>
<Date>2010-01-25</Date> <Date>2010-02-08</Date>
</Lua> </Lua>
+4 -4
View File
@@ -1071,7 +1071,7 @@
</Class> </Class>
<Class name='GameManager'> <Class name='GameManager'>
<Function name='GetFirstStepsTypeForGame' return='StepsType' arguments='Game game'> <Function name='GetFirstStepsTypeForGame' return='StepsType' arguments='Game game'>
Return the first of the <Link class='StepsType' /> corresponding to <code>game</code>. Return the first <Link class='StepsType' /> for the specified <code>game</code>.
</Function> </Function>
<Function name='IsGameEnabled' sm-ssc='true' return='bool' arguments='Game g'> <Function name='IsGameEnabled' sm-ssc='true' return='bool' arguments='Game g'>
Returns <code>true</code> if any noteskins exist for the specified Game <code>g</code>. Returns <code>true</code> if any noteskins exist for the specified Game <code>g</code>.
@@ -2097,13 +2097,13 @@
<Function name='GetDisplaySubTitle' return='string' arguments=''> <Function name='GetDisplaySubTitle' return='string' arguments=''>
Returns the displayed subtitle of the song. Returns the displayed subtitle of the song.
</Function> </Function>
<Function name='GetElapsedTimeFromBeat' sm-ssc='true' return='float' arguments='float fBeat'> <Function name='GetElapsedTimeFromBeat' return='float' arguments='float fBeat'>
Returns the elapsed time from <code>fBeat</code>. Returns the elapsed time from <code>fBeat</code>.
</Function> </Function>
<Function name='GetFirstBeat' sm-ssc='true' return='float' arguments=''> <Function name='GetFirstBeat' return='float' arguments=''>
Returns the first beat of the song. Returns the first beat of the song.
</Function> </Function>
<Function name='GetLastBeat' sm-ssc='true' return='float' arguments=''> <Function name='GetLastBeat' return='float' arguments=''>
Returns the last beat of the song. Returns the last beat of the song.
</Function> </Function>
<Function name='GetLyricsPath' sm-ssc='true' return='string' arguments=''> <Function name='GetLyricsPath' sm-ssc='true' return='string' arguments=''>
-4
View File
@@ -16,10 +16,7 @@
#include "RageFileManager.h" #include "RageFileManager.h"
#include "CourseWriterCRS.h" #include "CourseWriterCRS.h"
//
// Sorting stuff // Sorting stuff
//
static bool CompareCoursePointersByName( const Course* pCourse1, const Course* pCourse2 ) static bool CompareCoursePointersByName( const Course* pCourse1, const Course* pCourse2 )
{ {
RString sName1 = pCourse1->GetDisplayFullTitle(); RString sName1 = pCourse1->GetDisplayFullTitle();
@@ -188,7 +185,6 @@ void CourseUtil::SortCoursePointerArrayByAvgDifficulty( vector<Course*> &vpCours
stable_sort( vpCoursesInOut.begin(), vpCoursesInOut.end(), MovePlayersBestToEnd ); stable_sort( vpCoursesInOut.begin(), vpCoursesInOut.end(), MovePlayersBestToEnd );
} }
void CourseUtil::SortCoursePointerArrayByNumPlays( vector<Course*> &vpCoursesInOut, ProfileSlot slot, bool bDescending ) void CourseUtil::SortCoursePointerArrayByNumPlays( vector<Course*> &vpCoursesInOut, ProfileSlot slot, bool bDescending )
{ {
if( !PROFILEMAN->IsPersistentProfile(slot) ) if( !PROFILEMAN->IsPersistentProfile(slot) )
+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 ) static int GetLuaStack( lua_State *L )
{ {
+9 -6
View File
@@ -30,12 +30,12 @@ public:
Lua *Get(); Lua *Get();
void Release( Lua *&p ); void Release( Lua *&p );
/* Explicitly lock and unlock Lua access. This is done automatically by Get() and /* Explicitly lock and unlock Lua access. This is done automatically by
* Release(). */ * Get() and Release(). */
void YieldLua(); void YieldLua();
void UnyieldLua(); 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 RegisterTypes();
void SetGlobal( const RString &sName, int val ); void SetGlobal( const RString &sName, int val );
@@ -64,8 +64,8 @@ namespace LuaHelpers
* at the top of the stack. */ * at the top of the stack. */
bool RunScript( Lua *L, const RString &sScript, const RString &sName, RString &sError, int iArgs = 0, int iReturnValues = 0 ); 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 /* Run the given expression, returning a single value, and leave the return
* stack. On error, push nil. */ * value on the stack. On error, push nil. */
bool RunExpression( Lua *L, const RString &sExpression, const RString &sName = "" ); bool RunExpression( Lua *L, const RString &sExpression, const RString &sName = "" );
bool RunScriptFile( const RString &sFile ); bool RunScriptFile( const RString &sFile );
@@ -74,11 +74,14 @@ namespace LuaHelpers
* and push it on the stack. */ * and push it on the stack. */
void CreateTableFromArrayB( Lua *L, const vector<bool> &aIn ); 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 /* Recursively copy elements from the table at stack element -2 into the table
* at stack -1. Pop both elements from the stack. */ * at stack -1. Pop both elements from the stack. */
void DeepCopy( lua_State *L ); 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 ReadArrayFromTableB( Lua *L, vector<bool> &aOut );
void ParseCommandList( lua_State *L, const RString &sCommands, const RString &sName ); 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 ) if( (so!=SORT_ROULETTE || !RANDOM_PICKS_LOCKED_SONGS) && iLocked )
continue; continue;
if( PREFSMAN->m_bOnlyPreferredDifficulties ) if( PREFSMAN->m_bOnlyPreferredDifficulties )
{ {
// if the song has steps that fit the preferred difficulty of the default player // 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 ); arraySongs.push_back( pSong );
} }
} }
/* Hack: Add extra stage item if it was eliminated for any reason (eg. it's a long /* 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 // Make an array of Song*, then sort them
vector<Song*> arraySongs; vector<Song*> arraySongs;
GetSongList(arraySongs, so); GetSongList( arraySongs, so );
bool bUseSections = true; bool bUseSections = true;
+1 -1
View File
@@ -36,7 +36,7 @@ NoteField::NoteField()
m_pNoteData = NULL; m_pNoteData = NULL;
m_pCurDisplay = 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.SetZoom( 1.0f );
m_textMeasureNumber.SetShadowLength( 2 ); m_textMeasureNumber.SetShadowLength( 2 );
m_textMeasureNumber.SetWrapWidthPixels( 300 ); m_textMeasureNumber.SetWrapWidthPixels( 300 );
+40 -21
View File
@@ -147,6 +147,8 @@ void Profile::InitGeneralData()
m_iNumTotalSongsPlayed = 0; m_iNumTotalSongsPlayed = 0;
ZERO( m_iNumStagesPassedByPlayMode ); ZERO( m_iNumStagesPassedByPlayMode );
ZERO( m_iNumStagesPassedByGrade ); ZERO( m_iNumStagesPassedByGrade );
m_UserData.Unset();
} }
void Profile::InitSongScores() void Profile::InitSongScores()
@@ -550,9 +552,7 @@ Course *Profile::GetMostPopularCourse() const
return id.ToCourse(); return id.ToCourse();
} }
//
// Steps high scores // Steps high scores
//
void Profile::AddStepsHighScore( const Song* pSong, const Steps* pSteps, HighScore hs, int &iIndexOut ) void Profile::AddStepsHighScore( const Song* pSong, const Steps* pSteps, HighScore hs, int &iIndexOut )
{ {
GetStepsHighScoreList(pSong,pSteps).AddHighScore( hs, iIndexOut, IsMachine() ); GetStepsHighScoreList(pSong,pSteps).AddHighScore( hs, iIndexOut, IsMachine() );
@@ -639,7 +639,6 @@ void Profile::GetGrades( const Song* pSong, StepsType st, int iCounts[NUM_Grade]
SongID songID; SongID songID;
songID.FromSong( pSong ); songID.FromSong( pSong );
memset( iCounts, 0, sizeof(int)*NUM_Grade ); memset( iCounts, 0, sizeof(int)*NUM_Grade );
const HighScoresForASong *hsSong = GetHighScoresForASong( songID ); const HighScoresForASong *hsSong = GetHighScoresForASong( songID );
if( hsSong == NULL ) if( hsSong == NULL )
@@ -660,9 +659,7 @@ void Profile::GetGrades( const Song* pSong, StepsType st, int iCounts[NUM_Grade]
} }
} }
//
// Course high scores // Course high scores
//
void Profile::AddCourseHighScore( const Course* pCourse, const Trail* pTrail, HighScore hs, int &iIndexOut ) void Profile::AddCourseHighScore( const Course* pCourse, const Trail* pTrail, HighScore hs, int &iIndexOut )
{ {
GetCourseHighScoreList(pCourse,pTrail).AddHighScore( hs, iIndexOut, IsMachine() ); 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 ); GetCourseHighScoreList(pCourse,pTrail).IncrementPlayCount( now );
} }
//
// Category high scores // Category high scores
//
void Profile::AddCategoryHighScore( StepsType st, RankingCategory rc, HighScore hs, int &iIndexOut ) void Profile::AddCategoryHighScore( StepsType st, RankingCategory rc, HighScore hs, int &iIndexOut )
{ {
m_CategoryHighScores[st][rc].AddHighScore( hs, iIndexOut, IsMachine() ); m_CategoryHighScores[st][rc].AddHighScore( hs, iIndexOut, IsMachine() );
@@ -772,10 +767,7 @@ void Profile::IncrementCategoryPlayCount( StepsType st, RankingCategory rc )
} }
//
// Loading and saving // Loading and saving
//
#define WARN_PARSER ShowWarningOrTrace( __FILE__, __LINE__, "Error parsing file.", true ) #define WARN_PARSER ShowWarningOrTrace( __FILE__, __LINE__, "Error parsing file.", true )
#define WARN_AND_RETURN { WARN_PARSER; return; } #define WARN_AND_RETURN { WARN_PARSER; return; }
#define WARN_AND_CONTINUE { WARN_PARSER; continue; } #define WARN_AND_CONTINUE { WARN_PARSER; continue; }
@@ -836,9 +828,7 @@ ProfileLoadResult Profile::LoadAllFromDir( RString sDir, bool bRequireSignature
pFile.reset( pInflate ); pFile.reset( pInflate );
} }
// // Don't load unreasonably large stats.xml files.
// Don't unreasonably large stats.xml files.
//
if( !IsMachine() ) // only check stats coming from the player if( !IsMachine() ) // only check stats coming from the player
{ {
int iBytes = pFile->GetFileSize(); int iBytes = pFile->GetFileSize();
@@ -884,8 +874,8 @@ ProfileLoadResult Profile::LoadAllFromDir( RString sDir, bool bRequireSignature
ProfileLoadResult Profile::LoadStatsXmlFromNode( const XNode *xml, bool bIgnoreEditable ) ProfileLoadResult Profile::LoadStatsXmlFromNode( const XNode *xml, bool bIgnoreEditable )
{ {
/* The placeholder stats.xml file has an <html> tag. Don't load it, but don't /* The placeholder stats.xml file has an <html> tag. Don't load it,
* warn about it. */ * but don't warn about it. */
if( xml->GetName() == "html" ) if( xml->GetName() == "html" )
return ProfileLoadResult_FailedNoProfile; return ProfileLoadResult_FailedNoProfile;
@@ -895,8 +885,7 @@ ProfileLoadResult Profile::LoadStatsXmlFromNode( const XNode *xml, bool bIgnoreE
return ProfileLoadResult_FailedTampered; return ProfileLoadResult_FailedTampered;
} }
/* These are loaded from Editable, so we usually want to ignore them // These are loaded from Editable, so we usually want to ignore them here.
* here. */
RString sName = m_sDisplayName; RString sName = m_sDisplayName;
RString sCharacterID = m_sCharacterID; RString sCharacterID = m_sCharacterID;
RString sLastUsedHighScoreName = m_sLastUsedHighScoreName; RString sLastUsedHighScoreName = m_sLastUsedHighScoreName;
@@ -1097,7 +1086,7 @@ XNode* Profile::SaveGeneralDataCreateNode() const
XNode* pNumSongsPlayedByPlayMode = pGeneralDataNode->AppendChild("NumSongsPlayedByPlayMode"); XNode* pNumSongsPlayedByPlayMode = pGeneralDataNode->AppendChild("NumSongsPlayedByPlayMode");
FOREACH_ENUM( PlayMode, pm ) FOREACH_ENUM( PlayMode, pm )
{ {
/* Don't save unplayed PlayModes. */ // Don't save unplayed PlayModes.
if( !m_iNumSongsPlayedByPlayMode[pm] ) if( !m_iNumSongsPlayedByPlayMode[pm] )
continue; continue;
pNumSongsPlayedByPlayMode->AppendChild( PlayModeToString(pm), m_iNumSongsPlayedByPlayMode[pm] ); pNumSongsPlayedByPlayMode->AppendChild( PlayModeToString(pm), m_iNumSongsPlayedByPlayMode[pm] );
@@ -1144,7 +1133,7 @@ XNode* Profile::SaveGeneralDataCreateNode() const
XNode* pNumStagesPassedByPlayMode = pGeneralDataNode->AppendChild("NumStagesPassedByPlayMode"); XNode* pNumStagesPassedByPlayMode = pGeneralDataNode->AppendChild("NumStagesPassedByPlayMode");
FOREACH_ENUM( PlayMode, pm ) FOREACH_ENUM( PlayMode, pm )
{ {
/* Don't save unplayed PlayModes. */ // Don't save unplayed PlayModes.
if( !m_iNumStagesPassedByPlayMode[pm] ) if( !m_iNumStagesPassedByPlayMode[pm] )
continue; continue;
pNumStagesPassedByPlayMode->AppendChild( PlayModeToString(pm), m_iNumStagesPassedByPlayMode[pm] ); 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; return pGeneralDataNode;
} }
@@ -1168,9 +1170,7 @@ ProfileLoadResult Profile::LoadEditableDataFromDir( RString sDir )
{ {
RString fn = sDir + EDITABLE_INI; RString fn = sDir + EDITABLE_INI;
//
// Don't load unreasonably large editable.xml files. // Don't load unreasonably large editable.xml files.
//
int iBytes = FILEMAN->GetFileSizeInBytes( fn ); int iBytes = FILEMAN->GetFileSizeInBytes( fn );
if( iBytes > MAX_EDITABLE_INI_SIZE_BYTES ) if( iBytes > MAX_EDITABLE_INI_SIZE_BYTES )
{ {
@@ -1334,6 +1334,23 @@ void Profile::LoadGeneralDataFromNode( const XNode* pNode )
} }
// 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 );
}
} }
void Profile::AddStepTotals( int iTotalTapsAndHolds, int iTotalJumps, int iTotalHolds, int iTotalRolls, int iTotalMines, int iTotalHands, float fCaloriesBurned ) void Profile::AddStepTotals( int iTotalTapsAndHolds, int iTotalJumps, int iTotalHolds, int iTotalRolls, int iTotalMines, int iTotalHands, float fCaloriesBurned )
@@ -2001,6 +2018,7 @@ public:
static int GetTotalRolls( T* p, lua_State *L ) { lua_pushnumber(L, p->m_iTotalRolls ); return 1; } 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 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 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() LunaProfile()
{ {
@@ -2044,6 +2062,7 @@ public:
ADD_METHOD( GetTotalRolls ); ADD_METHOD( GetTotalRolls );
ADD_METHOD( GetTotalMines ); ADD_METHOD( GetTotalMines );
ADD_METHOD( GetTotalHands ); ADD_METHOD( GetTotalHands );
ADD_METHOD( GetUserData );
} }
}; };
+2 -20
View File
@@ -15,6 +15,7 @@
#include "CourseUtil.h" // for CourseID #include "CourseUtil.h" // for CourseID
#include "TrailUtil.h" // for TrailID #include "TrailUtil.h" // for TrailID
#include "StyleUtil.h" // for StyleID #include "StyleUtil.h" // for StyleID
#include "LuaReference.h"
class XNode; class XNode;
struct lua_State; struct lua_State;
@@ -63,9 +64,7 @@ public:
InitAll(); InitAll();
} }
//
// smart accessors // smart accessors
//
RString GetDisplayNameOrHighScoreName() const; RString GetDisplayNameOrHighScoreName() const;
Character *GetCharacter() const; Character *GetCharacter() const;
RString GetDisplayTotalCaloriesBurned() const; // remove me and use Lua instead RString GetDisplayTotalCaloriesBurned() const; // remove me and use Lua instead
@@ -92,17 +91,13 @@ public:
bool IsMachine() const; bool IsMachine() const;
//
// Editable data // Editable data
//
RString m_sDisplayName; RString m_sDisplayName;
RString m_sCharacterID; 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. 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 int m_iWeightPounds; // 0 == not set
//
// General data // General data
//
static RString MakeGuid(); static RString MakeGuid();
RString m_sGuid; RString m_sGuid;
@@ -143,10 +138,9 @@ public:
int m_iNumTotalSongsPlayed; int m_iNumTotalSongsPlayed;
int m_iNumStagesPassedByPlayMode[NUM_PlayMode]; int m_iNumStagesPassedByPlayMode[NUM_PlayMode];
int m_iNumStagesPassedByGrade[NUM_Grade]; int m_iNumStagesPassedByGrade[NUM_Grade];
LuaReference m_UserData;
//
// Song high scores // Song high scores
//
struct HighScoresForASteps struct HighScoresForASteps
{ {
HighScoreList hsl; HighScoreList hsl;
@@ -170,9 +164,7 @@ public:
bool HasPassedSteps( const Song* pSong, const Steps* pSteps ) const; bool HasPassedSteps( const Song* pSong, const Steps* pSteps ) const;
bool HasPassedAnyStepsInSong( const Song* pSong ) const; bool HasPassedAnyStepsInSong( const Song* pSong ) const;
//
// Course high scores // Course high scores
//
// struct was a typedef'd array of HighScores, but VC6 freaks out // struct was a typedef'd array of HighScores, but VC6 freaks out
// in processing the templates for map::operator[]. // in processing the templates for map::operator[].
struct HighScoresForATrail struct HighScoresForATrail
@@ -195,9 +187,7 @@ public:
void IncrementCoursePlayCount( const Course* pCourse, const Trail* pTrail ); void IncrementCoursePlayCount( const Course* pCourse, const Trail* pTrail );
//
// Category high scores // Category high scores
//
HighScoreList m_CategoryHighScores[NUM_StepsType][NUM_RankingCategory]; HighScoreList m_CategoryHighScores[NUM_StepsType][NUM_RankingCategory];
void AddCategoryHighScore( StepsType st, RankingCategory rc, HighScore hs, int &iIndexOut ); void AddCategoryHighScore( StepsType st, RankingCategory rc, HighScore hs, int &iIndexOut );
@@ -207,17 +197,13 @@ public:
void IncrementCategoryPlayCount( StepsType st, RankingCategory rc ); void IncrementCategoryPlayCount( StepsType st, RankingCategory rc );
//
// Screenshot Data // Screenshot Data
//
vector<Screenshot> m_vScreenshots; vector<Screenshot> m_vScreenshots;
void AddScreenshot( const Screenshot &screenshot ); void AddScreenshot( const Screenshot &screenshot );
int GetNextScreenshotIndex() { return m_vScreenshots.size(); } int GetNextScreenshotIndex() { return m_vScreenshots.size(); }
//
// Calorie Data // Calorie Data
//
// Why track calories in a map, and not in a static sized array like // 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. // 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 // 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 ); void SaveCourseRecentScore( const Course* pCourse, const Trail* pTrail, HighScore hs );
*/ */
//
// Init'ing // Init'ing
//
void InitAll() void InitAll()
{ {
InitEditableData(); InitEditableData();
@@ -285,9 +269,7 @@ public:
void InitCalorieData(); void InitCalorieData();
void ClearStats(); void ClearStats();
//
// Loading and saving // Loading and saving
//
ProfileLoadResult LoadAllFromDir( RString sDir, bool bRequireSignature ); ProfileLoadResult LoadAllFromDir( RString sDir, bool bRequireSignature );
bool SaveAllToDir( RString sDir, bool bSignData ) const; bool SaveAllToDir( RString sDir, bool bSignData ) const;
-8
View File
@@ -82,24 +82,17 @@ public:
bool LastLoadWasTamperedOrCorrupt( PlayerNumber pn ) const; bool LastLoadWasTamperedOrCorrupt( PlayerNumber pn ) const;
bool LastLoadWasFromLastGood( PlayerNumber pn ) const; bool LastLoadWasFromLastGood( PlayerNumber pn ) const;
//
// Song stats // Song stats
//
int GetSongNumTimesPlayed( const Song* pSong, ProfileSlot card ) const; int GetSongNumTimesPlayed( const Song* pSong, ProfileSlot card ) const;
bool IsSongNew( const Song* pSong ) const { return GetSongNumTimesPlayed(pSong,ProfileSlot_Machine)==0; } 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 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 ); void IncrementStepsPlayCount( const Song* pSong, const Steps* pSteps, PlayerNumber pn );
//
// Course stats // Course stats
//
void AddCourseScore( const Course* pCourse, const Trail* pTrail, PlayerNumber pn, const HighScore &hs, int &iPersonalIndexOut, int &iMachineIndexOut ); 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 ); void IncrementCoursePlayCount( const Course* pCourse, const Trail* pTrail, PlayerNumber pn );
//
// Category stats // Category stats
//
void AddCategoryScore( StepsType st, RankingCategory rc, PlayerNumber pn, const HighScore &hs, int &iPersonalIndexOut, int &iMachineIndexOut ); void AddCategoryScore( StepsType st, RankingCategory rc, PlayerNumber pn, const HighScore &hs, int &iPersonalIndexOut, int &iMachineIndexOut );
void IncrementCategoryPlayCount( StepsType st, RankingCategory rc, PlayerNumber pn ); void IncrementCategoryPlayCount( StepsType st, RankingCategory rc, PlayerNumber pn );
@@ -131,7 +124,6 @@ private:
Profile *m_pMachineProfile; Profile *m_pMachineProfile;
}; };
extern ProfileManager* PROFILEMAN; // global and accessable from anywhere in our program extern ProfileManager* PROFILEMAN; // global and accessable from anywhere in our program
#endif #endif
-1
View File
@@ -19,7 +19,6 @@ static void GetResolutionFromFileName( RString sPath, int &iWidth, int &iHeight
* Foo (res 512x128).png * Foo (res 512x128).png
* Also allow, eg: * Also allow, eg:
* Foo (dither, res 512x128).png * Foo (dither, res 512x128).png
*
* Be careful that this doesn't get mixed up with frame dimensions. */ * Be careful that this doesn't get mixed up with frame dimensions. */
static Regex re( "\\([^\\)]*res ([0-9]+)x([0-9]+).*\\)" ); static Regex re( "\\([^\\)]*res ([0-9]+)x([0-9]+).*\\)" );
+4 -7
View File
@@ -15,9 +15,7 @@
#include "DisplayResolutions.h" #include "DisplayResolutions.h"
#include "arch/ArchHooks/ArchHooks.h" #include "arch/ArchHooks/ArchHooks.h"
//
// Statistics stuff // Statistics stuff
//
RageTimer g_LastCheckTimer; RageTimer g_LastCheckTimer;
int g_iNumVerts; int g_iNumVerts;
int g_iFPS, g_iVPF, g_iCFPS; int g_iFPS, g_iVPF, g_iCFPS;
@@ -145,7 +143,7 @@ void RageDisplay::ResetStats()
RString RageDisplay::GetStats() const RString RageDisplay::GetStats() const
{ {
RString s; RString s;
/* If FPS == 0, we don't have stats yet. */ // If FPS == 0, we don't have stats yet.
if( !GetFPS() ) if( !GetFPS() )
s = "-- FPS\n-- av FPS\n-- VPF"; s = "-- FPS\n-- av FPS\n-- VPF";
@@ -182,7 +180,7 @@ void RageDisplay::StatsAddVerts( int iNumVertsRendered ) { g_iVertsRenderedSince
* angle of the line. */ * angle of the line. */
void RageDisplay::DrawPolyLine(const RageSpriteVertex &p1, const RageSpriteVertex &p2, float LineWidth ) 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 opp = p2.p.x - p1.p.x;
float adj = p2.p.y - p1.p.y; float adj = p2.p.y - p1.p.y;
float hyp = powf(opp*opp + adj*adj, 0.5f); float hyp = powf(opp*opp + adj*adj, 0.5f);
@@ -221,7 +219,7 @@ void RageDisplay::DrawLineStripInternal( const RageSpriteVertex v[], int iNumVer
for( int i = 0; i < iNumVerts-1; ++i ) for( int i = 0; i < iNumVerts-1; ++i )
DrawPolyLine(v[i], v[i+1], LineWidth); 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 ) for( int i = 0; i < iNumVerts; ++i )
DrawCircle( v[i], LineWidth/2 ); DrawCircle( v[i], LineWidth/2 );
} }
@@ -253,6 +251,7 @@ void RageDisplay::SetDefaultRenderStates()
SetCullMode( CULL_NONE ); SetCullMode( CULL_NONE );
SetZWrite( false ); SetZWrite( false );
SetZTestMode( ZTEST_OFF ); SetZTestMode( ZTEST_OFF );
SetStencilTestMode( STENCILTEST_OFF );
SetAlphaTest( true ); SetAlphaTest( true );
SetBlendMode( BLEND_NORMAL ); SetBlendMode( BLEND_NORMAL );
SetTextureFiltering( TextureUnit_1, true ); SetTextureFiltering( TextureUnit_1, true );
@@ -261,9 +260,7 @@ void RageDisplay::SetDefaultRenderStates()
} }
//
// Matrix stuff // Matrix stuff
//
class MatrixStack class MatrixStack
{ {
vector<RageMatrix> stack; vector<RageMatrix> stack;
+25 -20
View File
@@ -65,7 +65,6 @@ RageFileDriverReadAhead::RageFileDriverReadAhead( RageFileBasic *pFile, int iCac
m_pFile = pFile; m_pFile = pFile;
m_iFilePos = pFile->Tell(); m_iFilePos = pFile->Tell();
m_bFileOwned = false; m_bFileOwned = false;
m_bReadAheadNeeded = true;
m_iPostBufferReadAhead = iPostBufferReadAhead; m_iPostBufferReadAhead = iPostBufferReadAhead;
FillBuffer( iCacheBytes ); FillBuffer( iCacheBytes );
@@ -79,7 +78,6 @@ RageFileDriverReadAhead::RageFileDriverReadAhead( const RageFileDriverReadAhead
m_iFilePos = cpy.m_iFilePos; m_iFilePos = cpy.m_iFilePos;
m_bFileOwned = true; m_bFileOwned = true;
m_iPostBufferReadAhead = cpy.m_iPostBufferReadAhead; m_iPostBufferReadAhead = cpy.m_iPostBufferReadAhead;
m_bReadAheadNeeded = cpy.m_bReadAheadNeeded;
RageFileManagerReadAhead::CacheHintStreaming( m_pFile ); RageFileManagerReadAhead::CacheHintStreaming( m_pFile );
} }
@@ -117,32 +115,39 @@ void RageFileDriverReadAhead::FillBuffer( int iBytes )
int RageFileDriverReadAhead::ReadInternal( void *pBuffer, size_t 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() ) if( m_bReadAheadNeeded && m_iFilePos < (int) m_sBuffer.size() )
{ {
RageFileManagerReadAhead::ReadAhead( m_pFile, m_iPostBufferReadAhead ); // If we can serve data out of the buffer, use it.
iRet = min( iBytes, m_sBuffer.size() - m_iFilePos );
m_bReadAheadNeeded = false; 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. */ // Read out of the underlying file.
m_bReadAheadNeeded = true; 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 ) if( iRet != -1 )
m_iFilePos += iRet; 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; return iRet;
} }
+22
View File
@@ -22,6 +22,26 @@ void RageFileManagerReadAhead::ReadAhead( RageFileBasic *pFile, int iBytes )
posix_fadvise( iFD, iStart, iBytes, POSIX_FADV_WILLNEED ); 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 #else
#if 0 #if 0
/* This doesn't currently work, because dup() locks the file position of the new FD with the old /* 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 #else
void RageFileManagerReadAhead::Init() { } void RageFileManagerReadAhead::Init() { }
void RageFileManagerReadAhead::Shutdown() { } void RageFileManagerReadAhead::Shutdown() { }
void RageFileManagerReadAhead::ReadAhead( RageFileBasic *pFile, int iBytes ) { } void RageFileManagerReadAhead::ReadAhead( RageFileBasic *pFile, int iBytes ) { }
void RageFileManagerReadAhead::DiscardCache( RageFileBasic *pFile, int iRelativePosition, int iBytes ) { }
#endif #endif
#endif #endif
+5 -1
View File
@@ -8,9 +8,13 @@ namespace RageFileManagerReadAhead
void Init(); void Init();
void Shutdown(); 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 ); 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 ); void CacheHintStreaming( RageFileBasic *pFile );
}; };
-2
View File
@@ -60,9 +60,7 @@ public:
bool AllowOperatorMenuButton() const { return ALLOW_OPERATOR_MENU_BUTTON; } bool AllowOperatorMenuButton() const { return ALLOW_OPERATOR_MENU_BUTTON; }
virtual bool AllowLateJoin() const { return false; } virtual bool AllowLateJoin() const { return false; }
//
// Lua // Lua
//
virtual void PushSelf( lua_State *L ); virtual void PushSelf( lua_State *L );
protected: protected:
+9 -5
View File
@@ -58,6 +58,7 @@
#include "SongUtil.h" #include "SongUtil.h"
#include "Song.h" #include "Song.h"
#include "XmlFileUtil.h" #include "XmlFileUtil.h"
#include "Profile.h" // for replay data stuff
// Defines // Defines
#define SHOW_LIFE_METER_FOR_DISABLED_PLAYERS THEME->GetMetricB(m_sName,"ShowLifeMeterForDisabledPlayers") #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 m_Failed.SetDrawOrder( DRAW_ORDER_TRANSITIONS-1 ); // on top of everything else
this->AddChild( &m_Failed ); this->AddChild( &m_Failed );
m_textDebug.LoadFromFont( THEME->GetPathF("Common","normal") ); m_textDebug.LoadFromFont( THEME->GetPathF(m_sName,"debug") );
m_textDebug.SetName( "Debug" ); m_textDebug.SetName( "Debug" );
LOAD_ALL_COMMANDS_AND_SET_XY( m_textDebug ); LOAD_ALL_COMMANDS_AND_SET_XY( m_textDebug );
m_textDebug.SetDrawOrder( DRAW_ORDER_TRANSITIONS-1 ); // just under transitions, over the foreground 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 proper steps hash?
* Add modifiers used * Add modifiers used
* Add date played, machine played on, etc. * Add date played, machine played on, etc.
* Add/use player GUID
*/ */
FOREACH_HumanPlayer( pn ) FOREACH_HumanPlayer( pn )
{ {
FOREACH_EnabledPlayerInfo( m_vPlayerInfo, pi ) FOREACH_EnabledPlayerInfo( m_vPlayerInfo, pi )
{ {
Profile *pTempProfile = PROFILEMAN->GetProfile(pn);
XNode *p = new XNode("ReplayData"); 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 // song information node
SongID songID; SongID songID;
@@ -2787,7 +2790,8 @@ void ScreenGameplay::SaveReplay()
// player information node (rival data sup) // player information node (rival data sup)
XNode *pPlayerInfoNode = new XNode("Player"); 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); p->AppendChild(pPlayerInfoNode);
// the timings. // the timings.
@@ -2825,7 +2829,7 @@ void ScreenGameplay::SaveReplay()
/* /*
bool ScreenGameplay::LoadReplay() bool ScreenGameplay::LoadReplay()
{ {
// Load // Load replay which was selected via options
} }
*/ */
-2
View File
@@ -119,9 +119,7 @@ public:
bool Center1Player() const; bool Center1Player() const;
//
// Lua // Lua
//
virtual void PushSelf( lua_State *L ); virtual void PushSelf( lua_State *L );
Song *GetNextCourseSong() const; Song *GetNextCourseSong() const;
LifeMeter *GetLifeMeter( PlayerNumber pn ); LifeMeter *GetLifeMeter( PlayerNumber pn );
+1 -1
View File
@@ -41,7 +41,7 @@ void ScreenGameplaySyncMachine::Init()
m_DancingState = STATE_DANCING; m_DancingState = STATE_DANCING;
m_textSyncInfo.SetName( "SyncInfo" ); 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 ); ActorUtil::LoadAllCommands( m_textSyncInfo, m_sName );
this->AddChild( &m_textSyncInfo ); this->AddChild( &m_textSyncInfo );
-2
View File
@@ -47,8 +47,6 @@ void ScreenPrompt::Prompt( ScreenMessage smSendOnPop, const RString &sText, Prom
SCREENMAN->AddNewScreenToTop( "ScreenPrompt", smSendOnPop ); SCREENMAN->AddNewScreenToTop( "ScreenPrompt", smSendOnPop );
} }
REGISTER_SCREEN_CLASS( ScreenPrompt ); REGISTER_SCREEN_CLASS( ScreenPrompt );
void ScreenPrompt::Init() void ScreenPrompt::Init()
+5 -4
View File
@@ -29,8 +29,8 @@ public:
void Paint() void Paint()
{ {
/* We load songs much faster than we draw frames. Cap the draw rate, so we don't /* We load songs much faster than we draw frames. Cap the draw rate,
* slow down the reload. */ * so we don't slow down the reload. */
if( m_LastDraw.PeekDeltaTime() < 1.0f/DrawFrameRate ) if( m_LastDraw.PeekDeltaTime() < 1.0f/DrawFrameRate )
return; return;
m_LastDraw.GetDeltaTime(); m_LastDraw.GetDeltaTime();
@@ -51,7 +51,8 @@ void ScreenReloadSongs::Init()
m_iUpdates = 0; 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 ); m_Loading.SetXY( SCREEN_CENTER_X, SCREEN_CENTER_Y );
this->AddChild( &m_Loading ); this->AddChild( &m_Loading );
@@ -68,7 +69,7 @@ void ScreenReloadSongs::Update( float fDeltaTime )
{ {
Screen::Update( 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; ++m_iUpdates;
if( m_iUpdates != 2 ) if( m_iUpdates != 2 )
return; return;
+16 -30
View File
@@ -90,7 +90,6 @@ void ScreenSelectMaster::Init()
#define PLAYER_APPEND_NO_SPACE(p) (SHARED_SELECTION ? RString() : ssprintf("P%d",(p)+1)) #define PLAYER_APPEND_NO_SPACE(p) (SHARED_SELECTION ? RString() : ssprintf("P%d",(p)+1))
this->SubscribeToMessage( SM_MenuTimer ); this->SubscribeToMessage( SM_MenuTimer );
// init cursor // init cursor
if( SHOW_CURSOR ) if( SHOW_CURSOR )
{ {
@@ -415,11 +414,9 @@ void ScreenSelectMaster::HandleScreenMessage( const ScreenMessage SM )
{ {
ScreenSelect::HandleScreenMessage( SM ); ScreenSelect::HandleScreenMessage( SM );
vector<PlayerNumber> vpns; vector<PlayerNumber> vpns;
GetActiveElementPlayerNumbers( vpns ); GetActiveElementPlayerNumbers( vpns );
if( SM == SM_PlayPostSwitchPage ) if( SM == SM_PlayPostSwitchPage )
{ {
int iNewChoice = m_iChoice[ GAMESTATE->m_MasterPlayerNumber ]; int iNewChoice = m_iChoice[ GAMESTATE->m_MasterPlayerNumber ];
@@ -441,8 +438,6 @@ void ScreenSelectMaster::HandleScreenMessage( const ScreenMessage SM )
int iChoice = m_iChoice[*p]; int iChoice = m_iChoice[*p];
m_vsprScroll[*p][iChoice]->HandleMessage( msg ); m_vsprScroll[*p][iChoice]->HandleMessage( msg );
} }
} }
m_fLockInputSecs = POST_SWITCH_PAGE_SECONDS; m_fLockInputSecs = POST_SWITCH_PAGE_SECONDS;
@@ -461,7 +456,6 @@ void ScreenSelectMaster::HandleScreenMessage( const ScreenMessage SM )
} }
} }
} }
} }
int ScreenSelectMaster::GetSelectionIndex( PlayerNumber pn ) 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). * 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 ) FOREACH_HumanPlayer( p )
{ {
if(m_bUsingTwoLists && m_iSelectedList == 1) 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() ) if( !m_aGameCommandsB[m_iChoice[p]].IsPlayable() )
Move( p, MenuDir_Auto ); Move( p, MenuDir_Auto );
} }
@@ -701,8 +693,6 @@ void ScreenSelectMaster::MenuUp( const InputEventPlus &input )
{ {
m_bDoubleChoice[pn] = false; // player has cancelled their selection 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 m_bDoubleChoice[pn] = false; // player has cancelled their selection
} }
} }
} }
@@ -786,7 +775,7 @@ bool ScreenSelectMaster::ChangePage( int iNewChoice )
{ {
// XXX: only play this once (I thought we already did that?) // XXX: only play this once (I thought we already did that?)
// Play it on every change to page 2. -Chris // 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 // Should we lock input while it's scrolling? -Chris
m_soundDifficult.Stop(); m_soundDifficult.Stop();
m_soundDifficult.PlayRandom(); m_soundDifficult.PlayRandom();
@@ -1099,7 +1088,7 @@ void ScreenSelectMaster::MenuStart( const InputEventPlus &input )
SOUND->PlayOnceFromDir( ANNOUNCER->GetPathTo(ssprintf("%s comment %s",m_sName.c_str(), mc.m_sName.c_str())) ); 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 ) if( mc.m_sSoundPath.empty() && !m_bDoubleChoiceNoSound )
m_soundStart.PlayCopy(); m_soundStart.PlayCopy();
@@ -1113,7 +1102,7 @@ void ScreenSelectMaster::MenuStart( const InputEventPlus &input )
bool bAllDone = true; bool bAllDone = true;
if( (bool)SHARED_SELECTION || GetCurrentPage() == PAGE_2 ) 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 ) FOREACH_PlayerNumber( p )
{ {
ASSERT( !m_bChosen[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 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 * 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 * GainFocus or LoseFocus, which implies that the default setting is hard-coded
* the theme. Always run both. * in the theme. Always run both.
*
* However, the actual tween-in is OnCommand; we don't always want to actually run * 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 * 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. * 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", * This means that the focus command should be position neutral; eg. only use "addx",
* not "x". * not "x". */
*/
void ScreenSelectMaster::TweenOnScreen() void ScreenSelectMaster::TweenOnScreen()
{ {
vector<PlayerNumber> vpns; vector<PlayerNumber> vpns;
@@ -1175,8 +1161,8 @@ void ScreenSelectMaster::TweenOnScreen()
{ {
FOREACH( PlayerNumber, vpns, p ) FOREACH( PlayerNumber, vpns, p )
{ {
// Play Gain/LoseFocus before playing the on command. Gain/Lose will // Play Gain/LoseFocus before playing the on command.
// often stop tweening, which ruins the OnCommand. // Gain/Lose will often stop tweening, which ruins the OnCommand.
for( unsigned c=0; c<m_aGameCommands.size(); c++ ) for( unsigned c=0; c<m_aGameCommands.size(); c++ )
{ {
m_vsprScrollB[*p][c]->PlayCommand( int(c) == m_iChoice[*p]? "GainFocus":"LoseFocus" ); m_vsprScrollB[*p][c]->PlayCommand( int(c) == m_iChoice[*p]? "GainFocus":"LoseFocus" );
@@ -1190,8 +1176,8 @@ void ScreenSelectMaster::TweenOnScreen()
{ {
FOREACH( PlayerNumber, vpns, p ) FOREACH( PlayerNumber, vpns, p )
{ {
// Play Gain/LoseFocus before playing the on command. Gain/Lose will // Play Gain/LoseFocus before playing the on command.
// often stop tweening, which ruins the OnCommand. // Gain/Lose will often stop tweening, which ruins the OnCommand.
for( unsigned c=0; c<m_aGameCommands.size(); c++ ) for( unsigned c=0; c<m_aGameCommands.size(); c++ )
{ {
m_vsprScroll[*p][c]->PlayCommand( int(c) == m_iChoice[*p]? "GainFocus":"LoseFocus" ); m_vsprScroll[*p][c]->PlayCommand( int(c) == m_iChoice[*p]? "GainFocus":"LoseFocus" );
@@ -1223,7 +1209,7 @@ void ScreenSelectMaster::TweenOffScreen()
GetActiveElementPlayerNumbers( vpns ); GetActiveElementPlayerNumbers( vpns );
// using two lists -- may need to consider throwing a wider range of commands // 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) if(m_bUsingTwoLists && m_iSelectedList == 1)
{ {
for( unsigned c=0; c<m_aGameCommandsB.size(); c++ ) for( unsigned c=0; c<m_aGameCommandsB.size(); c++ )
+6 -13
View File
@@ -192,10 +192,8 @@ void ScreenSelectMusic::Init()
this->SortByDrawOrder(); this->SortByDrawOrder();
} }
//#include "RageTimer.h"
void ScreenSelectMusic::BeginScreen() void ScreenSelectMusic::BeginScreen()
{ {
//RageTimer tm;
g_ScreenStartedLoadingAt.Touch(); g_ScreenStartedLoadingAt.Touch();
if( CommonMetrics::AUTO_SET_STYLE ) if( CommonMetrics::AUTO_SET_STYLE )
@@ -215,7 +213,6 @@ void ScreenSelectMusic::BeginScreen()
GAMESTATE->m_PlayMode.Set( PLAY_MODE_REGULAR ); GAMESTATE->m_PlayMode.Set( PLAY_MODE_REGULAR );
LOG->Trace( "PlayMode not set, setting as regular." ); LOG->Trace( "PlayMode not set, setting as regular." );
} }
//LOG->Trace("XXX 1 %f", tm.GetDeltaTime());
FOREACH_ENUM( PlayerNumber, pn ) FOREACH_ENUM( PlayerNumber, pn )
{ {
if( GAMESTATE->IsHumanPlayer(pn) ) if( GAMESTATE->IsHumanPlayer(pn) )
@@ -226,30 +223,23 @@ void ScreenSelectMusic::BeginScreen()
OPTIONS_MENU_AVAILABLE.Load( m_sName, "OptionsMenuAvailable" ); OPTIONS_MENU_AVAILABLE.Load( m_sName, "OptionsMenuAvailable" );
PlayCommand( "Mods" ); PlayCommand( "Mods" );
//LOG->Trace("XXX 2a %f", tm.GetDeltaTime());
m_MusicWheel.BeginScreen(); m_MusicWheel.BeginScreen();
//LOG->Trace("XXX 2b %f", tm.GetDeltaTime());
m_SelectionState = SelectionState_SelectingSong; m_SelectionState = SelectionState_SelectingSong;
ZERO( m_bStepsChosen ); ZERO( m_bStepsChosen );
m_bGoToOptions = false; m_bGoToOptions = false;
m_bAllowOptionsMenu = m_bAllowOptionsMenuRepeat = false; m_bAllowOptionsMenu = m_bAllowOptionsMenuRepeat = false;
ZERO( m_iSelection ); ZERO( m_iSelection );
//LOG->Trace("XXX 3 %f", tm.GetDeltaTime());
if( USE_OPTIONS_LIST ) if( USE_OPTIONS_LIST )
FOREACH_PlayerNumber( pn ) FOREACH_PlayerNumber( pn )
m_OptionsList[pn].Reset(); m_OptionsList[pn].Reset();
//LOG->Trace("XXX 4a %f", tm.GetDeltaTime());
AfterMusicChange(); AfterMusicChange();
//LOG->Trace("XXX 4b %f", tm.GetDeltaTime());
SOUND->PlayOnceFromAnnouncer( "select music intro" ); SOUND->PlayOnceFromAnnouncer( "select music intro" );
//LOG->Trace("XXX 4c %f", tm.GetDeltaTime());
ScreenWithMenuElements::BeginScreen(); ScreenWithMenuElements::BeginScreen();
//LOG->Trace("XXX 5 %f", tm.GetDeltaTime());
} }
ScreenSelectMusic::~ScreenSelectMusic() ScreenSelectMusic::~ScreenSelectMusic()
@@ -1010,6 +1000,8 @@ void ScreenSelectMusic::MenuStart( const InputEventPlus &input )
* (Right now, we bump them to Beginner...can we come up with something better?) * (Right now, we bump them to Beginner...can we come up with something better?)
*/ */
if( !GAMESTATE->IsCourseMode() && GAMESTATE->GetNumSidesJoined() == 2 )
{
bool bSelectedRoutineSteps[NUM_PLAYERS], bAnySelectedRoutine = false; bool bSelectedRoutineSteps[NUM_PLAYERS], bAnySelectedRoutine = false;
bool bSelectedSameSteps = GAMESTATE->m_pCurSteps[PLAYER_1] == GAMESTATE->m_pCurSteps[PLAYER_2]; bool bSelectedSameSteps = GAMESTATE->m_pCurSteps[PLAYER_1] == GAMESTATE->m_pCurSteps[PLAYER_2];
@@ -1028,7 +1020,7 @@ void ScreenSelectMusic::MenuStart( const InputEventPlus &input )
* to Beginner. I'll admit that's annoying, but at least they won't lose more stages. */ * to Beginner. I'll admit that's annoying, but at least they won't lose more stages. */
if( bInitiatedByMenuTimer && !bSelectedSameSteps ) if( bInitiatedByMenuTimer && !bSelectedSameSteps )
{ {
// Since m_vpSteps is sorted by Difficulty, the first entry should be the easiest. /* Since m_vpSteps is sorted by Difficulty, the first entry should be the easiest. */
ASSERT( m_vpSteps.size() ); ASSERT( m_vpSteps.size() );
Steps *pSteps = m_vpSteps[0]; Steps *pSteps = m_vpSteps[0];
@@ -1041,7 +1033,7 @@ void ScreenSelectMusic::MenuStart( const InputEventPlus &input )
break; break;
} }
// If the steps don't match up, we need to check some more conditions... /* If the steps don't match up, we need to check some more conditions... */
if( !bSelectedSameSteps ) if( !bSelectedSameSteps )
{ {
const PlayerNumber other = OPPOSITE_PLAYER[pn]; const PlayerNumber other = OPPOSITE_PLAYER[pn];
@@ -1063,12 +1055,13 @@ void ScreenSelectMusic::MenuStart( const InputEventPlus &input )
} }
else if( bSelectedRoutineSteps[pn] ) else if( bSelectedRoutineSteps[pn] )
{ {
// They selected non-Routine steps, so we can't select Routine steps. /* They selected non-Routine steps, so we can't select Routine steps. */
return; return;
} }
} }
} }
} }
}
if( !bAllPlayersDoneSelectingSteps ) if( !bAllPlayersDoneSelectingSteps )
{ {
-6
View File
@@ -540,9 +540,7 @@ void Sprite::DrawTexture( const TweenState *state )
{ {
DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Modulate ); DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Modulate );
//////////////////////
// render the shadow // render the shadow
//////////////////////
if( m_fShadowLengthX != 0 || m_fShadowLengthY != 0 ) if( m_fShadowLengthX != 0 || m_fShadowLengthY != 0 )
{ {
DISPLAY->PushMatrix(); DISPLAY->PushMatrix();
@@ -554,9 +552,7 @@ void Sprite::DrawTexture( const TweenState *state )
DISPLAY->PopMatrix(); DISPLAY->PopMatrix();
} }
//////////////////////
// render the diffuse pass // render the diffuse pass
//////////////////////
v[0].c = state->diffuse[0]; // top left v[0].c = state->diffuse[0]; // top left
v[1].c = state->diffuse[2]; // bottom left v[1].c = state->diffuse[2]; // bottom left
v[2].c = state->diffuse[3]; // bottom right v[2].c = state->diffuse[3]; // bottom right
@@ -564,9 +560,7 @@ void Sprite::DrawTexture( const TweenState *state )
DISPLAY->DrawQuad( v ); DISPLAY->DrawQuad( v );
} }
//////////////////////
// render the glow pass // render the glow pass
//////////////////////
if( state->glow.a > 0.0001f ) if( state->glow.a > 0.0001f )
{ {
DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Glow ); DISPLAY->SetTextureMode( TextureUnit_1, TextureMode_Glow );