sm-ssc v1.0 Public Beta 1 code changes
This commit is contained in:
+1
-1
@@ -338,7 +338,7 @@ void ActorFrame::UpdateInternal( float fDeltaTime )
|
||||
pActor->Update(fDeltaTime);
|
||||
}
|
||||
|
||||
// todo: update lighting?
|
||||
// todo: update lighting? -aj
|
||||
|
||||
if( unlikely(!m_UpdateFunction.IsNil()) )
|
||||
{
|
||||
|
||||
+1
-1
@@ -106,7 +106,7 @@ Actor* ActorUtil::LoadFromNode( const XNode* pNode, Actor *pParentActor )
|
||||
{
|
||||
ASSERT( pNode );
|
||||
|
||||
/* TODO: Remove this in favor of using conditionals in Lua. */
|
||||
// TODO: Remove this in favor of using conditionals in Lua.
|
||||
{
|
||||
bool bCond;
|
||||
if( pNode->GetAttrValue("Condition", bCond) && !bCond )
|
||||
|
||||
+11
-16
@@ -114,7 +114,8 @@ void AutoKeysounds::LoadAutoplaySoundsInto( RageSoundReader_Chain *pChain )
|
||||
|
||||
void AutoKeysounds::LoadTracks( const Song *pSong, RageSoundReader *&pShared, RageSoundReader *&pPlayer1, RageSoundReader *&pPlayer2 )
|
||||
{
|
||||
/* If we have two players, prefer a three-track sound; otherwise prefer a two-track sound. */
|
||||
// If we have two players, prefer a three-track sound; otherwise prefer a
|
||||
// two-track sound.
|
||||
//bool bTwoPlayers = GAMESTATE->GetNumPlayersEnabled() == 2;
|
||||
|
||||
pPlayer1 = NULL;
|
||||
@@ -148,7 +149,7 @@ void AutoKeysounds::LoadTracks( const Song *pSong, RageSoundReader *&pShared, Ra
|
||||
{
|
||||
RageSoundReader *pSongReader = vpSounds[0];
|
||||
|
||||
/* Load the buffering filter before the effects filters, so effects aren't delayed. */
|
||||
// Load the buffering filter before the effects filters, so effects aren't delayed.
|
||||
pSongReader = new RageSoundReader_Extend( pSongReader );
|
||||
pSongReader = new RageSoundReader_ThreadedBuffer( pSongReader );
|
||||
pShared = pSongReader;
|
||||
@@ -163,20 +164,18 @@ void AutoKeysounds::LoadTracks( const Song *pSong, RageSoundReader *&pShared, Ra
|
||||
|
||||
RageSoundReader *pSongReader = pMerge;
|
||||
|
||||
/* Load the buffering filter before the effects filters, so effects aren't delayed. */
|
||||
// Load the buffering filter before the effects filters, so effects aren't delayed.
|
||||
pSongReader = new RageSoundReader_Extend( pSongReader );
|
||||
pSongReader = new RageSoundReader_ThreadedBuffer( pSongReader );
|
||||
pShared = pSongReader;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
if( pSong->HasInstrumentTrack(InstrumentTrack_Guitar) )
|
||||
{
|
||||
RString sError;
|
||||
RageSoundReader *pGuitarTrackReader = RageSoundReader_FileReader::OpenFile( pSong->GetInstrumentTrackPath(InstrumentTrack_Guitar), sError );
|
||||
/* Load the buffering filter before the effects filters, so effects aren't delayed. */
|
||||
// Load the buffering filter before the effects filters, so effects aren't delayed.
|
||||
pGuitarTrackReader = new RageSoundReader_Extend( pGuitarTrackReader );
|
||||
pGuitarTrackReader = new RageSoundReader_ThreadedBuffer( pGuitarTrackReader );
|
||||
pPlayer1 = pGuitarTrackReader;
|
||||
@@ -193,10 +192,9 @@ void AutoKeysounds::LoadTracks( const Song *pSong, RageSoundReader *&pShared, Ra
|
||||
|
||||
// TODO: Make this work for player 2, and for 2 players
|
||||
|
||||
|
||||
/* The code below is used to split the main sound stream into per-player sounds.
|
||||
* The results of this method doesn't seem interesting enough to bother supporting this.
|
||||
*/
|
||||
/* The code below is used to split the main sound stream into per-player
|
||||
* sounds. The results of this method doesn't seem interesting enough to
|
||||
* bother supporting this. */
|
||||
|
||||
//RageSoundSplitter Splitter( pSongReader );
|
||||
|
||||
@@ -206,7 +204,6 @@ void AutoKeysounds::LoadTracks( const Song *pSong, RageSoundReader *&pShared, Ra
|
||||
// pMainSound->AddSourceChannelToSound( 1, 1 );
|
||||
//pShared = pMainSound;
|
||||
|
||||
//
|
||||
//RageSoundReader_Split *pLeadSound = Splitter.CreateSound();
|
||||
//pLeadSound->AddSourceChannelToSound( 2, 0 );
|
||||
//if( pSongReader->GetNumChannels() >= 4 ) // stereo
|
||||
@@ -256,7 +253,7 @@ void AutoKeysounds::FinishLoading()
|
||||
vector<RageSoundReader *> apSounds;
|
||||
LoadTracks( pSong, m_pSharedSound, m_pPlayerSounds[0], m_pPlayerSounds[1] );
|
||||
|
||||
/* Load autoplay sounds, if any. */
|
||||
// Load autoplay sounds, if any.
|
||||
{
|
||||
RageSoundReader_Chain *pChain = new RageSoundReader_Chain;
|
||||
pChain->SetPreferredSampleRate( SOUNDMAN->GetDriverSampleRate() );
|
||||
@@ -291,7 +288,7 @@ void AutoKeysounds::FinishLoading()
|
||||
m_pPlayerSounds[0] = new RageSoundReader_Pan( m_pPlayerSounds[0] );
|
||||
apSounds.push_back( m_pPlayerSounds[0] );
|
||||
}
|
||||
|
||||
|
||||
if( m_pPlayerSounds[1] != NULL )
|
||||
{
|
||||
m_pPlayerSounds[1] = new RageSoundReader_PitchChange( m_pPlayerSounds[1] );
|
||||
@@ -325,9 +322,7 @@ void AutoKeysounds::FinishLoading()
|
||||
|
||||
void AutoKeysounds::Update( float fDelta )
|
||||
{
|
||||
//
|
||||
// Play keysounds for crossed rows.
|
||||
//
|
||||
/*
|
||||
bool bCrossedABeat = false;
|
||||
{
|
||||
@@ -355,7 +350,7 @@ void AutoKeysounds::Update( float fDelta )
|
||||
ASSERT( tn.type == TapNote::autoKeysound );
|
||||
if( tn.bKeysound )
|
||||
m_vKeysounds[tn.iKeysoundIndex].Play();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-12
@@ -42,8 +42,6 @@ static Preference<bool> g_bSongBackgrounds( "SongBackgrounds", true );
|
||||
// Width of the region separating the left and right brightness areas:
|
||||
static float g_fBackgroundCenterWidth = 40;
|
||||
|
||||
|
||||
|
||||
class BrightnessOverlay: public ActorFrame
|
||||
{
|
||||
public:
|
||||
@@ -81,7 +79,7 @@ public:
|
||||
|
||||
void FadeToActualBrightness() { m_Brightness.FadeToActualBrightness(); }
|
||||
void SetBrightness( float fBrightness ) { m_Brightness.Set(fBrightness); } /* overrides pref and Cover */
|
||||
|
||||
|
||||
DancingCharacters* GetDancingCharacters() { return m_pDancingCharacters; };
|
||||
|
||||
void GetLoadedBackgroundChanges( vector<BackgroundChange> *pBackgroundChangesOut[NUM_BackgroundLayer] );
|
||||
@@ -92,10 +90,10 @@ protected:
|
||||
const Song *m_pSong;
|
||||
map<RString,BackgroundTransition> m_mapNameToTransition;
|
||||
deque<BackgroundDef> m_RandomBGAnimations; // random background to choose from. These may or may not be loaded into m_BGAnimations.
|
||||
|
||||
|
||||
void LoadFromRandom( float fFirstBeat, float fEndBeat, const BackgroundChange &change );
|
||||
bool IsDangerAllVisible();
|
||||
|
||||
|
||||
class Layer
|
||||
{
|
||||
public:
|
||||
@@ -112,7 +110,7 @@ protected:
|
||||
|
||||
map<BackgroundDef,Actor*> m_BGAnimations;
|
||||
vector<BackgroundChange> m_aBGChanges;
|
||||
int m_iCurBGChangeIndex;
|
||||
int m_iCurBGChangeIndex;
|
||||
Actor *m_pCurrentBGA;
|
||||
Actor *m_pFadingBGA;
|
||||
};
|
||||
@@ -121,7 +119,6 @@ protected:
|
||||
float m_fLastMusicSeconds;
|
||||
bool m_bDangerAllWasVisible;
|
||||
|
||||
|
||||
// cover up the edge of animations that might hang outside of the background rectangle
|
||||
Quad m_quadBorderLeft, m_quadBorderTop, m_quadBorderRight, m_quadBorderBottom;
|
||||
|
||||
@@ -131,7 +128,6 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
|
||||
static RageColor GetBrightnessColor( float fBrightnessPercent )
|
||||
{
|
||||
RageColor cBrightness = RageColor( 0,0,0,1-fBrightnessPercent );
|
||||
@@ -280,7 +276,7 @@ bool BackgroundImpl::Layer::CreateBackground( const Song *pSong, const Backgroun
|
||||
for( unsigned i=0; i<vsToResolve.size(); i++ )
|
||||
{
|
||||
const RString &sToResolve = vsToResolve[i];
|
||||
|
||||
|
||||
if( sToResolve.empty() )
|
||||
{
|
||||
if( i == 0 )
|
||||
@@ -318,7 +314,7 @@ bool BackgroundImpl::Layer::CreateBackground( const Song *pSong, const Backgroun
|
||||
else
|
||||
sResolved = "../"+ThemeManager::GetBlankGraphicPath();
|
||||
}
|
||||
|
||||
|
||||
ASSERT( !sResolved.empty() );
|
||||
|
||||
vsResolvedRef[i] = new LuaThreadVariable( ssprintf("File%d",i+1), sResolved );
|
||||
@@ -346,12 +342,10 @@ bool BackgroundImpl::Layer::CreateBackground( const Song *pSong, const Backgroun
|
||||
}
|
||||
ASSERT( !sEffect.empty() );
|
||||
|
||||
|
||||
// Set Lua color globals
|
||||
LuaThreadVariable sColor1( "Color1", bd.m_sColor1.empty() ? RString("1,1,1,1") : bd.m_sColor1 );
|
||||
LuaThreadVariable sColor2( "Color2", bd.m_sColor2.empty() ? RString("1,1,1,1") : bd.m_sColor2 );
|
||||
|
||||
|
||||
// Resolve the effect file.
|
||||
RString sEffectFile;
|
||||
for( int i=0; i<2; i++ )
|
||||
|
||||
+4
-6
@@ -34,8 +34,7 @@ static vector<RageColor> RAINBOW_COLORS;
|
||||
BitmapText::BitmapText()
|
||||
{
|
||||
// Loading these theme metrics is slow, so only do it every 20th time.
|
||||
// todo: why not check to see if you need to bother updating the fucker
|
||||
// at all? -aj
|
||||
// todo: why not check to see if you need to bother updating this at all? -aj
|
||||
static int iReloadCounter = 0;
|
||||
if( iReloadCounter % 20==0 )
|
||||
{
|
||||
@@ -396,12 +395,11 @@ void BitmapText::SetTextInternal()
|
||||
}
|
||||
else
|
||||
{
|
||||
//
|
||||
// Break sText into lines that don't exceed iWrapWidthPixels
|
||||
// (if only one word fits on the line, it may be larger than iWrapWidthPixels).
|
||||
//
|
||||
// TODO: Investigate whether this works in all languages
|
||||
/* It doesn't. I can add Japanese wrapping, at least. We could handle hyphens
|
||||
|
||||
// This does not work in all languages:
|
||||
/* "...I can add Japanese wrapping, at least. We could handle hyphens
|
||||
* and soft hyphens and pretty easily, too. -glenn */
|
||||
// TODO: Move this wrapping logic into Font
|
||||
vector<RString> asLines;
|
||||
|
||||
+1
-1
@@ -43,7 +43,7 @@ public:
|
||||
protected:
|
||||
void BeforeChange( bool bLowResToHighRes=false );
|
||||
|
||||
enum { NUM_BANNERS = 5 };
|
||||
static const int NUM_BANNERS = 5;
|
||||
Banner m_Banner[NUM_BANNERS];
|
||||
int m_iIndexLatest;
|
||||
|
||||
|
||||
@@ -2389,6 +2389,7 @@ public:
|
||||
static int JoinPlayer( T* p, lua_State *L ) { p->JoinPlayer(Enum::Check<PlayerNumber>(L, 1)); return 0; }
|
||||
static int UnjoinPlayer( T* p, lua_State *L ) { p->UnjoinPlayer(Enum::Check<PlayerNumber>(L, 1)); return 0; }
|
||||
static int GetSongPercent( T* p, lua_State *L ) { lua_pushnumber(L, p->GetSongPercent(FArg(1))); return 1; }
|
||||
DEFINE_METHOD( GetCurMusicSeconds, m_fMusicSeconds )
|
||||
|
||||
DEFINE_METHOD( GetWorkoutGoalComplete, m_bWorkoutGoalComplete )
|
||||
|
||||
@@ -2484,6 +2485,7 @@ public:
|
||||
ADD_METHOD( JoinPlayer );
|
||||
ADD_METHOD( UnjoinPlayer );
|
||||
ADD_METHOD( GetSongPercent );
|
||||
ADD_METHOD( GetCurMusicSeconds );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+3
-8
@@ -59,7 +59,6 @@ public:
|
||||
|
||||
void Update( float fDelta );
|
||||
|
||||
|
||||
// Main state info
|
||||
void SetCurGame( const Game *pGame ); // Call this instead of m_pCurGame.Set to make sure PREFSMAN->m_sCurrentGame stays in sync
|
||||
BroadcastOnChangePtr<const Game> m_pCurGame;
|
||||
@@ -83,7 +82,7 @@ public:
|
||||
RageTimer m_timeGameStarted; // from the moment the first player pressed Start
|
||||
LuaTable *m_Environment;
|
||||
|
||||
/* This is set to a random number per-game/round; it can be used for a random seed. */
|
||||
// This is set to a random number per-game/round; it can be used for a random seed.
|
||||
int m_iGameSeed, m_iStageSeed;
|
||||
RString m_sStageGUID;
|
||||
|
||||
@@ -111,7 +110,7 @@ public:
|
||||
|
||||
|
||||
bool IsCourseMode() const;
|
||||
bool IsBattleMode() const; /* not Rave */
|
||||
bool IsBattleMode() const; // not Rave
|
||||
|
||||
bool ShowW1() const;
|
||||
|
||||
@@ -191,7 +190,7 @@ public:
|
||||
float m_fMusicSecondsVisible;
|
||||
float m_fSongBeatVisible;
|
||||
|
||||
// if re-adding noteskin changes in courses, add functions and shit here -aj
|
||||
// if re-adding noteskin changes in courses, add functions and such here -aj
|
||||
void GetAllUsedNoteSkins( vector<RString> &out ) const;
|
||||
|
||||
static const float MUSIC_SECONDS_INVALID;
|
||||
@@ -250,10 +249,8 @@ public:
|
||||
// character stuff
|
||||
Character* m_pCurCharacters[NUM_PLAYERS];
|
||||
|
||||
|
||||
bool HasEarnedExtraStage() const { return m_bEarnedExtraStage; }
|
||||
|
||||
|
||||
// Ranking Stuff
|
||||
struct RankingFeat
|
||||
{
|
||||
@@ -274,13 +271,11 @@ public:
|
||||
void StoreRankingName( PlayerNumber pn, RString name ); // Called by name entry screens
|
||||
vector<RString*> m_vpsNamesThatWereFilled; // filled on StoreRankingName,
|
||||
|
||||
|
||||
// Award stuff
|
||||
// lowest priority in front, highest priority at the back.
|
||||
deque<StageAward> m_vLastStageAwards[NUM_PLAYERS];
|
||||
deque<PeakComboAward> m_vLastPeakComboAwards[NUM_PLAYERS];
|
||||
|
||||
|
||||
// Attract stuff
|
||||
int m_iNumTimesThroughAttract; // negative means play regardless of m_iAttractSoundFrequency setting
|
||||
bool IsTimeToPlayAttractSounds() const;
|
||||
|
||||
@@ -138,7 +138,7 @@ void PercentageDisplay::Refresh()
|
||||
{
|
||||
float fPercentDancePoints = m_pPlayerStageStats->GetPercentDancePoints();
|
||||
float fCurMaxPercentDancePoints = m_pPlayerStageStats->GetCurMaxPercentDancePoints();
|
||||
|
||||
|
||||
if( m_bApplyScoreDisplayOptions )
|
||||
{
|
||||
switch( m_pPlayerState->m_PlayerOptions.GetCurrent().m_ScoreDisplay )
|
||||
@@ -169,7 +169,7 @@ void PercentageDisplay::Refresh()
|
||||
m_textPercentRemainder.SetText( ssprintf(".%01d%%", iPercentRemainder) );
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
Lua *L = LUA->Get();
|
||||
m_FormatPercentScore.PushSelf( L );
|
||||
ASSERT( !lua_isnil(L, -1) );
|
||||
|
||||
@@ -23,9 +23,7 @@ public:
|
||||
|
||||
bool ShowDancePointsNotPercentage() const;
|
||||
|
||||
//
|
||||
// Lua
|
||||
//
|
||||
virtual void PushSelf( lua_State *L );
|
||||
|
||||
private:
|
||||
|
||||
+10
-5
@@ -644,8 +644,8 @@ void Player::Update( float fDeltaTime )
|
||||
if( fCurrentGameTime > 1.0f )
|
||||
{
|
||||
/* Update the attack if there are no others currently running.
|
||||
* Note that we have a new one activate a little early; this is to have a bit
|
||||
* of overlap rather than an abrupt change */
|
||||
* Note that we have a new one activate a little early; This is
|
||||
* to have a bit of overlap rather than an abrupt change. */
|
||||
if( (fCurrentGameTime - m_fActiveRandomAttackStart) > (fAttackRunTime - 0.5f) )
|
||||
{
|
||||
m_fActiveRandomAttackStart = fCurrentGameTime;
|
||||
@@ -2443,8 +2443,9 @@ void Player::UpdateJudgedRows()
|
||||
setSounds.insert( &m_soundMine );
|
||||
|
||||
/* Attack Mines:
|
||||
* Only difference is these launch an attack rather than affecting the lifebar. All the
|
||||
* other mine impacts (score, dance points, etc.) are still applied. */
|
||||
* Only difference is these launch an attack rather than affecting
|
||||
* the lifebar. All the other mine impacts (score, dance points,
|
||||
* etc.) are still applied. */
|
||||
if( m_pPlayerState->m_PlayerOptions.GetCurrent().m_bTransforms[PlayerOptions::TRANSFORM_ATTACKMINES] )
|
||||
{
|
||||
// Should we hardcode this, or make it a preference/theme metric? ~ Mike
|
||||
@@ -3019,7 +3020,11 @@ RString Player::ApplyRandomAttack()
|
||||
if( GAMESTATE->m_RandomAttacks.size() < 1 )
|
||||
return "";
|
||||
|
||||
int iAttackToUse = rand() % GAMESTATE->m_RandomAttacks.size();
|
||||
//int iAttackToUse = rand() % GAMESTATE->m_RandomAttacks.size();
|
||||
DateTime now = DateTime::GetNowDate();
|
||||
int iSeed = now.tm_hour * now.tm_min * now.tm_sec * now.tm_mday;
|
||||
RandomGen rnd( GAMESTATE->m_iStageSeed * iSeed );
|
||||
int iAttackToUse = rnd() % GAMESTATE->m_RandomAttacks.size();
|
||||
return GAMESTATE->m_RandomAttacks[iAttackToUse];
|
||||
}
|
||||
|
||||
|
||||
+1
-2
@@ -23,13 +23,12 @@
|
||||
* "v0.0": Final Releases
|
||||
*/
|
||||
#ifndef PRODUCT_VER_BARE
|
||||
#define PRODUCT_VER_BARE private beta 1.4
|
||||
#define PRODUCT_VER_BARE v1.0 beta 1
|
||||
#endif
|
||||
|
||||
// A unique ID for a build of an application. This is used in crash reports and in the network code's version handling
|
||||
#define PRODUCT_ID_VER_BARE PRODUCT_ID_BARE PRODUCT_VER_BARE
|
||||
|
||||
|
||||
// These cannot be #undef'd so make them unlikely to conflict with anything
|
||||
#define PRODUCT_STRINGIFY(x) #x
|
||||
#define PRODUCT_XSTRINGIFY(x) PRODUCT_STRINGIFY(x)
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
|
||||
; see ProductInfo.h for use descriptions
|
||||
!define PRODUCT_ID "sm-ssc"
|
||||
!define PRODUCT_VER "private beta 1.4"
|
||||
!define PRODUCT_VER "v1.0 beta 1"
|
||||
!define PRODUCT_DISPLAY "${PRODUCT_ID} ${PRODUCT_VER}"
|
||||
!define PRODUCT_BITMAP "sm4"
|
||||
|
||||
|
||||
+8
-4
@@ -15,7 +15,9 @@
|
||||
#include "DisplayResolutions.h"
|
||||
#include "arch/ArchHooks/ArchHooks.h"
|
||||
|
||||
//
|
||||
// Statistics stuff
|
||||
//
|
||||
RageTimer g_LastCheckTimer;
|
||||
int g_iNumVerts;
|
||||
int g_iFPS, g_iVPF, g_iCFPS;
|
||||
@@ -143,7 +145,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";
|
||||
|
||||
@@ -180,7 +182,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);
|
||||
@@ -195,7 +197,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;
|
||||
@@ -219,7 +221,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 );
|
||||
}
|
||||
@@ -259,7 +261,9 @@ void RageDisplay::SetDefaultRenderStates()
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Matrix stuff
|
||||
//
|
||||
class MatrixStack
|
||||
{
|
||||
vector<RageMatrix> stack;
|
||||
|
||||
+25
-21
@@ -413,10 +413,10 @@ void ScoreKeeperNormal::AddScoreInternal( TapNoteScore score )
|
||||
|
||||
switch( score )
|
||||
{
|
||||
case TNS_W1: p = 10; break;
|
||||
case TNS_W2: p = GAMESTATE->ShowW1()? 9:10; break;
|
||||
case TNS_W3: p = 5; break;
|
||||
default: p = 0; break;
|
||||
case TNS_W1: p = 10; break;
|
||||
case TNS_W2: p = GAMESTATE->ShowW1()? 9:10; break;
|
||||
case TNS_W3: p = 5; break;
|
||||
default: p = 0; break;
|
||||
}
|
||||
|
||||
m_iTapNotesHit++;
|
||||
@@ -471,13 +471,13 @@ void ScoreKeeperNormal::AddScoreInternal( TapNoteScore score )
|
||||
|
||||
switch( score )
|
||||
{
|
||||
case TNS_W1: p = m_CustomTNS_W1; break;
|
||||
case TNS_W2: p = m_CustomTNS_W2; break;
|
||||
case TNS_W3: p = m_CustomTNS_W3; break;
|
||||
case TNS_W4: p = m_CustomTNS_W4; break;
|
||||
case TNS_W5: p = m_CustomTNS_W5; break;
|
||||
case TNS_W1: p = m_CustomTNS_W1; break;
|
||||
case TNS_W2: p = m_CustomTNS_W2; break;
|
||||
case TNS_W3: p = m_CustomTNS_W3; break;
|
||||
case TNS_W4: p = m_CustomTNS_W4; break;
|
||||
case TNS_W5: p = m_CustomTNS_W5; break;
|
||||
case TNS_Miss: p = m_CustomTNS_Miss; break;
|
||||
default: p = 0; break;
|
||||
default: p = 0; break;
|
||||
}
|
||||
|
||||
if( m_CustomComboBonus )
|
||||
@@ -657,9 +657,7 @@ void ScoreKeeperNormal::HandleTapRowScore( const NoteData &nd, int iRow )
|
||||
|
||||
AddTapRowScore( scoreOfLastTap, nd, iRow ); // only score once per row
|
||||
|
||||
//
|
||||
// handle combo logic
|
||||
//
|
||||
#ifndef DEBUG
|
||||
if( (GamePreferences::m_AutoPlay != PC_HUMAN || m_pPlayerState->m_PlayerOptions.GetCurrent().m_fPlayerAutoPlay != 0)
|
||||
&& !GAMESTATE->m_bDemonstrationOrJukebox ) // cheaters always prosper >:D -aj comment edit
|
||||
@@ -681,6 +679,9 @@ void ScoreKeeperNormal::HandleTapRowScore( const NoteData &nd, int iRow )
|
||||
!GAMESTATE->m_bDemonstrationOrJukebox )
|
||||
{
|
||||
SCREENMAN->PostMessageToTopScreen( SM_PlayToasty, 0 );
|
||||
Message msg("ToastyAchieved");
|
||||
msg.SetParam( "PlayerNumber", m_pPlayerState->m_PlayerNumber );
|
||||
MESSAGEMAN->Broadcast(msg);
|
||||
|
||||
// TODO: keep a pointer to the Profile. Don't index with m_PlayerNumber
|
||||
PROFILEMAN->IncrementToastiesCount( m_pPlayerState->m_PlayerNumber );
|
||||
@@ -688,6 +689,9 @@ void ScoreKeeperNormal::HandleTapRowScore( const NoteData &nd, int iRow )
|
||||
break;
|
||||
default:
|
||||
m_iCurToastyCombo = 0;
|
||||
Message msg("ToastyDropped");
|
||||
msg.SetParam( "PlayerNumber", m_pPlayerState->m_PlayerNumber );
|
||||
MESSAGEMAN->Broadcast(msg);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -816,8 +820,8 @@ int ScoreKeeperNormal::TapNoteScoreToDancePoints( TapNoteScore tns, bool bBeginn
|
||||
switch( tns )
|
||||
{
|
||||
DEFAULT_FAIL( tns );
|
||||
case TNS_None: iWeight = 0; break;
|
||||
case TNS_HitMine: iWeight = g_iPercentScoreWeight[SE_HitMine]; break;
|
||||
case TNS_None: iWeight = 0; break;
|
||||
case TNS_HitMine: iWeight = g_iPercentScoreWeight[SE_HitMine]; break;
|
||||
case TNS_Miss: iWeight = g_iPercentScoreWeight[SE_Miss]; break;
|
||||
case TNS_W5: iWeight = g_iPercentScoreWeight[SE_W5]; break;
|
||||
case TNS_W4: iWeight = g_iPercentScoreWeight[SE_W4]; break;
|
||||
@@ -838,9 +842,9 @@ int ScoreKeeperNormal::HoldNoteScoreToDancePoints( HoldNoteScore hns, bool bBegi
|
||||
switch( hns )
|
||||
{
|
||||
DEFAULT_FAIL( hns );
|
||||
case HNS_None: iWeight = 0; break;
|
||||
case HNS_None: iWeight = 0; break;
|
||||
case HNS_LetGo: iWeight = g_iPercentScoreWeight[SE_LetGo]; break;
|
||||
case HNS_Held: iWeight = g_iPercentScoreWeight[SE_Held]; break;
|
||||
case HNS_Held: iWeight = g_iPercentScoreWeight[SE_Held]; break;
|
||||
}
|
||||
if( bBeginner && PREFSMAN->m_bMercifulBeginner )
|
||||
iWeight = max( 0, iWeight );
|
||||
@@ -858,9 +862,9 @@ int ScoreKeeperNormal::TapNoteScoreToGradePoints( TapNoteScore tns, bool bBeginn
|
||||
switch( tns )
|
||||
{
|
||||
DEFAULT_FAIL( tns );
|
||||
case TNS_None: iWeight = 0; break;
|
||||
case TNS_AvoidMine: iWeight = 0; break;
|
||||
case TNS_HitMine: iWeight = g_iGradeWeight[SE_HitMine]; break;
|
||||
case TNS_None: iWeight = 0; break;
|
||||
case TNS_AvoidMine: iWeight = 0; break;
|
||||
case TNS_HitMine: iWeight = g_iGradeWeight[SE_HitMine]; break;
|
||||
case TNS_Miss: iWeight = g_iGradeWeight[SE_Miss]; break;
|
||||
case TNS_W5: iWeight = g_iGradeWeight[SE_W5]; break;
|
||||
case TNS_W4: iWeight = g_iGradeWeight[SE_W4]; break;
|
||||
@@ -881,9 +885,9 @@ int ScoreKeeperNormal::HoldNoteScoreToGradePoints( HoldNoteScore hns, bool bBegi
|
||||
switch( hns )
|
||||
{
|
||||
DEFAULT_FAIL( hns );
|
||||
case HNS_None: iWeight = 0; break;
|
||||
case HNS_None: iWeight = 0; break;
|
||||
case HNS_LetGo: iWeight = g_iGradeWeight[SE_LetGo]; break;
|
||||
case HNS_Held: iWeight = g_iGradeWeight[SE_Held]; break;
|
||||
case HNS_Held: iWeight = g_iGradeWeight[SE_Held]; break;
|
||||
}
|
||||
if( bBeginner && PREFSMAN->m_bMercifulBeginner )
|
||||
iWeight = max( 0, iWeight );
|
||||
|
||||
+3
-2
@@ -905,7 +905,7 @@ void ScreenEdit::MakeFilteredMenuDef( const MenuDef* pDef, MenuDef &menu )
|
||||
|
||||
void ScreenEdit::EditMiniMenu( const MenuDef* pDef, ScreenMessage SM_SendOnOK, ScreenMessage SM_SendOnCancel )
|
||||
{
|
||||
/* Reload options. */
|
||||
// Reload options.
|
||||
MenuDef menu("");
|
||||
MakeFilteredMenuDef( pDef, menu );
|
||||
ScreenMiniMenu::MiniMenu( &menu, SM_SendOnOK, SM_SendOnCancel );
|
||||
@@ -3375,7 +3375,8 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector<int> &iAns
|
||||
if( sIter[i]->IsAutogen() )
|
||||
continue;
|
||||
|
||||
/* XXX: Edits are distinguished by description. Compare vs m_pSteps. */
|
||||
// XXX: Edits are distinguished by description.
|
||||
// Compare vs m_pSteps.
|
||||
if( (sIter[i]->m_StepsType == GAMESTATE->m_pCurSteps[PLAYER_1]->m_StepsType) &&
|
||||
(sIter[i]->GetDifficulty() == GAMESTATE->m_pCurSteps[PLAYER_1]->GetDifficulty()) )
|
||||
continue;
|
||||
|
||||
+6
-8
@@ -47,7 +47,7 @@ enum EditButton
|
||||
EDIT_BUTTON_COLUMN_8,
|
||||
EDIT_BUTTON_COLUMN_9,
|
||||
|
||||
/* These are modifiers to EDIT_BUTTON_COLUMN_*. */
|
||||
// These are modifiers to EDIT_BUTTON_COLUMN_*.
|
||||
EDIT_BUTTON_RIGHT_SIDE,
|
||||
EDIT_BUTTON_LAY_MINE_OR_ROLL,
|
||||
EDIT_BUTTON_LAY_TAP_ATTACK,
|
||||
@@ -65,7 +65,7 @@ enum EditButton
|
||||
EDIT_BUTTON_SCROLL_NEXT,
|
||||
EDIT_BUTTON_SCROLL_PREV,
|
||||
|
||||
/* These are modifiers to EDIT_BUTTON_SCROLL_*. */
|
||||
// These are modifiers to EDIT_BUTTON_SCROLL_*.
|
||||
EDIT_BUTTON_SCROLL_SELECT,
|
||||
|
||||
EDIT_BUTTON_LAY_SELECT,
|
||||
@@ -118,7 +118,7 @@ enum EditButton
|
||||
EDIT_BUTTON_SAMPLE_LENGTH_UP,
|
||||
EDIT_BUTTON_SAMPLE_LENGTH_DOWN,
|
||||
|
||||
/* This modifies offset, BPM, and stop segment changes. */
|
||||
// This modifies offset, BPM, and stop segment changes.
|
||||
EDIT_BUTTON_ADJUST_FINE,
|
||||
|
||||
EDIT_BUTTON_SAVE,
|
||||
@@ -129,19 +129,17 @@ enum EditButton
|
||||
|
||||
EDIT_BUTTON_SWITCH_PLAYERS,
|
||||
|
||||
NUM_EditButton, // leave this at the end
|
||||
NUM_EditButton, // leave this at the end
|
||||
EditButton_Invalid
|
||||
};
|
||||
#define FOREACH_EditButton( e ) FOREACH_ENUM( EditButton, e )
|
||||
const int NUM_EDIT_TO_DEVICE_SLOTS = 2;
|
||||
const int NUM_EDIT_TO_MENU_SLOTS = 2;
|
||||
|
||||
/*
|
||||
* g_MapEditToDI is a simple mapping: edit functions map to DeviceInputs.
|
||||
/* g_MapEditToDI is a simple mapping: edit functions map to DeviceInputs.
|
||||
* If g_MapEditToDIHold for a given edit function is valid, then at least one
|
||||
* input in g_MapEditToDIHold must be held when pressing any key in g_MapEditToDI
|
||||
* for the input to occur.
|
||||
*/
|
||||
* for the input to occur. */
|
||||
struct MapEditToDI
|
||||
{
|
||||
DeviceInput button[NUM_EditButton][NUM_EDIT_TO_DEVICE_SLOTS];
|
||||
|
||||
+3
-3
@@ -48,9 +48,9 @@ public:
|
||||
void ThemeChanged();
|
||||
|
||||
|
||||
/* Return true if the given screen is in the main screen stack, but not the bottommost
|
||||
* screen. If true, the screen should usually exit by popping itself, not by loading
|
||||
* another screen. */
|
||||
/* Return true if the given screen is in the main screen stack, but not the
|
||||
* bottommost screen. If true, the screen should usually exit by popping
|
||||
* itself, not by loading another screen. */
|
||||
bool IsStackedScreen( const Screen *pScreen ) const;
|
||||
|
||||
// Lua
|
||||
|
||||
@@ -21,7 +21,7 @@ vector<int> ScreenMiniMenu::s_viLastAnswers;
|
||||
void PrepareToLoadScreen( const RString &sScreenName ) {}
|
||||
void FinishedLoadingScreen() {}
|
||||
|
||||
/* Settings: */
|
||||
// Settings:
|
||||
namespace
|
||||
{
|
||||
const MenuDef* g_pMenuDef = NULL;
|
||||
@@ -65,9 +65,9 @@ void ScreenMiniMenu::BeginScreen()
|
||||
|
||||
ScreenOptions::BeginScreen();
|
||||
|
||||
/* HACK: An OptionRow exits if a screen is set. ScreenMiniMenu is always pushed, so we
|
||||
* don't set screens to load. Set a dummy screen, so ScreenOptions::GetNextScreenForSelection
|
||||
* will know to move on. */
|
||||
/* HACK: An OptionRow exits if a screen is set. ScreenMiniMenu is always
|
||||
* pushed, so we don't set screens to load. Set a dummy screen, so
|
||||
* ScreenOptions::GetNextScreenForSelection will know to move on. */
|
||||
m_sNextScreen = "xxx";
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ bool ScreenOptionsMemoryCard::UpdateCurrentUsbStorageDevices()
|
||||
void ScreenOptionsMemoryCard::CreateMenu()
|
||||
{
|
||||
vector<OptionRowHandler*> vHands;
|
||||
|
||||
|
||||
FOREACH_CONST( UsbStorageDevice, m_CurrentUsbStorageDevices, iter )
|
||||
{
|
||||
// TODO: Make these strings themable
|
||||
|
||||
+50
-44
@@ -14,18 +14,18 @@
|
||||
#include <cstdlib>
|
||||
#include "LocalizedString.h"
|
||||
|
||||
#define EXISTINGBG_WIDTH THEME->GetMetricF(m_sName,"PackagesBGWidth")
|
||||
#define WEBBG_WIDTH THEME->GetMetricF(m_sName,"WebBGWidth")
|
||||
#define NUM_PACKAGES_SHOW THEME->GetMetricI(m_sName,"NumPackagesShow")
|
||||
#define NUM_LINKS_SHOW THEME->GetMetricI(m_sName,"NumLinksShow")
|
||||
#define DEFAULT_URL THEME->GetMetric(m_sName,"DefaultUrl")
|
||||
|
||||
AutoScreenMessage( SM_BackFromURL )
|
||||
|
||||
REGISTER_SCREEN_CLASS( ScreenPackages );
|
||||
|
||||
static LocalizedString VISIT_URL( "ScreenPackages", "VisitURL" );
|
||||
void ScreenPackages::Init()
|
||||
{
|
||||
EXISTINGBG_WIDTH.Load(m_sName, "PackagesBGWidth");
|
||||
WEBBG_WIDTH.Load(m_sName, "WebBGWidth");
|
||||
NUM_PACKAGES_SHOW.Load(m_sName, "NumPackagesShow");
|
||||
NUM_LINKS_SHOW.Load(m_sName, "NumLinksShow");
|
||||
DEFAULT_URL.Load(m_sName, "DefaultUrl");
|
||||
ScreenWithMenuElements::Init();
|
||||
|
||||
m_iPackagesPos = 0;
|
||||
@@ -69,9 +69,8 @@ void ScreenPackages::Init()
|
||||
m_textWeb.SetMaxWidth( WEBBG_WIDTH );
|
||||
LOAD_ALL_COMMANDS_AND_SET_XY_AND_ON_COMMAND( m_textWeb );
|
||||
this->AddChild( &m_textWeb);
|
||||
m_Links.push_back( " " );
|
||||
// TODO: make this a localized string -aj
|
||||
m_LinkTitles.push_back( "--Visit URL--" );
|
||||
m_Links.push_back( " " ); // what is this here for? -aj
|
||||
m_LinkTitles.push_back( VISIT_URL );
|
||||
|
||||
m_textURL.LoadFromFont( THEME->GetPathF( m_sName,"default") );
|
||||
m_textURL.SetShadowLength( 0 );
|
||||
@@ -104,20 +103,20 @@ void ScreenPackages::Init()
|
||||
this->AddChild( &m_textStatus );
|
||||
|
||||
// if the default url isn't empty, load it.
|
||||
if( !DEFAULT_URL.empty() )
|
||||
if( !DEFAULT_URL.GetValue().empty() )
|
||||
EnterURL( DEFAULT_URL );
|
||||
|
||||
UpdateProgress();
|
||||
|
||||
//Workaround: For some reason, the first download sometimes
|
||||
//corrupts; by opening and closing the rage file, this
|
||||
//problem does not occur. Go figure?
|
||||
// Workaround: For some reason, the first download sometimes
|
||||
// corrupts; by opening and closing the RageFile, this
|
||||
// problem does not occur. Go figure?
|
||||
|
||||
//XXX: This is a really dirty work around!
|
||||
//Why does RageFile do this?
|
||||
// XXX: This is a really dirty work around!
|
||||
// Why does RageFile do this?
|
||||
|
||||
//It's always some strange number of bytes at the end of the
|
||||
//file when it corrupts.
|
||||
// It's always some strange number of bytes at the end of the
|
||||
// file when it corrupts.
|
||||
m_fOutputFile.Open( "Packages/dummy.txt", RageFile::WRITE );
|
||||
m_fOutputFile.Close();
|
||||
}
|
||||
@@ -140,6 +139,7 @@ void ScreenPackages::HandleScreenMessage( const ScreenMessage SM )
|
||||
ScreenWithMenuElements::HandleScreenMessage( SM );
|
||||
}
|
||||
|
||||
static LocalizedString DOWNLOAD_PROGRESS( "ScreenPackages", "DL @ %d KB/s" );
|
||||
void ScreenPackages::Update( float fDeltaTime )
|
||||
{
|
||||
HTTPUpdate();
|
||||
@@ -147,9 +147,8 @@ void ScreenPackages::Update( float fDeltaTime )
|
||||
m_fLastUpdate += fDeltaTime;
|
||||
if ( m_fLastUpdate >= 1.0 )
|
||||
{
|
||||
// TODO: Make this a themeable string -aj
|
||||
if ( m_bIsDownloading && m_bGotHeader )
|
||||
m_sStatus = ssprintf( "DL @ %d KB/s", int((m_iDownloaded-m_bytesLastUpdate)/1024) );
|
||||
m_sStatus = ssprintf( DOWNLOAD_PROGRESS.GetValue(), int((m_iDownloaded-m_bytesLastUpdate)/1024) );
|
||||
|
||||
m_bytesLastUpdate = m_iDownloaded;
|
||||
UpdateProgress();
|
||||
@@ -199,7 +198,7 @@ void ScreenPackages::MenuDown( const InputEventPlus &input )
|
||||
{
|
||||
if ( m_bIsDownloading )
|
||||
return;
|
||||
|
||||
|
||||
if ( m_iDLorLST == 0)
|
||||
{
|
||||
if( (unsigned) m_iPackagesPos < m_Packages.size() - 1 )
|
||||
@@ -251,7 +250,7 @@ void ScreenPackages::MenuRight( const InputEventPlus &input )
|
||||
if ( m_bIsDownloading )
|
||||
return;
|
||||
|
||||
/* Huh? */
|
||||
// Huh?
|
||||
//MenuLeft( input );
|
||||
|
||||
if ( m_iDLorLST == 1 )
|
||||
@@ -261,7 +260,7 @@ void ScreenPackages::MenuRight( const InputEventPlus &input )
|
||||
COMMAND( m_sprWebBG, "Back" );
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
m_iDLorLST = 1;
|
||||
COMMAND( m_sprExistingBG, "Back" );
|
||||
COMMAND( m_sprWebBG, "Away" );
|
||||
@@ -354,10 +353,10 @@ void ScreenPackages::HTMLParse()
|
||||
m_Links.clear();
|
||||
m_LinkTitles.clear();
|
||||
m_Links.push_back( " " );
|
||||
m_LinkTitles.push_back( "--Visit URL--" );
|
||||
m_LinkTitles.push_back( VISIT_URL.GetValue() );
|
||||
|
||||
//XXX: VERY DIRTY HTML PARSER!
|
||||
//Only designed to find links on websites.
|
||||
// XXX: VERY DIRTY HTML PARSER!
|
||||
// Only designed to find links on websites.
|
||||
size_t i = m_sBUFFER.find( "<A " );
|
||||
size_t j = 0;
|
||||
size_t k = 0;
|
||||
@@ -383,7 +382,7 @@ void ScreenPackages::HTMLParse()
|
||||
|
||||
l = m_sBUFFER.find( "</", m+1 );
|
||||
|
||||
//Special case: There is exactly one extra tag in the link.
|
||||
// Special case: There is exactly one extra tag in the link.
|
||||
j = m_sBUFFER.find( ">", k+1 );
|
||||
if ( j < l )
|
||||
k = j;
|
||||
@@ -454,6 +453,7 @@ void ScreenPackages::UpdateProgress()
|
||||
m_textStatus.SetText( m_sStatus );
|
||||
}
|
||||
|
||||
static LocalizedString DOWNLOAD_FAILED( "ScreenPackages", "Failed." );
|
||||
void ScreenPackages::CancelDownload( )
|
||||
{
|
||||
m_wSocket.close();
|
||||
@@ -461,11 +461,16 @@ void ScreenPackages::CancelDownload( )
|
||||
m_iDownloaded = 0;
|
||||
m_bGotHeader = false;
|
||||
m_fOutputFile.Close();
|
||||
m_sStatus = "Failed.";
|
||||
m_sStatus = DOWNLOAD_FAILED.GetValue();
|
||||
m_sBUFFER = "";
|
||||
if( !FILEMAN->Remove( "Packages/" + m_sEndName ) )
|
||||
SCREENMAN->SystemMessage( "Packages/" + m_sEndName );
|
||||
}
|
||||
|
||||
static LocalizedString INVALID_URL( "ScreenPackages", "Invalid URL." );
|
||||
static LocalizedString FILE_ALREADY_EXISTS( "ScreenPackages", "File Already Exists" );
|
||||
static LocalizedString FAILED_TO_CONNECT( "ScreenPackages", "Failed to connect." );
|
||||
static LocalizedString HEADER_SENT( "ScreenPackages", "Header Sent." );
|
||||
void ScreenPackages::EnterURL( const RString & sURL )
|
||||
{
|
||||
RString Proto;
|
||||
@@ -475,13 +480,13 @@ void ScreenPackages::EnterURL( const RString & sURL )
|
||||
|
||||
if( !ParseHTTPAddress( sURL, Proto, Server, Port, sAddress ) )
|
||||
{
|
||||
m_sStatus = "Invalid URL.";
|
||||
m_sStatus = INVALID_URL.GetValue();
|
||||
UpdateProgress();
|
||||
return;
|
||||
}
|
||||
|
||||
//Determine if this is a website, or a package?
|
||||
//Criteria: does it end with *zip?
|
||||
// Determine if this is a website, or a package?
|
||||
// Criteria: does it end with *zip?
|
||||
if( sAddress.Right(3).CompareNoCase("zip") == 0 )
|
||||
m_bIsPackage=true;
|
||||
else
|
||||
@@ -502,20 +507,20 @@ void ScreenPackages::EnterURL( const RString & sURL )
|
||||
m_sEndName = "";
|
||||
}
|
||||
|
||||
//Open the file...
|
||||
// Open the file...
|
||||
|
||||
//First find out if a file by this name already exists
|
||||
//if so, then we gotta ditch out.
|
||||
//XXX: This should be fixed by a prompt or something?
|
||||
// First find out if a file by this name already exists
|
||||
// if so, then we gotta ditch out.
|
||||
// XXX: This should be fixed by a prompt or something?
|
||||
|
||||
//if we are not talking about a file, let's not worry
|
||||
// if we are not talking about a file, let's not worry
|
||||
if( m_sEndName != "" && m_bIsPackage )
|
||||
{
|
||||
vector<RString> AddTo;
|
||||
GetDirListing( "Packages/"+m_sEndName, AddTo, false, false );
|
||||
if ( AddTo.size() > 0 )
|
||||
{
|
||||
m_sStatus = "File Already Exists";
|
||||
m_sStatus = FILE_ALREADY_EXISTS.GetValue();
|
||||
UpdateProgress();
|
||||
return;
|
||||
}
|
||||
@@ -527,7 +532,7 @@ void ScreenPackages::EnterURL( const RString & sURL )
|
||||
return;
|
||||
}
|
||||
}
|
||||
//Continue...
|
||||
// Continue...
|
||||
|
||||
sAddress = URLEncode( StripOutContainers(sAddress) );
|
||||
|
||||
@@ -541,7 +546,7 @@ void ScreenPackages::EnterURL( const RString & sURL )
|
||||
|
||||
if( !m_wSocket.connect( Server, (short) Port ) )
|
||||
{
|
||||
m_sStatus = "Failed to connect.";
|
||||
m_sStatus = FAILED_TO_CONNECT.GetValue();
|
||||
UpdateProgress();
|
||||
return;
|
||||
}
|
||||
@@ -555,7 +560,7 @@ void ScreenPackages::EnterURL( const RString & sURL )
|
||||
Header+= "Connection: closed\r\n\r\n";
|
||||
|
||||
m_wSocket.SendData( Header.c_str(), Header.length() );
|
||||
m_sStatus = "Header Sent.";
|
||||
m_sStatus = HEADER_SENT.GetValue();
|
||||
m_wSocket.blocking = false;
|
||||
m_bIsDownloading = true;
|
||||
m_sBUFFER = "";
|
||||
@@ -577,14 +582,15 @@ static size_t FindEndOfHeaders( const RString &buf )
|
||||
return string::npos;
|
||||
}
|
||||
|
||||
static LocalizedString WAITING_FOR_HEADER( "ScreenPackages", "Waiting for header." );
|
||||
void ScreenPackages::HTTPUpdate()
|
||||
{
|
||||
if( !m_bIsDownloading )
|
||||
return;
|
||||
|
||||
int BytesGot=0;
|
||||
//Keep this as a code block
|
||||
//as there may be need to "if" it out some time.
|
||||
// Keep this as a code block
|
||||
// as there may be need to "if" it out some time.
|
||||
/* If you need a conditional for a large block of code, stick it in
|
||||
* a function and return. */
|
||||
while(1)
|
||||
@@ -600,8 +606,8 @@ void ScreenPackages::HTTPUpdate()
|
||||
|
||||
if( !m_bGotHeader )
|
||||
{
|
||||
m_sStatus = "Waiting for header.";
|
||||
//We don't know if we are using unix-style or dos-style
|
||||
m_sStatus = WAITING_FOR_HEADER.GetValue();
|
||||
// We don't know if we are using unix-style or dos-style
|
||||
size_t iHeaderEnd = FindEndOfHeaders( m_sBUFFER );
|
||||
if( iHeaderEnd == m_sBUFFER.npos )
|
||||
return;
|
||||
@@ -652,7 +658,7 @@ void ScreenPackages::HTTPUpdate()
|
||||
m_wSocket.close();
|
||||
m_bIsDownloading = false;
|
||||
m_bGotHeader=false;
|
||||
m_sStatus = ssprintf( "Done;%dB", int(m_iDownloaded) );
|
||||
m_sStatus = ssprintf( "Done ;%dB", int(m_iDownloaded) );
|
||||
|
||||
if( m_iResponseCode < 200 || m_iResponseCode >= 400 )
|
||||
{
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "RageFileManager.h"
|
||||
#include "RageFile.h"
|
||||
#include "Sprite.h"
|
||||
#include "ThemeMetric.h"
|
||||
|
||||
#if !defined(WITHOUT_NETWORKING)
|
||||
|
||||
@@ -27,6 +28,13 @@ public:
|
||||
virtual void TweenOffScreen( );
|
||||
virtual void Update(float f);
|
||||
|
||||
protected:
|
||||
ThemeMetric<float> EXISTINGBG_WIDTH; // "PackagesBGWidth"
|
||||
ThemeMetric<float> WEBBG_WIDTH; // "WebBGWidth"
|
||||
ThemeMetric<int> NUM_PACKAGES_SHOW; // "NumPackagesShow"
|
||||
ThemeMetric<int> NUM_LINKS_SHOW; // "NumLinksShow"
|
||||
ThemeMetric<RString> DEFAULT_URL; // "DefaultUrl"
|
||||
|
||||
private:
|
||||
void UpdatePackagesList();
|
||||
void UpdateLinksList();
|
||||
@@ -56,7 +64,7 @@ private:
|
||||
int m_iDLorLST;
|
||||
int m_bCanDL;
|
||||
|
||||
//HTTP portion
|
||||
// HTTP portion
|
||||
void CancelDownload( );
|
||||
void EnterURL( const RString & sURL );
|
||||
void HTTPUpdate( );
|
||||
|
||||
@@ -40,9 +40,7 @@ void ScreenSelect::Init()
|
||||
|
||||
ScreenWithMenuElements::Init();
|
||||
|
||||
//
|
||||
// Load messages to update on
|
||||
//
|
||||
split( UPDATE_ON_MESSAGE, ",", m_asSubscribedMessages );
|
||||
for( unsigned i = 0; i < m_asSubscribedMessages.size(); ++i )
|
||||
MESSAGEMAN->Subscribe( this, m_asSubscribedMessages[i] );
|
||||
@@ -50,9 +48,7 @@ void ScreenSelect::Init()
|
||||
if( !MESSAGEMAN->IsSubscribedToMessage(this, Message_PlayerJoined) )
|
||||
this->SubscribeToMessage( Message_PlayerJoined );
|
||||
|
||||
//
|
||||
// Load choices
|
||||
//
|
||||
{
|
||||
// Instead of using NUM_CHOICES, use a comma-separated list of choices. Each
|
||||
// element in the list is a choice name. This level of indirection
|
||||
@@ -207,8 +203,7 @@ void ScreenSelect::HandleScreenMessage( const ScreenMessage SM )
|
||||
{
|
||||
if( SM == SM_BeginFadingOut ) /* Screen is starting to tween out. */
|
||||
{
|
||||
/*
|
||||
* Don't call GameCommand::Apply once per player on screens that
|
||||
/* Don't call GameCommand::Apply once per player on screens that
|
||||
* have a shared selection. This can cause change messages to be broadcast
|
||||
* multiple times. Detect whether all players have the same choice, and
|
||||
* if so, call ApplyToAll instead.
|
||||
|
||||
@@ -26,12 +26,11 @@ AutoScreenMessage( SM_PlayPostSwitchPage )
|
||||
|
||||
static RString CURSOR_OFFSET_X_FROM_ICON_NAME( size_t p ) { return ssprintf("CursorP%dOffsetXFromIcon",int(p+1)); }
|
||||
static RString CURSOR_OFFSET_Y_FROM_ICON_NAME( size_t p ) { return ssprintf("CursorP%dOffsetYFromIcon",int(p+1)); }
|
||||
/* e.g. "OptionOrderLeft=0:1,1:2,2:3,3:4" */
|
||||
// e.g. "OptionOrderLeft=0:1,1:2,2:3,3:4"
|
||||
static RString OPTION_ORDER_NAME( size_t dir ) { return "OptionOrder"+MenuDirToString((MenuDir)dir); }
|
||||
|
||||
static RString OPTION_ORDER_NAME_LIST2( size_t dir ) { return "OptionOrderB"+MenuDirToString((MenuDir)dir); }
|
||||
|
||||
|
||||
REGISTER_SCREEN_CLASS( ScreenSelectMaster );
|
||||
|
||||
#define GetActiveElementPlayerNumbers( vpns ) \
|
||||
@@ -828,7 +827,6 @@ bool ScreenSelectMaster::ChangeSelection( PlayerNumber pn, MenuDir dir, int iNew
|
||||
bNewAlreadyHadFocus |= m_iChoice[p2] == iNewChoice;
|
||||
}
|
||||
|
||||
//todo: condense this section
|
||||
if(DOUBLE_PRESS_TO_SELECT)
|
||||
{
|
||||
if(m_bUsingTwoLists && m_iSelectedList == 1)
|
||||
|
||||
+100
-94
@@ -174,11 +174,11 @@ void ScreenSelectMusic::Init()
|
||||
|
||||
m_textHighScore[p].SetName( ssprintf("ScoreP%d",p+1) );
|
||||
m_textHighScore[p].LoadFromFont( THEME->GetPathF(m_sName,"score") );
|
||||
m_textHighScore[p].SetShadowLength( 0 );
|
||||
//m_textHighScore[p].SetShadowLength( 0 );
|
||||
//m_textHighScore[p].RunCommands( CommonMetrics::PLAYER_COLOR.GetValue(p) );
|
||||
LOAD_ALL_COMMANDS_AND_SET_XY( m_textHighScore[p] );
|
||||
this->AddChild( &m_textHighScore[p] );
|
||||
}
|
||||
}
|
||||
|
||||
RageSoundLoadParams SoundParams;
|
||||
SoundParams.m_bSupportPan = true;
|
||||
@@ -209,7 +209,7 @@ void ScreenSelectMusic::BeginScreen()
|
||||
|
||||
if( GAMESTATE->m_PlayMode == PlayMode_Invalid )
|
||||
{
|
||||
/* Instead of crashing here, let's just set the PlayMode to regular */
|
||||
// Instead of crashing here, let's just set the PlayMode to regular
|
||||
GAMESTATE->m_PlayMode.Set( PLAY_MODE_REGULAR );
|
||||
LOG->Trace( "PlayMode not set, setting as regular." );
|
||||
}
|
||||
@@ -220,7 +220,7 @@ void ScreenSelectMusic::BeginScreen()
|
||||
m_sprHighScoreFrame[pn].SetVisible( false );
|
||||
m_textHighScore[pn].SetVisible( false );
|
||||
}
|
||||
|
||||
|
||||
OPTIONS_MENU_AVAILABLE.Load( m_sName, "OptionsMenuAvailable" );
|
||||
PlayCommand( "Mods" );
|
||||
m_MusicWheel.BeginScreen();
|
||||
@@ -249,12 +249,12 @@ ScreenSelectMusic::~ScreenSelectMusic()
|
||||
|
||||
}
|
||||
|
||||
/* If bForce is true, the next request will be started even if it might cause a skip. */
|
||||
// If bForce is true, the next request will be started even if it might cause a skip.
|
||||
void ScreenSelectMusic::CheckBackgroundRequests( bool bForce )
|
||||
{
|
||||
if( g_bCDTitleWaiting )
|
||||
{
|
||||
/* The CDTitle is normally very small, so we don't bother waiting to display it. */
|
||||
// The CDTitle is normally very small, so we don't bother waiting to display it.
|
||||
RString sPath;
|
||||
if( !m_BackgroundLoader.IsCacheFileFinished(g_sCDTitlePath, sPath) )
|
||||
return;
|
||||
@@ -277,11 +277,11 @@ void ScreenSelectMusic::CheckBackgroundRequests( bool bForce )
|
||||
m_BackgroundLoader.FinishedWithCachedFile( g_sCDTitlePath );
|
||||
}
|
||||
|
||||
/* Loading the rest can cause small skips, so don't do it until the wheel settles.
|
||||
/* Loading the rest can cause small skips, so don't do it until the wheel settles.
|
||||
* Do load if we're transitioning out, though, so we don't miss starting the music
|
||||
* for the options screen if a song is selected quickly. Also, don't do this
|
||||
* if the wheel is locked, since we're just bouncing around after selecting TYPE_RANDOM,
|
||||
* and it'll take a while before the wheel will settle. */
|
||||
* if the wheel is locked, since we're just bouncing around after selecting
|
||||
* TYPE_RANDOM, and it'll take a while before the wheel will settle. */
|
||||
if( !m_MusicWheel.IsSettled() && !m_MusicWheel.WheelIsLocked() && !bForce )
|
||||
return;
|
||||
|
||||
@@ -312,13 +312,13 @@ void ScreenSelectMusic::CheckBackgroundRequests( bool bForce )
|
||||
m_BackgroundLoader.FinishedWithCachedFile( g_sBannerPath );
|
||||
}
|
||||
|
||||
/* Nothing else is going. Start the music, if we haven't yet. */
|
||||
// Nothing else is going. Start the music, if we haven't yet.
|
||||
if( g_bSampleMusicWaiting )
|
||||
{
|
||||
if(g_ScreenStartedLoadingAt.Ago() < SAMPLE_MUSIC_DELAY_INIT)
|
||||
return;
|
||||
|
||||
/* Don't start the music sample when moving fast. */
|
||||
// Don't start the music sample when moving fast.
|
||||
if( g_StartedLoadingAt.Ago() < SAMPLE_MUSIC_DELAY && !bForce )
|
||||
return;
|
||||
|
||||
@@ -398,11 +398,11 @@ void ScreenSelectMusic::Input( const InputEventPlus &input )
|
||||
}
|
||||
|
||||
if( !input.GameI.IsValid() )
|
||||
return; // don't care
|
||||
return; // don't care
|
||||
|
||||
// Handle late joining
|
||||
if( m_SelectionState != SelectionState_Finalized && input.MenuI == GAME_BUTTON_START && input.type == IET_FIRST_PRESS && GAMESTATE->JoinInput(input.pn) )
|
||||
return; // don't handle this press again below
|
||||
return; // don't handle this press again below
|
||||
|
||||
if( !GAMESTATE->IsHumanPlayer(input.pn) )
|
||||
return;
|
||||
@@ -414,13 +414,13 @@ void ScreenSelectMusic::Input( const InputEventPlus &input )
|
||||
OPTIONS_MENU_AVAILABLE.GetValue() )
|
||||
{
|
||||
if( m_bGoToOptions )
|
||||
return; /* got it already */
|
||||
return; // got it already
|
||||
if( !m_bAllowOptionsMenu )
|
||||
return; /* not allowed */
|
||||
return; // not allowed
|
||||
|
||||
if( !m_bAllowOptionsMenuRepeat && input.type == IET_REPEAT )
|
||||
{
|
||||
return; /* not allowed yet */
|
||||
return; // not allowed yet
|
||||
}
|
||||
|
||||
m_bGoToOptions = true;
|
||||
@@ -436,7 +436,7 @@ void ScreenSelectMusic::Input( const InputEventPlus &input )
|
||||
}
|
||||
|
||||
if( IsTransitioning() )
|
||||
return; // ignore
|
||||
return; // ignore
|
||||
|
||||
// Handle unselect steps
|
||||
if( m_SelectionState == SelectionState_SelectingSteps && m_bStepsChosen[input.pn] && input.MenuI == GAME_BUTTON_SELECT && input.type == IET_FIRST_PRESS )
|
||||
@@ -450,7 +450,7 @@ void ScreenSelectMusic::Input( const InputEventPlus &input )
|
||||
|
||||
if( m_SelectionState == SelectionState_Finalized ||
|
||||
m_bStepsChosen[input.pn] )
|
||||
return; // ignore
|
||||
return; // ignore
|
||||
|
||||
if( USE_PLAYER_SELECT_MENU )
|
||||
{
|
||||
@@ -460,7 +460,7 @@ void ScreenSelectMusic::Input( const InputEventPlus &input )
|
||||
}
|
||||
}
|
||||
|
||||
// handle options list input
|
||||
// handle OptionsList input
|
||||
if( USE_OPTIONS_LIST )
|
||||
{
|
||||
PlayerNumber pn = input.pn;
|
||||
@@ -528,10 +528,10 @@ void ScreenSelectMusic::Input( const InputEventPlus &input )
|
||||
(input.MenuI == m_GameButtonNextSong || input.MenuI == m_GameButtonPreviousSong || input.MenuI == GAME_BUTTON_SELECT) )
|
||||
{
|
||||
{
|
||||
/* If we're rouletting, hands off. */
|
||||
// If we're rouletting, hands off.
|
||||
if( m_MusicWheel.IsRouletting() )
|
||||
return;
|
||||
|
||||
|
||||
bool bLeftIsDown = false;
|
||||
bool bRightIsDown = false;
|
||||
FOREACH_HumanPlayer( p )
|
||||
@@ -544,14 +544,13 @@ void ScreenSelectMusic::Input( const InputEventPlus &input )
|
||||
bLeftIsDown |= INPUTMAPPER->IsBeingPressed( m_GameButtonPreviousSong, p );
|
||||
bRightIsDown |= INPUTMAPPER->IsBeingPressed( m_GameButtonNextSong, p );
|
||||
}
|
||||
|
||||
|
||||
bool bBothDown = bLeftIsDown && bRightIsDown;
|
||||
bool bNeitherDown = !bLeftIsDown && !bRightIsDown;
|
||||
|
||||
|
||||
if( bNeitherDown )
|
||||
{
|
||||
/* Both buttons released. */
|
||||
// Both buttons released.
|
||||
m_MusicWheel.Move( 0 );
|
||||
}
|
||||
else if( bBothDown )
|
||||
@@ -615,7 +614,7 @@ void ScreenSelectMusic::Input( const InputEventPlus &input )
|
||||
m_soundLocked.Play();
|
||||
else
|
||||
ChangeSteps( input.pn, +1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( input.type == IET_FIRST_PRESS && DetectCodes(input) )
|
||||
@@ -728,7 +727,7 @@ void ScreenSelectMusic::ChangeSteps( PlayerNumber pn, int dir )
|
||||
return;
|
||||
}
|
||||
|
||||
// the user explicity switched difficulties. Update the preferred Difficulty and StepsType
|
||||
// the user explicity switched difficulties. Update the preferred Difficulty and StepsType
|
||||
Steps *pSteps = m_vpSteps[ m_iSelection[pn] ];
|
||||
GAMESTATE->ChangePreferredDifficultyAndStepsType( pn, pSteps->GetDifficulty(), pSteps->m_StepsType );
|
||||
}
|
||||
@@ -745,15 +744,17 @@ void ScreenSelectMusic::ChangeSteps( PlayerNumber pn, int dir )
|
||||
return;
|
||||
}
|
||||
|
||||
// the user explicity switched difficulties. Update the preferred Difficulty and StepsType
|
||||
// the user explicity switched difficulties. Update the preferred Difficulty and StepsType
|
||||
Trail *pTrail = m_vpTrails[ m_iSelection[pn] ];
|
||||
GAMESTATE->ChangePreferredCourseDifficultyAndStepsType( pn, pTrail->m_CourseDifficulty, pTrail->m_StepsType );
|
||||
}
|
||||
else
|
||||
{
|
||||
// If we're showing multiple StepsTypes in the list, don't allow changing the difficulty/StepsType
|
||||
// when a non-Song, non-Course is selected. Chaning the preferred Difficulty and StepsType
|
||||
// by direction is complicated when multiple StepsTypes are being shown, so we don't support it.
|
||||
// If we're showing multiple StepsTypes in the list, don't allow
|
||||
// changing the difficulty/StepsType when a non-Song, non-Course is
|
||||
// selected. Changing the preferred Difficulty and StepsType by
|
||||
// direction is complicated when multiple StepsTypes are being shown,
|
||||
// so we don't support it.
|
||||
if( CommonMetrics::AUTO_SET_STYLE )
|
||||
return;
|
||||
if( !GAMESTATE->ChangePreferredDifficulty( pn, dir ) )
|
||||
@@ -793,17 +794,17 @@ void ScreenSelectMusic::HandleMessage( const Message &msg )
|
||||
{
|
||||
if( m_bRunning && msg == Message_PlayerJoined )
|
||||
{
|
||||
// The current steps may no longer be playable. If one player has double steps
|
||||
// selected, they are no longer playable now that P2 has joined.
|
||||
|
||||
// TODO: Invalidate the CurSteps only if they are no longer playable. That way,
|
||||
// after music change will clamp to the nearest in the StepsDisplayList.
|
||||
// The current steps may no longer be playable. If one player has double
|
||||
// steps selected, they are no longer playable now that P2 has joined.
|
||||
|
||||
// TODO: Invalidate the CurSteps only if they are no longer playable.
|
||||
// That way, after music change will clamp to the nearest in the StepsDisplayList.
|
||||
GAMESTATE->m_pCurSteps[GAMESTATE->m_MasterPlayerNumber].SetWithoutBroadcast( NULL );
|
||||
FOREACH_ENUM( PlayerNumber, p )
|
||||
GAMESTATE->m_pCurSteps[p].SetWithoutBroadcast( NULL );
|
||||
|
||||
/* If a course is selected, it may no longer be playable. Let MusicWheel know
|
||||
* about the late join. */
|
||||
/* If a course is selected, it may no longer be playable.
|
||||
* Let MusicWheel know about the late join. */
|
||||
m_MusicWheel.PlayerJoined();
|
||||
|
||||
AfterMusicChange();
|
||||
@@ -858,8 +859,8 @@ void ScreenSelectMusic::HandleScreenMessage( const ScreenMessage SM )
|
||||
}
|
||||
else
|
||||
{
|
||||
// Finish sort changing so that the wheel can respond immediately to our
|
||||
// request to choose random.
|
||||
// Finish sort changing so that the wheel can respond immediately to
|
||||
// our request to choose random.
|
||||
m_MusicWheel.FinishChangingSorts();
|
||||
if( m_MusicWheel.GetSelectedSong() == NULL && m_MusicWheel.GetSelectedCourse() == NULL )
|
||||
m_MusicWheel.StartRandom();
|
||||
@@ -870,9 +871,9 @@ void ScreenSelectMusic::HandleScreenMessage( const ScreenMessage SM )
|
||||
}
|
||||
else if( SM == SM_GoToPrevScreen )
|
||||
{
|
||||
/* We may have stray SM_SongChanged messages from the music wheel. We can't
|
||||
* handle them anymore, since the title menu (and attract screens) reset
|
||||
* the game state, so just discard them. */
|
||||
/* We may have stray SM_SongChanged messages from the music wheel.
|
||||
* We can't handle them anymore, since the title menu (and attract
|
||||
* screens) reset the game state, so just discard them. */
|
||||
ClearMessageQueue();
|
||||
}
|
||||
else if( SM == SM_BeginFadingOut )
|
||||
@@ -892,7 +893,7 @@ void ScreenSelectMusic::HandleScreenMessage( const ScreenMessage SM )
|
||||
{
|
||||
AfterMusicChange();
|
||||
}
|
||||
else if( SM == SM_SortOrderChanging ) /* happens immediately */
|
||||
else if( SM == SM_SortOrderChanging ) // happens immediately
|
||||
{
|
||||
this->PlayCommand( "SortChange" );
|
||||
}
|
||||
@@ -902,7 +903,7 @@ void ScreenSelectMusic::HandleScreenMessage( const ScreenMessage SM )
|
||||
}
|
||||
else if( SM == SM_LoseFocus )
|
||||
{
|
||||
CodeDetector::RefreshCacheItems(); /* reset for other screens */
|
||||
CodeDetector::RefreshCacheItems(); // reset for other screens
|
||||
}
|
||||
|
||||
ScreenWithMenuElements::HandleScreenMessage( SM );
|
||||
@@ -913,9 +914,9 @@ void ScreenSelectMusic::MenuStart( const InputEventPlus &input )
|
||||
if( input.type != IET_FIRST_PRESS )
|
||||
return;
|
||||
|
||||
/* If select is being pressed, this is probably an attempt to change the sort, not
|
||||
* to pick a song or difficulty. If it gets here, the actual select press was probably
|
||||
* hit during a tween and ignored. Ignore it. */
|
||||
/* If select is being pressed, this is probably an attempt to change the
|
||||
* sort, not to pick a song or difficulty. If it gets here, the actual
|
||||
* select press was probably hit during a tween and ignored. Ignore it. */
|
||||
if( input.pn != PLAYER_INVALID && INPUTMAPPER->IsBeingPressed(GAME_BUTTON_SELECT, input.pn) )
|
||||
return;
|
||||
|
||||
@@ -928,7 +929,7 @@ void ScreenSelectMusic::MenuStart( const InputEventPlus &input )
|
||||
DEFAULT_FAIL( m_SelectionState );
|
||||
case SelectionState_SelectingSong:
|
||||
|
||||
/* If false, we don't have a selection just yet. */
|
||||
// If false, we don't have a selection just yet.
|
||||
if( !m_MusicWheel.Select() )
|
||||
return;
|
||||
|
||||
@@ -943,7 +944,8 @@ void ScreenSelectMusic::MenuStart( const InputEventPlus &input )
|
||||
bIsHard = true;
|
||||
}
|
||||
|
||||
/* See if this song is a repeat. If we're in event mode, only check the last five songs. */
|
||||
// See if this song is a repeat.
|
||||
// If we're in event mode, only check the last five songs.
|
||||
bool bIsRepeat = false;
|
||||
int i = 0;
|
||||
if( GAMESTATE->IsEventMode() )
|
||||
@@ -952,7 +954,7 @@ void ScreenSelectMusic::MenuStart( const InputEventPlus &input )
|
||||
if( STATSMAN->m_vPlayedStageStats[i].m_vpPlayedSongs.back() == m_MusicWheel.GetSelectedSong() )
|
||||
bIsRepeat = true;
|
||||
|
||||
/* Don't complain about repeats if the user didn't get to pick. */
|
||||
// Don't complain about repeats if the user didn't get to pick.
|
||||
if( GAMESTATE->IsAnExtraStageAndSelectionLocked() )
|
||||
bIsRepeat = false;
|
||||
|
||||
@@ -965,8 +967,8 @@ void ScreenSelectMusic::MenuStart( const InputEventPlus &input )
|
||||
else
|
||||
SOUND->PlayOnceFromAnnouncer( "select music comment general" );
|
||||
|
||||
/* If we're in event mode, we may have just played a course (putting us
|
||||
* in course mode). Make sure we're in a single song mode. */
|
||||
/* If we're in event mode, we may have just played a course (putting
|
||||
* us in course mode). Make sure we're in a single song mode. */
|
||||
if( GAMESTATE->IsCourseMode() )
|
||||
GAMESTATE->m_PlayMode.Set( PLAY_MODE_REGULAR );
|
||||
}
|
||||
@@ -989,11 +991,11 @@ void ScreenSelectMusic::MenuStart( const InputEventPlus &input )
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We haven't made a selection yet. */
|
||||
// We haven't made a selection yet.
|
||||
return;
|
||||
}
|
||||
|
||||
// I believe this is for those who like pump pro.
|
||||
// I believe this is for those who like pump pro. -aj
|
||||
MESSAGEMAN->Broadcast("SongChosen");
|
||||
|
||||
break;
|
||||
@@ -1012,16 +1014,18 @@ void ScreenSelectMusic::MenuStart( const InputEventPlus &input )
|
||||
|
||||
bool bAllPlayersDoneSelectingSteps = bInitiatedByMenuTimer || bAllOtherHumanPlayersDone;
|
||||
|
||||
/*
|
||||
* TRICKY: if we have a Routine chart selected, we need to ensure the following:
|
||||
*
|
||||
/* TRICKY: if we have a Routine chart selected, we need to ensure
|
||||
* the following:
|
||||
* 1. Both players must select the same Routine steps.
|
||||
* 2. If the other player picks non-Routine steps, this player cannot pick Routine.
|
||||
* 3. If the other player picked Routine steps, and we pick non-Routine steps, the other
|
||||
* player's steps must be unselected.
|
||||
* 4. If time runs out, and both players don't have the same Routine chart selected,
|
||||
* we need to bump the player with a Routine chart selection to a playable chart.
|
||||
* (Right now, we bump them to Beginner...can we come up with something better?)
|
||||
* 2. If the other player picks non-Routine steps, this player
|
||||
* cannot pick Routine.
|
||||
* 3. If the other player picked Routine steps, and we pick
|
||||
* non-Routine steps, the other player's steps must be unselected.
|
||||
* 4. If time runs out, and both players don't have the same Routine
|
||||
* chart selected, we need to bump the player with a Routine
|
||||
* chart selection to a playable chart.
|
||||
* (Right now, we bump them to Beginner... Can we come up with
|
||||
* something better?)
|
||||
*/
|
||||
|
||||
if( !GAMESTATE->IsCourseMode() && GAMESTATE->GetNumSidesJoined() == 2 )
|
||||
@@ -1040,11 +1044,13 @@ void ScreenSelectMusic::MenuStart( const InputEventPlus &input )
|
||||
|
||||
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. */
|
||||
/* 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 )
|
||||
{
|
||||
/* 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() );
|
||||
Steps *pSteps = m_vpSteps[0];
|
||||
|
||||
@@ -1057,14 +1063,15 @@ void ScreenSelectMusic::MenuStart( const InputEventPlus &input )
|
||||
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 )
|
||||
{
|
||||
const PlayerNumber other = OPPOSITE_PLAYER[pn];
|
||||
|
||||
if( m_bStepsChosen[other] )
|
||||
{
|
||||
/* Unready the other player if they selected Routine steps, but we didn't. */
|
||||
/* Unready the other player if they selected Routine
|
||||
* steps, but we didn't. */
|
||||
if( bSelectedRoutineSteps[other] )
|
||||
{
|
||||
m_bStepsChosen[other] = false;
|
||||
@@ -1079,7 +1086,8 @@ void ScreenSelectMusic::MenuStart( const InputEventPlus &input )
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -1092,7 +1100,7 @@ void ScreenSelectMusic::MenuStart( const InputEventPlus &input )
|
||||
m_bStepsChosen[pn] = true;
|
||||
m_soundStart.Play();
|
||||
|
||||
// ttt: Pro uses "StepsSelected".
|
||||
// impldiff: Pump it Up Pro uses "StepsSelected". -aj
|
||||
Message msg("StepsChosen");
|
||||
msg.SetParam( "Player", pn );
|
||||
MESSAGEMAN->Broadcast( msg );
|
||||
@@ -1123,13 +1131,12 @@ void ScreenSelectMusic::MenuStart( const InputEventPlus &input )
|
||||
{
|
||||
m_MenuTimer->Stop();
|
||||
|
||||
|
||||
FOREACH_HumanPlayer( p )
|
||||
{
|
||||
if( !m_bStepsChosen[p] )
|
||||
{
|
||||
m_bStepsChosen[p] = true;
|
||||
/* Don't play start sound. We play it again below on finalized */
|
||||
// Don't play start sound. We play it again below on finalized
|
||||
//m_soundStart.Play();
|
||||
|
||||
Message msg("StepsChosen");
|
||||
@@ -1140,7 +1147,7 @@ void ScreenSelectMusic::MenuStart( const InputEventPlus &input )
|
||||
|
||||
if( CommonMetrics::AUTO_SET_STYLE )
|
||||
{
|
||||
/* Now that Steps have been chosen, set a Style that can play them. */
|
||||
// Now that Steps have been chosen, set a Style that can play them.
|
||||
const Style *pStyle = NULL;
|
||||
if( GAMESTATE->IsCourseMode() )
|
||||
pStyle = GAMESTATE->m_pCurCourse->GetCourseStyle( GAMESTATE->m_pCurGame, GAMESTATE->GetNumSidesJoined() );
|
||||
@@ -1164,10 +1171,9 @@ void ScreenSelectMusic::MenuStart( const InputEventPlus &input )
|
||||
GAMESTATE->SetCurrentStyle( pStyle );
|
||||
}
|
||||
|
||||
|
||||
/* If we're currently waiting on song assets, abort all except the music and
|
||||
* start the music, so if we make a choice quickly before background requests
|
||||
* come through, the music will still start. */
|
||||
/* If we're currently waiting on song assets, abort all except the music
|
||||
* and start the music, so if we make a choice quickly before background
|
||||
* requests come through, the music will still start. */
|
||||
g_bCDTitleWaiting = g_bBannerWaiting = false;
|
||||
m_BackgroundLoader.Abort();
|
||||
CheckBackgroundRequests( true );
|
||||
@@ -1180,9 +1186,9 @@ void ScreenSelectMusic::MenuStart( const InputEventPlus &input )
|
||||
m_bAllowOptionsMenu = true;
|
||||
|
||||
/* Don't accept a held START for a little while, so it's not
|
||||
* hit accidentally. Accept an initial START right away, though,
|
||||
* so we don't ignore deliberate fast presses (which would be
|
||||
* annoying). */
|
||||
* hit accidentally. Accept an initial START right away, though,
|
||||
* so we don't ignore deliberate fast presses (which would be
|
||||
* annoying). */
|
||||
this->PostScreenMessage( SM_AllowOptionsMenuRepeat, 0.5f );
|
||||
|
||||
StartTransitioningScreen( SM_None );
|
||||
@@ -1199,7 +1205,7 @@ void ScreenSelectMusic::MenuStart( const InputEventPlus &input )
|
||||
float fSeconds = m_MenuTimer->GetSeconds();
|
||||
if( fSeconds < 10 )
|
||||
{
|
||||
// TODO: make this a theme option -aj
|
||||
// TODO: make this a theme metric -aj
|
||||
m_MenuTimer->SetSeconds( 13 );
|
||||
m_MenuTimer->Start();
|
||||
}
|
||||
@@ -1235,7 +1241,7 @@ void ScreenSelectMusic::AfterStepsOrTrailChange( const vector<PlayerNumber> &vpn
|
||||
{
|
||||
PlayerNumber pn = *p;
|
||||
ASSERT( GAMESTATE->IsHumanPlayer(pn) );
|
||||
|
||||
|
||||
if( GAMESTATE->m_pCurSong )
|
||||
{
|
||||
CLAMP( m_iSelection[pn], 0, m_vpSteps.size()-1 );
|
||||
@@ -1261,7 +1267,7 @@ void ScreenSelectMusic::AfterStepsOrTrailChange( const vector<PlayerNumber> &vpn
|
||||
|
||||
Course* pCourse = GAMESTATE->m_pCurCourse;
|
||||
Trail* pTrail = m_vpTrails.empty()? NULL: m_vpTrails[m_iSelection[pn]];
|
||||
|
||||
|
||||
GAMESTATE->m_pCurSteps[pn].Set( NULL );
|
||||
GAMESTATE->m_pCurTrail[pn].Set( pTrail );
|
||||
|
||||
@@ -1283,14 +1289,14 @@ void ScreenSelectMusic::SwitchToPreferredDifficulty()
|
||||
{
|
||||
FOREACH_HumanPlayer( pn )
|
||||
{
|
||||
/* Find the closest match to the user's preferred difficulty and StepsType. */
|
||||
// Find the closest match to the user's preferred difficulty and StepsType.
|
||||
int iCurDifference = -1;
|
||||
int &iSelection = m_iSelection[pn];
|
||||
FOREACH_CONST( Steps*, m_vpSteps, s )
|
||||
{
|
||||
int i = s - m_vpSteps.begin();
|
||||
|
||||
/* If the current steps are listed, use them. */
|
||||
// If the current steps are listed, use them.
|
||||
if( GAMESTATE->m_pCurSteps[pn] == *s )
|
||||
{
|
||||
iSelection = i;
|
||||
@@ -1320,14 +1326,14 @@ void ScreenSelectMusic::SwitchToPreferredDifficulty()
|
||||
{
|
||||
FOREACH_HumanPlayer( pn )
|
||||
{
|
||||
/* Find the closest match to the user's preferred difficulty. */
|
||||
// Find the closest match to the user's preferred difficulty.
|
||||
int iCurDifference = -1;
|
||||
int &iSelection = m_iSelection[pn];
|
||||
FOREACH_CONST( Trail*, m_vpTrails, t )
|
||||
{
|
||||
int i = t - m_vpTrails.begin();
|
||||
|
||||
/* If the current trail is listed, use it. */
|
||||
// If the current trail is listed, use it.
|
||||
if( GAMESTATE->m_pCurTrail[pn] == m_vpTrails[i] )
|
||||
{
|
||||
iSelection = i;
|
||||
@@ -1416,17 +1422,17 @@ void ScreenSelectMusic::AfterMusicChange()
|
||||
m_sSampleMusicToPlay = m_sSectionMusicPath;
|
||||
break;
|
||||
case TYPE_SORT:
|
||||
bWantBanner = false; /* we load it ourself */
|
||||
bWantBanner = false; // we load it ourself
|
||||
m_Banner.LoadMode();
|
||||
m_sSampleMusicToPlay = m_sSortMusicPath;
|
||||
break;
|
||||
case TYPE_ROULETTE:
|
||||
bWantBanner = false; /* we load it ourself */
|
||||
bWantBanner = false; // we load it ourself
|
||||
m_Banner.LoadRoulette();
|
||||
m_sSampleMusicToPlay = m_sRouletteMusicPath;
|
||||
break;
|
||||
case TYPE_RANDOM:
|
||||
bWantBanner = false; /* we load it ourself */
|
||||
bWantBanner = false; // we load it ourself
|
||||
m_Banner.LoadRandom();
|
||||
m_sSampleMusicToPlay = m_sRandomMusicPath;
|
||||
break;
|
||||
@@ -1495,7 +1501,8 @@ void ScreenSelectMusic::AfterMusicChange()
|
||||
m_sprCDTitleFront.UnloadTexture();
|
||||
m_sprCDTitleBack.UnloadTexture();
|
||||
|
||||
/* Cancel any previous, incomplete requests for song assets, since we need new ones. */
|
||||
// Cancel any previous, incomplete requests for song assets,
|
||||
// since we need new ones.
|
||||
m_BackgroundLoader.Abort();
|
||||
|
||||
g_bCDTitleWaiting = false;
|
||||
@@ -1512,9 +1519,8 @@ void ScreenSelectMusic::AfterMusicChange()
|
||||
LOG->Trace("LoadFromCachedBanner(%s)",g_sBannerPath .c_str());
|
||||
if( m_Banner.LoadFromCachedBanner( g_sBannerPath ) )
|
||||
{
|
||||
/* If the high-res banner is already loaded, just
|
||||
* delay before loading it, so the low-res one has
|
||||
* time to fade in. */
|
||||
/* If the high-res banner is already loaded, just delay before
|
||||
* loading it, so the low-res one has time to fade in. */
|
||||
if( !TEXTUREMAN->IsTextureRegistered( Sprite::SongBannerTexture(g_sBannerPath) ) )
|
||||
m_BackgroundLoader.CacheFile( g_sBannerPath );
|
||||
|
||||
|
||||
@@ -189,8 +189,7 @@ void ScreenWithMenuElements::StartPlayingMusic()
|
||||
{
|
||||
GameSoundManager::PlayMusicParams pmp;
|
||||
FileType ft = ActorUtil::GetFileType( m_sPathToMusic );
|
||||
/*
|
||||
* If m_sPathToMusic points to a Lua file, parse it and make sure it
|
||||
/* If m_sPathToMusic points to a Lua file, parse it and make sure it
|
||||
* returns a string pointing to a sound. Otherwise, if it points to
|
||||
* a normal music file, use the normal playback code. -aj
|
||||
* TODO: Make Lua music files accept playback params.
|
||||
|
||||
@@ -30,9 +30,7 @@ public:
|
||||
virtual void TweenOnScreen();
|
||||
virtual void TweenOffScreen();
|
||||
|
||||
//
|
||||
// Lua
|
||||
//
|
||||
virtual void PushSelf( lua_State *L );
|
||||
|
||||
protected:
|
||||
@@ -40,10 +38,10 @@ protected:
|
||||
void SetHelpText( RString s );
|
||||
|
||||
AutoActor m_sprUnderlay;
|
||||
MemoryCardDisplay *m_MemoryCardDisplay[NUM_PLAYERS];
|
||||
MemoryCardDisplay *m_MemoryCardDisplay[NUM_PLAYERS];
|
||||
MenuTimer *m_MenuTimer;
|
||||
AutoActor m_sprOverlay;
|
||||
vector<Actor*> m_vDecorations;
|
||||
vector<Actor*> m_vDecorations;
|
||||
|
||||
Transition m_In;
|
||||
Transition m_Out;
|
||||
@@ -53,11 +51,11 @@ protected:
|
||||
ThemeMetric<bool> MUSIC_ALIGN_BEAT;
|
||||
ThemeMetric<bool> CANCEL_TRANSITIONS_OUT;
|
||||
ThemeMetric<float> TIMER_SECONDS;
|
||||
ThemeMetric<RString> TIMER_METRICS_GROUP;
|
||||
ThemeMetric<RString> TIMER_METRICS_GROUP;
|
||||
ThemeMetric<bool> RESET_GAMESTATE;
|
||||
|
||||
private:
|
||||
RString m_sPathToMusic;
|
||||
RString m_sPathToMusic;
|
||||
};
|
||||
|
||||
class ScreenWithMenuElementsSimple: public ScreenWithMenuElements
|
||||
@@ -66,9 +64,7 @@ public:
|
||||
void MenuStart( const InputEventPlus &input );
|
||||
void MenuBack( const InputEventPlus &input );
|
||||
|
||||
//
|
||||
// Lua
|
||||
//
|
||||
virtual void PushSelf( lua_State *L );
|
||||
|
||||
protected:
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ class SnapDisplay : public ActorFrame
|
||||
{
|
||||
public:
|
||||
SnapDisplay();
|
||||
|
||||
|
||||
void Load( PlayerNumber pn );
|
||||
|
||||
bool PrevSnapMode();
|
||||
|
||||
+2
-6
@@ -977,6 +977,8 @@ void Song::AutoGen( StepsType ntTo, StepsType ntFrom )
|
||||
// going by Pump Pro. -aj
|
||||
if(ntTo == StepsType_pump_halfdouble && pNewNotes->GetDifficulty() != Difficulty_Medium)
|
||||
continue;
|
||||
// todo: don't generate steps for Couples and Routine if
|
||||
// AutoSetStyle is on? -aj
|
||||
this->AddSteps( pNewNotes );
|
||||
}
|
||||
}
|
||||
@@ -1453,9 +1455,6 @@ public:
|
||||
static int HasBGChanges( T* p, lua_State *L ) { lua_pushboolean(L, p->HasBGChanges()); return 1; }
|
||||
static int HasLyrics( T* p, lua_State *L ) { lua_pushboolean(L, p->HasLyrics()); return 1; }
|
||||
// functions that AJ loves
|
||||
static int GetBPMAtBeat( T* p, lua_State *L ) { lua_pushnumber(L, p->GetBPMAtBeat(FArg(1))); return 1; }
|
||||
static int GetBeatFromElapsedTime( T* p, lua_State *L ) { lua_pushnumber(L, p->GetBeatFromElapsedTime(FArg(1))); return 1; }
|
||||
static int GetElapsedTimeFromBeat( T* p, lua_State *L ) { lua_pushnumber(L, p->GetElapsedTimeFromBeat(FArg(1))); return 1; }
|
||||
static int HasSignificantBPMChangesOrStops( T* p, lua_State *L ) { lua_pushboolean(L, p->HasSignificantBpmChangesOrStops()); return 1; }
|
||||
static int HasEdits( T* p, lua_State *L )
|
||||
{
|
||||
@@ -1511,9 +1510,6 @@ public:
|
||||
ADD_METHOD( HasBGChanges );
|
||||
ADD_METHOD( HasLyrics );
|
||||
// danger will robinson
|
||||
ADD_METHOD( GetBPMAtBeat );
|
||||
ADD_METHOD( GetBeatFromElapsedTime );
|
||||
ADD_METHOD( GetElapsedTimeFromBeat );
|
||||
ADD_METHOD( HasSignificantBPMChangesOrStops );
|
||||
ADD_METHOD( HasEdits );
|
||||
ADD_METHOD( IsEasy );
|
||||
|
||||
+9
-24
@@ -821,17 +821,6 @@ void SongManager::InitRandomAttacks()
|
||||
continue;
|
||||
}
|
||||
|
||||
vector<RString> sAttackCheck;
|
||||
split( sAttack, ",", sAttackCheck, false );
|
||||
|
||||
// Make sure only one attack has been specified.
|
||||
// TODO: Allow combinations of mods. (shouldn't be too hard -aj)
|
||||
if( sAttackCheck.size() > 1 )
|
||||
{
|
||||
LOG->Warn( "Attack \"%s\" has more than one modifier; must only be one modifier specified", sAttack.c_str() );
|
||||
continue;
|
||||
}
|
||||
|
||||
GAMESTATE->m_RandomAttacks.push_back( sAttack );
|
||||
}
|
||||
}
|
||||
@@ -1587,9 +1576,7 @@ void SongManager::RefreshCourseGroupInfo()
|
||||
void SongManager::LoadStepEditsFromProfileDir( const RString &sProfileDir, ProfileSlot slot )
|
||||
{
|
||||
{
|
||||
//
|
||||
// Load all edit steps
|
||||
//
|
||||
RString sDir = sProfileDir + EDIT_STEPS_SUBDIR;
|
||||
|
||||
vector<RString> vsFiles;
|
||||
@@ -1610,9 +1597,7 @@ void SongManager::LoadStepEditsFromProfileDir( const RString &sProfileDir, Profi
|
||||
void SongManager::LoadCourseEditsFromProfileDir( const RString &sProfileDir, ProfileSlot slot )
|
||||
{
|
||||
{
|
||||
//
|
||||
// Load all edit courses
|
||||
//
|
||||
RString sDir = sProfileDir + EDIT_COURSES_SUBDIR;
|
||||
|
||||
vector<RString> vsFiles;
|
||||
@@ -1651,20 +1636,20 @@ int SongManager::GetNumEditsLoadedFromProfile( ProfileSlot slot ) const
|
||||
|
||||
void SongManager::FreeAllLoadedFromProfile( ProfileSlot slot )
|
||||
{
|
||||
/* Profile courses may refer to profile steps, so free profile courses first. */
|
||||
// Profile courses may refer to profile steps, so free profile courses first.
|
||||
vector<Course*> apToDelete;
|
||||
FOREACH( Course*, m_pCourses, c )
|
||||
{
|
||||
Course *pCourse = *c;
|
||||
if( pCourse->GetLoadedFromProfileSlot() == ProfileSlot_Invalid )
|
||||
continue;
|
||||
|
||||
|
||||
if( slot == ProfileSlot_Invalid || pCourse->GetLoadedFromProfileSlot() == slot )
|
||||
apToDelete.push_back( *c );
|
||||
}
|
||||
|
||||
/* We don't use DeleteCourse here, so we don't UpdatePopular and UpdateShuffled
|
||||
* repeatedly. */
|
||||
/* We don't use DeleteCourse here, so we don't UpdatePopular and
|
||||
* UpdateShuffled repeatedly. */
|
||||
for( unsigned i = 0; i < apToDelete.size(); ++i )
|
||||
{
|
||||
vector<Course*>::iterator iter = find( m_pCourses.begin(), m_pCourses.end(), apToDelete[i] );
|
||||
@@ -1673,12 +1658,12 @@ void SongManager::FreeAllLoadedFromProfile( ProfileSlot slot )
|
||||
delete apToDelete[i];
|
||||
}
|
||||
|
||||
/* Popular and Shuffled may refer to courses that we just freed. */
|
||||
// Popular and Shuffled may refer to courses that we just freed.
|
||||
UpdatePopular();
|
||||
UpdateShuffled();
|
||||
RefreshCourseGroupInfo();
|
||||
|
||||
/* Free profile steps. */
|
||||
// Free profile steps.
|
||||
set<Steps*> setInUse;
|
||||
if( STATSMAN )
|
||||
STATSMAN->GetStepsInUse( setInUse );
|
||||
@@ -1698,7 +1683,7 @@ int SongManager::GetNumStepsLoadedFromProfile()
|
||||
if( (*ss)->GetLoadedFromProfileSlot() != ProfileSlot_Invalid )
|
||||
iCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return iCount;
|
||||
}
|
||||
@@ -1707,14 +1692,14 @@ template<class T>
|
||||
int FindCourseIndexOfSameMode( T begin, T end, const Course *p )
|
||||
{
|
||||
const PlayMode pm = p->GetPlayMode();
|
||||
|
||||
|
||||
int n = 0;
|
||||
for( T it = begin; it != end; ++it )
|
||||
{
|
||||
if( *it == p )
|
||||
return n;
|
||||
|
||||
/* If it's not playable in this mode, don't increment. It might result in
|
||||
/* If it's not playable in this mode, don't increment. It might result in
|
||||
* different output in different modes, but that's better than having holes. */
|
||||
if( !(*it)->IsPlayableIn( GAMESTATE->GetCurrentStyle()->m_StepsType ) )
|
||||
continue;
|
||||
|
||||
+89
-90
@@ -102,8 +102,8 @@ RageTextureID Sprite::SongBannerTexture( RageTextureID ID )
|
||||
/* TODO: Change to use color keying only if the graphic is a diagonal banner. The color key convention is
|
||||
* causing small holes in moderm banners that use magenta, and it's not good to require graphic
|
||||
* makers to know about archaic color key conventions. -Chris */
|
||||
|
||||
/* I disabled this anyways, it's extremely annoying -Colby */
|
||||
|
||||
// I disabled this anyways, it's extremely annoying -Colby
|
||||
ID.bHotPinkColorKey = false;
|
||||
|
||||
/* Ignore the texture color depth preference and always use 32-bit textures
|
||||
@@ -131,8 +131,8 @@ void Sprite::Load( RageTextureID ID )
|
||||
|
||||
void Sprite::LoadFromNode( const XNode* pNode )
|
||||
{
|
||||
/* Texture may refer to the ID of a render target; if it's already registered,
|
||||
* use it without trying ot resolve it. */
|
||||
/* Texture may refer to the ID of a render target; if it's already
|
||||
* registered, use it without trying to resolve it. */
|
||||
RString sPath;
|
||||
pNode->GetAttrValue( "Texture", sPath );
|
||||
if( !sPath.empty() && !TEXTUREMAN->IsTextureRegistered( RageTextureID(sPath) ) )
|
||||
@@ -145,7 +145,6 @@ void Sprite::LoadFromNode( const XNode* pNode )
|
||||
|
||||
LoadStatesFromTexture();
|
||||
|
||||
|
||||
// Read in frames and delays from the sprite file,
|
||||
// overwriting the states that LoadFromTexture created.
|
||||
// If the .sprite file doesn't define any states, leave
|
||||
@@ -155,8 +154,7 @@ void Sprite::LoadFromNode( const XNode* pNode )
|
||||
const XNode *pFrames = pNode->GetChild( "Frames" );
|
||||
if( pFrames != NULL )
|
||||
{
|
||||
/*
|
||||
* All attributes are optional. If Frame is omitted, use the previous state's
|
||||
/* All attributes are optional. If Frame is omitted, use the previous state's
|
||||
* frame (or 0 if the first).
|
||||
* Frames = {
|
||||
* { Delay=1.0f; Frame=0; { x=0, y=0 }, { x=1, y=1 } };
|
||||
@@ -234,14 +232,14 @@ void Sprite::LoadFromNode( const XNode* pNode )
|
||||
|
||||
void Sprite::UnloadTexture()
|
||||
{
|
||||
if( m_pTexture != NULL ) // If there was a previous bitmap...
|
||||
if( m_pTexture != NULL ) // If there was a previous bitmap...
|
||||
{
|
||||
TEXTUREMAN->UnloadTexture( m_pTexture ); // Unload it.
|
||||
TEXTUREMAN->UnloadTexture( m_pTexture ); // Unload it.
|
||||
m_pTexture = NULL;
|
||||
|
||||
/* Make sure we're reset to frame 0, so if we're reused, we aren't left on
|
||||
* a frame number that may be greater than the number of frames in the newly
|
||||
* loaded image. */
|
||||
/* Make sure we're reset to frame 0, so if we're reused, we aren't left
|
||||
* on a frame number that may be greater than the number of frames in
|
||||
* the newly loaded image. */
|
||||
SetState( 0 );
|
||||
}
|
||||
}
|
||||
@@ -253,19 +251,18 @@ void Sprite::EnableAnimation( bool bEnable )
|
||||
|
||||
if( bEnable && !bWasEnabled )
|
||||
{
|
||||
/*
|
||||
* When we start animating a movie, we need to discard the first update; send
|
||||
* 0 instead of the passed time. This is for two reasons:
|
||||
/* When we start animating a movie, we need to discard the first update; send
|
||||
* 0 instead of the passed time. This is for two reasons:
|
||||
*
|
||||
* First, and most fundamentally, the time we'll receive on the next update
|
||||
* represents time that passed *before* the movie was started. For example,
|
||||
* 1: 20ms passes; 2: EnableAnimation(true); 3: Update(.020). We don't want
|
||||
* represents time that passed *before* the movie was started. For example,
|
||||
* 1: 20ms passes; 2: EnableAnimation(true); 3: Update(.020). We don't want
|
||||
* to send that 20ms to the texture; on the first update, the movie's time
|
||||
* should be 0.
|
||||
*
|
||||
* Second, we don't receive Update() calls if we're in a BGAnimation that
|
||||
* doesn't have focus. It looks like 1: EnableAnimation(false); 2: 30 seconds
|
||||
* pass; 3: EnableAnimation(true); 4: Update(30). We must be sure not to send
|
||||
* doesn't have focus. It looks like 1: EnableAnimation(false); 2: 30 seconds
|
||||
* pass; 3: EnableAnimation(true); 4: Update(30). We must be sure not to send
|
||||
* that long 30-second update to the movie.
|
||||
*
|
||||
* (detail: the timestamps here are actually coming from GetEffectDeltaTime())
|
||||
@@ -295,7 +292,7 @@ void Sprite::SetTexture( RageTexture *pTexture )
|
||||
if( m_fRememberedClipWidth != -1 && m_fRememberedClipHeight != -1 )
|
||||
ScaleToClipped( m_fRememberedClipWidth, m_fRememberedClipHeight );
|
||||
|
||||
/* Load default states if we haven't before. */
|
||||
// Load default states if we haven't before.
|
||||
if( m_States.empty() )
|
||||
LoadStatesFromTexture();
|
||||
}
|
||||
@@ -351,25 +348,24 @@ void Sprite::UpdateAnimationState()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We treat frame animation and movie animation slightly differently.
|
||||
/* We treat frame animation and movie animation slightly differently.
|
||||
*
|
||||
* Sprite animation is always tied directly to the effect timer. If you pause
|
||||
* animation, wait a while and restart it, sprite animations will snap back to the
|
||||
* effect timer. This allows sprites to animate to the beat in BGAnimations, where
|
||||
* they might be disabled for a while.
|
||||
* Sprite animation is always tied directly to the effect timer. If you pause
|
||||
* animation, wait a while and restart it, sprite animations will snap back to
|
||||
* the effect timer. This allows sprites to animate to the beat in BGAnimations,
|
||||
* where they might be disabled for a while.
|
||||
*
|
||||
* Movies don't do this; if you pause a movie, wait a while and restart it, it'll
|
||||
* pick up where it left off. We may have a lot of movies loaded, so it's too
|
||||
* expensive to decode movies that aren't being displayed. Movies also don't loop
|
||||
* when the effect timer loops.
|
||||
* Movies don't do this; if you pause a movie, wait a while and restart it,
|
||||
* it'll pick up where it left off. We may have a lot of movies loaded, so
|
||||
* it's too expensive to decode movies that aren't being displayed. Movies
|
||||
* also don't loop when the effect timer loops.
|
||||
*
|
||||
* (I'd like to handle sprite and movie animation as consistently as possible; the above
|
||||
* is just documentation of current practice.)
|
||||
*/
|
||||
* (I'd like to handle sprite and movie animation as consistently as possible;
|
||||
* the above is just documentation of current practice.) */
|
||||
// todo: source above comment, see if "current" practice is just that. -aj
|
||||
void Sprite::Update( float fDelta )
|
||||
{
|
||||
Actor::Update( fDelta ); // do tweening
|
||||
Actor::Update( fDelta ); // do tweening
|
||||
|
||||
const bool bSkipThisMovieUpdate = m_bSkipNextUpdate;
|
||||
m_bSkipNextUpdate = false;
|
||||
@@ -377,8 +373,8 @@ void Sprite::Update( float fDelta )
|
||||
if( !m_bIsAnimating )
|
||||
return;
|
||||
|
||||
if( !m_pTexture ) // no texture, nothing to animate
|
||||
return;
|
||||
if( !m_pTexture ) // no texture, nothing to animate
|
||||
return;
|
||||
|
||||
float fTimePassed = GetEffectDeltaTime();
|
||||
m_fSecsIntoState += fTimePassed;
|
||||
@@ -388,13 +384,11 @@ void Sprite::Update( float fDelta )
|
||||
|
||||
UpdateAnimationState();
|
||||
|
||||
/* If the texture is a movie, decode frames. */
|
||||
// If the texture is a movie, decode frames.
|
||||
if( !bSkipThisMovieUpdate )
|
||||
m_pTexture->DecodeSeconds( max(0, fTimePassed) );
|
||||
|
||||
//
|
||||
// update scrolling
|
||||
//
|
||||
if( m_fTexCoordVelocityX != 0 || m_fTexCoordVelocityY != 0 )
|
||||
{
|
||||
float fTexCoords[8];
|
||||
@@ -410,9 +404,10 @@ void Sprite::Update( float fDelta )
|
||||
fTexCoords[6] += fDelta*m_fTexCoordVelocityX;
|
||||
fTexCoords[7] += fDelta*m_fTexCoordVelocityY;
|
||||
|
||||
/* When wrapping, avoid gradual loss of precision and sending unreasonably large
|
||||
* texture coordinates to the renderer by pushing texture coordinates back to 0.
|
||||
* As long as we adjust all four coordinates by the same amount, this won't be visible. */
|
||||
/* When wrapping, avoid gradual loss of precision and sending
|
||||
* unreasonably large texture coordinates to the renderer by pushing
|
||||
* texture coordinates back to 0. As long as we adjust all four
|
||||
* coordinates by the same amount, this won't be visible. */
|
||||
if( m_bTextureWrapping )
|
||||
{
|
||||
const float fXAdjust = floorf( fTexCoords[0] );
|
||||
@@ -441,7 +436,7 @@ void TexCoordArrayFromRect( float fImageCoords[8], const RectF &rect )
|
||||
|
||||
void Sprite::DrawTexture( const TweenState *state )
|
||||
{
|
||||
Actor::SetGlobalRenderStates(); // set Actor-specified render states
|
||||
Actor::SetGlobalRenderStates(); // set Actor-specified render states
|
||||
|
||||
// bail if cropped all the way
|
||||
if( state->crop.left + state->crop.right >= 1 ||
|
||||
@@ -455,11 +450,10 @@ void Sprite::DrawTexture( const TweenState *state )
|
||||
quadVerticies.top = -m_size.y/2.0f;
|
||||
quadVerticies.bottom = +m_size.y/2.0f;
|
||||
|
||||
|
||||
/* Don't draw anything outside of the texture's image area. Texels outside
|
||||
* of the image area aren't guaranteed to be initialized. */
|
||||
/* HACK: Clamp the crop values. It would be more accurate to clip the
|
||||
* vertices to that the diffuse value is adjusted. */
|
||||
* vertices so that the diffuse value is adjusted. */
|
||||
RectF crop = state->crop;
|
||||
CLAMP( crop.left, 0, 1 );
|
||||
CLAMP( crop.right, 0, 1 );
|
||||
@@ -532,7 +526,7 @@ void Sprite::DrawTexture( const TweenState *state )
|
||||
v[i].t.x = v[i].t.y = 0;
|
||||
}
|
||||
|
||||
/* Draw if we're not fully transparent */
|
||||
// Draw if we're not fully transparent
|
||||
if( state->diffuse[0].a > 0 ||
|
||||
state->diffuse[1].a > 0 ||
|
||||
state->diffuse[2].a > 0 ||
|
||||
@@ -553,10 +547,10 @@ void Sprite::DrawTexture( const TweenState *state )
|
||||
}
|
||||
|
||||
// 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
|
||||
v[3].c = state->diffuse[1]; // top right
|
||||
v[0].c = state->diffuse[0]; // top left
|
||||
v[1].c = state->diffuse[2]; // bottom left
|
||||
v[2].c = state->diffuse[3]; // bottom right
|
||||
v[3].c = state->diffuse[1]; // top right
|
||||
DISPLAY->DrawQuad( v );
|
||||
}
|
||||
|
||||
@@ -582,13 +576,13 @@ void Sprite::DrawPrimitives()
|
||||
m_pTempState->fade.left > 0 ||
|
||||
m_pTempState->fade.right > 0 )
|
||||
{
|
||||
/* We're fading the edges. */
|
||||
// We're fading the edges.
|
||||
const RectF &FadeDist = m_pTempState->fade;
|
||||
|
||||
/* Actual size of the fade on each side: */
|
||||
// Actual size of the fade on each side:
|
||||
RectF FadeSize = FadeDist;
|
||||
|
||||
/* If the cropped size is less than the fade distance in either dimension, clamp. */
|
||||
// If the cropped size is less than the fade distance in either dimension, clamp.
|
||||
const float HorizRemaining = 1.0f - (m_pTempState->crop.left + m_pTempState->crop.right);
|
||||
if( FadeDist.left+FadeDist.right > 0 &&
|
||||
HorizRemaining < FadeDist.left+FadeDist.right )
|
||||
@@ -607,13 +601,13 @@ void Sprite::DrawPrimitives()
|
||||
FadeSize.bottom = (1.0f-TopPercent) * VertRemaining;
|
||||
}
|
||||
|
||||
/* Alpha value of the un-faded side of each fade rect: */
|
||||
// Alpha value of the un-faded side of each fade rect:
|
||||
const float RightAlpha = SCALE( FadeSize.right, FadeDist.right, 0, 1, 0 );
|
||||
const float LeftAlpha = SCALE( FadeSize.left, FadeDist.left, 0, 1, 0 );
|
||||
const float TopAlpha = SCALE( FadeSize.top, FadeDist.top, 0, 1, 0 );
|
||||
const float BottomAlpha = SCALE( FadeSize.bottom, FadeDist.bottom, 0, 1, 0 );
|
||||
|
||||
/* Draw the inside: */
|
||||
// Draw the inside:
|
||||
TweenState ts = *m_pTempState;
|
||||
ts.crop.left += FadeDist.left;
|
||||
ts.crop.right += FadeDist.right;
|
||||
@@ -623,7 +617,7 @@ void Sprite::DrawPrimitives()
|
||||
|
||||
if( FadeSize.left > 0.001f )
|
||||
{
|
||||
/* Draw the left: */
|
||||
// Draw the left:
|
||||
ts.crop = m_pTempState->crop; // restore
|
||||
ts.crop.right = 1 - (ts.crop.left + FadeSize.left);
|
||||
ts.crop.top += FadeDist.top; // lop off the corner if fading both x and y
|
||||
@@ -642,7 +636,7 @@ void Sprite::DrawPrimitives()
|
||||
|
||||
if( FadeSize.right > 0.001f )
|
||||
{
|
||||
/* Draw the right: */
|
||||
// Draw the right:
|
||||
ts.crop = m_pTempState->crop; // restore
|
||||
ts.crop.left = 1 - (ts.crop.right + FadeSize.right);
|
||||
ts.crop.top += FadeDist.top;
|
||||
@@ -662,7 +656,7 @@ void Sprite::DrawPrimitives()
|
||||
|
||||
if( FadeSize.top > 0.001f )
|
||||
{
|
||||
/* Draw the top: */
|
||||
// Draw the top:
|
||||
ts.crop = m_pTempState->crop; // restore
|
||||
ts.crop.bottom = 1 - (ts.crop.top + FadeSize.top);
|
||||
ts.crop.left += FadeDist.left;
|
||||
@@ -682,7 +676,7 @@ void Sprite::DrawPrimitives()
|
||||
|
||||
if( FadeSize.bottom > 0.001f )
|
||||
{
|
||||
/* Draw the bottom: */
|
||||
// Draw the bottom:
|
||||
ts.crop = m_pTempState->crop; // restore
|
||||
ts.crop.top = 1 - (ts.crop.bottom + FadeSize.bottom);
|
||||
ts.crop.left += FadeDist.left;
|
||||
@@ -714,7 +708,7 @@ int Sprite::GetNumStates() const
|
||||
void Sprite::SetState( int iNewState )
|
||||
{
|
||||
// This assert will likely trigger if the "missing" theme element graphic
|
||||
// is loaded in place of a multi-frame sprite. We want to know about these
|
||||
// is loaded in place of a multi-frame sprite. We want to know about these
|
||||
// problems in debug builds, but they're not fatal.
|
||||
//
|
||||
// Never warn about setting state 0.
|
||||
@@ -722,7 +716,7 @@ void Sprite::SetState( int iNewState )
|
||||
{
|
||||
// Don't warn about number of states in "_blank" or "_missing".
|
||||
if( !m_pTexture || (m_pTexture->GetID().filename.find("_blank") == string::npos &&
|
||||
m_pTexture->GetID().filename.find("_missing") == string::npos) )
|
||||
m_pTexture->GetID().filename.find("_missing") == string::npos) )
|
||||
{
|
||||
RString sError;
|
||||
if( m_pTexture )
|
||||
@@ -815,8 +809,8 @@ const RectF *Sprite::GetTextureCoordRectForState( int iState ) const
|
||||
return &m_States[iState].rect;
|
||||
}
|
||||
|
||||
/* If we're using custom coordinates, return them; otherwise return the coordinates
|
||||
* for the current state. */
|
||||
/* If we're using custom coordinates, return them; otherwise return the
|
||||
* coordinates for the current state. */
|
||||
void Sprite::GetActiveTextureCoords( float fTexCoordsOut[8] ) const
|
||||
{
|
||||
if(m_bUsingCustomTexCoords)
|
||||
@@ -858,17 +852,17 @@ void Sprite::ScaleToClipped( float fWidth, float fHeight )
|
||||
int iSourceWidth = m_pTexture->GetSourceWidth();
|
||||
int iSourceHeight = m_pTexture->GetSourceHeight();
|
||||
|
||||
// save the original X&Y. We're going to restore them later.
|
||||
// save the original X and Y. We're going to restore them later.
|
||||
float fOriginalX = GetX();
|
||||
float fOriginalY = GetY();
|
||||
|
||||
if( IsDiagonalBanner(iSourceWidth, iSourceHeight) ) // this is a SSR/DWI CroppedSprite
|
||||
if( IsDiagonalBanner(iSourceWidth, iSourceHeight) ) // this is a SSR/DWI CroppedSprite
|
||||
{
|
||||
float fCustomImageCoords[8] = {
|
||||
0.02f, 0.78f, // top left
|
||||
0.22f, 0.98f, // bottom left
|
||||
0.98f, 0.22f, // bottom right
|
||||
0.78f, 0.02f, // top right
|
||||
0.02f, 0.78f, // top left
|
||||
0.22f, 0.98f, // bottom left
|
||||
0.98f, 0.22f, // bottom right
|
||||
0.78f, 0.02f, // top right
|
||||
};
|
||||
Sprite::SetCustomImageCoords( fCustomImageCoords );
|
||||
|
||||
@@ -880,7 +874,7 @@ void Sprite::ScaleToClipped( float fWidth, float fHeight )
|
||||
{
|
||||
/* If no crop size is set, then we're only being used to crop diagonal
|
||||
* banners so they look like regular ones. We don't actually care about
|
||||
* the size of the image, only that it has an aspect ratio of 4:1. */
|
||||
* the size of the image, only that it has an aspect ratio of 4:1. */
|
||||
m_size = RageVector2( 256, 64 );
|
||||
}
|
||||
SetZoom( 1 );
|
||||
@@ -888,12 +882,12 @@ void Sprite::ScaleToClipped( float fWidth, float fHeight )
|
||||
else if( m_pTexture->GetID().filename.find("(was rotated)") != string::npos &&
|
||||
fWidth != -1 && fHeight != -1 )
|
||||
{
|
||||
/* Dumb hack. Normally, we crop all sprites except for diagonal banners,
|
||||
* which are stretched. Low-res versions of banners need to do the same
|
||||
/* Dumb hack: Normally, we crop all sprites except for diagonal banners,
|
||||
* which are stretched. Low-res versions of banners need to do the same
|
||||
* thing as their full resolution counterpart, so the crossfade looks right.
|
||||
* However, low-res diagonal banners are un-rotated, to save space. BannerCache
|
||||
* drops the above text into the "filename" (which is otherwise unused for
|
||||
* these banners) to tell us this.
|
||||
* However, low-res diagonal banners are un-rotated, to save space.
|
||||
* BannerCache drops the above text into the "filename" (which is
|
||||
* otherwise unused for these banners) to tell us this.
|
||||
*/
|
||||
Sprite::StopUsingCustomCoords();
|
||||
m_size = RageVector2( fWidth, fHeight );
|
||||
@@ -909,12 +903,12 @@ void Sprite::ScaleToClipped( float fWidth, float fHeight )
|
||||
// find which dimension is larger
|
||||
bool bXDimNeedsToBeCropped = GetZoomedWidth() > fWidth+0.01;
|
||||
|
||||
if( bXDimNeedsToBeCropped ) // crop X
|
||||
if( bXDimNeedsToBeCropped ) // crop X
|
||||
{
|
||||
float fPercentageToCutOff = (this->GetZoomedWidth() - fWidth) / this->GetZoomedWidth();
|
||||
fPercentageToCutOff = max( fPercentageToCutOff-fScaleFudgePercent, 0 );
|
||||
float fPercentageToCutOffEachSide = fPercentageToCutOff / 2;
|
||||
|
||||
|
||||
// generate a rectangle with new texture coordinates
|
||||
RectF fCustomImageRect(
|
||||
fPercentageToCutOffEachSide,
|
||||
@@ -923,12 +917,12 @@ void Sprite::ScaleToClipped( float fWidth, float fHeight )
|
||||
1 );
|
||||
SetCustomImageRect( fCustomImageRect );
|
||||
}
|
||||
else // crop Y
|
||||
else // crop Y
|
||||
{
|
||||
float fPercentageToCutOff = (this->GetZoomedHeight() - fHeight) / this->GetZoomedHeight();
|
||||
fPercentageToCutOff = max( fPercentageToCutOff-fScaleFudgePercent, 0 );
|
||||
float fPercentageToCutOffEachSide = fPercentageToCutOff / 2;
|
||||
|
||||
|
||||
// generate a rectangle with new texture coordinates
|
||||
RectF fCustomImageRect(
|
||||
0,
|
||||
@@ -944,7 +938,10 @@ void Sprite::ScaleToClipped( float fWidth, float fHeight )
|
||||
// restore original XY
|
||||
SetXY( fOriginalX, fOriginalY );
|
||||
}
|
||||
/* magic hurr */
|
||||
|
||||
|
||||
// magic hurr
|
||||
// This code should either be removed or refactored in the future -aj
|
||||
void Sprite::CropTo( float fWidth, float fHeight )
|
||||
{
|
||||
m_fRememberedClipWidth = fWidth;
|
||||
@@ -960,13 +957,13 @@ void Sprite::CropTo( float fWidth, float fHeight )
|
||||
float fOriginalX = GetX();
|
||||
float fOriginalY = GetY();
|
||||
|
||||
if( IsDiagonalBanner(iSourceWidth, iSourceHeight) ) // this is a SSR/DWI CroppedSprite
|
||||
if( IsDiagonalBanner(iSourceWidth, iSourceHeight) ) // this is a SSR/DWI CroppedSprite
|
||||
{
|
||||
float fCustomImageCoords[8] = {
|
||||
0.02f, 0.78f, // top left
|
||||
0.22f, 0.98f, // bottom left
|
||||
0.98f, 0.22f, // bottom right
|
||||
0.78f, 0.02f, // top right
|
||||
0.02f, 0.78f, // top left
|
||||
0.22f, 0.98f, // bottom left
|
||||
0.98f, 0.22f, // bottom right
|
||||
0.78f, 0.02f, // top right
|
||||
};
|
||||
Sprite::SetCustomImageCoords( fCustomImageCoords );
|
||||
|
||||
@@ -986,7 +983,7 @@ void Sprite::CropTo( float fWidth, float fHeight )
|
||||
else if( m_pTexture->GetID().filename.find("(was rotated)") != string::npos &&
|
||||
fWidth != -1 && fHeight != -1 )
|
||||
{
|
||||
/* Dumb hack. Normally, we crop all sprites except for diagonal banners,
|
||||
/* Dumb hack: Normally, we crop all sprites except for diagonal banners,
|
||||
* which are stretched. Low-res versions of banners need to do the same
|
||||
* thing as their full resolution counterpart, so the crossfade looks right.
|
||||
* However, low-res diagonal banners are un-rotated, to save space. BannerCache
|
||||
@@ -1011,7 +1008,7 @@ void Sprite::CropTo( float fWidth, float fHeight )
|
||||
{
|
||||
float fPercentageToCutOff = (this->GetZoomedWidth() - fWidth) / this->GetZoomedWidth();
|
||||
float fPercentageToCutOffEachSide = fPercentageToCutOff / 2;
|
||||
|
||||
|
||||
// generate a rectangle with new texture coordinates
|
||||
RectF fCustomImageRect(
|
||||
fPercentageToCutOffEachSide,
|
||||
@@ -1024,7 +1021,7 @@ void Sprite::CropTo( float fWidth, float fHeight )
|
||||
{
|
||||
float fPercentageToCutOff = (this->GetZoomedHeight() - fHeight) / this->GetZoomedHeight();
|
||||
float fPercentageToCutOffEachSide = fPercentageToCutOff / 2;
|
||||
|
||||
|
||||
// generate a rectangle with new texture coordinates
|
||||
RectF fCustomImageRect(
|
||||
0,
|
||||
@@ -1040,10 +1037,12 @@ void Sprite::CropTo( float fWidth, float fHeight )
|
||||
// restore original XY
|
||||
SetXY( fOriginalX, fOriginalY );
|
||||
}
|
||||
/* end magic */
|
||||
// end magic
|
||||
|
||||
|
||||
bool Sprite::IsDiagonalBanner( int iWidth, int iHeight )
|
||||
{
|
||||
/* A diagonal banner is a square. Give a couple pixels of leeway. */
|
||||
// A diagonal banner is a square. Give a couple pixels of leeway.
|
||||
return iWidth >= 100 && abs(iWidth - iHeight) < 2;
|
||||
}
|
||||
|
||||
|
||||
+10
-12
@@ -11,8 +11,7 @@
|
||||
#include "Profile.h"
|
||||
#include "ProfileManager.h"
|
||||
|
||||
/*
|
||||
* Arcade: for the current stage (one song).
|
||||
/* Arcade: for the current stage (one song).
|
||||
* Nonstop/Oni/Endless: for current course (which usually contains multiple songs)
|
||||
*/
|
||||
|
||||
@@ -74,7 +73,6 @@ int StageStats::GetAverageMeter( PlayerNumber pn ) const
|
||||
AssertValid( pn );
|
||||
|
||||
// TODO: This isn't correct for courses.
|
||||
|
||||
int iTotalMeter = 0;
|
||||
|
||||
for( unsigned i=0; i<m_vpPlayedSongs.size(); i++ )
|
||||
@@ -97,7 +95,7 @@ void StageStats::AddStats( const StageStats& other )
|
||||
|
||||
m_bGaveUp |= other.m_bGaveUp;
|
||||
m_bUsedAutoplay |= other.m_bUsedAutoplay;
|
||||
|
||||
|
||||
m_fGameplaySeconds += other.m_fGameplaySeconds;
|
||||
m_fStepsSeconds += other.m_fStepsSeconds;
|
||||
|
||||
@@ -170,7 +168,7 @@ void StageStats::FinalizeScores( bool bSummary )
|
||||
{
|
||||
case PLAY_MODE_BATTLE:
|
||||
case PLAY_MODE_RAVE:
|
||||
return; /* don't save scores in battle */
|
||||
return; // don't save scores in battle
|
||||
}
|
||||
|
||||
if( PREFSMAN->m_sTestInitialScreen.Get() != "" )
|
||||
@@ -188,9 +186,8 @@ void StageStats::FinalizeScores( bool bSummary )
|
||||
|
||||
LOG->Trace( "saving stats and high scores" );
|
||||
|
||||
//
|
||||
// generate a HighScore for each player
|
||||
//
|
||||
|
||||
// whether or not to save scores when the stage was failed
|
||||
// depends on if this is a course or not ... it's handled
|
||||
// below in the switch
|
||||
@@ -205,6 +202,7 @@ void StageStats::FinalizeScores( bool bSummary )
|
||||
m_multiPlayer[mp].m_HighScore = FillInHighScore( m_multiPlayer[mp], *GAMESTATE->m_pMultiPlayerState[mp], "", sPlayerGuid );
|
||||
}
|
||||
|
||||
// todo: check if player was CPU autoplay here? -aj
|
||||
FOREACH_HumanPlayer( p )
|
||||
{
|
||||
const HighScore &hs = m_player[p].m_HighScore;
|
||||
@@ -227,8 +225,8 @@ void StageStats::FinalizeScores( bool bSummary )
|
||||
m_player[p].m_rc = AverageMeterToRankingCategory( iAverageMeter );
|
||||
|
||||
PROFILEMAN->AddCategoryScore( st, m_player[p].m_rc, p, hs, m_player[p].m_iPersonalHighScoreIndex, m_player[p].m_iMachineHighScoreIndex );
|
||||
|
||||
// TRICKY: Increment play count here, and not on ScreenGameplay like the others.
|
||||
|
||||
// TRICKY: Increment play count here, and not on ScreenGameplay like the others.
|
||||
PROFILEMAN->IncrementCategoryPlayCount( st, m_player[p].m_rc, p );
|
||||
}
|
||||
else if( GAMESTATE->IsCourseMode() )
|
||||
@@ -249,7 +247,7 @@ void StageStats::FinalizeScores( bool bSummary )
|
||||
}
|
||||
|
||||
// If both players get a machine high score in the same HighScoreList,
|
||||
// then one player's score may have bumped the other player. Look in
|
||||
// then one player's score may have bumped the other player. Look in
|
||||
// the HighScoreList and re-get the high score index.
|
||||
FOREACH_HumanPlayer( p )
|
||||
{
|
||||
@@ -279,7 +277,7 @@ void StageStats::FinalizeScores( bool bSummary )
|
||||
Steps* pSteps = GAMESTATE->m_pCurSteps[p];
|
||||
pHSL = &pProfile->GetStepsHighScoreList( pSong, pSteps );
|
||||
}
|
||||
|
||||
|
||||
vector<HighScore>::const_iterator iter = find( pHSL->vHighScores.begin(), pHSL->vHighScores.end(), hs );
|
||||
if( iter == pHSL->vHighScores.end() )
|
||||
m_player[p].m_iMachineHighScoreIndex = -1;
|
||||
@@ -357,7 +355,7 @@ public:
|
||||
lua_rawseti( L, -2, i+1 );
|
||||
}
|
||||
return 1;
|
||||
|
||||
|
||||
}
|
||||
static int GetGameplaySeconds( T* p, lua_State *L ) { lua_pushnumber(L, p->m_fGameplaySeconds); return 1; }
|
||||
static int OnePassed( T* p, lua_State *L ) { lua_pushboolean(L, p->OnePassed()); return 1; }
|
||||
|
||||
+30
-57
@@ -1216,52 +1216,25 @@ int main(int argc, char* argv[])
|
||||
|
||||
CodeDetector::RefreshCacheItems();
|
||||
|
||||
/* Initialize which courses are ranking courses here. */
|
||||
// Initialize which courses are ranking courses here.
|
||||
SONGMAN->UpdateRankingCourses();
|
||||
|
||||
if( GetCommandlineArgument("netip") )
|
||||
NSMAN->DisplayStartupStatus(); // If we're using networking show what happened
|
||||
|
||||
/* this code should only be enabled in distributed builds
|
||||
* HI PLEASE MAKE SURE THIS SECTION IS USING THE RIGHT VARIABLE WHEN YOU
|
||||
* GENERATE THE BUILDS FOR BETA WAVES, THANKS -aj
|
||||
* also remember to comment this out when it comes time for normal builds
|
||||
* the point of this section is to mark executables in case of leaks.
|
||||
* by the time sm-ssc v1.0 is out, this code should be GONE. ENTIRELY. -aj
|
||||
*/
|
||||
//RString sVariableFuzzer1995EXAnotherStep;
|
||||
|
||||
// generic codes //
|
||||
//sVariableFuzzer1995EXAnotherStep = "9D76A02B8D814AEE7B8BF8A03359CB7D"; // SSC generic (input string "h01yd!v3rZ2009R33LR4C1NGR007$")
|
||||
//sVariableFuzzer1995EXAnotherStep = "A333181F0F5DCBE20636ED99127F3C12"; // BoXoRRoXoRs (input string "l3tzR0X0RglennzBoXorZ")
|
||||
|
||||
// private beta wave 1 - 20091201 release //
|
||||
// sVariableFuzzer1995EXAnotherStep = "4312B0FD2FB1B26BD8B5DCD8305813AA"; // FSX {input string "FSXFFFSSSXXX1283"}
|
||||
// sVariableFuzzer1995EXAnotherStep = "1B9035054F6076F9E20696FEB0E4D8E3"; // Wolfman2000 {input string "jasonfeldenstein3Dz"}
|
||||
// sVariableFuzzer1995EXAnotherStep = "804CF9D006ECCFD695541AEFD1EDB5C5"; // NitroX72 {input string "!nfam0uZn1tr0Glyc3r1n"}
|
||||
// sVariableFuzzer1995EXAnotherStep = "285F8E6398F12485894BD6257C2524C7"; // Wanny {input string "wansicles2081"}
|
||||
// sVariableFuzzer1995EXAnotherStep = "57AB620779AE965597AE7700CF378511"; // Tio {input string "teeba00lenmEhik0"}
|
||||
// sVariableFuzzer1995EXAnotherStep = "226460C1442F11F2B7D1F5C926C5f6DA"; // cerbo {input string "audpnzstxnotseepiu"}
|
||||
// sVariableFuzzer1995EXAnotherStep = "3AC41B7211C8BC18C974220EC55B77BA"; // Daisuke Master {input string "daisuBaisuWaisuNaisu!!"}
|
||||
|
||||
// sVariableFuzzer1995EXAnotherStep = "2A7ECF8AAC00C7E4BE657FCC4B73ADEA"; // Sniper257? {input string "McSn1p3rF3aT0uTsId3r"}
|
||||
// sVariableFuzzer1995EXAnotherStep = "915ABA60E7FD1524076859B8B1C4A203"; // Karai? {input string "turororocobocolocoOMGz"}
|
||||
// sVariableFuzzer1995EXAnotherStep = "8C310A867555866CA1A044F54B6EA4CD"; // djaydino? {input string "ez2dzaydinosaurusbagelz"}
|
||||
// private beta wave 1 - 20091208 release //
|
||||
|
||||
/* Run the main loop. */
|
||||
// Run the main loop.
|
||||
GameLoop::RunGameLoop();
|
||||
|
||||
|
||||
PREFSMAN->SavePrefsToDisk();
|
||||
|
||||
ShutdownGame();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
RString StepMania::SaveScreenshot( RString sDir, bool bSaveCompressed, bool bMakeSignature, int iIndex )
|
||||
{
|
||||
/* Files should be of the form "screen#####.xxx". Ignore the extension; find
|
||||
/* Files should be of the form "screen#####.xxx". Ignore the extension; find
|
||||
* the last file of this form, and use the next number. This way, we don't
|
||||
* write the same screenshot number for different formats (screen00011.bmp,
|
||||
* screen00011.jpg), and we always increase from the end, so if screen00003.jpg
|
||||
@@ -1272,8 +1245,8 @@ RString StepMania::SaveScreenshot( RString sDir, bool bSaveCompressed, bool bMak
|
||||
else
|
||||
sFileNameNoExtension = Profile::MakeFileNameNoExtension( "screen", iIndex );
|
||||
|
||||
// Save the screenshot. If writing lossy to a memcard, use SAVE_LOSSY_LOW_QUAL, so we
|
||||
// don't eat up lots of space.
|
||||
// Save the screenshot. If writing lossy to a memcard, use
|
||||
// SAVE_LOSSY_LOW_QUAL, so we don't eat up lots of space.
|
||||
RageDisplay::GraphicsFileFormat fmt;
|
||||
if( bSaveCompressed && MEMCARDMAN->PathIsMemCard(sDir) )
|
||||
fmt = RageDisplay::SAVE_LOSSY_LOW_QUAL;
|
||||
@@ -1320,15 +1293,15 @@ void StepMania::InsertCoin( int iNum, bool bCountInBookkeeping )
|
||||
else
|
||||
SCREENMAN->PlayInvalidSound();
|
||||
|
||||
/* If AutoJoin and a player is already joined, then try to join a player. (If no players
|
||||
* are joined, they'll join on the first JoinInput.) */
|
||||
/* If AutoJoin and a player is already joined, then try to join a player.
|
||||
* (If no players are joined, they'll join on the first JoinInput.) */
|
||||
if( GAMESTATE->m_bAutoJoin.Get() && GAMESTATE->GetNumSidesJoined() > 0 )
|
||||
{
|
||||
if( GAMESTATE->GetNumSidesJoined() > 0 && GAMESTATE->JoinPlayers() )
|
||||
SCREENMAN->PlayStartSound();
|
||||
}
|
||||
|
||||
/* TODO: remove this redundant message and things that depend on it */
|
||||
// TODO: remove this redundant message and things that depend on it
|
||||
Message msg( "CoinInserted" );
|
||||
// below params are unused
|
||||
//msg.SetParam( "Coins", GAMESTATE->m_iCoins );
|
||||
@@ -1347,8 +1320,8 @@ void StepMania::ClearCredits()
|
||||
LOG->Trace("%i coins cleared", GAMESTATE->m_iCoins.Get() );
|
||||
GAMESTATE->m_iCoins.Set( 0 );
|
||||
SCREENMAN->PlayInvalidSound();
|
||||
|
||||
/* TODO: remove this redundant message and things that depend on it */
|
||||
|
||||
// TODO: remove this redundant message and things that depend on it
|
||||
Message msg( "CoinInserted" );
|
||||
// below params are unused
|
||||
//msg.SetParam( "Coins", GAMESTATE->m_iCoins );
|
||||
@@ -1362,12 +1335,12 @@ static LocalizedString SERVICE_SWITCH_PRESSED ( "StepMania", "Service switch pre
|
||||
// xxx: okay these probably shouldn't be here, but I wanted them to be
|
||||
// localized and this was the place to do it since this is where the control
|
||||
// structure is placed... apologies to those who like properly structured
|
||||
// metrics. I like compatibility.
|
||||
// metrics. I like compatibility. -aj
|
||||
static LocalizedString RELOADED_METRICS( "ThemeManager", "Reloaded metrics" );
|
||||
static LocalizedString RELOADED_METRICS_AND_TEXTURES( "ThemeManager", "Reloaded metrics and textures" );
|
||||
bool HandleGlobalInputs( const InputEventPlus &input )
|
||||
{
|
||||
/* None of the globals keys act on types other than FIRST_PRESS */
|
||||
// None of the globals keys act on types other than FIRST_PRESS
|
||||
if( input.type != IET_FIRST_PRESS )
|
||||
return false;
|
||||
|
||||
@@ -1388,19 +1361,19 @@ bool HandleGlobalInputs( const InputEventPlus &input )
|
||||
return true;
|
||||
|
||||
case GAME_BUTTON_COIN:
|
||||
/* Handle a coin insertion. */
|
||||
// Handle a coin insertion.
|
||||
if( GAMESTATE->IsEditing() ) // no coins while editing
|
||||
{
|
||||
LOG->Trace( "Ignored coin insertion (editing)" );
|
||||
break;
|
||||
}
|
||||
StepMania::InsertCoin();
|
||||
return false; // Attract need to know because they go to TitleMenu on > 1 credit
|
||||
return false; // Attract needs to know because it goes to TitleMenu on > 1 credit
|
||||
}
|
||||
|
||||
// re-added for 3.9 veterans, plus it's just plain old faster than the
|
||||
// debug menu. However, this is without the LShift capability that was
|
||||
// in 3.9; if we get enough requests, we'll re-add it, but meh. -aj
|
||||
// re-added for StepMania 3.9 veterans, plus it's just plain old faster
|
||||
// than the debug menu. However, this is without the LShift capability
|
||||
// that was in 3.9; if we get enough requests, we'll re-add it, but meh. -aj
|
||||
if( input.DeviceI == DeviceInput(DEVICE_KEYBOARD, KEY_F2) )
|
||||
{
|
||||
if( INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_LSHIFT), &input.InputList) ||
|
||||
@@ -1443,19 +1416,19 @@ bool HandleGlobalInputs( const InputEventPlus &input )
|
||||
}
|
||||
#else
|
||||
if( input.DeviceI == DeviceInput(DEVICE_KEYBOARD, KEY_Cq) &&
|
||||
(INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_LMETA), &input.InputList ) ||
|
||||
INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_RMETA), &input.InputList )) )
|
||||
(INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_LMETA), &input.InputList ) ||
|
||||
INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD, KEY_RMETA), &input.InputList )) )
|
||||
{
|
||||
/* The user quit is handled by the menu item so we don't need to set it here;
|
||||
* however, we do want to return that it has been handled since this will happen
|
||||
* first. */
|
||||
/* The user quit is handled by the menu item so we don't need to set it
|
||||
* here; however, we do want to return that it has been handled since
|
||||
* this will happen first. */
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool bDoScreenshot =
|
||||
#if defined(MACOSX)
|
||||
/* Notebooks don't have F13. Use cmd-F12 as well. */
|
||||
// Notebooks don't have F13. Use cmd-F12 as well.
|
||||
input.DeviceI == DeviceInput( DEVICE_KEYBOARD, KEY_PRTSC ) ||
|
||||
input.DeviceI == DeviceInput( DEVICE_KEYBOARD, KEY_F13 ) ||
|
||||
( input.DeviceI == DeviceInput(DEVICE_KEYBOARD, KEY_F12) &&
|
||||
@@ -1486,7 +1459,7 @@ bool HandleGlobalInputs( const InputEventPlus &input )
|
||||
(INPUTFILTER->IsBeingPressed(DeviceInput(DEVICE_KEYBOARD, KEY_RALT), &input.InputList) ||
|
||||
INPUTFILTER->IsBeingPressed(DeviceInput(DEVICE_KEYBOARD, KEY_LALT), &input.InputList)) )
|
||||
{
|
||||
/* alt-enter */
|
||||
// alt-enter
|
||||
/* In OS X, this is a menu item and will be handled as such. This will happen
|
||||
* first and then the lower priority GUI thread will happen second causing the
|
||||
* window to toggle twice. Another solution would be to put a timer in
|
||||
@@ -1515,7 +1488,7 @@ void HandleInputEvents(float fDeltaTime)
|
||||
vector<InputEvent> ieArray;
|
||||
INPUTFILTER->GetInputEvents( ieArray );
|
||||
|
||||
/* If we don't have focus, discard input. */
|
||||
// If we don't have focus, discard input.
|
||||
if( !HOOKS->AppHasFocus() )
|
||||
return;
|
||||
|
||||
@@ -1526,7 +1499,7 @@ void HandleInputEvents(float fDeltaTime)
|
||||
input.type = ieArray[i].type;
|
||||
swap( input.InputList, ieArray[i].m_ButtonState );
|
||||
|
||||
// hack for testing with only one joytick
|
||||
// hack for testing (MultiPlayer) with only one joystick
|
||||
if( input.DeviceI.IsJoystick() )
|
||||
{
|
||||
if( INPUTFILTER->IsBeingPressed( DeviceInput(DEVICE_KEYBOARD,KEY_LSHIFT) ) )
|
||||
@@ -1546,7 +1519,7 @@ void HandleInputEvents(float fDeltaTime)
|
||||
input.mp = MultiPlayer_Invalid;
|
||||
|
||||
{
|
||||
// Translate input to the appropriate MultiPlayer. Assume that all
|
||||
// Translate input to the appropriate MultiPlayer. Assume that all
|
||||
// joystick devices are mapped the same as the master player.
|
||||
if( input.DeviceI.IsJoystick() )
|
||||
{
|
||||
@@ -1578,7 +1551,7 @@ void HandleInputEvents(float fDeltaTime)
|
||||
|
||||
INPUTQUEUE->RememberInput( input );
|
||||
|
||||
/* When a GameButton is pressed, stop repeating other keys on the same controller. */
|
||||
// When a GameButton is pressed, stop repeating other keys on the same controller.
|
||||
if( input.type == IET_FIRST_PRESS && input.MenuI != GameButton_Invalid )
|
||||
{
|
||||
FOREACH_ENUM( GameButton, m )
|
||||
|
||||
+7
-7
@@ -41,7 +41,7 @@ private:
|
||||
const Steps *pSteps;
|
||||
const Trail *pTrail;
|
||||
int iMeter;
|
||||
StepsType st; // pass because there may be a StepType icons
|
||||
StepsType st; // pass because there may be a StepType icon
|
||||
Difficulty dc;
|
||||
CourseType ct;
|
||||
};
|
||||
@@ -49,12 +49,12 @@ private:
|
||||
|
||||
RString m_sMetricsGroup;
|
||||
|
||||
AutoActor m_sprFrame;
|
||||
BitmapText m_textTicks; /* 111100000 */
|
||||
BitmapText m_textMeter; /* 3, 9 */
|
||||
BitmapText m_textDescription; /* Easy, Medium, SuperCoolEdit */
|
||||
AutoActor m_sprAutogen; // visible if Steps and is autogen'd
|
||||
AutoActor m_sprStepsType; // TODO: Make this an AutoActor
|
||||
AutoActor m_sprFrame;
|
||||
BitmapText m_textTicks; // 111100000
|
||||
BitmapText m_textMeter; // 3, 9
|
||||
BitmapText m_textDescription; // Easy, Medium, SuperCoolEdit
|
||||
AutoActor m_sprAutogen; // visible if Steps and is autogen'd
|
||||
AutoActor m_sprStepsType;
|
||||
|
||||
ThemeMetric<int> m_iNumTicks;
|
||||
ThemeMetric<int> m_iMaxTicks;
|
||||
|
||||
+33
-34
@@ -377,7 +377,7 @@ void ThemeManager::SwitchThemeAndLanguage( const RString &sThemeName_, const RSt
|
||||
sThemeName = PREFSMAN->m_sTheme.GetDefault();
|
||||
#endif
|
||||
// sm-ssc's SpecialFiles::BASE_THEME_NAME is _fallback, which you can't
|
||||
// select. This requires a metric, which allows it to be adapted for
|
||||
// select. This requires a preference, which allows it to be adapted for
|
||||
// other purposes (e.g. PARASTAR).
|
||||
if( !IsThemeSelectable(sThemeName) )
|
||||
sThemeName = PREFSMAN->m_sDefaultTheme;
|
||||
@@ -385,8 +385,8 @@ void ThemeManager::SwitchThemeAndLanguage( const RString &sThemeName_, const RSt
|
||||
|
||||
ASSERT( IsThemeSelectable(sThemeName) );
|
||||
|
||||
/* We haven't actually loaded the theme yet, so we can't check whether sLanguage
|
||||
* exists. Just check for empty. */
|
||||
/* We haven't actually loaded the theme yet, so we can't check whether
|
||||
* sLanguage exists. Just check for empty. */
|
||||
if( sLanguage.empty() )
|
||||
sLanguage = GetDefaultLanguage();
|
||||
LOG->Trace("ThemeManager::SwitchThemeAndLanguage: \"%s\", \"%s\"",
|
||||
@@ -398,13 +398,13 @@ void ThemeManager::SwitchThemeAndLanguage( const RString &sThemeName_, const RSt
|
||||
|
||||
m_bPseudoLocalize = bPseudoLocalize;
|
||||
|
||||
// Load theme metrics. If only the language is changing, this is all
|
||||
// Load theme metrics. If only the language is changing, this is all
|
||||
// we need to reload.
|
||||
bool bThemeChanging = (sThemeName != m_sCurThemeName);
|
||||
LoadThemeMetrics( sThemeName, sLanguage );
|
||||
|
||||
// Clear the theme path cache. This caches language-specific graphic paths, so do this
|
||||
// even if only the language is changing.
|
||||
// Clear the theme path cache. This caches language-specific graphic paths,
|
||||
// so do this even if only the language is changing.
|
||||
ClearThemePathCache();
|
||||
if( bThemeChanging )
|
||||
{
|
||||
@@ -454,7 +454,7 @@ void ThemeManager::RunLuaScripts( const RString &sMask )
|
||||
{
|
||||
--iter;
|
||||
const RString &sThemeDir = GetThemeDirFromName( iter->sThemeName );
|
||||
|
||||
|
||||
vector<RString> asElementPaths;
|
||||
// get files from directories
|
||||
vector<RString> asElementChildPaths;
|
||||
@@ -492,7 +492,7 @@ void ThemeManager::RunLuaScripts( const RString &sMask )
|
||||
void ThemeManager::UpdateLuaGlobals()
|
||||
{
|
||||
#if !defined(SMPACKAGE)
|
||||
/* explicitly refresh cached metrics that we use. */
|
||||
// explicitly refresh cached metrics that we use.
|
||||
ScreenDimensions::ReloadScreenDimensions();
|
||||
|
||||
RunLuaScripts( "*.lua" );
|
||||
@@ -523,8 +523,7 @@ struct CompareLanguageTag
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* If there's more than one result, check for language tags. For example,
|
||||
/* If there's more than one result, check for language tags. For example,
|
||||
*
|
||||
* ScreenCompany graphic (lang English).png
|
||||
* ScreenCompany graphic (lang French).png
|
||||
@@ -532,8 +531,7 @@ struct CompareLanguageTag
|
||||
* We still want to warn for ambiguous results. Use std::unique to filter
|
||||
* files with the current language tag to the top, so choosing "ignore" from
|
||||
* the multiple-match dialog will cause it to default to the first entry, so
|
||||
* it'll still use a preferred language match if there were any.
|
||||
*/
|
||||
* it'll still use a preferred language match if there were any. */
|
||||
void ThemeManager::FilterFileLanguages( vector<RString> &asPaths )
|
||||
{
|
||||
if( asPaths.size() <= 1 )
|
||||
@@ -544,7 +542,7 @@ void ThemeManager::FilterFileLanguages( vector<RString> &asPaths )
|
||||
int iDist = distance( asPaths.begin(), it );
|
||||
if( iDist == 0 )
|
||||
{
|
||||
/* We didn't find any for the current language. Try BASE_LANGUAGE. */
|
||||
// We didn't find any for the current language. Try BASE_LANGUAGE.
|
||||
it = partition( asPaths.begin(), asPaths.end(), CompareLanguageTag(SpecialFiles::BASE_LANGUAGE) );
|
||||
iDist = distance( asPaths.begin(), it );
|
||||
}
|
||||
@@ -555,8 +553,9 @@ void ThemeManager::FilterFileLanguages( vector<RString> &asPaths )
|
||||
|
||||
bool ThemeManager::GetPathInfoToRaw( PathInfo &out, const RString &sThemeName_, ElementCategory category, const RString &sMetricsGroup_, const RString &sElement_ )
|
||||
{
|
||||
/* Ugly: the parameters to this function may be a reference into g_vThemes, or something
|
||||
* else that might suddenly go away when we call ReloadMetrics, so make a copy. */
|
||||
/* Ugly: the parameters to this function may be a reference into g_vThemes,
|
||||
* or something else that might suddenly go away when we call ReloadMetrics,
|
||||
* so make a copy. */
|
||||
const RString sThemeName = sThemeName_;
|
||||
const RString sMetricsGroup = sMetricsGroup_;
|
||||
const RString sElement = sElement_;
|
||||
@@ -597,12 +596,12 @@ try_element_again:
|
||||
|
||||
for( int i = 0; asset_masks[i]; ++i )
|
||||
{
|
||||
/* No extension means directories. */
|
||||
// No extension means directories.
|
||||
if( asset_masks[i][0] == 0 )
|
||||
{
|
||||
if( !IsADirectory(asPaths[p]) )
|
||||
continue;
|
||||
|
||||
|
||||
RString sXMLPath = asPaths[p] + "/default.xml";
|
||||
if( DoesFileExist(sXMLPath) )
|
||||
{
|
||||
@@ -676,8 +675,8 @@ try_element_again:
|
||||
* the default theme point to "_shared background", and themes override
|
||||
* just "_shared background"; the redirs in the default theme should end
|
||||
* up resolving to the overridden background. */
|
||||
/* Use GetPathToOptional because we don't want report that there's an element
|
||||
* missing. Instead we want to report that the redirect is invalid. */
|
||||
/* Use GetPathToOptional because we don't want report that there's an
|
||||
* element missing. Instead we want to report that the redirect is invalid. */
|
||||
if( GetPathInfo(out,category,sNewClassName,sNewFile,true) )
|
||||
return true;
|
||||
|
||||
@@ -724,15 +723,15 @@ bool ThemeManager::GetPathInfoToAndFallback( PathInfo &out, ElementCategory cate
|
||||
|
||||
RageException::Throw( "Infinite recursion looking up theme element \"%s\"",
|
||||
MetricsGroupAndElementToFileName(sMetricsGroup, sElement).c_str() );
|
||||
/* Not really reached, but Appple's gcc 4 can't figure that out without optimization
|
||||
* even though RE:Throw() is correctly annotated. */
|
||||
/* Not really reached, but Appple's gcc 4 can't figure that out without
|
||||
* optimization even though RE:Throw() is correctly annotated. */
|
||||
while( true ) {}
|
||||
}
|
||||
|
||||
bool ThemeManager::GetPathInfo( PathInfo &out, ElementCategory category, const RString &sMetricsGroup_, const RString &sElement_, bool bOptional )
|
||||
{
|
||||
/* Ugly: the parameters to this function may be a reference into g_vThemes, or something
|
||||
* else that might suddenly go away when we call ReloadMetrics. */
|
||||
/* Ugly: the parameters to this function may be a reference into g_vThemes,
|
||||
* or something else that might suddenly go away when we call ReloadMetrics. */
|
||||
const RString sMetricsGroup = sMetricsGroup_;
|
||||
const RString sElement = sElement_;
|
||||
|
||||
@@ -741,7 +740,7 @@ bool ThemeManager::GetPathInfo( PathInfo &out, ElementCategory category, const R
|
||||
map<RString, PathInfo> &Cache = g_ThemePathCache[category];
|
||||
{
|
||||
map<RString, PathInfo>::const_iterator i;
|
||||
|
||||
|
||||
i = Cache.find( sFileName );
|
||||
if( i != Cache.end() )
|
||||
{
|
||||
@@ -749,9 +748,9 @@ bool ThemeManager::GetPathInfo( PathInfo &out, ElementCategory category, const R
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try_element_again:
|
||||
|
||||
|
||||
// search the current theme
|
||||
if( GetPathInfoToAndFallback( out, category, sMetricsGroup, sElement ) ) // we found something
|
||||
{
|
||||
@@ -767,7 +766,7 @@ try_element_again:
|
||||
|
||||
const RString &sCategory = ElementCategoryToString(category);
|
||||
|
||||
/* We can't fall back on _missing in Other: the file types are unknown. */
|
||||
// We can't fall back on _missing in Other: the file types are unknown.
|
||||
RString sMessage = "The theme element \"" + sCategory + "/" + sFileName +"\" is missing.";
|
||||
Dialog::Result res;
|
||||
if( category != EC_OTHER )
|
||||
@@ -781,11 +780,11 @@ try_element_again:
|
||||
goto try_element_again;
|
||||
case Dialog::ignore:
|
||||
LOG->UserLog( "Theme element", sCategory + '/' + sFileName,
|
||||
"could not be found in \"%s\" or \"%s\".",
|
||||
GetThemeDirFromName(m_sCurThemeName).c_str(),
|
||||
GetThemeDirFromName(SpecialFiles::BASE_THEME_NAME).c_str() );
|
||||
"could not be found in \"%s\" or \"%s\".",
|
||||
GetThemeDirFromName(m_sCurThemeName).c_str(),
|
||||
GetThemeDirFromName(SpecialFiles::BASE_THEME_NAME).c_str() );
|
||||
|
||||
/* Err? */
|
||||
// Err?
|
||||
if( sFileName == "_missing" )
|
||||
RageException::Throw( "\"_missing\" isn't present in \"%s%s\".", GetThemeDirFromName(SpecialFiles::BASE_THEME_NAME).c_str(), sCategory.c_str() );
|
||||
|
||||
@@ -794,9 +793,9 @@ try_element_again:
|
||||
return true;
|
||||
case Dialog::abort:
|
||||
LOG->UserLog( "Theme element", sCategory + '/' + sFileName,
|
||||
"could not be found in \"%s\" or \"%s\".",
|
||||
GetThemeDirFromName(m_sCurThemeName).c_str(),
|
||||
GetThemeDirFromName(SpecialFiles::BASE_THEME_NAME).c_str() );
|
||||
"could not be found in \"%s\" or \"%s\".",
|
||||
GetThemeDirFromName(m_sCurThemeName).c_str(),
|
||||
GetThemeDirFromName(SpecialFiles::BASE_THEME_NAME).c_str() );
|
||||
RageException::Throw( "Theme element \"%s/%s\" could not be found in \"%s\" or \"%s\".",
|
||||
sCategory.c_str(),
|
||||
sFileName.c_str(),
|
||||
|
||||
+25
-1
@@ -539,12 +539,27 @@ public:
|
||||
{
|
||||
const float fStartRow = NoteRowToBeat(seg->m_iStartRow);
|
||||
const float fStopLength = seg->m_fStopSeconds;
|
||||
vStops.push_back( ssprintf("%f=%f", fStartRow, fStopLength) );
|
||||
if(!seg->m_bDelay)
|
||||
vStops.push_back( ssprintf("%f=%f", fStartRow, fStopLength) );
|
||||
}
|
||||
|
||||
LuaHelpers::CreateTableFromArray(vStops, L);
|
||||
return 1;
|
||||
}
|
||||
static int GetDelays( T* p, lua_State *L )
|
||||
{
|
||||
vector<RString> vDelays;
|
||||
FOREACH_CONST( StopSegment, p->m_StopSegments, seg )
|
||||
{
|
||||
const float fStartRow = NoteRowToBeat(seg->m_iStartRow);
|
||||
const float fStopLength = seg->m_fStopSeconds;
|
||||
if(seg->m_bDelay)
|
||||
vDelays.push_back( ssprintf("%f=%f", fStartRow, fStopLength) );
|
||||
}
|
||||
|
||||
LuaHelpers::CreateTableFromArray(vDelays, L);
|
||||
return 1;
|
||||
}
|
||||
static int GetBPMs( T* p, lua_State *L )
|
||||
{
|
||||
vector<float> vBPMs;
|
||||
@@ -581,15 +596,24 @@ public:
|
||||
LuaHelpers::CreateTableFromArray(fBPMs, L);
|
||||
return 1;
|
||||
}
|
||||
// formerly in Song.cpp in sm-ssc private beta 1.x:
|
||||
static int GetBPMAtBeat( T* p, lua_State *L ) { lua_pushnumber(L, p->GetBPMAtBeat(FArg(1))); return 1; }
|
||||
static int GetBeatFromElapsedTime( T* p, lua_State *L ) { lua_pushnumber(L, p->GetBeatFromElapsedTime(FArg(1))); return 1; }
|
||||
static int GetElapsedTimeFromBeat( T* p, lua_State *L ) { lua_pushnumber(L, p->GetElapsedTimeFromBeat(FArg(1))); return 1; }
|
||||
|
||||
LunaTimingData()
|
||||
{
|
||||
ADD_METHOD( HasStops );
|
||||
ADD_METHOD( HasBPMChanges );
|
||||
ADD_METHOD( GetStops );
|
||||
ADD_METHOD( GetDelays );
|
||||
ADD_METHOD( GetBPMs );
|
||||
ADD_METHOD( GetBPMsAndTimes );
|
||||
ADD_METHOD( GetActualBPM );
|
||||
// formerly in Song.cpp in sm-ssc private beta 1.x:
|
||||
ADD_METHOD( GetBPMAtBeat );
|
||||
ADD_METHOD( GetBeatFromElapsedTime );
|
||||
ADD_METHOD( GetElapsedTimeFromBeat );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+1
-1
@@ -18,7 +18,7 @@
|
||||
|
||||
|
||||
const int MAX_WHEEL_SOUND_SPEED = 15;
|
||||
AutoScreenMessage( SM_SongChanged ) // TODO: Replace this with a Message and MESSAGEMAN
|
||||
AutoScreenMessage( SM_SongChanged ) // TODO: Replace this with a Message and MESSAGEMAN
|
||||
|
||||
WheelBase::~WheelBase()
|
||||
{
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
#include "RageTimer.h"
|
||||
#include "ThemeManager.h"
|
||||
|
||||
/*
|
||||
* todo: replace this entire thing with a set of AutoActors and a Scroller.
|
||||
/* todo: replace this entire thing with a set of AutoActors and a Scroller.
|
||||
* In reality, everything except the Beginner/Training icon can be replicated
|
||||
* in Lua (in stock StepMania 4), so I'm not sure if we even need this... -aj
|
||||
*/
|
||||
|
||||
@@ -156,7 +156,7 @@ void MemoryCardDriverThreaded_Windows::GetUSBStorageDevices( vector<UsbStorageDe
|
||||
for( size_t i = 0; i < vDevicesOut.size(); ++i )
|
||||
{
|
||||
UsbStorageDevice &usbd = vDevicesOut[i];
|
||||
|
||||
|
||||
// TODO: fill in bus/level/port with this:
|
||||
// http://www.codeproject.com/system/EnumDeviceProperties.asp
|
||||
|
||||
|
||||
@@ -309,6 +309,7 @@ private:
|
||||
|
||||
avcodec::AVPacket m_Packet;
|
||||
int m_iCurrentPacketOffset;
|
||||
float m_fLastFrame;
|
||||
|
||||
/* 0 = no EOF
|
||||
* 1 = EOF from ReadPacket
|
||||
@@ -328,6 +329,8 @@ MovieDecoder_FFMpeg::MovieDecoder_FFMpeg()
|
||||
* they exist. */
|
||||
m_bHadBframes = true;
|
||||
|
||||
m_fLastFrame = 0;
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
@@ -371,6 +374,16 @@ void MovieDecoder_FFMpeg::Init()
|
||||
/* Read until we get a frame, EOF or error. Return -1 on error, 0 on EOF, 1 if we have a frame. */
|
||||
int MovieDecoder_FFMpeg::DecodeFrame( float fTargetTime )
|
||||
{
|
||||
//hack to filter out stuttering
|
||||
if(fTargetTime<m_fLastFrame)
|
||||
{
|
||||
fTargetTime=m_fLastFrame;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fLastFrame=fTargetTime;
|
||||
}
|
||||
|
||||
while( 1 )
|
||||
{
|
||||
int ret = DecodePacket( fTargetTime );
|
||||
|
||||
Reference in New Issue
Block a user