diff --git a/extern/jsoncpp/src/lib_json/json_writer.cpp b/extern/jsoncpp/src/lib_json/json_writer.cpp index 41373250bb..8412670e2f 100644 --- a/extern/jsoncpp/src/lib_json/json_writer.cpp +++ b/extern/jsoncpp/src/lib_json/json_writer.cpp @@ -111,7 +111,7 @@ std::string valueToString( bool value ) std::string valueToQuotedString( const char *value ) { // Not sure how to handle unicode... - if (strpbrk(value, "\"\\\b\f\n\r\t") == NULL && !containsControlCharacter( value )) + if (strpbrk(value, "\"\\\b\f\n\r\t") == nullptr && !containsControlCharacter( value )) return std::string("\"") + value + "\""; // We have to walk value and escape any special characters. // Appending to std::string is not efficient, but this should be rare. @@ -542,7 +542,7 @@ StyledWriter::normalizeEOL( const std::string &text ) // ////////////////////////////////////////////////////////////////// StyledStreamWriter::StyledStreamWriter( std::string indentation ) - : document_(NULL) + : document_(nullptr) , rightMargin_( 74 ) , indentation_( indentation ) { @@ -559,7 +559,7 @@ StyledStreamWriter::write( std::ostream &out, const Value &root ) writeValue( root ); writeCommentAfterValueOnSameLine( root ); *document_ << "\n"; - document_ = NULL; // Forget the stream, for safety. + document_ = nullptr; // Forget the stream, for safety. } diff --git a/src/Actor.cpp b/src/Actor.cpp index fc8689bb57..727dca6e5f 100644 --- a/src/Actor.cpp +++ b/src/Actor.cpp @@ -5,7 +5,6 @@ #include "RageUtil.h" #include "RageMath.h" #include "RageLog.h" -#include "Foreach.h" #include "XmlFile.h" #include "LuaBinding.h" #include "ThemeManager.h" @@ -87,7 +86,7 @@ void Actor::InitState() { this->StopTweening(); - m_pTempState = NULL; + m_pTempState = nullptr; m_baseRotation = RageVector3( 0, 0, 0 ); m_baseScale = RageVector3( 1, 1, 1 ); @@ -162,8 +161,8 @@ Actor::Actor() m_size = RageVector2( 1, 1 ); InitState(); - m_pParent = NULL; - m_FakeParent= NULL; + m_pParent = nullptr; + m_FakeParent= nullptr; m_bFirstUpdate = true; m_tween_uses_effect_delta= false; } @@ -183,8 +182,8 @@ Actor::Actor( const Actor &cpy ): MessageSubscriber( cpy ) { /* Don't copy an Actor in the middle of rendering. */ - ASSERT( cpy.m_pTempState == NULL ); - m_pTempState = NULL; + ASSERT( cpy.m_pTempState == nullptr ); + m_pTempState = nullptr; #define CPY(x) x = cpy.x CPY( m_sName ); @@ -457,7 +456,7 @@ void Actor::Draw() this->SetInternalGlow(last_glow); } this->PreDraw(); - ASSERT( m_pTempState != NULL ); + ASSERT( m_pTempState != nullptr ); if(PartiallyOpaque()) { this->BeginDraw(); @@ -475,16 +474,16 @@ void Actor::Draw() } abort_with_end_draw= true; state->PostDraw(); - state->m_pTempState= NULL; + state->m_pTempState= nullptr; } if(m_FakeParent) { m_FakeParent->EndDraw(); m_FakeParent->PostDraw(); - m_FakeParent->m_pTempState= NULL; + m_FakeParent->m_pTempState= nullptr; } - m_pTempState = NULL; + m_pTempState = nullptr; } void Actor::PostDraw() // reset internal diffuse and glow @@ -1364,7 +1363,7 @@ void Actor::RunCommands( const LuaReference& cmds, const LuaReference *pParamTab this->PushSelf( L ); // 2nd parameter - if( pParamTable == NULL ) + if( pParamTable == nullptr ) lua_pushnil( L ); else pParamTable->PushSelf( L ); @@ -1533,14 +1532,14 @@ void Actor::AddCommand( const RString &sCmdName, apActorCommands apac, bool warn bool Actor::HasCommand( const RString &sCmdName ) const { - return GetCommand(sCmdName) != NULL; + return GetCommand(sCmdName) != nullptr; } const apActorCommands *Actor::GetCommand( const RString &sCommandName ) const { map::const_iterator it = m_mapNameToCommands.find( sCommandName ); if( it == m_mapNameToCommands.end() ) - return NULL; + return nullptr; return &it->second; } @@ -1552,7 +1551,7 @@ void Actor::HandleMessage( const Message &msg ) void Actor::PlayCommandNoRecurse( const Message &msg ) { const apActorCommands *pCmd = GetCommand( msg.GetName() ); - if(pCmd != NULL && (*pCmd)->IsSet() && !(*pCmd)->IsNil()) + if(pCmd != nullptr && (*pCmd)->IsSet() && !(*pCmd)->IsNil()) { RunCommands( *pCmd, &msg.GetParamTable() ); } @@ -1584,7 +1583,7 @@ void Actor::SetParent( Actor *pParent ) Actor::TweenInfo::TweenInfo() { - m_pTween = NULL; + m_pTween = nullptr; } Actor::TweenInfo::~TweenInfo() @@ -1594,14 +1593,14 @@ Actor::TweenInfo::~TweenInfo() Actor::TweenInfo::TweenInfo( const TweenInfo &cpy ) { - m_pTween = NULL; + m_pTween = nullptr; *this = cpy; } Actor::TweenInfo &Actor::TweenInfo::operator=( const TweenInfo &rhs ) { delete m_pTween; - m_pTween = (rhs.m_pTween? rhs.m_pTween->Copy():NULL); + m_pTween = (rhs.m_pTween? rhs.m_pTween->Copy():nullptr); m_fTimeLeftInTween = rhs.m_fTimeLeftInTween; m_fTweenTime = rhs.m_fTweenTime; m_sCommandName = rhs.m_sCommandName; @@ -1680,7 +1679,7 @@ public: COMMON_RETURN_SELF; } ITween *pTween = ITween::CreateFromStack( L, 2 ); - if(pTween != NULL) + if(pTween != nullptr) { p->BeginTweening(fTime, pTween); } @@ -1875,7 +1874,7 @@ public: static int GetCommand( T* p, lua_State *L ) { const apActorCommands *pCommand = p->GetCommand(SArg(1)); - if( pCommand == NULL ) + if( pCommand == nullptr ) lua_pushnil( L ); else (*pCommand)->PushSelf(L); @@ -1933,7 +1932,7 @@ public: static int GetParent( T* p, lua_State *L ) { Actor *pParent = p->GetParent(); - if( pParent == NULL ) + if( pParent == nullptr ) lua_pushnil( L ); else pParent->PushSelf(L); @@ -1942,7 +1941,7 @@ public: static int GetFakeParent(T* p, lua_State *L) { Actor* fake= p->GetFakeParent(); - if(fake == NULL) + if(fake == nullptr) { lua_pushnil(L); } @@ -1956,7 +1955,7 @@ public: { if(lua_isnoneornil(L, 1)) { - p->SetFakeParent(NULL); + p->SetFakeParent(nullptr); } else { diff --git a/src/Actor.h b/src/Actor.h index c6455e979b..50de27d4a3 100644 --- a/src/Actor.h +++ b/src/Actor.h @@ -602,11 +602,11 @@ public: void PlayCommandNoRecurse( const Message &msg ); // Commands by reference - virtual void RunCommands( const LuaReference& cmds, const LuaReference *pParamTable = NULL ); - void RunCommands( const apActorCommands& cmds, const LuaReference *pParamTable = NULL ) { this->RunCommands( *cmds, pParamTable ); } // convenience - virtual void RunCommandsRecursively( const LuaReference& cmds, const LuaReference *pParamTable = NULL ) { RunCommands(cmds, pParamTable); } + virtual void RunCommands( const LuaReference& cmds, const LuaReference *pParamTable = nullptr ); + void RunCommands( const apActorCommands& cmds, const LuaReference *pParamTable = nullptr ) { this->RunCommands( *cmds, pParamTable ); } // convenience + virtual void RunCommandsRecursively( const LuaReference& cmds, const LuaReference *pParamTable = nullptr ) { RunCommands(cmds, pParamTable); } // If we're a leaf, then execute this command. - virtual void RunCommandsOnLeaves( const LuaReference& cmds, const LuaReference *pParamTable = NULL ) { RunCommands(cmds, pParamTable); } + virtual void RunCommandsOnLeaves( const LuaReference& cmds, const LuaReference *pParamTable = nullptr ) { RunCommands(cmds, pParamTable); } // Messages virtual void HandleMessage( const Message &msg ); diff --git a/src/ActorFrame.cpp b/src/ActorFrame.cpp index dd165eac62..c9b62767f1 100644 --- a/src/ActorFrame.cpp +++ b/src/ActorFrame.cpp @@ -9,7 +9,7 @@ #include "ActorUtil.h" #include "RageDisplay.h" #include "ScreenDimensions.h" -#include "Foreach.h" + /* Tricky: We need ActorFrames created in Lua to auto delete their children. * We don't want classes that derive from ActorFrame to auto delete their @@ -82,8 +82,7 @@ ActorFrame::ActorFrame( const ActorFrame &cpy ): void ActorFrame::InitState() { - FOREACH( Actor*, m_SubActors, a ) - (*a)->InitState(); + std::for_each(m_SubActors.begin(), m_SubActors.end(), [](Actor *a) { a->InitState(); }); Actor::InitState(); } @@ -119,7 +118,7 @@ void ActorFrame::LoadChildrenFromNode( const XNode* pNode ) // Load children const XNode* pChildren = pNode->GetChild("children"); bool bArrayOnly = false; - if( pChildren == NULL ) + if( pChildren == nullptr ) { bArrayOnly = true; pChildren = pNode; @@ -146,7 +145,7 @@ void ActorFrame::AddChild( Actor *pActor ) Dialog::OK( ssprintf("Actor \"%s\" adds child \"%s\" more than once", GetLineage().c_str(), pActor->GetName().c_str()) ); #endif - ASSERT( pActor != NULL ); + ASSERT( pActor != nullptr ); ASSERT( (void*)pActor != (void*)0xC0000005 ); m_SubActors.push_back( pActor ); @@ -162,19 +161,18 @@ void ActorFrame::RemoveChild( Actor *pActor ) void ActorFrame::TransferChildren( ActorFrame *pTo ) { - FOREACH( Actor*, m_SubActors, i ) - pTo->AddChild( *i ); + std::for_each(m_SubActors.begin(), m_SubActors.end(), [&](Actor *a) { pTo->AddChild(a); }); RemoveAllChildren(); } Actor* ActorFrame::GetChild( const RString &sName ) { - FOREACH( Actor*, m_SubActors, a ) + for (Actor *a : m_SubActors) { - if( (*a)->GetName() == sName ) - return *a; + if( a->GetName() == sName ) + return a; } - return NULL; + return nullptr; } void ActorFrame::RemoveAllChildren() @@ -374,15 +372,15 @@ static void AddToChildTable(lua_State* L, Actor* a) void ActorFrame::PushChildrenTable( lua_State *L ) { lua_newtable( L ); // stack: all_actors - FOREACH( Actor*, m_SubActors, a ) + for (Actor *a: m_SubActors) { - LuaHelpers::Push( L, (*a)->GetName() ); // stack: all_actors, name + LuaHelpers::Push( L, a->GetName() ); // stack: all_actors, name lua_gettable(L, -2); // stack: all_actors, entry if(lua_isnil(L, -1)) { lua_pop(L, 1); // stack: all_actors - LuaHelpers::Push( L, (*a)->GetName() ); // stack: all_actors, name - (*a)->PushSelf( L ); // stack: all_actors, name, actor + LuaHelpers::Push( L, a->GetName() ); // stack: all_actors, name + a->PushSelf( L ); // stack: all_actors, name, actor lua_rawset( L, -3 ); // stack: all_actors } else @@ -391,14 +389,14 @@ void ActorFrame::PushChildrenTable( lua_State *L ) if(lua_objlen(L, -1) > 0) { // stack: all_actors, table_entry - AddToChildTable(L, *a); // stack: all_actors, table_entry + AddToChildTable(L, a); // stack: all_actors, table_entry lua_pop(L, 1); // stack: all_actors } else { // stack: all_actors, old_entry - CreateChildTable(L, *a); // stack: all_actors, table_entry - LuaHelpers::Push(L, (*a)->GetName()); // stack: all_actors, table_entry, name + CreateChildTable(L, a); // stack: all_actors, table_entry + LuaHelpers::Push(L, a->GetName()); // stack: all_actors, table_entry, name lua_insert(L, -2); // stack: all_actors, name, table_entry lua_rawset(L, -3); // stack: all_actors } @@ -409,20 +407,20 @@ void ActorFrame::PushChildrenTable( lua_State *L ) void ActorFrame::PushChildTable(lua_State* L, const RString &sName) { int found= 0; - FOREACH(Actor*, m_SubActors, a) + for (Actor *a: m_SubActors) { - if((*a)->GetName() == sName) + if(a->GetName() == sName) { switch(found) { case 0: - (*a)->PushSelf(L); + a->PushSelf(L); break; case 1: - CreateChildTable(L, *a); + CreateChildTable(L, a); break; default: - AddToChildTable(L, *a); + AddToChildTable(L, a); break; } ++found; @@ -437,14 +435,14 @@ void ActorFrame::PushChildTable(lua_State* L, const RString &sName) void ActorFrame::PlayCommandOnChildren( const RString &sCommandName, const LuaReference *pParamTable ) { const apActorCommands *pCmd = GetCommand( sCommandName ); - if( pCmd != NULL ) + if( pCmd != nullptr ) RunCommandsOnChildren( *pCmd, pParamTable ); } void ActorFrame::PlayCommandOnLeaves( const RString &sCommandName, const LuaReference *pParamTable ) { const apActorCommands *pCmd = GetCommand( sCommandName ); - if( pCmd != NULL ) + if( pCmd != nullptr ) RunCommandsOnLeaves( **pCmd, pParamTable ); } @@ -720,7 +718,7 @@ public: { // this one is tricky, we need to get an Actor from Lua. Actor *pActor = ActorUtil::MakeActor( SArg(1) ); - if ( pActor == NULL ) + if ( pActor == nullptr ) { lua_pushboolean( L, 0 ); return 1; diff --git a/src/ActorFrame.h b/src/ActorFrame.h index bee6935b22..2d86c64af0 100644 --- a/src/ActorFrame.h +++ b/src/ActorFrame.h @@ -56,13 +56,13 @@ public: virtual void PushSelf( lua_State *L ); void PushChildrenTable( lua_State *L ); void PushChildTable( lua_State *L, const RString &sName ); - void PlayCommandOnChildren( const RString &sCommandName, const LuaReference *pParamTable = NULL ); - void PlayCommandOnLeaves( const RString &sCommandName, const LuaReference *pParamTable = NULL ); + void PlayCommandOnChildren( const RString &sCommandName, const LuaReference *pParamTable = nullptr ); + void PlayCommandOnLeaves( const RString &sCommandName, const LuaReference *pParamTable = nullptr ); - virtual void RunCommandsRecursively( const LuaReference& cmds, const LuaReference *pParamTable = NULL ); - virtual void RunCommandsOnChildren( const LuaReference& cmds, const LuaReference *pParamTable = NULL ); /* but not on self */ - void RunCommandsOnChildren( const apActorCommands& cmds, const LuaReference *pParamTable = NULL ) { this->RunCommandsOnChildren( *cmds, pParamTable ); } // convenience - virtual void RunCommandsOnLeaves( const LuaReference& cmds, const LuaReference *pParamTable = NULL ); /* but not on self */ + virtual void RunCommandsRecursively( const LuaReference& cmds, const LuaReference *pParamTable = nullptr ); + virtual void RunCommandsOnChildren( const LuaReference& cmds, const LuaReference *pParamTable = nullptr ); /* but not on self */ + void RunCommandsOnChildren( const apActorCommands& cmds, const LuaReference *pParamTable = nullptr ) { this->RunCommandsOnChildren( *cmds, pParamTable ); } // convenience + virtual void RunCommandsOnLeaves( const LuaReference& cmds, const LuaReference *pParamTable = nullptr ); /* but not on self */ virtual void UpdateInternal( float fDeltaTime ); virtual void BeginDraw(); @@ -92,8 +92,8 @@ public: virtual float GetTweenTimeLeft() const; virtual void HandleMessage( const Message &msg ); - virtual void RunCommands( const LuaReference& cmds, const LuaReference *pParamTable = NULL ); - void RunCommands( const apActorCommands& cmds, const LuaReference *pParamTable = NULL ) { this->RunCommands( *cmds, pParamTable ); } // convenience + virtual void RunCommands( const LuaReference& cmds, const LuaReference *pParamTable = nullptr ); + void RunCommands( const apActorCommands& cmds, const LuaReference *pParamTable = nullptr ) { this->RunCommands( *cmds, pParamTable ); } // convenience protected: void LoadChildrenFromNode( const XNode* pNode ); diff --git a/src/ActorFrameTexture.cpp b/src/ActorFrameTexture.cpp index 0943843561..8a9578f525 100644 --- a/src/ActorFrameTexture.cpp +++ b/src/ActorFrameTexture.cpp @@ -18,7 +18,7 @@ ActorFrameTexture::ActorFrameTexture() ++i; m_sTextureName = ssprintf( ConvertI64FormatString("ActorFrameTexture %lli"), i ); - m_pRenderTarget = NULL; + m_pRenderTarget = nullptr; } ActorFrameTexture::ActorFrameTexture( const ActorFrameTexture &cpy ): @@ -35,7 +35,7 @@ ActorFrameTexture::~ActorFrameTexture() void ActorFrameTexture::Create() { - if( m_pRenderTarget != NULL ) + if( m_pRenderTarget != nullptr ) { LuaHelpers::ReportScriptError( "Can't Create an already created ActorFrameTexture" ); return; @@ -71,7 +71,7 @@ void ActorFrameTexture::Create() void ActorFrameTexture::DrawPrimitives() { - if( m_pRenderTarget == NULL ) + if( m_pRenderTarget == nullptr ) return; m_pRenderTarget->BeginRenderingTo( m_bPreserveTexture ); @@ -97,7 +97,7 @@ public: static int GetTexture( T* p, lua_State *L ) { RageTexture *pTexture = p->GetTexture(); - if( pTexture == NULL ) + if( pTexture == nullptr ) { lua_pushnil(L); } diff --git a/src/ActorMultiTexture.cpp b/src/ActorMultiTexture.cpp index 01e4e2d958..3fd83fd236 100644 --- a/src/ActorMultiTexture.cpp +++ b/src/ActorMultiTexture.cpp @@ -9,7 +9,7 @@ #include "RageTexture.h" #include "RageUtil.h" #include "ActorUtil.h" -#include "Foreach.h" + #include "LuaBinding.h" #include "LuaManager.h" @@ -35,8 +35,8 @@ ActorMultiTexture::ActorMultiTexture( const ActorMultiTexture &cpy ): CPY( m_aTextureUnits ); #undef CPY - FOREACH( TextureUnitState, m_aTextureUnits, tex ) - tex->m_pTexture = TEXTUREMAN->CopyTexture( tex->m_pTexture ); + for (TextureUnitState &tex : m_aTextureUnits) + tex.m_pTexture = TEXTUREMAN->CopyTexture( tex.m_pTexture ); } void ActorMultiTexture::SetTextureCoords( const RectF &r ) @@ -58,14 +58,14 @@ void ActorMultiTexture::SetSizeFromTexture( RageTexture *pTexture ) void ActorMultiTexture::ClearTextures() { - FOREACH( TextureUnitState, m_aTextureUnits, tex ) - TEXTUREMAN->UnloadTexture( tex->m_pTexture ); + for (TextureUnitState &tex : m_aTextureUnits) + TEXTUREMAN->UnloadTexture( tex.m_pTexture ); m_aTextureUnits.clear(); } int ActorMultiTexture::AddTexture( RageTexture *pTexture ) { - if( pTexture == NULL ) + if( pTexture == nullptr ) { LOG->Warn( "Can't add nil texture to ActorMultiTexture" ); return m_aTextureUnits.size(); diff --git a/src/ActorMultiTexture.h b/src/ActorMultiTexture.h index 6f4d793361..5b3c34333e 100644 --- a/src/ActorMultiTexture.h +++ b/src/ActorMultiTexture.h @@ -1,73 +1,73 @@ -/** @brief ActorMultiTexture - A texture created from multiple textures. */ - -#ifndef ACTOR_MULTI_TEXTURE_H -#define ACTOR_MULTI_TEXTURE_H - -#include "Actor.h" -#include "RageDisplay.h" - -class RageTexture; - -class ActorMultiTexture: public Actor -{ -public: - ActorMultiTexture(); - ActorMultiTexture( const ActorMultiTexture &cpy ); - virtual ~ActorMultiTexture(); - - void LoadFromNode( const XNode* pNode ); - virtual ActorMultiTexture *Copy() const; - - virtual bool EarlyAbortDraw() const; - virtual void DrawPrimitives(); - - void ClearTextures(); - int AddTexture( RageTexture *pTexture ); - void SetTextureMode( int iIndex, TextureMode tm ); - - void SetSizeFromTexture( RageTexture *pTexture ); - void SetTextureCoords( const RectF &r ); - void SetEffectMode( EffectMode em ) { m_EffectMode = em; } - - virtual void PushSelf( lua_State *L ); - -private: - EffectMode m_EffectMode; - struct TextureUnitState - { - TextureUnitState(): m_pTexture(NULL), m_TextureMode(TextureMode_Modulate) {} - RageTexture *m_pTexture; - TextureMode m_TextureMode; - }; - vector m_aTextureUnits; - RectF m_Rect; -}; - -#endif - -/** - * @file - * @author Chris Danford (c) 2001-2004 - * @section LICENSE - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +/** @brief ActorMultiTexture - A texture created from multiple textures. */ + +#ifndef ACTOR_MULTI_TEXTURE_H +#define ACTOR_MULTI_TEXTURE_H + +#include "Actor.h" +#include "RageDisplay.h" + +class RageTexture; + +class ActorMultiTexture: public Actor +{ +public: + ActorMultiTexture(); + ActorMultiTexture( const ActorMultiTexture &cpy ); + virtual ~ActorMultiTexture(); + + void LoadFromNode( const XNode* pNode ); + virtual ActorMultiTexture *Copy() const; + + virtual bool EarlyAbortDraw() const; + virtual void DrawPrimitives(); + + void ClearTextures(); + int AddTexture( RageTexture *pTexture ); + void SetTextureMode( int iIndex, TextureMode tm ); + + void SetSizeFromTexture( RageTexture *pTexture ); + void SetTextureCoords( const RectF &r ); + void SetEffectMode( EffectMode em ) { m_EffectMode = em; } + + virtual void PushSelf( lua_State *L ); + +private: + EffectMode m_EffectMode; + struct TextureUnitState + { + TextureUnitState(): m_pTexture(nullptr), m_TextureMode(TextureMode_Modulate) {} + RageTexture *m_pTexture; + TextureMode m_TextureMode; + }; + vector m_aTextureUnits; + RectF m_Rect; +}; + +#endif + +/** + * @file + * @author Chris Danford (c) 2001-2004 + * @section LICENSE + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/ActorMultiVertex.cpp b/src/ActorMultiVertex.cpp index 183c80bd24..2508892188 100644 --- a/src/ActorMultiVertex.cpp +++ b/src/ActorMultiVertex.cpp @@ -10,7 +10,6 @@ #include "RageTimer.h" #include "RageUtil.h" #include "ActorUtil.h" -#include "Foreach.h" #include "LuaBinding.h" #include "LuaManager.h" #include "LocalizedString.h" @@ -100,13 +99,13 @@ ActorMultiVertex::ActorMultiVertex( const ActorMultiVertex &cpy ): CPY(_states); #undef CPY - if( cpy._Texture != NULL ) + if( cpy._Texture != nullptr ) { _Texture = TEXTUREMAN->CopyTexture( cpy._Texture ); } else { - _Texture = NULL; + _Texture = nullptr; } } @@ -137,7 +136,7 @@ void ActorMultiVertex::SetTexture( RageTexture *Texture ) void ActorMultiVertex::LoadFromTexture( RageTextureID ID ) { - RageTexture *Texture = NULL; + RageTexture *Texture = nullptr; if( _Texture && _Texture->GetID() == ID ) { return; @@ -148,10 +147,10 @@ void ActorMultiVertex::LoadFromTexture( RageTextureID ID ) void ActorMultiVertex::UnloadTexture() { - if( _Texture != NULL ) + if( _Texture != nullptr ) { TEXTUREMAN->UnloadTexture( _Texture ); - _Texture = NULL; + _Texture = nullptr; } } @@ -409,20 +408,18 @@ void ActorMultiVertex::SetState(size_t i) void ActorMultiVertex::SetAllStateDelays(float delay) { - FOREACH(State, _states, s) + for (State &s : _states) { - s->delay= delay; + s.delay= delay; } } float ActorMultiVertex::GetAnimationLengthSeconds() const { - float tot= 0.0f; - FOREACH_CONST(State, _states, s) - { - tot+= s->delay; - } - return tot; + auto calcDelay = [](float total, State const &s) { + return total + s.delay; + }; + return std::accumulate(_states.begin(), _states.end(), 0.f, calcDelay); } void ActorMultiVertex::SetSecondsIntoAnimation(float seconds) @@ -958,7 +955,7 @@ public: static void FillStateFromLua(lua_State *L, ActorMultiVertex::State& state, RageTexture* tex, int index) { - if(tex == NULL) + if(tex == nullptr) { luaL_error(L, "The texture must be set before adding states."); } @@ -1027,7 +1024,7 @@ public: static int GetStateData(T* p, lua_State *L) { RageTexture* tex= p->GetTexture(); - if(tex == NULL) + if(tex == nullptr) { luaL_error(L, "The texture must be set before adding states."); } @@ -1065,7 +1062,7 @@ public: luaL_error(L, "The states must be inside a table."); } RageTexture* tex= p->GetTexture(); - if(tex == NULL) + if(tex == nullptr) { luaL_error(L, "The texture must be set before adding states."); } @@ -1148,7 +1145,7 @@ public: static int GetTexture(T* p, lua_State *L) { RageTexture *texture = p->GetTexture(); - if(texture != NULL) + if(texture != nullptr) { texture->PushSelf(L); } diff --git a/src/ActorProxy.cpp b/src/ActorProxy.cpp index 1b23e7e912..7ff4aaba46 100644 --- a/src/ActorProxy.cpp +++ b/src/ActorProxy.cpp @@ -6,17 +6,17 @@ REGISTER_ACTOR_CLASS( ActorProxy ); ActorProxy::ActorProxy() { - m_pActorTarget = NULL; + m_pActorTarget = nullptr; } bool ActorProxy::EarlyAbortDraw() const { - return m_pActorTarget == NULL || Actor::EarlyAbortDraw(); + return m_pActorTarget == nullptr || Actor::EarlyAbortDraw(); } void ActorProxy::DrawPrimitives() { - if( m_pActorTarget != NULL ) + if( m_pActorTarget != nullptr ) { bool bVisible = m_pActorTarget->GetVisible(); m_pActorTarget->SetVisible( true ); @@ -47,7 +47,7 @@ public: static int GetTarget( T* p, lua_State *L ) { Actor *pTarget = p->GetTarget(); - if( pTarget != NULL ) + if( pTarget != nullptr ) pTarget->PushSelf( L ); else lua_pushnil( L ); diff --git a/src/ActorScroller.cpp b/src/ActorScroller.cpp index 87730ed89d..794f40372b 100644 --- a/src/ActorScroller.cpp +++ b/src/ActorScroller.cpp @@ -1,6 +1,6 @@ #include "global.h" #include "ActorScroller.h" -#include "Foreach.h" + #include "RageUtil.h" #include "XmlFile.h" #include "arch/Dialog/Dialog.h" @@ -312,8 +312,8 @@ void ActorScroller::PositionItemsAndDrawPrimitives( bool bDrawPrimitives ) if( m_bDrawByZPosition ) { ActorUtil::SortByZPosition( subs ); - FOREACH( Actor*, subs, a ) - (*a)->Draw(); + for (Actor *a : subs) + a->Draw(); } } diff --git a/src/ActorUtil.cpp b/src/ActorUtil.cpp index 70c2aa891f..4470a1eea5 100644 --- a/src/ActorUtil.cpp +++ b/src/ActorUtil.cpp @@ -10,7 +10,6 @@ #include "XmlFileUtil.h" #include "IniFile.h" #include "LuaManager.h" -#include "Foreach.h" #include "Song.h" #include "Course.h" #include "GameState.h" @@ -19,7 +18,7 @@ // Actor registration -static map *g_pmapRegistrees = NULL; +static map *g_pmapRegistrees = nullptr; static bool IsRegistered( const RString& sClassName ) { @@ -28,7 +27,7 @@ static bool IsRegistered( const RString& sClassName ) void ActorUtil::Register( const RString& sClassName, CreateActorFn pfn ) { - if( g_pmapRegistrees == NULL ) + if( g_pmapRegistrees == nullptr ) g_pmapRegistrees = new map; map::iterator iter = g_pmapRegistrees->find( sClassName ); @@ -123,7 +122,7 @@ namespace // The non-legacy LoadFromNode has already checked the Class and // Type attributes. - if (pActor->GetAttr("Text") != NULL) + if (pActor->GetAttr("Text") != nullptr) return "BitmapText"; RString sFile; @@ -172,7 +171,7 @@ namespace Actor *ActorUtil::LoadFromNode( const XNode* _pNode, Actor *pParentActor ) { - ASSERT( _pNode != NULL ); + ASSERT( _pNode != nullptr ); XNode node = *_pNode; @@ -182,7 +181,7 @@ Actor *ActorUtil::LoadFromNode( const XNode* _pNode, Actor *pParentActor ) { bool bCond; if( node.GetAttrValue("Condition", bCond) && !bCond ) - return NULL; + return nullptr; } RString sClass; @@ -190,7 +189,7 @@ Actor *ActorUtil::LoadFromNode( const XNode* _pNode, Actor *pParentActor ) if( !bHasClass ) bHasClass = node.GetAttrValue( "Type", sClass ); - bool bLegacy = (node.GetAttr( "_LegacyXml" ) != NULL); + bool bLegacy = (node.GetAttr( "_LegacyXml" ) != nullptr); if( !bHasClass && bLegacy ) sClass = GetLegacyActorClass( &node ); @@ -209,8 +208,8 @@ Actor *ActorUtil::LoadFromNode( const XNode* _pNode, Actor *pParentActor ) if (ResolvePath(sPath, GetWhere(&node))) { Actor *pNewActor = MakeActor(sPath, pParentActor); - if (pNewActor == NULL) - return NULL; + if (pNewActor == nullptr) + return nullptr; if (pParentActor) pNewActor->SetParent(pParentActor); pNewActor->LoadFromNode(&node); @@ -241,7 +240,7 @@ namespace { RString sScript; if( !GetFileContents(sFile, sScript) ) - return NULL; + return nullptr; Lua *L = LUA->Get(); @@ -251,10 +250,10 @@ namespace LUA->Release( L ); sError = ssprintf( "Lua runtime error: %s", sError.c_str() ); LuaHelpers::ReportScriptError(sError); - return NULL; + return nullptr; } - XNode *pRet = NULL; + XNode *pRet = nullptr; if( ActorUtil::LoadTableFromStackShowErrors(L) ) pRet = XmlFileUtil::XNodeFromTable( L ); @@ -295,7 +294,7 @@ bool ActorUtil::LoadTableFromStackShowErrors( Lua *L ) return true; } -// NOTE: This function can return NULL if the actor should not be displayed. +// NOTE: This function can return nullptr if the actor should not be displayed. // Callers should be aware of this and handle it appropriately. Actor* ActorUtil::MakeActor( const RString &sPath_, Actor *pParentActor ) { @@ -306,8 +305,8 @@ Actor* ActorUtil::MakeActor( const RString &sPath_, Actor *pParentActor ) { case FT_Lua: { - auto_ptr pNode( LoadXNodeFromLuaShowErrors(sPath) ); - if( pNode.get() == NULL ) + unique_ptr pNode( LoadXNodeFromLuaShowErrors(sPath) ); + if( pNode.get() == nullptr ) { // XNode will warn about the error return new Actor; @@ -475,9 +474,8 @@ void ActorUtil::LoadAllCommandsFromName( Actor& actor, const RString &sMetricsGr set vsValueNames; THEME->GetMetricsThatBeginWith( sMetricsGroup, sName, vsValueNames ); - FOREACHS_CONST( RString, vsValueNames, v ) + for (RString const & sv : vsValueNames) { - const RString &sv = *v; static const RString sEnding = "Command"; if( EndsWith(sv,sEnding) ) { @@ -680,7 +678,7 @@ namespace LIST_METHOD( LoadAllCommands ), LIST_METHOD( LoadAllCommandsFromName ), LIST_METHOD( LoadAllCommandsAndSetXY ), - { NULL, NULL } + { nullptr, nullptr } }; } diff --git a/src/ActorUtil.h b/src/ActorUtil.h index d6c6e8d33e..16163588cf 100644 --- a/src/ActorUtil.h +++ b/src/ActorUtil.h @@ -115,8 +115,8 @@ namespace ActorUtil inline void LoadAllCommandsAndSetXYAndOnCommand( Actor* pActor, const RString &sMetricsGroup ) { if(pActor) LoadAllCommandsAndSetXYAndOnCommand( *pActor, sMetricsGroup ); } // Return a Sprite, BitmapText, or Model depending on the file type - Actor* LoadFromNode( const XNode* pNode, Actor *pParentActor = NULL ); - Actor* MakeActor( const RString &sPath, Actor *pParentActor = NULL ); + Actor* LoadFromNode( const XNode* pNode, Actor *pParentActor = nullptr ); + Actor* MakeActor( const RString &sPath, Actor *pParentActor = nullptr ); RString GetSourcePath( const XNode *pNode ); RString GetWhere( const XNode *pNode ); bool GetAttrPath( const XNode *pNode, const RString &sName, RString &sOut, bool optional= false ); diff --git a/src/AdjustSync.cpp b/src/AdjustSync.cpp index 7258f0dcbb..b217d6ece9 100644 --- a/src/AdjustSync.cpp +++ b/src/AdjustSync.cpp @@ -41,7 +41,7 @@ #include "LocalizedString.h" #include "PrefsManager.h" #include "ScreenManager.h" -#include "Foreach.h" + vector AdjustSync::s_vpTimingDataOriginal; float AdjustSync::s_fGlobalOffsetSecondsOriginal = 0.0f; @@ -61,9 +61,9 @@ void AdjustSync::ResetOriginalSyncData() { s_vpTimingDataOriginal.push_back(GAMESTATE->m_pCurSong->m_SongTiming); const vector& vpSteps = GAMESTATE->m_pCurSong->GetAllSteps(); - FOREACH( Steps*, const_cast&>(vpSteps), s ) + for (Steps const *s : vpSteps) { - s_vpTimingDataOriginal.push_back((*s)->m_Timing); + s_vpTimingDataOriginal.push_back(s->m_Timing); } } else @@ -128,9 +128,9 @@ void AdjustSync::RevertSyncChanges() unsigned location = 1; const vector& vpSteps = GAMESTATE->m_pCurSong->GetAllSteps(); - FOREACH( Steps*, const_cast&>(vpSteps), s ) + for (Steps *s : vpSteps) { - (*s)->m_Timing = s_vpTimingDataOriginal[location]; + s->m_Timing = s_vpTimingDataOriginal[location]; location++; } @@ -199,13 +199,13 @@ void AdjustSync::AutosyncOffset() { GAMESTATE->m_pCurSong->m_SongTiming.m_fBeat0OffsetInSeconds += mean; const vector& vpSteps = GAMESTATE->m_pCurSong->GetAllSteps(); - FOREACH( Steps*, const_cast&>(vpSteps), s ) + for (Steps *s : vpSteps) { // Empty TimingData means it's inherited // from the song and is already changed. - if( (*s)->m_Timing.empty() ) + if( s->m_Timing.empty() ) continue; - (*s)->m_Timing.m_fBeat0OffsetInSeconds += mean; + s->m_Timing.m_fBeat0OffsetInSeconds += mean; } break; } diff --git a/src/AnnouncerManager.cpp b/src/AnnouncerManager.cpp index 7d5576e2ec..f116257673 100644 --- a/src/AnnouncerManager.cpp +++ b/src/AnnouncerManager.cpp @@ -5,7 +5,7 @@ #include "RageFile.h" #include -AnnouncerManager* ANNOUNCER = NULL; // global and accessible from anywhere in our program +AnnouncerManager* ANNOUNCER = nullptr; // global and accessible from anywhere in our program const RString EMPTY_ANNOUNCER_NAME = "Empty"; @@ -101,7 +101,7 @@ static const char *aliases[][2] = { { "gameplay combo 900", "gameplay 900 combo" }, { "gameplay combo 1000", "gameplay 1000 combo" }, - { NULL, NULL } + { nullptr, nullptr } }; /* Find an announcer directory with sounds in it. First search sFolderName, @@ -120,7 +120,7 @@ RString AnnouncerManager::GetPathTo( RString sAnnouncerName, RString sFolderName /* Search for the announcer folder in the list of aliases. */ int i; - for(i = 0; aliases[i][0] != NULL; ++i) + for(i = 0; aliases[i][0] != nullptr; ++i) { if(!sFolderName.EqualsNoCase(aliases[i][0])) continue; /* no match */ diff --git a/src/ArrowEffects.cpp b/src/ArrowEffects.cpp index 40aa8650bd..e5938722f4 100644 --- a/src/ArrowEffects.cpp +++ b/src/ArrowEffects.cpp @@ -78,7 +78,7 @@ static ThemeMetric BEAT_Z_PI_HEIGHT( "ArrowEffects", "BeatZPIHeight" ); static ThemeMetric TINY_PERCENT_BASE( "ArrowEffects", "TinyPercentBase" ); static ThemeMetric TINY_PERCENT_GATE( "ArrowEffects", "TinyPercentGate" ); -static const PlayerOptions* curr_options= NULL; +static const PlayerOptions* curr_options= nullptr; float ArrowGetPercentVisible(float fYPosWithoutReverse, int iCol, float fYOffset); @@ -1653,7 +1653,7 @@ namespace LIST_METHOD( NeedZBuffer ), LIST_METHOD( GetZoom ), LIST_METHOD( GetFrameWidthScale ), - { NULL, NULL } + { nullptr, nullptr } }; } diff --git a/src/Attack.cpp b/src/Attack.cpp index 7062b303cf..3e6cec20fa 100644 --- a/src/Attack.cpp +++ b/src/Attack.cpp @@ -3,13 +3,13 @@ #include "GameState.h" #include "RageUtil.h" #include "Song.h" -#include "Foreach.h" + #include "PlayerOptions.h" #include "PlayerState.h" void Attack::GetAttackBeats( const Song *pSong, float &fStartBeat, float &fEndBeat ) const { - ASSERT( pSong != NULL ); + ASSERT( pSong != nullptr ); ASSERT_M( fStartSecond >= 0, ssprintf("StartSecond: %f",fStartSecond) ); const TimingData &timing = pSong->m_SongTiming; @@ -22,7 +22,7 @@ void Attack::GetAttackBeats( const Song *pSong, float &fStartBeat, float &fEndBe * prevent popping when the attack has note modifers. */ void Attack::GetRealtimeAttackBeats( const Song *pSong, const PlayerState* pPlayerState, float &fStartBeat, float &fEndBeat ) const { - ASSERT( pSong != NULL ); + ASSERT( pSong != nullptr ); if( fStartSecond >= 0 ) { @@ -30,7 +30,7 @@ void Attack::GetRealtimeAttackBeats( const Song *pSong, const PlayerState* pPlay return; } - ASSERT( pPlayerState != NULL ); + ASSERT( pPlayerState != nullptr ); /* If reasonable, push the attack forward 8 beats so that notes on screen don't change suddenly. */ fStartBeat = min( GAMESTATE->m_Position.m_fSongBeat+8, pPlayerState->m_fLastDrawnBeat ); @@ -91,32 +91,27 @@ int Attack::GetNumAttacks() const bool AttackArray::ContainsTransformOrTurn() const { - FOREACH_CONST( Attack, *this, a ) - { - if( a->ContainsTransformOrTurn() ) - return true; - } - return false; + return std::any_of((*this).begin(), (*this).end(), [](Attack const &a) { return a.ContainsTransformOrTurn(); }); } vector AttackArray::ToVectorString() const { vector ret; - FOREACH_CONST( Attack, *this, a ) + for (Attack const &a : *this) { ret.push_back(ssprintf("TIME=%f:LEN=%f:MODS=%s", - a->fStartSecond, - a->fSecsRemaining, - a->sModifiers.c_str())); + a.fStartSecond, + a.fSecsRemaining, + a.sModifiers.c_str())); } return ret; } void AttackArray::UpdateStartTimes(float delta) { - FOREACH(Attack, *this, a) + for (Attack &a : *this) { - a->fStartSecond += delta; + a.fStartSecond += delta; } } diff --git a/src/AttackDisplay.cpp b/src/AttackDisplay.cpp index 81ea6d37a0..db286c9f2a 100644 --- a/src/AttackDisplay.cpp +++ b/src/AttackDisplay.cpp @@ -1,138 +1,138 @@ -#include "global.h" -#include "AttackDisplay.h" -#include "ThemeManager.h" -#include "GameState.h" -#include "ActorUtil.h" -#include "Character.h" -#include "RageLog.h" -#include -#include "PlayerState.h" - - -RString GetAttackPieceName( const RString &sAttack ) -{ - RString ret = ssprintf( "attack %s", sAttack.c_str() ); - - /* 1.5x -> 1_5x. If we pass a period to THEME->GetPathTo, it'll think - * we're looking for a specific file and not search. */ - ret.Replace( ".", "_" ); - - return ret; -} - -AttackDisplay::AttackDisplay() -{ - if( GAMESTATE->m_PlayMode != PLAY_MODE_BATTLE && - GAMESTATE->m_PlayMode != PLAY_MODE_RAVE ) - return; - - m_sprAttack.SetDiffuseAlpha( 0 ); // invisible - this->AddChild( &m_sprAttack ); -} - -void AttackDisplay::Init( const PlayerState* pPlayerState ) -{ - m_pPlayerState = pPlayerState; - - // TODO: Remove use of PlayerNumber. - PlayerNumber pn = m_pPlayerState->m_PlayerNumber; - m_sprAttack.SetName( ssprintf("TextP%d",pn+1) ); - - if( GAMESTATE->m_PlayMode != PLAY_MODE_BATTLE && - GAMESTATE->m_PlayMode != PLAY_MODE_RAVE ) - return; - - set attacks; - for( int al=0; alm_pCurCharacters[pn]; - ASSERT( ch != NULL ); - const RString* asAttacks = ch->m_sAttacks[al]; - for( int att = 0; att < NUM_ATTACKS_PER_LEVEL; ++att ) - attacks.insert( asAttacks[att] ); - } - - for( set::const_iterator it = attacks.begin(); it != attacks.end(); ++it ) - { - const RString path = THEME->GetPathG( "AttackDisplay", GetAttackPieceName( *it ), true ); - if( path == "" ) - { - LOG->Trace( "Couldn't find \"%s\"", GetAttackPieceName( *it ).c_str() ); - continue; - } - - m_TexturePreload.Load( path ); - } -} - - -void AttackDisplay::Update( float fDelta ) -{ - ActorFrame::Update( fDelta ); - - if( GAMESTATE->m_PlayMode != PLAY_MODE_BATTLE && - GAMESTATE->m_PlayMode != PLAY_MODE_RAVE ) - return; - - if( !m_pPlayerState->m_bAttackBeganThisUpdate ) - return; - // don't handle this again - - for( unsigned s=0; sm_ActiveAttacks.size(); s++ ) - { - const Attack& attack = m_pPlayerState->m_ActiveAttacks[s]; - - if( attack.fStartSecond >= 0 ) - continue; /* hasn't started yet */ - - if( attack.fSecsRemaining <= 0 ) - continue; /* ended already */ - - if( attack.IsBlank() ) - continue; - - SetAttack( attack.sModifiers ); - break; - } -} - -void AttackDisplay::SetAttack( const RString &sText ) -{ - const RString path = THEME->GetPathG( "AttackDisplay", GetAttackPieceName(sText), true ); - if( path == "" ) - return; - - m_sprAttack.SetDiffuseAlpha( 1 ); - m_sprAttack.Load( path ); - - // TODO: Remove use of PlayerNumber. - PlayerNumber pn = m_pPlayerState->m_PlayerNumber; - - const RString sName = ssprintf( "%sP%i", sText.c_str(), pn+1 ); - m_sprAttack.RunCommands( THEME->GetMetricA("AttackDisplay", sName + "OnCommand") ); -} - -/* - * (c) 2003 Chris Danford - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "AttackDisplay.h" +#include "ThemeManager.h" +#include "GameState.h" +#include "ActorUtil.h" +#include "Character.h" +#include "RageLog.h" +#include +#include "PlayerState.h" + + +RString GetAttackPieceName( const RString &sAttack ) +{ + RString ret = ssprintf( "attack %s", sAttack.c_str() ); + + /* 1.5x -> 1_5x. If we pass a period to THEME->GetPathTo, it'll think + * we're looking for a specific file and not search. */ + ret.Replace( ".", "_" ); + + return ret; +} + +AttackDisplay::AttackDisplay() +{ + if( GAMESTATE->m_PlayMode != PLAY_MODE_BATTLE && + GAMESTATE->m_PlayMode != PLAY_MODE_RAVE ) + return; + + m_sprAttack.SetDiffuseAlpha( 0 ); // invisible + this->AddChild( &m_sprAttack ); +} + +void AttackDisplay::Init( const PlayerState* pPlayerState ) +{ + m_pPlayerState = pPlayerState; + + // TODO: Remove use of PlayerNumber. + PlayerNumber pn = m_pPlayerState->m_PlayerNumber; + m_sprAttack.SetName( ssprintf("TextP%d",pn+1) ); + + if( GAMESTATE->m_PlayMode != PLAY_MODE_BATTLE && + GAMESTATE->m_PlayMode != PLAY_MODE_RAVE ) + return; + + set attacks; + for( int al=0; alm_pCurCharacters[pn]; + ASSERT( ch != nullptr ); + const RString* asAttacks = ch->m_sAttacks[al]; + for( int att = 0; att < NUM_ATTACKS_PER_LEVEL; ++att ) + attacks.insert( asAttacks[att] ); + } + + for( set::const_iterator it = attacks.begin(); it != attacks.end(); ++it ) + { + const RString path = THEME->GetPathG( "AttackDisplay", GetAttackPieceName( *it ), true ); + if( path == "" ) + { + LOG->Trace( "Couldn't find \"%s\"", GetAttackPieceName( *it ).c_str() ); + continue; + } + + m_TexturePreload.Load( path ); + } +} + + +void AttackDisplay::Update( float fDelta ) +{ + ActorFrame::Update( fDelta ); + + if( GAMESTATE->m_PlayMode != PLAY_MODE_BATTLE && + GAMESTATE->m_PlayMode != PLAY_MODE_RAVE ) + return; + + if( !m_pPlayerState->m_bAttackBeganThisUpdate ) + return; + // don't handle this again + + for( unsigned s=0; sm_ActiveAttacks.size(); s++ ) + { + const Attack& attack = m_pPlayerState->m_ActiveAttacks[s]; + + if( attack.fStartSecond >= 0 ) + continue; /* hasn't started yet */ + + if( attack.fSecsRemaining <= 0 ) + continue; /* ended already */ + + if( attack.IsBlank() ) + continue; + + SetAttack( attack.sModifiers ); + break; + } +} + +void AttackDisplay::SetAttack( const RString &sText ) +{ + const RString path = THEME->GetPathG( "AttackDisplay", GetAttackPieceName(sText), true ); + if( path == "" ) + return; + + m_sprAttack.SetDiffuseAlpha( 1 ); + m_sprAttack.Load( path ); + + // TODO: Remove use of PlayerNumber. + PlayerNumber pn = m_pPlayerState->m_PlayerNumber; + + const RString sName = ssprintf( "%sP%i", sText.c_str(), pn+1 ); + m_sprAttack.RunCommands( THEME->GetMetricA("AttackDisplay", sName + "OnCommand") ); +} + +/* + * (c) 2003 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/AutoActor.cpp b/src/AutoActor.cpp index b3620f96c5..78e76b1544 100644 --- a/src/AutoActor.cpp +++ b/src/AutoActor.cpp @@ -6,17 +6,17 @@ void AutoActor::Unload() { - if(m_pActor != NULL) + if(m_pActor != nullptr) { delete m_pActor; } - m_pActor=NULL; + m_pActor=nullptr; } AutoActor::AutoActor( const AutoActor &cpy ) { - if( cpy.m_pActor == NULL ) - m_pActor = NULL; + if( cpy.m_pActor == nullptr ) + m_pActor = nullptr; else m_pActor = cpy.m_pActor->Copy(); } @@ -25,8 +25,8 @@ AutoActor &AutoActor::operator=( const AutoActor &cpy ) { Unload(); - if( cpy.m_pActor == NULL ) - m_pActor = NULL; + if( cpy.m_pActor == nullptr ) + m_pActor = nullptr; else m_pActor = cpy.m_pActor->Copy(); return *this; @@ -43,8 +43,8 @@ void AutoActor::Load( const RString &sPath ) Unload(); m_pActor = ActorUtil::MakeActor( sPath ); - // If a Condition is false, MakeActor will return NULL. - if( m_pActor == NULL ) + // If a Condition is false, MakeActor will return nullptr. + if( m_pActor == nullptr ) m_pActor = new Actor; } diff --git a/src/AutoActor.h b/src/AutoActor.h index 3ee95bec09..d9bc295c5c 100644 --- a/src/AutoActor.h +++ b/src/AutoActor.h @@ -12,7 +12,7 @@ class XNode; class AutoActor { public: - AutoActor(): m_pActor(NULL) {} + AutoActor(): m_pActor(nullptr) {} ~AutoActor() { Unload(); } AutoActor( const AutoActor &cpy ); AutoActor &operator =( const AutoActor &cpy ); @@ -24,7 +24,7 @@ public: /** * @brief Determine if this actor is presently loaded. * @return true if it is loaded, or false otherwise. */ - bool IsLoaded() const { return m_pActor != NULL; } + bool IsLoaded() const { return m_pActor != nullptr; } void Load( Actor *pActor ); // transfer pointer void Load( const RString &sPath ); void LoadB( const RString &sMetricsGroup, const RString &sElement ); // load a background and set up LuaThreadVariables for recursive loading diff --git a/src/AutoKeysounds.cpp b/src/AutoKeysounds.cpp index d7a8d2618b..6910b242ce 100644 --- a/src/AutoKeysounds.cpp +++ b/src/AutoKeysounds.cpp @@ -30,7 +30,7 @@ #include "RageSoundManager.h" #include "RageLog.h" #include "RageSoundReader_FileReader.h" -#include "Foreach.h" + void AutoKeysounds::Load( PlayerNumber pn, const NoteData& ndAutoKeysoundsOnly ) { @@ -107,9 +107,9 @@ void AutoKeysounds::LoadTracks( const Song *pSong, RageSoundReader *&pShared, Ra // two-track sound. //bool bTwoPlayers = GAMESTATE->GetNumPlayersEnabled() == 2; - pPlayer1 = NULL; - pPlayer2 = NULL; - pShared = NULL; + pPlayer1 = nullptr; + pPlayer2 = nullptr; + pShared = nullptr; vector vsMusicFile; const RString sMusicPath = GAMESTATE->m_pCurSteps[GAMESTATE->GetMasterPlayerNumber()]->GetMusicPath(); @@ -127,10 +127,10 @@ void AutoKeysounds::LoadTracks( const Song *pSong, RageSoundReader *&pShared, Ra vector vpSounds; - FOREACH( RString, vsMusicFile, s ) + for (RString const &s : vsMusicFile) { RString sError; - RageSoundReader *pSongReader = RageSoundReader_FileReader::OpenFile( *s, sError ); + RageSoundReader *pSongReader = RageSoundReader_FileReader::OpenFile( s, sError ); vpSounds.push_back( pSongReader ); } @@ -147,8 +147,8 @@ void AutoKeysounds::LoadTracks( const Song *pSong, RageSoundReader *&pShared, Ra { RageSoundReader_Merge *pMerge = new RageSoundReader_Merge; - FOREACH( RageSoundReader *, vpSounds, so ) - pMerge->AddSound( *so ); + for (RageSoundReader *so : vpSounds) + pMerge->AddSound( so ); pMerge->Finish( SOUNDMAN->GetDriverSampleRate() ); RageSoundReader *pSongReader = pMerge; @@ -263,14 +263,14 @@ void AutoKeysounds::FinishLoading() delete pChain; } } - ASSERT_M( m_pSharedSound != NULL, ssprintf("No keysounds were loaded for the song %s!", pSong->m_sMainTitle.c_str() )); + ASSERT_M( m_pSharedSound != nullptr, ssprintf("No keysounds were loaded for the song %s!", pSong->m_sMainTitle.c_str() )); m_pSharedSound = new RageSoundReader_PitchChange( m_pSharedSound ); m_pSharedSound = new RageSoundReader_PostBuffering( m_pSharedSound ); m_pSharedSound = new RageSoundReader_Pan( m_pSharedSound ); apSounds.push_back( m_pSharedSound ); - if( m_pPlayerSounds[0] != NULL ) + if( m_pPlayerSounds[0] != nullptr ) { m_pPlayerSounds[0] = new RageSoundReader_PitchChange( m_pPlayerSounds[0] ); m_pPlayerSounds[0] = new RageSoundReader_PostBuffering( m_pPlayerSounds[0] ); @@ -278,7 +278,7 @@ void AutoKeysounds::FinishLoading() apSounds.push_back( m_pPlayerSounds[0] ); } - if( m_pPlayerSounds[1] != NULL ) + if( m_pPlayerSounds[1] != nullptr ) { m_pPlayerSounds[1] = new RageSoundReader_PitchChange( m_pPlayerSounds[1] ); m_pPlayerSounds[1] = new RageSoundReader_PostBuffering( m_pPlayerSounds[1] ); @@ -293,8 +293,8 @@ void AutoKeysounds::FinishLoading() { RageSoundReader_Merge *pMerge = new RageSoundReader_Merge; - FOREACH( RageSoundReader *, apSounds, ps ) - pMerge->AddSound( *ps ); + for (RageSoundReader *ps : apSounds) + pMerge->AddSound( ps ); pMerge->Finish( SOUNDMAN->GetDriverSampleRate() ); diff --git a/src/AutoKeysounds.h b/src/AutoKeysounds.h index 554088aa53..ca6e14647c 100644 --- a/src/AutoKeysounds.h +++ b/src/AutoKeysounds.h @@ -18,7 +18,7 @@ public: void FinishLoading(); RageSound *GetSound() { return &m_sSound; } RageSoundReader *GetSharedSound() { return m_pSharedSound; } - RageSoundReader *GetPlayerSound( PlayerNumber pn ) { if( pn == PLAYER_INVALID ) return NULL; return m_pPlayerSounds[pn]; } + RageSoundReader *GetPlayerSound( PlayerNumber pn ) { if( pn == PLAYER_INVALID ) return nullptr; return m_pPlayerSounds[pn]; } protected: void LoadAutoplaySoundsInto( RageSoundReader_Chain *pChain ); diff --git a/src/BGAnimation.cpp b/src/BGAnimation.cpp index 66530cc350..57166cf59f 100644 --- a/src/BGAnimation.cpp +++ b/src/BGAnimation.cpp @@ -1,204 +1,203 @@ -#include "global.h" -#include "BGAnimation.h" -#include "IniFile.h" -#include "BGAnimationLayer.h" -#include "RageUtil.h" -#include "ActorUtil.h" -#include "Foreach.h" -#include "LuaManager.h" -#include "PrefsManager.h" - -REGISTER_ACTOR_CLASS(BGAnimation); - -BGAnimation::BGAnimation() -{ -} - -BGAnimation::~BGAnimation() -{ - DeleteAllChildren(); -} - -static bool CompareLayerNames( const RString& s1, const RString& s2 ) -{ - int i1, i2; - int ret; - - ret = sscanf( s1, "Layer%d", &i1 ); - ASSERT( ret == 1 ); - ret = sscanf( s2, "Layer%d", &i2 ); - ASSERT( ret == 1 ); - return i1 < i2; -} - -void BGAnimation::AddLayersFromAniDir( const RString &_sAniDir, const XNode *pNode ) -{ - const RString& sAniDir = _sAniDir; - - { - vector vsLayerNames; - FOREACH_CONST_Child( pNode, pLayer ) - { - if( strncmp(pLayer->GetName(), "Layer", 5) == 0 ) - vsLayerNames.push_back( pLayer->GetName() ); - } - - sort( vsLayerNames.begin(), vsLayerNames.end(), CompareLayerNames ); - - - FOREACH_CONST( RString, vsLayerNames, s ) - { - const RString &sLayer = *s; - const XNode* pKey = pNode->GetChild( sLayer ); - ASSERT( pKey != NULL ); - - RString sImportDir; - if( pKey->GetAttrValue("Import", sImportDir) ) - { - bool bCond; - if( pKey->GetAttrValue("Condition",bCond) && !bCond ) - continue; - - // import a whole BGAnimation - sImportDir = sAniDir + sImportDir; - CollapsePath( sImportDir ); - - if( sImportDir.Right(1) != "/" ) - sImportDir += "/"; - - ASSERT_M( IsADirectory(sImportDir), sImportDir + " isn't a directory" ); - - RString sPathToIni = sImportDir + "BGAnimation.ini"; - - IniFile ini2; - ini2.ReadFile( sPathToIni ); - - AddLayersFromAniDir( sImportDir, &ini2 ); - } - else - { - // import as a single layer - BGAnimationLayer* bgLayer = new BGAnimationLayer; - bgLayer->LoadFromNode( pKey ); - this->AddChild( bgLayer ); - } - } - } -} - -void BGAnimation::LoadFromAniDir( const RString &_sAniDir ) -{ - DeleteAllChildren(); - - if( _sAniDir.empty() ) - return; - - RString sAniDir = _sAniDir; - if( sAniDir.Right(1) != "/" ) - sAniDir += "/"; - - ASSERT_M( IsADirectory(sAniDir), sAniDir + " isn't a directory" ); - - RString sPathToIni = sAniDir + "BGAnimation.ini"; - - if( DoesFileExist(sPathToIni) ) - { - if( PREFSMAN->m_bQuirksMode ) - { - // This is a 3.9-style BGAnimation (using .ini) - IniFile ini; - ini.ReadFile( sPathToIni ); - - AddLayersFromAniDir( sAniDir, &ini ); // TODO: Check for circular load - - XNode* pBGAnimation = ini.GetChild( "BGAnimation" ); - XNode dummy( "BGAnimation" ); - if( pBGAnimation == NULL ) - pBGAnimation = &dummy; - - LoadFromNode( pBGAnimation ); - } - else // We don't officially support .ini files anymore. - { - XNode dummy( "BGAnimation" ); - XNode *pBG = &dummy; - LoadFromNode( pBG ); - } - } - else - { - // This is an 3.0 and before-style BGAnimation (not using .ini) - - // loading a directory of layers - vector asImagePaths; - ASSERT( sAniDir != "" ); - - GetDirListing( sAniDir+"*.png", asImagePaths, false, true ); - GetDirListing( sAniDir+"*.jpg", asImagePaths, false, true ); - GetDirListing( sAniDir+"*.jpeg", asImagePaths, false, true ); - GetDirListing( sAniDir+"*.gif", asImagePaths, false, true ); - GetDirListing( sAniDir+"*.ogv", asImagePaths, false, true ); - GetDirListing( sAniDir+"*.avi", asImagePaths, false, true ); - GetDirListing( sAniDir+"*.mpg", asImagePaths, false, true ); - GetDirListing( sAniDir+"*.mpeg", asImagePaths, false, true ); - - SortRStringArray( asImagePaths ); - - for( unsigned i=0; iLoadFromAniLayerFile( asImagePaths[i] ); - AddChild( pLayer ); - } - } -} - -void BGAnimation::LoadFromNode( const XNode* pNode ) -{ - RString sDir; - if( pNode->GetAttrValue("AniDir", sDir) ) - LoadFromAniDir( sDir ); - - ActorFrame::LoadFromNode( pNode ); - - /* Backwards-compatibility: if a "LengthSeconds" value is present, create a dummy - * actor that sleeps for the given length of time. This will extend GetTweenTimeLeft. */ - float fLengthSeconds = 0; - if( pNode->GetAttrValue( "LengthSeconds", fLengthSeconds ) ) - { - Actor *pActor = new Actor; - pActor->SetName( "BGAnimation dummy" ); - pActor->SetVisible( false ); - apActorCommands ap = ActorUtil::ParseActorCommands( ssprintf("sleep,%f",fLengthSeconds) ); - pActor->AddCommand( "On", ap ); - AddChild( pActor ); - } -} - -/* - * (c) 2001-2004 Ben Nordstrom, Chris Danford - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "BGAnimation.h" +#include "IniFile.h" +#include "BGAnimationLayer.h" +#include "RageUtil.h" +#include "ActorUtil.h" + +#include "LuaManager.h" +#include "PrefsManager.h" + +REGISTER_ACTOR_CLASS(BGAnimation); + +BGAnimation::BGAnimation() +{ +} + +BGAnimation::~BGAnimation() +{ + DeleteAllChildren(); +} + +static bool CompareLayerNames( const RString& s1, const RString& s2 ) +{ + int i1, i2; + int ret; + + ret = sscanf( s1, "Layer%d", &i1 ); + ASSERT( ret == 1 ); + ret = sscanf( s2, "Layer%d", &i2 ); + ASSERT( ret == 1 ); + return i1 < i2; +} + +void BGAnimation::AddLayersFromAniDir( const RString &_sAniDir, const XNode *pNode ) +{ + const RString& sAniDir = _sAniDir; + + { + vector vsLayerNames; + FOREACH_CONST_Child( pNode, pLayer ) + { + if( strncmp(pLayer->GetName(), "Layer", 5) == 0 ) + vsLayerNames.push_back( pLayer->GetName() ); + } + + sort( vsLayerNames.begin(), vsLayerNames.end(), CompareLayerNames ); + + + for (RString const &sLayer : vsLayerNames) + { + const XNode* pKey = pNode->GetChild( sLayer ); + ASSERT( pKey != nullptr ); + + RString sImportDir; + if( pKey->GetAttrValue("Import", sImportDir) ) + { + bool bCond; + if( pKey->GetAttrValue("Condition",bCond) && !bCond ) + continue; + + // import a whole BGAnimation + sImportDir = sAniDir + sImportDir; + CollapsePath( sImportDir ); + + if( sImportDir.Right(1) != "/" ) + sImportDir += "/"; + + ASSERT_M( IsADirectory(sImportDir), sImportDir + " isn't a directory" ); + + RString sPathToIni = sImportDir + "BGAnimation.ini"; + + IniFile ini2; + ini2.ReadFile( sPathToIni ); + + AddLayersFromAniDir( sImportDir, &ini2 ); + } + else + { + // import as a single layer + BGAnimationLayer* bgLayer = new BGAnimationLayer; + bgLayer->LoadFromNode( pKey ); + this->AddChild( bgLayer ); + } + } + } +} + +void BGAnimation::LoadFromAniDir( const RString &_sAniDir ) +{ + DeleteAllChildren(); + + if( _sAniDir.empty() ) + return; + + RString sAniDir = _sAniDir; + if( sAniDir.Right(1) != "/" ) + sAniDir += "/"; + + ASSERT_M( IsADirectory(sAniDir), sAniDir + " isn't a directory" ); + + RString sPathToIni = sAniDir + "BGAnimation.ini"; + + if( DoesFileExist(sPathToIni) ) + { + if( PREFSMAN->m_bQuirksMode ) + { + // This is a 3.9-style BGAnimation (using .ini) + IniFile ini; + ini.ReadFile( sPathToIni ); + + AddLayersFromAniDir( sAniDir, &ini ); // TODO: Check for circular load + + XNode* pBGAnimation = ini.GetChild( "BGAnimation" ); + XNode dummy( "BGAnimation" ); + if( pBGAnimation == nullptr ) + pBGAnimation = &dummy; + + LoadFromNode( pBGAnimation ); + } + else // We don't officially support .ini files anymore. + { + XNode dummy( "BGAnimation" ); + XNode *pBG = &dummy; + LoadFromNode( pBG ); + } + } + else + { + // This is an 3.0 and before-style BGAnimation (not using .ini) + + // loading a directory of layers + vector asImagePaths; + ASSERT( sAniDir != "" ); + + GetDirListing( sAniDir+"*.png", asImagePaths, false, true ); + GetDirListing( sAniDir+"*.jpg", asImagePaths, false, true ); + GetDirListing( sAniDir+"*.jpeg", asImagePaths, false, true ); + GetDirListing( sAniDir+"*.gif", asImagePaths, false, true ); + GetDirListing( sAniDir+"*.ogv", asImagePaths, false, true ); + GetDirListing( sAniDir+"*.avi", asImagePaths, false, true ); + GetDirListing( sAniDir+"*.mpg", asImagePaths, false, true ); + GetDirListing( sAniDir+"*.mpeg", asImagePaths, false, true ); + + SortRStringArray( asImagePaths ); + + for( unsigned i=0; iLoadFromAniLayerFile( asImagePaths[i] ); + AddChild( pLayer ); + } + } +} + +void BGAnimation::LoadFromNode( const XNode* pNode ) +{ + RString sDir; + if( pNode->GetAttrValue("AniDir", sDir) ) + LoadFromAniDir( sDir ); + + ActorFrame::LoadFromNode( pNode ); + + /* Backwards-compatibility: if a "LengthSeconds" value is present, create a dummy + * actor that sleeps for the given length of time. This will extend GetTweenTimeLeft. */ + float fLengthSeconds = 0; + if( pNode->GetAttrValue( "LengthSeconds", fLengthSeconds ) ) + { + Actor *pActor = new Actor; + pActor->SetName( "BGAnimation dummy" ); + pActor->SetVisible( false ); + apActorCommands ap = ActorUtil::ParseActorCommands( ssprintf("sleep,%f",fLengthSeconds) ); + pActor->AddCommand( "On", ap ); + AddChild( pActor ); + } +} + +/* + * (c) 2001-2004 Ben Nordstrom, Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/BGAnimationLayer.cpp b/src/BGAnimationLayer.cpp index a30e9a880c..8928688a74 100644 --- a/src/BGAnimationLayer.cpp +++ b/src/BGAnimationLayer.cpp @@ -402,16 +402,16 @@ void BGAnimationLayer::LoadFromNode( const XNode* pNode ) { m_Type = TYPE_TILES; } - else if( StringToInt(type) == 1 ) + else if( std::stoi(type) == 1 ) { m_Type = TYPE_SPRITE; bStretch = true; } - else if( StringToInt(type) == 2 ) + else if( std::stoi(type) == 2 ) { m_Type = TYPE_PARTICLES; } - else if( StringToInt(type) == 3 ) + else if( std::stoi(type) == 3 ) { m_Type = TYPE_TILES; } @@ -482,7 +482,7 @@ void BGAnimationLayer::LoadFromNode( const XNode* pNode ) for( int i=0; iAddChild( pActor ); pActor->SetXY( randomf(float(FullScreenRectF.left),float(FullScreenRectF.right)), @@ -520,7 +520,7 @@ void BGAnimationLayer::LoadFromNode( const XNode* pNode ) for( unsigned i=0; iAddChild( pSprite ); pSprite->SetTextureWrapping( true ); // gets rid of some "cracks" diff --git a/src/BPMDisplay.cpp b/src/BPMDisplay.cpp index 1f10ccbadc..b0a5415b59 100644 --- a/src/BPMDisplay.cpp +++ b/src/BPMDisplay.cpp @@ -179,7 +179,7 @@ void BPMDisplay::NoBPM() void BPMDisplay::SetBpmFromSong( const Song* pSong ) { - ASSERT( pSong != NULL ); + ASSERT( pSong != nullptr ); switch( pSong->m_DisplayBPMType ) { case DISPLAY_BPM_ACTUAL: @@ -201,7 +201,7 @@ void BPMDisplay::SetBpmFromSong( const Song* pSong ) void BPMDisplay::SetBpmFromSteps( const Steps* pSteps ) { - ASSERT( pSteps != NULL ); + ASSERT( pSteps != nullptr ); DisplayBpms bpms; float fMinBPM, fMaxBPM; pSteps->GetTimingData()->GetActualBPM( fMinBPM, fMaxBPM ); @@ -212,13 +212,13 @@ void BPMDisplay::SetBpmFromSteps( const Steps* pSteps ) void BPMDisplay::SetBpmFromCourse( const Course* pCourse ) { - ASSERT( pCourse != NULL ); - ASSERT( GAMESTATE->GetCurrentStyle(PLAYER_INVALID) != NULL ); + ASSERT( pCourse != nullptr ); + ASSERT( GAMESTATE->GetCurrentStyle(PLAYER_INVALID) != nullptr ); StepsType st = GAMESTATE->GetCurrentStyle(PLAYER_INVALID)->m_StepsType; Trail *pTrail = pCourse->GetTrail( st ); // GetTranslitFullTitle because "Crashinfo.txt is garbled because of the ANSI output as usual." -f - ASSERT_M( pTrail != NULL, ssprintf("Course '%s' has no trail for StepsType '%s'", pCourse->GetTranslitFullTitle().c_str(), StringConversion::ToString(st).c_str() ) ); + ASSERT_M( pTrail != nullptr, ssprintf("Course '%s' has no trail for StepsType '%s'", pCourse->GetTranslitFullTitle().c_str(), StringConversion::ToString(st).c_str() ) ); m_fCycleTime = (float)COURSE_CYCLE_SPEED; @@ -259,7 +259,7 @@ void BPMDisplay::SetFromGameState() } if( GAMESTATE->m_pCurCourse.Get() ) { - if( GAMESTATE->GetCurrentStyle(PLAYER_INVALID) == NULL ) + if( GAMESTATE->GetCurrentStyle(PLAYER_INVALID) == nullptr ) ; // This is true when backing out from ScreenSelectCourse to ScreenTitleMenu. So, don't call SetBpmFromCourse where an assert will fire. else SetBpmFromCourse( GAMESTATE->m_pCurCourse ); diff --git a/src/Background.cpp b/src/Background.cpp index 7e996c5820..03d7b7f2ca 100644 --- a/src/Background.cpp +++ b/src/Background.cpp @@ -151,15 +151,15 @@ static RageColor GetBrightnessColor( float fBrightnessPercent ) BackgroundImpl::BackgroundImpl() { m_bInitted = false; - m_pDancingCharacters = NULL; - m_pSong = NULL; + m_pDancingCharacters = nullptr; + m_pSong = nullptr; } BackgroundImpl::Layer::Layer() { m_iCurBGChangeIndex = -1; - m_pCurrentBGA = NULL; - m_pFadingBGA = NULL; + m_pCurrentBGA = nullptr; + m_pFadingBGA = nullptr; } void BackgroundImpl::Init() @@ -246,20 +246,20 @@ void BackgroundImpl::Unload() { FOREACH_BackgroundLayer( i ) m_Layer[i].Unload(); - m_pSong = NULL; + m_pSong = nullptr; m_fLastMusicSeconds = -9999; m_RandomBGAnimations.clear(); } void BackgroundImpl::Layer::Unload() { - FOREACHM( BackgroundDef, Actor*, m_BGAnimations, iter ) - delete iter->second; + for (std::pair iter : m_BGAnimations) + delete iter.second; m_BGAnimations.clear(); m_aBGChanges.clear(); - m_pCurrentBGA = NULL; - m_pFadingBGA = NULL; + m_pCurrentBGA = nullptr; + m_pFadingBGA = nullptr; m_iCurBGChangeIndex = -1; } @@ -386,7 +386,7 @@ bool BackgroundImpl::Layer::CreateBackground( const Song *pSong, const Backgroun Actor *pActor = ActorUtil::MakeActor( sEffectFile ); - if( pActor == NULL ) + if( pActor == nullptr ) pActor = new Actor; m_BGAnimations[bd] = pActor; @@ -542,10 +542,10 @@ void BackgroundImpl::LoadFromSong( const Song* pSong ) int iSize = min( (int)g_iNumBackgrounds, (int)vsNames.size() ); vsNames.resize( iSize ); - FOREACH_CONST( RString, vsNames, s ) + for (RString const &s : vsNames) { BackgroundDef bd; - bd.m_sFile1 = *s; + bd.m_sFile1 = s; m_RandomBGAnimations.push_back( bd ); } } @@ -574,9 +574,9 @@ void BackgroundImpl::LoadFromSong( const Song* pSong ) Layer &layer = m_Layer[i]; // Load all song-specified backgrounds - FOREACH_CONST( BackgroundChange, pSong->GetBackgroundChanges(i), bgc ) + for (BackgroundChange const &bgc : pSong->GetBackgroundChanges(i)) { - BackgroundChange change = *bgc; + BackgroundChange change = bgc; BackgroundDef &bd = change.m_def; bool bIsAlreadyLoaded = layer.m_BGAnimations.find(bd) != layer.m_BGAnimations.end(); @@ -643,9 +643,9 @@ void BackgroundImpl::LoadFromSong( const Song* pSong ) FOREACH_BackgroundLayer( i ) { Layer &layer = m_Layer[i]; - FOREACH_CONST( BackgroundChange, layer.m_aBGChanges, bgc ) + for (BackgroundChange const &bgc : layer.m_aBGChanges) { - const BackgroundDef &bd = bgc->m_def; + const BackgroundDef &bd = bgc.m_def; if( bd == m_StaticBackgroundDef ) { bStaticBackgroundUsed = true; @@ -765,7 +765,7 @@ void BackgroundImpl::Layer::UpdateCurBGChange( const Song *pSong, float fLastMus if( m_pFadingBGA == m_pCurrentBGA ) { - m_pFadingBGA = NULL; + m_pFadingBGA = nullptr; //LOG->Trace( "bg didn't actually change. Ignoring." ); } else @@ -807,7 +807,7 @@ void BackgroundImpl::Layer::UpdateCurBGChange( const Song *pSong, float fLastMus if( m_pFadingBGA ) { if( m_pFadingBGA->GetTweenTimeLeft() == 0 ) - m_pFadingBGA = NULL; + m_pFadingBGA = nullptr; } /* This is unaffected by the music rate. */ diff --git a/src/BackgroundUtil.cpp b/src/BackgroundUtil.cpp index 18db7382cd..24a5eb4976 100644 --- a/src/BackgroundUtil.cpp +++ b/src/BackgroundUtil.cpp @@ -2,7 +2,7 @@ #include "BackgroundUtil.h" #include "RageUtil.h" #include "Song.h" -#include "Foreach.h" + #include "IniFile.h" #include "RageLog.h" #include @@ -148,8 +148,8 @@ void BackgroundUtil::GetBackgroundEffects( const RString &_sName, vector vsMatches; - FOREACH_CONST( RString, vsPathsOut, s ) + for (RString const &s : vsPathsOut) { - RString sBasename = Basename( *s ); + RString sBasename = Basename( s ); bool bFound = ssFileNameWhitelist.find(sBasename) != ssFileNameWhitelist.end(); if( bFound ) - vsMatches.push_back(*s); + vsMatches.push_back(s); } // If we found any that match the whitelist, use only them. // If none match the whitelist, ignore the whitelist.. @@ -359,9 +359,9 @@ void BackgroundUtil::GetGlobalRandomMovies( GetGlobalRandomMoviePaths( pSong, sMatch, vsPathsOut, bTryInsideOfSongGroupAndGenreFirst, bTryInsideOfSongGroupFirst ); - FOREACH_CONST( RString, vsPathsOut, s ) + for (RString const &s : vsPathsOut) { - RString sName = s->Right( s->size() - RANDOMMOVIES_DIR.size() - 1 ); + RString sName = s.Right( s.size() - RANDOMMOVIES_DIR.size() - 1 ); vsNamesOut.push_back( sName ); } StripCvsAndSvn( vsPathsOut, vsNamesOut ); diff --git a/src/Banner.cpp b/src/Banner.cpp index 02349609ef..0240145ada 100644 --- a/src/Banner.cpp +++ b/src/Banner.cpp @@ -107,9 +107,9 @@ void Banner::SetScrolling( bool bScroll, float Percent) Update(0); } -void Banner::LoadFromSong( Song* pSong ) // NULL means no song +void Banner::LoadFromSong( Song* pSong ) // nullptr means no song { - if( pSong == NULL ) LoadFallback(); + if( pSong == nullptr ) LoadFallback(); else if( pSong->HasBanner() ) Load( pSong->GetBannerPath() ); else LoadFallback(); @@ -130,9 +130,9 @@ void Banner::LoadFromSongGroup( RString sSongGroup ) m_bScrolling = false; } -void Banner::LoadFromCourse( const Course *pCourse ) // NULL means no course +void Banner::LoadFromCourse( const Course *pCourse ) // nullptr means no course { - if( pCourse == NULL ) LoadFallback(); + if( pCourse == nullptr ) LoadFallback(); else if( pCourse->GetBannerPath() != "" ) Load( pCourse->GetBannerPath() ); else LoadCourseFallback(); @@ -141,7 +141,7 @@ void Banner::LoadFromCourse( const Course *pCourse ) // NULL means no course void Banner::LoadCardFromCharacter( const Character *pCharacter ) { - if( pCharacter == NULL ) LoadFallback(); + if( pCharacter == nullptr ) LoadFallback(); else if( pCharacter->GetCardPath() != "" ) Load( pCharacter->GetCardPath() ); else LoadFallback(); @@ -150,7 +150,7 @@ void Banner::LoadCardFromCharacter( const Character *pCharacter ) void Banner::LoadIconFromCharacter( const Character *pCharacter ) { - if( pCharacter == NULL ) LoadFallbackCharacterIcon(); + if( pCharacter == nullptr ) LoadFallbackCharacterIcon(); else if( pCharacter->GetIconPath() != "" ) Load( pCharacter->GetIconPath(), false ); else LoadFallbackCharacterIcon(); @@ -159,7 +159,7 @@ void Banner::LoadIconFromCharacter( const Character *pCharacter ) void Banner::LoadBannerFromUnlockEntry( const UnlockEntry* pUE ) { - if( pUE == NULL ) + if( pUE == nullptr ) LoadFallback(); else { @@ -171,7 +171,7 @@ void Banner::LoadBannerFromUnlockEntry( const UnlockEntry* pUE ) void Banner::LoadBackgroundFromUnlockEntry( const UnlockEntry* pUE ) { - if( pUE == NULL ) + if( pUE == nullptr ) LoadFallback(); else { @@ -224,7 +224,7 @@ void Banner::LoadRandom() void Banner::LoadFromSortOrder( SortOrder so ) { - // TODO: See if the check for NULL/PREFERRED(?) is needed. + // TODO: See if the check for nullptr/PREFERRED(?) is needed. if( so == SortOrder_Invalid ) { LoadFallback(); @@ -248,13 +248,13 @@ public: static int ScaleToClipped( T* p, lua_State *L ) { p->ScaleToClipped(FArg(1),FArg(2)); COMMON_RETURN_SELF; } static int LoadFromSong( T* p, lua_State *L ) { - if( lua_isnil(L,1) ) { p->LoadFromSong( NULL ); } + if( lua_isnil(L,1) ) { p->LoadFromSong(nullptr); } else { Song *pS = Luna::check(L,1); p->LoadFromSong( pS ); } COMMON_RETURN_SELF; } static int LoadFromCourse( T* p, lua_State *L ) { - if( lua_isnil(L,1) ) { p->LoadFromCourse( NULL ); } + if( lua_isnil(L,1) ) { p->LoadFromCourse(nullptr); } else { Course *pC = Luna::check(L,1); p->LoadFromCourse( pC ); } COMMON_RETURN_SELF; } @@ -265,25 +265,25 @@ public: } static int LoadIconFromCharacter( T* p, lua_State *L ) { - if( lua_isnil(L,1) ) { p->LoadIconFromCharacter( NULL ); } + if( lua_isnil(L,1) ) { p->LoadIconFromCharacter(nullptr); } else { Character *pC = Luna::check(L,1); p->LoadIconFromCharacter( pC ); } COMMON_RETURN_SELF; } static int LoadCardFromCharacter( T* p, lua_State *L ) { - if( lua_isnil(L,1) ) { p->LoadIconFromCharacter( NULL ); } + if( lua_isnil(L,1) ) { p->LoadIconFromCharacter(nullptr); } else { Character *pC = Luna::check(L,1); p->LoadIconFromCharacter( pC ); } COMMON_RETURN_SELF; } static int LoadBannerFromUnlockEntry( T* p, lua_State *L ) { - if( lua_isnil(L,1) ) { p->LoadBannerFromUnlockEntry( NULL ); } + if( lua_isnil(L,1) ) { p->LoadBannerFromUnlockEntry(nullptr); } else { UnlockEntry *pUE = Luna::check(L,1); p->LoadBannerFromUnlockEntry( pUE ); } COMMON_RETURN_SELF; } static int LoadBackgroundFromUnlockEntry( T* p, lua_State *L ) { - if( lua_isnil(L,1) ) { p->LoadBackgroundFromUnlockEntry( NULL ); } + if( lua_isnil(L,1) ) { p->LoadBackgroundFromUnlockEntry(nullptr); } else { UnlockEntry *pUE = Luna::check(L,1); p->LoadBackgroundFromUnlockEntry( pUE ); } COMMON_RETURN_SELF; } diff --git a/src/Banner.h b/src/Banner.h index 527eff5ac0..e24030ac10 100644 --- a/src/Banner.h +++ b/src/Banner.h @@ -27,7 +27,7 @@ public: /** * @brief Attempt to load the banner from a song. - * @param pSong the song in question. If NULL, there is no song. + * @param pSong the song in question. If nullptr, there is no song. */ void LoadFromSong( Song* pSong ); void LoadMode(); diff --git a/src/BeginnerHelper.cpp b/src/BeginnerHelper.cpp index f43bf118c1..2fcc92faec 100644 --- a/src/BeginnerHelper.cpp +++ b/src/BeginnerHelper.cpp @@ -149,7 +149,7 @@ bool BeginnerHelper::Init( int iDancePadType ) // Load character data const Character *Character = GAMESTATE->m_pCurCharacters[pl]; - ASSERT( Character != NULL ); + ASSERT( Character != nullptr ); m_pDancer[pl]->SetName( ssprintf("PlayerP%d",pl+1) ); @@ -204,7 +204,7 @@ void BeginnerHelper::AddPlayer( PlayerNumber pn, const NoteData &ns ) return; const Character *Character = GAMESTATE->m_pCurCharacters[pn]; - ASSERT( Character != NULL ); + ASSERT( Character != nullptr ); if( !DoesFileExist(Character->GetModelPath()) ) return; @@ -219,7 +219,7 @@ bool BeginnerHelper::CanUse(PlayerNumber pn) return false; // This does not pass PLAYER_INVALID to GetCurrentStyle because that would - // only check the first non-NULL style. Both styles need to be checked. -Kyz + // only check the first non-nullptr style. Both styles need to be checked. -Kyz if(pn == PLAYER_INVALID) { return GAMESTATE->GetCurrentStyle(PLAYER_1)->m_bCanUseBeginnerHelper || diff --git a/src/BeginnerHelper.h b/src/BeginnerHelper.h index 38bb8b144a..ffd47239ac 100644 --- a/src/BeginnerHelper.h +++ b/src/BeginnerHelper.h @@ -29,13 +29,13 @@ public: protected: void Step( PlayerNumber pn, int CSTEP ); - NoteData m_NoteData[NUM_PLAYERS]; - bool m_bPlayerEnabled[NUM_PLAYERS]; - Model *m_pDancer[NUM_PLAYERS]; + std::array m_NoteData; + std::array m_bPlayerEnabled; + std::array m_pDancer; Model *m_pDancePad; Sprite m_sFlash; AutoActor m_sBackground; - Sprite m_sStepCircle[NUM_PLAYERS][4]; // More memory, but much easier to manage + std::array, NUM_PLAYERS> m_sStepCircle; // More memory, but much easier to manage. int m_iLastRowChecked; int m_iLastRowFlashed; diff --git a/src/BitmapText.cpp b/src/BitmapText.cpp index 3f5ec8e3b5..61fe813597 100644 --- a/src/BitmapText.cpp +++ b/src/BitmapText.cpp @@ -9,7 +9,7 @@ #include "Font.h" #include "ActorUtil.h" #include "LuaBinding.h" -#include "Foreach.h" + REGISTER_ACTOR_CLASS( BitmapText ); @@ -42,7 +42,7 @@ BitmapText::BitmapText() } iReloadCounter++; - m_pFont = NULL; + m_pFont = nullptr; m_bUppercase = false; m_bRainbowScroll = false; @@ -102,10 +102,10 @@ BitmapText & BitmapText::operator=(const BitmapText &cpy) if( m_pFont ) FONT->UnloadFont( m_pFont ); - if( cpy.m_pFont != NULL ) + if( cpy.m_pFont != nullptr ) m_pFont = FONT->CopyFont( cpy.m_pFont ); else - m_pFont = NULL; + m_pFont = nullptr; return *this; } @@ -113,7 +113,7 @@ BitmapText & BitmapText::operator=(const BitmapText &cpy) BitmapText::BitmapText( const BitmapText &cpy ): Actor( cpy ) { - m_pFont = NULL; + m_pFont = nullptr; *this = cpy; } @@ -212,7 +212,7 @@ bool BitmapText::LoadFromFont( const RString& sFontFilePath ) if( m_pFont ) { FONT->UnloadFont( m_pFont ); - m_pFont = NULL; + m_pFont = nullptr; } m_pFont = FONT->LoadFont( sFontFilePath ); @@ -231,7 +231,7 @@ bool BitmapText::LoadFromTextureAndChars( const RString& sTexturePath, const RSt if( m_pFont ) { FONT->UnloadFont( m_pFont ); - m_pFont = NULL; + m_pFont = nullptr; } m_pFont = FONT->LoadFont( sTexturePath, sChars ); @@ -244,7 +244,7 @@ bool BitmapText::LoadFromTextureAndChars( const RString& sTexturePath, const RSt void BitmapText::BuildChars() { // If we don't have a font yet, we'll do this when it loads. - if( m_pFont == NULL ) + if( m_pFont == nullptr ) return; // calculate line lengths and widths @@ -456,7 +456,7 @@ void BitmapText::DrawChars( bool bUseStrokeTexture ) * in sAlternateText, too, just use sText. */ void BitmapText::SetText( const RString& _sText, const RString& _sAlternateText, int iWrapWidthPixels ) { - ASSERT( m_pFont != NULL ); + ASSERT( m_pFont != nullptr ); RString sNewText = StringWillUseAlternate(_sText,_sAlternateText) ? _sAlternateText : _sText; @@ -624,7 +624,7 @@ void BitmapText::UpdateBaseZoom() bool BitmapText::StringWillUseAlternate( const RString& sText, const RString& sAlternateText ) const { - ASSERT( m_pFont != NULL ); + ASSERT( m_pFont != nullptr ); // Can't use the alternate if there isn't one. if( !sAlternateText.size() ) @@ -856,7 +856,7 @@ void BitmapText::SetHorizAlign( float f ) void BitmapText::SetWrapWidthPixels( int iWrapWidthPixels ) { - ASSERT( m_pFont != NULL ); // always load a font first + ASSERT( m_pFont != nullptr ); // always load a font first if( m_iWrapWidthPixels == iWrapWidthPixels ) return; m_iWrapWidthPixels = iWrapWidthPixels; @@ -878,9 +878,9 @@ void BitmapText::AddAttribute( size_t iPos, const Attribute &attr ) int iLines = 0; size_t iAdjustedPos = iPos; - FOREACH_CONST( wstring, m_wTextLines, line ) + for (wstring const & line : m_wTextLines) { - size_t length = line->length(); + size_t length = line.length(); if( length >= iAdjustedPos ) break; iAdjustedPos -= length; diff --git a/src/Bookkeeper.cpp b/src/Bookkeeper.cpp index ec383184ee..94a68acc9b 100644 --- a/src/Bookkeeper.cpp +++ b/src/Bookkeeper.cpp @@ -12,7 +12,7 @@ #include "SpecialFiles.h" #include -Bookkeeper* BOOKKEEPER = NULL; // global and accessible from anywhere in our program +Bookkeeper* BOOKKEEPER = nullptr; // global and accessible from anywhere in our program static const RString COINS_DAT = "Save/Coins.xml"; @@ -67,7 +67,7 @@ void Bookkeeper::LoadFromNode( const XNode *pNode ) } const XNode *pData = pNode->GetChild( "Data" ); - if( pData == NULL ) + if( pData == nullptr ) { LOG->Warn( "Error loading bookkeeping: Data node missing" ); return; @@ -146,14 +146,14 @@ void Bookkeeper::WriteToDisk() return; } - auto_ptr xml( CreateNode() ); + std::unique_ptr xml( CreateNode() ); XmlFileUtil::SaveToFile( xml.get(), f ); } void Bookkeeper::CoinInserted() { Date d; - d.Set( time(NULL) ); + d.Set( time(nullptr) ); ++m_mapCoinsForHour[d]; } @@ -199,7 +199,7 @@ int Bookkeeper::GetCoinsTotal() const void Bookkeeper::GetCoinsLastDays( int coins[NUM_LAST_DAYS] ) const { - time_t lOldTime = time(NULL); + time_t lOldTime = time(nullptr); tm time; localtime_r( &lOldTime, &time ); @@ -215,7 +215,7 @@ void Bookkeeper::GetCoinsLastDays( int coins[NUM_LAST_DAYS] ) const void Bookkeeper::GetCoinsLastWeeks( int coins[NUM_LAST_WEEKS] ) const { - time_t lOldTime = time(NULL); + time_t lOldTime = time(nullptr); tm time; localtime_r( &lOldTime, &time ); diff --git a/src/CMakeData-data.cmake b/src/CMakeData-data.cmake index dee6d8d691..210397503b 100644 --- a/src/CMakeData-data.cmake +++ b/src/CMakeData-data.cmake @@ -231,7 +231,6 @@ list(APPEND SM_DATA_REST_HPP "Difficulty.h" "EnumHelper.h" "FileDownload.h" - "Foreach.h" "Game.h" "GameCommand.h" "GameConstantsAndTypes.h" diff --git a/src/Character.h b/src/Character.h index d8c7f9fba2..5d5724a233 100644 --- a/src/Character.h +++ b/src/Character.h @@ -40,7 +40,7 @@ public: void PushSelf( Lua *L ); // smart accessor - const RString &GetDisplayName() { return !m_sDisplayName.empty() ? m_sDisplayName : m_sCharacterID; } + const RString &GetDisplayName() const { return !m_sDisplayName.empty() ? m_sDisplayName : m_sCharacterID; } RString m_sCharDir; RString m_sCharacterID; diff --git a/src/CharacterManager.cpp b/src/CharacterManager.cpp index 03df847012..87e5eada46 100644 --- a/src/CharacterManager.cpp +++ b/src/CharacterManager.cpp @@ -2,12 +2,12 @@ #include "CharacterManager.h" #include "Character.h" #include "GameState.h" -#include "Foreach.h" + #include "LuaManager.h" #define CHARACTERS_DIR "/Characters/" -CharacterManager* CHARMAN = NULL; // global object accessible from anywhere in the program +CharacterManager* CHARMAN = nullptr; // global object accessible from anywhere in the program CharacterManager::CharacterManager() { @@ -82,27 +82,27 @@ Character* CharacterManager::GetRandomCharacter() Character* CharacterManager::GetDefaultCharacter() { - for( unsigned i=0; iIsDefaultCharacter() ) - return m_pCharacters[i]; + if( c->IsDefaultCharacter() ) + return c; } /* We always have the default character. */ FAIL_M("There must be a default character available!"); - return NULL; + return nullptr; } void CharacterManager::DemandGraphics() { - FOREACH( Character*, m_pCharacters, c ) - (*c)->DemandGraphics(); + for (Character *c : m_pCharacters) + c->DemandGraphics(); } void CharacterManager::UndemandGraphics() { - FOREACH( Character*, m_pCharacters, c ) - (*c)->UndemandGraphics(); + for (Character *c : m_pCharacters) + c->UndemandGraphics(); } Character* CharacterManager::GetCharacterFromID( RString sCharacterID ) @@ -113,7 +113,7 @@ Character* CharacterManager::GetCharacterFromID( RString sCharacterID ) return m_pCharacters[i]; } - return NULL; + return nullptr; } @@ -127,7 +127,7 @@ public: static int GetCharacter( T* p, lua_State *L ) { Character *pCharacter = p->GetCharacterFromID(SArg(1)); - if( pCharacter != NULL ) + if( pCharacter != nullptr ) pCharacter->PushSelf( L ); else lua_pushnil( L ); @@ -137,7 +137,7 @@ public: static int GetRandomCharacter( T* p, lua_State *L ) { Character *pCharacter = p->GetRandomCharacter(); - if( pCharacter != NULL ) + if( pCharacter != nullptr ) pCharacter->PushSelf( L ); else lua_pushnil( L ); diff --git a/src/CombinedLifeMeterTug.h b/src/CombinedLifeMeterTug.h index 5b7f7fa62a..453691a0a5 100644 --- a/src/CombinedLifeMeterTug.h +++ b/src/CombinedLifeMeterTug.h @@ -3,6 +3,7 @@ #include "CombinedLifeMeter.h" #include "MeterDisplay.h" +#include /** @brief Dance Magic-like tug-o-war life meter. */ class CombinedLifeMeterTug : public CombinedLifeMeter @@ -19,7 +20,7 @@ public: protected: - MeterDisplay m_Stream[NUM_PLAYERS]; + std::array m_Stream; AutoActor m_sprSeparator; AutoActor m_sprFrame; }; diff --git a/src/ComboGraph.cpp b/src/ComboGraph.cpp index df441e716a..d743607943 100644 --- a/src/ComboGraph.cpp +++ b/src/ComboGraph.cpp @@ -14,9 +14,9 @@ ComboGraph::ComboGraph() { DeleteChildrenWhenDone( true ); - m_pNormalCombo = NULL; - m_pMaxCombo = NULL; - m_pComboNumber = NULL; + m_pNormalCombo = nullptr; + m_pMaxCombo = nullptr; + m_pComboNumber = nullptr; } void ComboGraph::Load( RString sMetricsGroup ) @@ -28,10 +28,10 @@ void ComboGraph::Load( RString sMetricsGroup ) this->SetWidth(BODY_WIDTH); this->SetHeight(BODY_HEIGHT); - Actor *pActor = NULL; + Actor *pActor = nullptr; m_pBacking = ActorUtil::MakeActor( THEME->GetPathG(sMetricsGroup,"Backing") ); - if( m_pBacking != NULL ) + if( m_pBacking != nullptr ) { m_pBacking->ZoomToWidth( BODY_WIDTH ); m_pBacking->ZoomToHeight( BODY_HEIGHT ); @@ -39,7 +39,7 @@ void ComboGraph::Load( RString sMetricsGroup ) } m_pNormalCombo = ActorUtil::MakeActor( THEME->GetPathG(sMetricsGroup,"NormalCombo") ); - if( m_pNormalCombo != NULL ) + if( m_pNormalCombo != nullptr ) { m_pNormalCombo->ZoomToWidth( BODY_WIDTH ); m_pNormalCombo->ZoomToHeight( BODY_HEIGHT ); @@ -47,7 +47,7 @@ void ComboGraph::Load( RString sMetricsGroup ) } m_pMaxCombo = ActorUtil::MakeActor( THEME->GetPathG(sMetricsGroup,"MaxCombo") ); - if( m_pMaxCombo != NULL ) + if( m_pMaxCombo != nullptr ) { m_pMaxCombo->ZoomToWidth( BODY_WIDTH ); m_pMaxCombo->ZoomToHeight( BODY_HEIGHT ); @@ -55,10 +55,10 @@ void ComboGraph::Load( RString sMetricsGroup ) } pActor = ActorUtil::MakeActor( THEME->GetPathG(sMetricsGroup,"ComboNumber") ); - if( pActor != NULL ) + if( pActor != nullptr ) { m_pComboNumber = dynamic_cast( pActor ); - if( m_pComboNumber != NULL ) + if( m_pComboNumber != nullptr ) this->AddChild( m_pComboNumber ); else LuaHelpers::ReportScriptErrorFmt( "ComboGraph: \"sMetricsGroup\" \"ComboNumber\" must be a BitmapText" ); diff --git a/src/Command.cpp b/src/Command.cpp index cb004a53f2..679f50f493 100644 --- a/src/Command.cpp +++ b/src/Command.cpp @@ -3,8 +3,8 @@ #include "RageUtil.h" #include "RageLog.h" #include "arch/Dialog/Dialog.h" -#include "Foreach.h" +#include RString Command::GetName() const { @@ -81,16 +81,7 @@ static void SplitWithQuotes( const RString sSource, const char Delimitor, vector RString Commands::GetOriginalCommandString() const { - RString s; - FOREACH_CONST( Command, v, c ) - { - if(s != "") - { - s += ";"; - } - s += c->GetOriginalCommandString(); - } - return s; + return std::accumulate(v.begin(), v.end(), RString(), [](RString &res, Command const &c) { return res + c.GetOriginalCommandString(); }); } void ParseCommands( const RString &sCommands, Commands &vCommandsOut, bool bLegacy ) diff --git a/src/CommandLineActions.cpp b/src/CommandLineActions.cpp index 794ea72472..203f168cda 100644 --- a/src/CommandLineActions.cpp +++ b/src/CommandLineActions.cpp @@ -8,7 +8,7 @@ #include "LuaManager.h" #include "ProductInfo.h" #include "DateTime.h" -#include "Foreach.h" + #include "arch/Dialog/Dialog.h" #include "RageFileManager.h" #include "SpecialFiles.h" @@ -38,17 +38,17 @@ static void Nsis() vector vs; GetDirListing(INSTALLER_LANGUAGES_DIR + "*.ini", vs, false, false); - FOREACH_CONST(RString, vs, s) + for (RString const &s : vs) { RString sThrowAway, sLangCode; - splitpath(*s, sThrowAway, sLangCode, sThrowAway); + splitpath(s, sThrowAway, sLangCode, sThrowAway); const LanguageInfo *pLI = GetLanguageInfo(sLangCode); RString sLangNameUpper = pLI->szEnglishName; sLangNameUpper.MakeUpper(); IniFile ini; - if(!ini.ReadFile(INSTALLER_LANGUAGES_DIR + *s)) + if(!ini.ReadFile(INSTALLER_LANGUAGES_DIR + s)) RageException::Throw("Error opening file for read."); FOREACH_CONST_Child(&ini, child) { diff --git a/src/CommonMetrics.cpp b/src/CommonMetrics.cpp index 1e733eb1a4..97ab63e3a6 100644 --- a/src/CommonMetrics.cpp +++ b/src/CommonMetrics.cpp @@ -1,7 +1,7 @@ #include "global.h" #include "CommonMetrics.h" #include "RageUtil.h" -#include "Foreach.h" + #include "GameManager.h" #include "RageLog.h" #include "GameState.h" @@ -45,12 +45,12 @@ void ThemeMetricDifficultiesToShow::Read() return; } - FOREACH_CONST( RString, v, i ) + for (RString const &i : v) { - Difficulty d = StringToDifficulty( *i ); + Difficulty d = StringToDifficulty( i ); if( d == Difficulty_Invalid ) { - LuaHelpers::ReportScriptErrorFmt("Unknown difficulty \"%s\" in CourseDifficultiesToShow.", i->c_str()); + LuaHelpers::ReportScriptErrorFmt("Unknown difficulty \"%s\" in CourseDifficultiesToShow.", i.c_str()); } else { @@ -84,12 +84,12 @@ void ThemeMetricCourseDifficultiesToShow::Read() return; } - FOREACH_CONST( RString, v, i ) + for (RString const &i : v) { - CourseDifficulty d = StringToDifficulty( *i ); + CourseDifficulty d = StringToDifficulty( i ); if( d == Difficulty_Invalid ) { - LuaHelpers::ReportScriptErrorFmt("Unknown CourseDifficulty \"%s\" in CourseDifficultiesToShow.", i->c_str()); + LuaHelpers::ReportScriptErrorFmt("Unknown CourseDifficulty \"%s\" in CourseDifficultiesToShow.", i.c_str()); } else { @@ -106,12 +106,12 @@ static void RemoveStepsTypes( vector& inout, RString sStepsTypesToRem if( v.size() == 0 ) return; // Nothing to do! // subtract StepsTypes - FOREACH_CONST( RString, v, i ) + for (RString const &i : v) { - StepsType st = GAMEMAN->StringToStepsType(*i); + StepsType st = GAMEMAN->StringToStepsType(i); if( st == StepsType_Invalid ) { - LuaHelpers::ReportScriptErrorFmt( "Invalid StepsType value '%s' in '%s'", i->c_str(), sStepsTypesToRemove.c_str() ); + LuaHelpers::ReportScriptErrorFmt( "Invalid StepsType value '%s' in '%s'", i.c_str(), sStepsTypesToRemove.c_str() ); continue; } diff --git a/src/Course.cpp b/src/Course.cpp index 9a58f853bb..90bb15faa4 100644 --- a/src/Course.cpp +++ b/src/Course.cpp @@ -2,7 +2,7 @@ #include "global.h" #include "Course.h" #include "CourseLoaderCRS.h" -#include "Foreach.h" + #include "GameManager.h" #include "GameState.h" #include "LocalizedString.h" @@ -266,7 +266,7 @@ RString Course::GetTranslitFullTitle() const /* This is called by many simple functions, like Course::GetTotalSeconds, and may * be called on all songs to sort. It can take time to execute, so we cache the * results. Returned pointers remain valid for the lifetime of the Course. If the - * course difficulty doesn't exist, NULL is returned. */ + * course difficulty doesn't exist, nullptr is returned. */ Trail* Course::GetTrail( StepsType st, CourseDifficulty cd ) const { ASSERT( cd != Difficulty_Invalid ); @@ -285,7 +285,7 @@ Trail* Course::GetTrail( StepsType st, CourseDifficulty cd ) const { CacheData &cache = it->second; if( cache.null ) - return NULL; + return nullptr; return &cache.trail; } } @@ -303,7 +303,7 @@ Trail* Course::GetTrailForceRegenCache( StepsType st, CourseDifficulty cd ) cons { // This course difficulty doesn't exist. cache.null = true; - return NULL; + return nullptr; } // If we have cached RadarValues for this trail, insert them. @@ -455,7 +455,7 @@ bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail ) else { vector vSongAndSteps; - FOREACH_CONST( CourseEntry, entries, e ) + for (std::vector::const_iterator e = entries.begin(); e != entries.end(); ++e) { SongAndSteps resolved; // fill this in SongCriteria soc = e->songCriteria; @@ -504,7 +504,7 @@ bool Course::GetTrailUnsorted( StepsType st, CourseDifficulty cd, Trail &trail ) vector vpSongs; typedef vector StepsVector; map mapSongToSteps; - FOREACH_CONST( SongAndSteps, vSongAndSteps, sas ) + for (std::vector::const_iterator sas = vSongAndSteps.begin(); sas != vSongAndSteps.end(); ++sas) { StepsVector &v = mapSongToSteps[ sas->pSong ]; @@ -658,7 +658,8 @@ void Course::GetTrailUnsortedEndless( const vector &entries, Trail map mapSongToSteps; int songIndex = 0; bool vpSongsSorted = false; - FOREACH_CONST( CourseEntry, entries, e ) + // Resolve each entry to a Song and Steps. + for (std::vector::const_iterator e = entries.begin(); e != entries.end(); ++e) { SongAndSteps resolved; // fill this in @@ -698,12 +699,15 @@ void Course::GetTrailUnsortedEndless( const vector &entries, Trail continue; if( !vpSongsSorted && !vSongAndSteps.empty() ) { - FOREACH_CONST( SongAndSteps, vSongAndSteps, sas ) + vector vpSongs; + typedef vector StepsVector; + map mapSongToSteps; + for (SongAndSteps const &sas : vSongAndSteps) { - StepsVector &v = mapSongToSteps[ sas->pSong ]; - v.push_back( sas->pSteps ); + StepsVector &v = mapSongToSteps[sas.pSong]; + v.push_back( sas.pSteps ); if( v.size() == 1 ) - vpSongs.push_back( sas->pSong ); + vpSongs.push_back( sas.pSong ); } vpSongsSorted = true; CourseSortSongs( e->songSort, vpSongs, rnd ); @@ -711,7 +715,7 @@ void Course::GetTrailUnsortedEndless( const vector &entries, Trail } ASSERT( e->iChooseIndex >= 0 ); - if( e->iChooseIndex < int( vSongAndSteps.size() ) ) + if( e->iChooseIndex < static_cast(vSongAndSteps.size()) ) { if( songIndex >= int(vpSongs.size()) ) { songIndex = 0; @@ -726,9 +730,9 @@ void Course::GetTrailUnsortedEndless( const vector &entries, Trail continue; } - /* If we're not COURSE_DIFFICULTY_REGULAR, then we should be choosing steps that are - * either easier or harder than the base difficulty. If no such steps exist, then - * just use the one we already have. */ + /* If we're not COURSE_DIFFICULTY_REGULAR, then we should be choosing steps that are + * either easier or harder than the base difficulty. If no such steps exist, then + * just use the one we already have. */ Difficulty dc = resolved.pSteps->GetDifficulty(); int iLowMeter = e->stepsCriteria.m_iLowMeter; int iHighMeter = e->stepsCriteria.m_iHighMeter; @@ -745,14 +749,14 @@ void Course::GetTrailUnsortedEndless( const vector &entries, Trail Difficulty new_dc; if( INCLUDE_BEGINNER_STEPS ) { - // don't factor in the course difficulty if we're including - // beginner steps -aj - new_dc = clamp( dc, Difficulty_Beginner, (Difficulty)(Difficulty_Edit-1) ); + // don't factor in the course difficulty if we're including + // beginner steps -aj + new_dc = clamp( dc, Difficulty_Beginner, (Difficulty)(Difficulty_Edit-1) ); } else { - new_dc = (Difficulty)(dc + cd - Difficulty_Medium); - new_dc = clamp( new_dc, (Difficulty)0, (Difficulty)(Difficulty_Edit-1) ); + new_dc = (Difficulty)(dc + cd - Difficulty_Medium); + new_dc = clamp( new_dc, (Difficulty)0, (Difficulty)(Difficulty_Edit-1) ); } */ @@ -770,21 +774,21 @@ void Course::GetTrailUnsortedEndless( const vector &entries, Trail } /* Hack: We used to adjust low_meter/high_meter above while searching for - * songs. However, that results in a different song being chosen for - * difficult courses, which is bad when LockCourseDifficulties is disabled; - * each player can end up with a different song. Instead, choose based - * on the original range, bump the steps based on course difficulty, and - * then retroactively tweak the low_meter/high_meter so course displays - * line up. */ + * songs. However, that results in a different song being chosen for + * difficult courses, which is bad when LockCourseDifficulties is disabled; + * each player can end up with a different song. Instead, choose based + * on the original range, bump the steps based on course difficulty, and + * then retroactively tweak the low_meter/high_meter so course displays + * line up. */ if( e->stepsCriteria.m_difficulty == Difficulty_Invalid && bChangedDifficulty ) { /* Minimum and maximum to add to make the meter range contain the actual - * meter: */ + * meter: */ int iMinDist = resolved.pSteps->GetMeter() - iHighMeter; int iMaxDist = resolved.pSteps->GetMeter() - iLowMeter; /* Clamp the possible adjustments to try to avoid going under 1 or over - * MAX_BOTTOM_RANGE. */ + * MAX_BOTTOM_RANGE. */ iMinDist = min( max( iMinDist, -iLowMeter + 1 ), iMaxDist ); iMaxDist = max( min( iMaxDist, MAX_BOTTOM_RANGE - iHighMeter ), iMinDist ); @@ -808,7 +812,7 @@ void Course::GetTrailUnsortedEndless( const vector &entries, Trail te.iHighMeter = iHighMeter; /* If we chose based on meter (not difficulty), then store Difficulty_Invalid, so - * other classes can tell that we used meter. */ + * other classes can tell that we used meter. */ if( e->stepsCriteria.m_difficulty == Difficulty_Invalid ) { te.dc = Difficulty_Invalid; @@ -816,7 +820,7 @@ void Course::GetTrailUnsortedEndless( const vector &entries, Trail else { /* Otherwise, store the actual difficulty we got (post-course-difficulty). - * This may or may not be the same as e.difficulty. */ + * This may or may not be the same as e.difficulty. */ te.dc = dc; } @@ -841,7 +845,7 @@ void Course::GetTrails( vector &AddTo, StepsType st ) const FOREACH_ShownCourseDifficulty( cd ) { Trail *pTrail = GetTrail( st, cd ); - if( pTrail == NULL ) + if( pTrail == nullptr ) continue; AddTo.push_back( pTrail ); } @@ -851,9 +855,9 @@ void Course::GetAllTrails( vector &AddTo ) const { vector vStepsTypesToShow; GAMEMAN->GetStepsTypesForGame( GAMESTATE->m_pCurGame, vStepsTypesToShow ); - FOREACH( StepsType, vStepsTypesToShow, st ) + for (StepsType const &st : vStepsTypesToShow) { - GetTrails( AddTo, *st ); + GetTrails( AddTo, st ); } } @@ -862,20 +866,14 @@ int Course::GetMeter( StepsType st, CourseDifficulty cd ) const if( m_iCustomMeter[cd] != -1 ) return m_iCustomMeter[cd]; const Trail* pTrail = GetTrail( st ); - if( pTrail != NULL ) + if( pTrail != nullptr ) return pTrail->GetMeter(); return 0; } bool Course::HasMods() const { - FOREACH_CONST( CourseEntry, m_vEntries, e ) - { - if( !e->attacks.empty() ) - return true; - } - - return false; + return std::any_of(m_vEntries.begin(), m_vEntries.end(), [](CourseEntry const &e) { return !e.attacks.empty(); }); } bool Course::HasTimedMods() const @@ -884,16 +882,15 @@ bool Course::HasTimedMods() const // HasTimedMods now searches for bGlobal in the attacks; if one of // them is false, it has timed mods. Also returning false will probably // take longer than expected. -aj - FOREACH_CONST( CourseEntry, m_vEntries, e ) + for (CourseEntry const &e : m_vEntries) { - if( !e->attacks.empty() ) + if( e.attacks.empty() ) { - for( unsigned s=0; s < e->attacks.size(); s++ ) - { - const Attack attack = e->attacks[s]; - if(!attack.bGlobal) - return true; - } + continue; + } + if (std::any_of(e.attacks.begin(), e.attacks.end(), [](Attack const &a) { return !a.bGlobal; })) + { + return true; } } return false; @@ -901,12 +898,7 @@ bool Course::HasTimedMods() const bool Course::AllSongsAreFixed() const { - FOREACH_CONST( CourseEntry, m_vEntries, e ) - { - if( !e->IsFixedSong() ) - return false; - } - return true; + return std::all_of(m_vEntries.begin(), m_vEntries.end(), [](CourseEntry const &e) { return e.IsFixedSong(); }); } const Style *Course::GetCourseStyle( const Game *pGame, int iNumPlayers ) const @@ -914,16 +906,15 @@ const Style *Course::GetCourseStyle( const Game *pGame, int iNumPlayers ) const vector vpStyles; GAMEMAN->GetCompatibleStyles( pGame, iNumPlayers, vpStyles ); - for( int s=0; s < (int) vpStyles.size(); ++s ) + for (Style const *pStyle : vpStyles) { - const Style *pStyle = vpStyles[s]; - FOREACHS_CONST( RString, m_setStyles, style ) + for (RString const &style : m_setStyles) { - if( !style->CompareNoCase(pStyle->m_szName) ) + if( !style.CompareNoCase(pStyle->m_szName) ) return pStyle; } } - return NULL; + return nullptr; } void Course::InvalidateTrailCache() @@ -933,9 +924,9 @@ void Course::InvalidateTrailCache() void Course::Invalidate( const Song *pStaleSong ) { - FOREACH_CONST( CourseEntry, m_vEntries, e ) + for (CourseEntry const &e : m_vEntries) { - Song *pSong = e->songID.ToSong(); + Song *pSong = e.songID.ToSong(); if( pSong == pStaleSong ) // a fixed entry that references the stale Song { RevertFromDisk(); @@ -971,9 +962,9 @@ void Course::RegenerateNonFixedTrails() const if( AllSongsAreFixed() ) return; - FOREACHM( CacheEntry, CacheData, m_TrailCache, e ) + for (auto const & e: m_TrailCache) { - const CacheEntry &ce = e->first; + const CacheEntry &ce = e.first; GetTrailForceRegenCache( ce.first, ce.second ); } } @@ -1046,11 +1037,11 @@ bool Course::GetTotalSeconds( StepsType st, float& fSecondsOut ) const bool Course::CourseHasBestOrWorst() const { - FOREACH_CONST( CourseEntry, m_vEntries, e ) + for (CourseEntry const &e : m_vEntries) { - if( e->songSort == SongSort_MostPlays && e->iChooseIndex != -1 ) + if( e.songSort == SongSort_MostPlays && e.iChooseIndex != -1 ) return true; - if( e->songSort == SongSort_FewestPlays && e->iChooseIndex != -1 ) + if( e.songSort == SongSort_FewestPlays && e.iChooseIndex != -1 ) return true; } @@ -1093,7 +1084,7 @@ void Course::UpdateCourseStats( StepsType st ) for(unsigned i = 0; i < m_vEntries.size(); i++) { Song *pSong = m_vEntries[i].songID.ToSong(); - if( pSong != NULL ) + if( pSong != nullptr ) continue; if ( m_SortOrder_Ranking == 2 ) @@ -1104,7 +1095,7 @@ void Course::UpdateCourseStats( StepsType st ) const Trail* pTrail = GetTrail( st, Difficulty_Medium ); - m_SortOrder_TotalDifficulty += pTrail != NULL? pTrail->GetTotalMeter():0; + m_SortOrder_TotalDifficulty += pTrail != nullptr? pTrail->GetTotalMeter():0; // OPTIMIZATION: Ranking info isn't dependent on style, so call it // sparingly. It's handled on startup and when themes change. @@ -1129,15 +1120,14 @@ bool Course::IsRanking() const const CourseEntry *Course::FindFixedSong( const Song *pSong ) const { - FOREACH_CONST( CourseEntry, m_vEntries, e ) + for (CourseEntry const &entry : m_vEntries) { - const CourseEntry &entry = *e; Song *lSong = entry.songID.ToSong(); if( pSong == lSong ) return &entry; } - return NULL; + return nullptr; } void Course::GetAllCachedTrails( vector &out ) @@ -1169,7 +1159,7 @@ void Course::CalculateRadarValues() if( AllSongsAreFixed() ) { Trail *pTrail = GetTrail( st, cd ); - if( pTrail == NULL ) + if( pTrail == nullptr ) continue; RadarValues rv = pTrail->GetRadarValues(); m_RadarCache[CacheEntry(st, cd)] = rv; diff --git a/src/CourseContentsList.cpp b/src/CourseContentsList.cpp index f5aa87fc3c..3064135113 100644 --- a/src/CourseContentsList.cpp +++ b/src/CourseContentsList.cpp @@ -14,8 +14,8 @@ REGISTER_ACTOR_CLASS( CourseContentsList ); CourseContentsList::~CourseContentsList() { - FOREACH( Actor *, m_vpDisplay, d ) - delete *d; + for (Actor *d : m_vpDisplay) + delete d; m_vpDisplay.clear(); } @@ -25,7 +25,7 @@ void CourseContentsList::LoadFromNode( const XNode* pNode ) pNode->GetAttrValue( "MaxSongs", iMaxSongs ); const XNode *pDisplayNode = pNode->GetChild( "Display" ); - if( pDisplayNode == NULL ) + if( pDisplayNode == nullptr ) { LuaHelpers::ReportScriptErrorFmt("%s: CourseContentsList: missing the Display child", ActorUtil::GetWhere(pNode).c_str()); return; @@ -48,7 +48,7 @@ void CourseContentsList::SetFromGameState() if( GAMESTATE->GetMasterPlayerNumber() == PlayerNumber_Invalid ) return; const Trail *pMasterTrail = GAMESTATE->m_pCurTrail[GAMESTATE->GetMasterPlayerNumber()]; - if( pMasterTrail == NULL ) + if( pMasterTrail == nullptr ) return; unsigned uNumEntriesToShow = pMasterTrail->m_vEntries.size(); CLAMP( uNumEntriesToShow, 0, m_vpDisplay.size() ); @@ -81,21 +81,21 @@ void CourseContentsList::SetItemFromGameState( Actor *pActor, int iCourseEntryIn FOREACH_HumanPlayer(pn) { const Trail *pTrail = GAMESTATE->m_pCurTrail[pn]; - if( pTrail == NULL + if( pTrail == nullptr || iCourseEntryIndex >= (int) pTrail->m_vEntries.size() || iCourseEntryIndex >= (int) pCourse->m_vEntries.size() ) continue; const TrailEntry *te = &pTrail->m_vEntries[iCourseEntryIndex]; const CourseEntry *ce = &pCourse->m_vEntries[iCourseEntryIndex]; - if( te == NULL ) + if( te == nullptr ) continue; RString s; Difficulty dc; if( te->bSecret ) { - if( ce == NULL ) + if( ce == nullptr ) continue; int iLow = ce->stepsCriteria.m_iLowMeter; diff --git a/src/CourseLoaderCRS.cpp b/src/CourseLoaderCRS.cpp index 5974626a5d..3d67fb041c 100644 --- a/src/CourseLoaderCRS.cpp +++ b/src/CourseLoaderCRS.cpp @@ -87,7 +87,7 @@ bool CourseLoaderCRS::LoadFromMsd( const RString &sPath, const MsdFile &msd, Cou } else if( sValueName.EqualsNoCase("LIVES") ) { - out.m_iLives = max( StringToInt(sParams[1]), 0 ); + out.m_iLives = max( std::stoi(sParams[1]), 0 ); } else if( sValueName.EqualsNoCase("GAINSECONDS") ) { @@ -97,7 +97,7 @@ bool CourseLoaderCRS::LoadFromMsd( const RString &sPath, const MsdFile &msd, Cou { if( sParams.params.size() == 2 ) { - out.m_iCustomMeter[Difficulty_Medium] = max( StringToInt(sParams[1]), 0 ); /* compat */ + out.m_iCustomMeter[Difficulty_Medium] = max( std::stoi(sParams[1]), 0 ); /* compat */ } else if( sParams.params.size() == 3 ) { @@ -107,7 +107,7 @@ bool CourseLoaderCRS::LoadFromMsd( const RString &sPath, const MsdFile &msd, Cou LOG->UserLog( "Course file", sPath, "contains an invalid #METER string: \"%s\"", sParams[1].c_str() ); continue; } - out.m_iCustomMeter[cd] = max( StringToInt(sParams[2]), 0 ); + out.m_iCustomMeter[cd] = max( std::stoi(sParams[2]), 0 ); } } @@ -168,7 +168,7 @@ bool CourseLoaderCRS::LoadFromMsd( const RString &sPath, const MsdFile &msd, Cou // most played if( sParams[1].Left(strlen("BEST")) == "BEST" ) { - int iChooseIndex = StringToInt( sParams[1].Right(sParams[1].size()-strlen("BEST")) ) - 1; + int iChooseIndex = std::stoi( sParams[1].Right(sParams[1].size()-strlen("BEST")) ) - 1; if( iChooseIndex > iNumSongs ) { // looking up a song that doesn't exist. @@ -185,7 +185,7 @@ bool CourseLoaderCRS::LoadFromMsd( const RString &sPath, const MsdFile &msd, Cou // least played else if( sParams[1].Left(strlen("WORST")) == "WORST" ) { - int iChooseIndex = StringToInt( sParams[1].Right(sParams[1].size()-strlen("WORST")) ) - 1; + int iChooseIndex = std::stoi( sParams[1].Right(sParams[1].size()-strlen("WORST")) ) - 1; if( iChooseIndex > iNumSongs ) { // looking up a song that doesn't exist. @@ -202,14 +202,14 @@ bool CourseLoaderCRS::LoadFromMsd( const RString &sPath, const MsdFile &msd, Cou // best grades else if( sParams[1].Left(strlen("GRADEBEST")) == "GRADEBEST" ) { - new_entry.iChooseIndex = StringToInt( sParams[1].Right(sParams[1].size()-strlen("GRADEBEST")) ) - 1; + new_entry.iChooseIndex = std::stoi( sParams[1].Right(sParams[1].size()-strlen("GRADEBEST")) ) - 1; CLAMP( new_entry.iChooseIndex, 0, 500 ); new_entry.songSort = SongSort_TopGrades; } // worst grades else if( sParams[1].Left(strlen("GRADEWORST")) == "GRADEWORST" ) { - new_entry.iChooseIndex = StringToInt( sParams[1].Right(sParams[1].size()-strlen("GRADEWORST")) ) - 1; + new_entry.iChooseIndex = std::stoi( sParams[1].Right(sParams[1].size()-strlen("GRADEWORST")) ) - 1; CLAMP( new_entry.iChooseIndex, 0, 500 ); new_entry.songSort = SongSort_LowestGrades; } @@ -250,7 +250,7 @@ bool CourseLoaderCRS::LoadFromMsd( const RString &sPath, const MsdFile &msd, Cou vector bits; split( sSong, "/", bits ); - Song *pSong = NULL; + Song *pSong = nullptr; if( bits.size() == 2 ) { new_entry.songCriteria.m_sGroupName = bits[0]; @@ -262,7 +262,7 @@ bool CourseLoaderCRS::LoadFromMsd( const RString &sPath, const MsdFile &msd, Cou } new_entry.songID.FromSong( pSong ); - if( pSong == NULL ) + if( pSong == nullptr ) { LOG->UserLog( "Course file", sPath, "contains a fixed song entry \"%s\" that does not exist. " "This entry will be ignored.", sSong.c_str()); @@ -308,7 +308,7 @@ bool CourseLoaderCRS::LoadFromMsd( const RString &sPath, const MsdFile &msd, Cou else if( !sMod.CompareNoCase("nodifficult") ) new_entry.bNoDifficult = true; else if( sMod.length() > 5 && !sMod.Left(5).CompareNoCase("award") ) - new_entry.iGainLives = StringToInt( sMod.substr(5) ); + new_entry.iGainLives = std::stoi( sMod.substr(5) ); else continue; mods.erase( mods.begin() + j ); @@ -330,8 +330,8 @@ bool CourseLoaderCRS::LoadFromMsd( const RString &sPath, const MsdFile &msd, Cou else if( bFromCache && !sValueName.EqualsNoCase("RADAR") ) { - StepsType st = (StepsType) StringToInt(sParams[1]); - CourseDifficulty cd = (CourseDifficulty) StringToInt( sParams[2] ); + StepsType st = (StepsType) std::stoi(sParams[1]); + CourseDifficulty cd = (CourseDifficulty) std::stoi( sParams[2] ); RadarValues rv; rv.FromString( sParams[3] ); @@ -342,8 +342,8 @@ bool CourseLoaderCRS::LoadFromMsd( const RString &sPath, const MsdFile &msd, Cou RString sStyles = sParams[1]; vector asStyles; split( sStyles, ",", asStyles ); - FOREACH( RString, asStyles, s ) - out.m_setStyles.insert( *s ); + for (RString const &s : asStyles) + out.m_setStyles.insert( s ); } else diff --git a/src/CourseUtil.cpp b/src/CourseUtil.cpp index f2a53a8752..043f6894b0 100644 --- a/src/CourseUtil.cpp +++ b/src/CourseUtil.cpp @@ -8,7 +8,7 @@ #include "XmlFile.h" #include "GameState.h" #include "Style.h" -#include "Foreach.h" + #include "GameState.h" #include "LocalizedString.h" #include "RageLog.h" @@ -110,7 +110,7 @@ void CourseUtil::SortCoursePointerArrayByTotalDifficulty( vector &vpCou #if 0 RString GetSectionNameFromCourseAndSort( const Course *pCourse, SortOrder so ) { - if( pCourse == NULL ) + if( pCourse == nullptr ) return RString(); // more code here } @@ -195,7 +195,7 @@ void CourseUtil::SortCoursePointerArrayByNumPlays( vector &vpCoursesInO void CourseUtil::SortCoursePointerArrayByNumPlays( vector &vpCoursesInOut, const Profile* pProfile, bool bDescending ) { - ASSERT( pProfile != NULL ); + ASSERT( pProfile != nullptr ); for(unsigned i = 0; i < vpCoursesInOut.size(); ++i) course_sort_val[vpCoursesInOut[i]] = ssprintf( "%09i", pProfile->GetCourseNumTimesPlayed(vpCoursesInOut[i]) ); stable_sort( vpCoursesInOut.begin(), vpCoursesInOut.end(), bDescending ? CompareCoursePointersBySortValueDescending : CompareCoursePointersBySortValueAscending ); @@ -206,11 +206,11 @@ void CourseUtil::SortByMostRecentlyPlayedForMachine( vector &vpCoursesI { Profile *pProfile = PROFILEMAN->GetMachineProfile(); - FOREACH_CONST( Course*, vpCoursesInOut, c ) + for (Course const * c: vpCoursesInOut) { - int iNumTimesPlayed = pProfile->GetCourseNumTimesPlayed( *c ); - RString val = iNumTimesPlayed ? pProfile->GetCourseLastPlayedDateTime(*c).GetString() : "9999999999999"; - course_sort_val[*c] = val; + int iNumTimesPlayed = pProfile->GetCourseNumTimesPlayed( c ); + RString val = iNumTimesPlayed ? pProfile->GetCourseLastPlayedDateTime(c).GetString() : "9999999999999"; + course_sort_val[c] = val; } stable_sort( vpCoursesInOut.begin(), vpCoursesInOut.end(), CompareCoursePointersBySortValueAscending ); @@ -327,12 +327,12 @@ void CourseUtil::WarnOnInvalidMods( RString sMods ) SongOptions so; vector vs; split( sMods, ",", vs, true ); - FOREACH_CONST( RString, vs, s ) + for (RString const &s : vs) { bool bValid = false; RString sErrorDetail; - bValid |= po.FromOneModString( *s, sErrorDetail ); - bValid |= so.FromOneModString( *s, sErrorDetail ); + bValid |= po.FromOneModString( s, sErrorDetail ); + bValid |= so.FromOneModString( s, sErrorDetail ); /* ==Invalid options that used to be valid== * all noteskins (solo, note, foon, &c.) * protiming (done in Lua now) @@ -346,7 +346,7 @@ void CourseUtil::WarnOnInvalidMods( RString sMods ) */ if( !bValid ) { - RString sFullError = ssprintf("Error processing '%s' in '%s'", (*s).c_str(), sMods.c_str() ); + RString sFullError = ssprintf("Error processing '%s' in '%s'", s.c_str(), sMods.c_str() ); if( !sErrorDetail.empty() ) sFullError += ": " + sErrorDetail; LOG->UserLog( "", "", "%s", sFullError.c_str() ); @@ -422,7 +422,7 @@ bool EditCourseUtil::ValidateEditCourseName( const RString &sAnswer, RString &sE } static const RString sInvalidChars = "\\/:*?\"<>|"; - if( strpbrk(sAnswer, sInvalidChars) != NULL ) + if( strpbrk(sAnswer, sInvalidChars) != nullptr ) { sErrorOut = ssprintf( EDIT_NAME_CANNOT_CONTAIN.GetValue(), sInvalidChars.c_str() ); return false; @@ -431,12 +431,12 @@ bool EditCourseUtil::ValidateEditCourseName( const RString &sAnswer, RString &sE // Check for name conflicts vector vpCourses; EditCourseUtil::GetAllEditCourses( vpCourses ); - FOREACH_CONST( Course*, vpCourses, p ) + for (Course const *p : vpCourses) { - if( GAMESTATE->m_pCurCourse == *p ) + if( GAMESTATE->m_pCurCourse == p ) continue; // don't comepare name against ourself - if( (*p)->GetDisplayFullTitle() == sAnswer ) + if( p->GetDisplayFullTitle() == sAnswer ) { sErrorOut = EDIT_NAME_CONFLICTS; return false; @@ -448,9 +448,9 @@ bool EditCourseUtil::ValidateEditCourseName( const RString &sAnswer, RString &sE void EditCourseUtil::UpdateAndSetTrail() { - ASSERT( GAMESTATE->GetCurrentStyle(PLAYER_INVALID) != NULL ); + ASSERT( GAMESTATE->GetCurrentStyle(PLAYER_INVALID) != nullptr ); StepsType st = GAMESTATE->GetCurrentStyle(PLAYER_INVALID)->m_StepsType; - Trail *pTrail = NULL; + Trail *pTrail = nullptr; if( GAMESTATE->m_pCurCourse ) pTrail = GAMESTATE->m_pCurCourse->GetTrailForceRegenCache( st ); GAMESTATE->m_pCurTrail[PLAYER_1].Set( pTrail ); @@ -458,7 +458,7 @@ void EditCourseUtil::UpdateAndSetTrail() void EditCourseUtil::PrepareForPlay() { - GAMESTATE->m_pCurSong.Set( NULL ); // CurSong will be set if we back out. Set it back to NULL so that ScreenStage won't show the last song. + GAMESTATE->m_pCurSong.Set(nullptr); // CurSong will be set if we back out. Set it back to nullptr so that ScreenStage won't show the last song. GAMESTATE->m_PlayMode.Set( PLAY_MODE_ENDLESS ); GAMESTATE->m_bSideIsJoined[0] = true; @@ -471,10 +471,10 @@ void EditCourseUtil::GetAllEditCourses( vector &vpCoursesOut ) { vector vpCoursesTemp; SONGMAN->GetAllCourses( vpCoursesTemp, false ); - FOREACH_CONST( Course*, vpCoursesTemp, c ) + for (Course *c : vpCoursesTemp) { - if( (*c)->GetLoadedFromProfileSlot() != ProfileSlot_Invalid ) - vpCoursesOut.push_back( *c ); + if( c->GetLoadedFromProfileSlot() != ProfileSlot_Invalid ) + vpCoursesOut.push_back( c ); } } @@ -489,20 +489,11 @@ void EditCourseUtil::LoadDefaults( Course &out ) for( int i=0; i<10000; i++ ) { out.m_sMainTitle = ssprintf("Workout %d", i+1); - bool bNameInUse = false; - + vector vpCourses; EditCourseUtil::GetAllEditCourses( vpCourses ); - FOREACH_CONST( Course*, vpCourses, p ) - { - if( out.m_sMainTitle == (*p)->m_sMainTitle ) - { - bNameInUse = true; - break; - } - } - if( !bNameInUse ) + if (std::any_of(vpCourses.begin(), vpCourses.end(), [&](Course const *p) { return out.m_sMainTitle == p->m_sMainTitle; })) break; } @@ -552,7 +543,7 @@ void CourseID::FromCourse( const Course *p ) Course *CourseID::ToCourse() const { - Course *pCourse = NULL; + Course *pCourse = nullptr; if(m_Cache.Get(&pCourse)) { return pCourse; @@ -567,13 +558,13 @@ Course *CourseID::ToCourse() const slash_path = "/" + slash_path; } - if(pCourse == NULL) + if(pCourse == nullptr) { pCourse = SONGMAN->GetCourseFromPath(slash_path); } } - if( pCourse == NULL && !sFullTitle.empty() ) + if( pCourse == nullptr && !sFullTitle.empty() ) { pCourse = SONGMAN->GetCourseFromName( sFullTitle ); } diff --git a/src/CourseUtil.h b/src/CourseUtil.h index 6be86abe77..2afcd874ed 100644 --- a/src/CourseUtil.h +++ b/src/CourseUtil.h @@ -73,7 +73,7 @@ class CourseID { public: CourseID(): sPath(""), sFullTitle(""), m_Cache() { Unset(); } - void Unset() { FromCourse(NULL); } + void Unset() { FromCourse(nullptr); } void FromCourse( const Course *p ); Course *ToCourse() const; const RString &GetPath() const { return sPath; } diff --git a/src/CreateZip.cpp b/src/CreateZip.cpp index 32ab3dc9d0..5ad22d36f4 100644 --- a/src/CreateZip.cpp +++ b/src/CreateZip.cpp @@ -532,7 +532,7 @@ const ulg crc_table[256] = { ulg crc32(ulg crc, const uch *buf, size_t len) { - if (buf==NULL) return 0L; + if (buf== nullptr) return 0L; crc = crc ^ 0xffffffffL; while (len >= 8) {DO8(buf); len -= 8;} if (len) do {DO1(buf);} while (--len); @@ -543,7 +543,7 @@ ulg crc32(ulg crc, const uch *buf, size_t len) class TZip { public: - TZip() : pfout(NULL),ooffset(0),oerr(false),writ(0),hasputcen(false),zfis(0),hfin(0) + TZip() : pfout(nullptr),ooffset(0),oerr(false),writ(0),hasputcen(false),zfis(0),hfin(0) { } ~TZip() @@ -631,7 +631,7 @@ unsigned TZip::swrite(void *param,const char *buf, unsigned size) unsigned int TZip::write(const char *buf,unsigned int size) { const char *srcbuf=buf; - if (pfout != NULL) + if (pfout != nullptr) { unsigned long writ = pfout->Write( srcbuf, size ); return writ; @@ -717,7 +717,7 @@ ZRESULT TZip::set_times() unsigned short dosdate,dostime; filetime2dosdatetime(*ptm,&dosdate,&dostime); - times.atime = time(NULL); + times.atime = time(nullptr); times.mtime = times.atime; times.ctime = times.atime; timestamp = (unsigned short)dostime | (((unsigned long)dosdate)<<16); @@ -826,7 +826,7 @@ ZRESULT TZip::Add(const TCHAR *odstzn, const TCHAR *src,unsigned long flags) // then the compressed data, and possibly an extended local header. // Initialize the local header - TZipFileInfo zfi; zfi.nxt=NULL; + TZipFileInfo zfi; zfi.nxt=nullptr; strcpy(zfi.name,""); #ifdef UNICODE WideCharToMultiByte(CP_UTF8,0,dstzn,-1,zfi.iname,MAX_PATH,0,0); @@ -840,9 +840,9 @@ ZRESULT TZip::Add(const TCHAR *odstzn, const TCHAR *src,unsigned long flags) zfi.nam++; } strcpy(zfi.zname,""); - zfi.extra=NULL; zfi.ext=0; // extra header to go after this compressed data, and its length - zfi.cextra=NULL; zfi.cext=0; // extra header to go in the central end-of-zip directory, and its length - zfi.comment=NULL; zfi.com=0; // comment, and its length + zfi.extra=nullptr; zfi.ext=0; // extra header to go after this compressed data, and its length + zfi.cextra=nullptr; zfi.cext=0; // extra header to go in the central end-of-zip directory, and its length + zfi.comment=nullptr; zfi.com=0; // comment, and its length zfi.mark = 1; zfi.dosflag = 0; zfi.att = (ush)BINARY; @@ -935,12 +935,12 @@ ZRESULT TZip::Add(const TCHAR *odstzn, const TCHAR *src,unsigned long flags) // Keep a copy of the zipfileinfo, for our end-of-zip directory char *cextra = new char[zfi.cext]; memcpy(cextra,zfi.cextra,zfi.cext); zfi.cextra=cextra; TZipFileInfo *pzfi = new TZipFileInfo; memcpy(pzfi,&zfi,sizeof(zfi)); - if (zfis==NULL) + if (zfis==nullptr) zfis=pzfi; else { TZipFileInfo *z=zfis; - while (z->nxt!=NULL) + while (z->nxt!=nullptr) z=z->nxt; z->nxt=pzfi; } @@ -954,7 +954,7 @@ ZRESULT TZip::AddCentral() ulg pos_at_start_of_central = writ; //ulg tot_unc_size=0, tot_compressed_size=0; bool okay=true; - for (TZipFileInfo *zfi=zfis; zfi!=NULL; ) + for (TZipFileInfo *zfi=zfis; zfi!= nullptr; ) { if (okay) { @@ -975,7 +975,7 @@ ZRESULT TZip::AddCentral() ulg center_size = writ - pos_at_start_of_central; if (okay) { - int res = putend(numentries, center_size, pos_at_start_of_central+ooffset, 0, NULL, swrite,this); + int res = putend(numentries, center_size, pos_at_start_of_central+ooffset, 0, nullptr, swrite,this); if (res!=ZE_OK) okay=false; writ += 4 + ENDHEAD + 0; @@ -994,7 +994,7 @@ ZRESULT lasterrorZ=ZR_OK; CreateZip::CreateZip() { - hz=NULL; + hz=nullptr; } bool CreateZip::Start( RageFile *f) @@ -1016,7 +1016,7 @@ bool CreateZip::AddFile(RString fn) } bool CreateZip::AddDir(RString fn) { - lasterrorZ = hz->Add(MakeDestZipFileName(fn),NULL,ZIP_FOLDER); + lasterrorZ = hz->Add(MakeDestZipFileName(fn),nullptr,ZIP_FOLDER); return lasterrorZ == ZR_OK; } bool CreateZip::Finish() diff --git a/src/CreateZip.h b/src/CreateZip.h index b8bf634e50..e9f1ba9c78 100644 --- a/src/CreateZip.h +++ b/src/CreateZip.h @@ -49,7 +49,7 @@ public: // char buf[1000]; for (int i=0; i<1000; i++) buf[i]=(char)(i&0x7F); // ZipAdd(hz,"file.dat", buf,1000); // // adding something from a pipe... -// HANDLE hread,hwrite; CreatePipe(&hread,&hwrite,NULL,0); +// HANDLE hread,hwrite; CreatePipe(&hread,&hwrite,nullptr,0); // HANDLE hthread = CreateThread(0,0,ThreadFunc,(void*)hwrite,0,0); // ZipAdd(hz,"unz3.dat", hread,1000); // the '1000' is optional. // WaitForSingleObject(hthread,INFINITE); @@ -57,14 +57,14 @@ public: // ... meanwhile DWORD WINAPI ThreadFunc(void *dat) // { HANDLE hwrite = (HANDLE)dat; // char buf[1000]={17}; -// DWORD writ; WriteFile(hwrite,buf,1000,&writ,NULL); +// DWORD writ; WriteFile(hwrite,buf,1000,&writ,nullptr); // CloseHandle(hwrite); // return 0; // } // // and now that the zip is created, let's do something with it: // void *zbuf; unsigned long zlen; ZipGetMemory(hz,&zbuf,&zlen); // HANDLE hfz = CreateFile("test2.zip",GENERIC_WRITE,0,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0); -// DWORD writ; WriteFile(hfz,zbuf,zlen,&writ,NULL); +// DWORD writ; WriteFile(hfz,zbuf,zlen,&writ,nullptr); // CloseHandle(hfz); // CloseZip(hz); // @@ -81,7 +81,7 @@ public: // { HANDLE hread = (HANDLE)dat; // char buf[1000]; // for(;;) -// { DWORD red; ReadFile(hread,buf,1000,&red,NULL); +// { DWORD red; ReadFile(hread,buf,1000,&red,nullptr); // // ... and do something with this zip data we're receiving // if (red==0) break; // } diff --git a/src/CryptHelpers.cpp b/src/CryptHelpers.cpp index f561eb8b84..6531ff69a9 100644 --- a/src/CryptHelpers.cpp +++ b/src/CryptHelpers.cpp @@ -6,7 +6,7 @@ PRNGWrapper::PRNGWrapper( const struct ltc_prng_descriptor *pPRNGDescriptor ) m_iPRNG = register_prng( pPRNGDescriptor ); ASSERT( m_iPRNG >= 0 ); - int iRet = rng_make_prng( 128, m_iPRNG, &m_PRNG, NULL ); + int iRet = rng_make_prng( 128, m_iPRNG, &m_PRNG, nullptr ); ASSERT_M( iRet == CRYPT_OK, error_to_string(iRet) ); } @@ -28,7 +28,7 @@ void PRNGWrapper::AddEntropy( const void *pData, int iSize ) void PRNGWrapper::AddRandomEntropy() { unsigned char buf[256]; - int iRet = rng_get_bytes( buf, sizeof(buf), NULL ); + int iRet = rng_get_bytes( buf, sizeof(buf), nullptr ); ASSERT( iRet == sizeof(buf) ); AddEntropy( buf, sizeof(buf) ); diff --git a/src/CryptManager.cpp b/src/CryptManager.cpp index 7806fdbdb8..f61b467760 100644 --- a/src/CryptManager.cpp +++ b/src/CryptManager.cpp @@ -11,7 +11,7 @@ #include "libtomcrypt/src/headers/tomcrypt.h" -CryptManager* CRYPTMAN = NULL; // global and accessible from anywhere in our program +CryptManager* CRYPTMAN = nullptr; // global and accessible from anywhere in our program static const RString PRIVATE_KEY_PATH = "Data/private.rsa"; static const RString PUBLIC_KEY_PATH = "Data/public.rsa"; @@ -79,7 +79,7 @@ static const int KEY_LENGTH = 1024; * */ -static PRNGWrapper *g_pPRNG = NULL; +static PRNGWrapper *g_pPRNG = nullptr; ltc_math_descriptor ltc_mp = ltm_desc; CryptManager::CryptManager() diff --git a/src/CsvFile.cpp b/src/CsvFile.cpp index 93ce3bee28..05d39fd1cc 100644 --- a/src/CsvFile.cpp +++ b/src/CsvFile.cpp @@ -3,7 +3,6 @@ #include "RageUtil.h" #include "RageFile.h" #include "RageLog.h" -#include "Foreach.h" CsvFile::CsvFile() { @@ -114,15 +113,15 @@ bool CsvFile::WriteFile( const RString &sPath ) const bool CsvFile::WriteFile( RageFileBasic &f ) const { - FOREACH_CONST( StringVector, m_vvs, line ) + for (StringVector const &line : m_vvs) { RString sLine; - FOREACH_CONST( RString, *line, value ) + for (auto value = line.begin(); value != line.end(); ++value) { RString sVal = *value; sVal.Replace( "\"", "\"\"" ); // escape quotes to double-quotes sLine += "\"" + sVal + "\""; - if( value != line->end()-1 ) + if( value != line.end()-1 ) sLine += ","; } if( f.PutLine(sLine) == -1 ) diff --git a/src/DancingCharacters.cpp b/src/DancingCharacters.cpp index 3d84a64a6f..e977c4cca5 100644 --- a/src/DancingCharacters.cpp +++ b/src/DancingCharacters.cpp @@ -1,440 +1,440 @@ -#include "global.h" -#include "DancingCharacters.h" -#include "GameConstantsAndTypes.h" -#include "RageDisplay.h" -#include "RageUtil.h" -#include "RageMath.h" -#include "GameState.h" -#include "Song.h" -#include "Character.h" -#include "StatsManager.h" -#include "PrefsManager.h" -#include "Model.h" - -int Neg1OrPos1(); - -#define DC_X( choice ) THEME->GetMetricF("DancingCharacters",ssprintf("2DCharacterXP%d",choice+1)) -#define DC_Y( choice ) THEME->GetMetricF("DancingCharacters",ssprintf("2DCharacterYP%d",choice+1)) - -/* - * TODO: - * - Metrics/Lua for lighting and camera sweeping. - * - Ability to load secondary elements i.e. stages. - * - Remove support for 2D characters (Lua can do it). - * - Cleanup! - * - * -- Colby - */ - -#define CAMERA_REST_DISTANCE THEME->GetMetricF("DancingCamera","RestDistance") -#define CAMERA_REST_LOOK_AT_HEIGHT THEME->GetMetricF("DancingCamera","RestHeight") -#define CAMERA_SWEEP_DISTANCE THEME->GetMetricF("DancingCamera","SweepDistance") -#define CAMERA_SWEEP_DISTANCE_VARIANCE THEME->GetMetricF("DancingCamera","SweepDistanceVariable") -#define CAMERA_SWEEP_HEIGHT_VARIANCE THEME->GetMetricF("DancingCamera","SweepHeightVariable") -#define CAMERA_SWEEP_PAN_Y_RANGE_DEGREES THEME->GetMetricF("DancingCamera","SweepPanYRangeDegrees") -#define CAMERA_SWEEP_PAN_Y_VARIANCE_DEGREES THEME->GetMetricF("DancingCamera","SweepPanYVarianceDegrees") -#define CAMERA_SWEEP_LOOK_AT_HEIGHT THEME->GetMetricF("DancingCamera","SweepHeight") -#define CAMERA_STILL_DISTANCE THEME->GetMetricF("DancingCamera","StillDistance") -#define CAMERA_STILL_DISTANCE_VARIANCE THEME->GetMetricF("DancingCamera","StillDistanceVariance") -#define CAMERA_STILL_PAN_Y_RANGE_DEGREES THEME->GetMetricF("DancingCamera","StillPanYRangeDegrees") -#define CAMERA_STILL_HEIGHT_VARIANCE THEME->GetMetricF("DancingCamera","StillHeightVariance") -#define CAMERA_STILL_LOOK_AT_HEIGHT THEME->GetMetricF("DancingCamera","StillHeight") - -// This is to setup the lighting color. -const ThemeMetric LIGHT_AMBIENT_COLOR ( "DancingCamera", "AmbientColor" ); -const ThemeMetric LIGHT_DIFFUSE_COLOR ( "DancingCamera", "DiffuseColor" ); - -// This is for Danger and Failed colors. -const ThemeMetric LIGHT_ADANGER_COLOR ( "DancingCamera", "AmbientDangerColor" ); -const ThemeMetric LIGHT_AFAILED_COLOR ( "DancingCamera", "AmbientFailedColor" ); -const ThemeMetric LIGHT_DDANGER_COLOR ( "DancingCamera", "DiffuseDangerColor" ); -const ThemeMetric LIGHT_DFAILED_COLOR ( "DancingCamera", "DiffuseFailedColor" ); - -// This is to make positioning of said light. -#define LIGHTING_X THEME->GetMetricF("DancingCamera","LightX") -#define LIGHTING_Y THEME->GetMetricF("DancingCamera","LightY") -#define LIGHTING_Z THEME->GetMetricF("DancingCamera","LightZ") - -// Position of the model in X (one player) -#define MODEL_X_ONE_PLAYER THEME->GetMetricF("DancingCharacters","OnePlayerModelX") - -// As the name implies, this sets the ammount of beats that the camera will -// stay in its current state until transitioning to the next camera tween. -#define AMM_BEATS_TIL_NEXTCAMERA THEME->GetMetricF("DancingCamera","BeatsUntilNextCamPos") -#define CAM_FOV THEME->GetMetricF("DancingCamera","CameraFOV") - -const float MODEL_X_TWO_PLAYERS[NUM_PLAYERS] = { +8, -8 }; -const float MODEL_ROTATIONY_TWO_PLAYERS[NUM_PLAYERS] = { -90, 90 }; - -DancingCharacters::DancingCharacters(): m_bDrawDangerLight(false), - m_CameraDistance(0), m_CameraPanYStart(0), m_CameraPanYEnd(0), - m_fLookAtHeight(0), m_fCameraHeightStart(0), m_fCameraHeightEnd(0), - m_fThisCameraStartBeat(0), m_fThisCameraEndBeat(0) -{ - FOREACH_PlayerNumber( p ) - { - m_pCharacter[p] = new Model; - m_2DIdleTimer[p].SetZero(); - m_i2DAnimState[p] = AS2D_IDLE; // start on idle state - if( !GAMESTATE->IsPlayerEnabled(p) ) - continue; - - Character* pChar = GAMESTATE->m_pCurCharacters[p]; - if( !pChar ) - continue; - - // load in any potential 2D stuff - RString sCharacterDirectory = pChar->m_sCharDir; - RString sCurrentAnim; - sCurrentAnim = sCharacterDirectory + "2DIdle"; - if( DoesFileExist(sCurrentAnim + "/BGAnimation.ini") ) // check 2D Idle BGAnim exists - { - m_bgIdle[p].Load( sCurrentAnim ); - m_bgIdle[p]->SetXY(DC_X(p),DC_Y(p)); - } - - sCurrentAnim = sCharacterDirectory + "2DMiss"; - if( DoesFileExist(sCurrentAnim + "/BGAnimation.ini") ) // check 2D Idle BGAnim exists - { - m_bgMiss[p].Load( sCurrentAnim ); - m_bgMiss[p]->SetXY(DC_X(p),DC_Y(p)); - } - - sCurrentAnim = sCharacterDirectory + "2DGood"; - if( DoesFileExist(sCurrentAnim + "/BGAnimation.ini") ) // check 2D Idle BGAnim exists - { - m_bgGood[p].Load( sCurrentAnim ); - m_bgGood[p]->SetXY(DC_X(p),DC_Y(p)); - } - - sCurrentAnim = sCharacterDirectory + "2DGreat"; - if( DoesFileExist(sCurrentAnim + "/BGAnimation.ini") ) // check 2D Idle BGAnim exists - { - m_bgGreat[p].Load( sCurrentAnim ); - m_bgGreat[p]->SetXY(DC_X(p),DC_Y(p)); - } - - sCurrentAnim = sCharacterDirectory + "2DFever"; - if( DoesFileExist(sCurrentAnim + "/BGAnimation.ini") ) // check 2D Idle BGAnim exists - { - m_bgFever[p].Load( sCurrentAnim ); - m_bgFever[p]->SetXY(DC_X(p),DC_Y(p)); - } - - sCurrentAnim = sCharacterDirectory + "2DFail"; - if( DoesFileExist(sCurrentAnim + "/BGAnimation.ini") ) // check 2D Idle BGAnim exists - { - m_bgFail[p].Load( sCurrentAnim ); - m_bgFail[p]->SetXY(DC_X(p),DC_Y(p)); - } - - sCurrentAnim = sCharacterDirectory + "2DWin"; - if( DoesFileExist(sCurrentAnim + "/BGAnimation.ini") ) // check 2D Idle BGAnim exists - { - m_bgWin[p].Load( sCurrentAnim ); - m_bgWin[p]->SetXY(DC_X(p),DC_Y(p)); - } - - sCurrentAnim = sCharacterDirectory + "2DWinFever"; - if( DoesFileExist(sCurrentAnim + "/BGAnimation.ini") ) // check 2D Idle BGAnim exists - { - m_bgWinFever[p].Load( sCurrentAnim ); - m_bgWinFever[p]->SetXY(DC_X(p),DC_Y(p)); - } - - if( pChar->GetModelPath().empty() ) - continue; - - if( GAMESTATE->GetNumPlayersEnabled()==2 ) - m_pCharacter[p]->SetX( MODEL_X_TWO_PLAYERS[p] ); - else - m_pCharacter[p]->SetX( MODEL_X_ONE_PLAYER ); - - switch( GAMESTATE->m_PlayMode ) - { - case PLAY_MODE_BATTLE: - case PLAY_MODE_RAVE: - m_pCharacter[p]->SetRotationY( MODEL_ROTATIONY_TWO_PLAYERS[p] ); - default: - break; - } - - m_pCharacter[p]->LoadMilkshapeAscii( pChar->GetModelPath() ); - m_pCharacter[p]->LoadMilkshapeAsciiBones( "rest", pChar->GetRestAnimationPath() ); - m_pCharacter[p]->LoadMilkshapeAsciiBones( "warmup", pChar->GetWarmUpAnimationPath() ); - m_pCharacter[p]->LoadMilkshapeAsciiBones( "dance", pChar->GetDanceAnimationPath() ); - m_pCharacter[p]->SetCullMode( CULL_NONE ); // many of the models floating around have the vertex order flipped - - m_pCharacter[p]->RunCommands( pChar->m_cmdInit ); - } -} - -DancingCharacters::~DancingCharacters() -{ - FOREACH_PlayerNumber( p ) - delete m_pCharacter[p]; -} - -void DancingCharacters::LoadNextSong() -{ - // initial camera sweep is still - m_CameraDistance = CAMERA_REST_DISTANCE; - m_CameraPanYStart = 0; - m_CameraPanYEnd = 0; - m_fCameraHeightStart = CAMERA_REST_LOOK_AT_HEIGHT; - m_fCameraHeightEnd = CAMERA_REST_LOOK_AT_HEIGHT; - m_fLookAtHeight = CAMERA_REST_LOOK_AT_HEIGHT; - m_fThisCameraStartBeat = 0; - m_fThisCameraEndBeat = 0; - - ASSERT( GAMESTATE->m_pCurSong != NULL ); - m_fThisCameraEndBeat = GAMESTATE->m_pCurSong->GetFirstBeat(); - - FOREACH_PlayerNumber( p ) - if( GAMESTATE->IsPlayerEnabled(p) ) - m_pCharacter[p]->PlayAnimation( "rest" ); -} - -int Neg1OrPos1() { return RandomInt( 2 ) ? -1 : +1; } - -void DancingCharacters::Update( float fDelta ) -{ - if( GAMESTATE->m_Position.m_bFreeze || GAMESTATE->m_Position.m_bDelay ) - { - // spin the camera Matrix-style - m_CameraPanYStart += fDelta*40; - m_CameraPanYEnd += fDelta*40; - } - else - { - // make the characters move - float fBPM = GAMESTATE->m_Position.m_fCurBPS*60; - float fUpdateScale = SCALE( fBPM, 60.f, 300.f, 0.75f, 1.5f ); - CLAMP( fUpdateScale, 0.75f, 1.5f ); - - /* It's OK for the animation to go slower than natural when we're - * at a very low music rate. */ - fUpdateScale *= GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate; - - FOREACH_PlayerNumber( p ) - { - if( GAMESTATE->IsPlayerEnabled(p) ) - m_pCharacter[p]->Update( fDelta*fUpdateScale ); - } - } - - static bool bWasGameplayStarting = false; - bool bGameplayStarting = GAMESTATE->m_bGameplayLeadIn; - if( !bWasGameplayStarting && bGameplayStarting ) - { - FOREACH_PlayerNumber( p ) - if( GAMESTATE->IsPlayerEnabled(p) ) - m_pCharacter[p]->PlayAnimation( "warmup" ); - } - bWasGameplayStarting = bGameplayStarting; - - static float fLastBeat = GAMESTATE->m_Position.m_fSongBeat; - float firstBeat = GAMESTATE->m_pCurSong->GetFirstBeat(); - float fThisBeat = GAMESTATE->m_Position.m_fSongBeat; - if( fLastBeat < firstBeat && fThisBeat >= firstBeat ) - { - FOREACH_PlayerNumber( p ) - m_pCharacter[p]->PlayAnimation( "dance" ); - } - fLastBeat = fThisBeat; - - // time for a new sweep? - if (GAMESTATE->m_Position.m_fSongBeat > m_fThisCameraEndBeat) - { - if (RandomInt(6) >= 4) - { - // sweeping camera - m_CameraDistance = CAMERA_SWEEP_DISTANCE + RandomInt(-1, 1) * CAMERA_SWEEP_DISTANCE_VARIANCE; - m_CameraPanYStart = m_CameraPanYEnd = RandomInt(-1, 1) * CAMERA_SWEEP_PAN_Y_RANGE_DEGREES; - m_fCameraHeightStart = m_fCameraHeightEnd = CAMERA_STILL_LOOK_AT_HEIGHT; - - m_CameraPanYEnd += RandomInt(-1, 1) * CAMERA_SWEEP_PAN_Y_VARIANCE_DEGREES; - m_fCameraHeightStart = m_fCameraHeightEnd = m_fCameraHeightStart + RandomInt(-1, 1) * CAMERA_SWEEP_HEIGHT_VARIANCE; - - float fCameraHeightVariance = RandomInt(-1, 1) * CAMERA_SWEEP_HEIGHT_VARIANCE; - m_fCameraHeightStart -= fCameraHeightVariance; - m_fCameraHeightEnd += fCameraHeightVariance; - - m_fLookAtHeight = CAMERA_SWEEP_LOOK_AT_HEIGHT; - } - else - { - // still camera - m_CameraDistance = CAMERA_STILL_DISTANCE + RandomInt(-1, 1) * CAMERA_STILL_DISTANCE_VARIANCE; - m_CameraPanYStart = m_CameraPanYEnd = Neg1OrPos1() * CAMERA_STILL_PAN_Y_RANGE_DEGREES; - m_fCameraHeightStart = m_fCameraHeightEnd = CAMERA_SWEEP_LOOK_AT_HEIGHT + Neg1OrPos1() * CAMERA_STILL_HEIGHT_VARIANCE; - - m_fLookAtHeight = CAMERA_STILL_LOOK_AT_HEIGHT; - } - - int iCurBeat = (int)GAMESTATE->m_Position.m_fSongBeat; - // Need to convert it to a int, otherwise it complains. - int NewBeatToSet = (int)AMM_BEATS_TIL_NEXTCAMERA; - iCurBeat -= iCurBeat % NewBeatToSet; - - m_fThisCameraStartBeat = (float)iCurBeat; - m_fThisCameraEndBeat = float(iCurBeat + AMM_BEATS_TIL_NEXTCAMERA); - } - /* - // is there any of this still around? This block of code is _ugly_. -Colby - // update any 2D stuff - FOREACH_PlayerNumber( p ) - { - if( m_bgIdle[p].IsLoaded() ) - { - if( m_bgIdle[p].IsLoaded() && m_i2DAnimState[p] == AS2D_IDLE ) - m_bgIdle[p]->Update( fDelta ); - if( m_bgMiss[p].IsLoaded() && m_i2DAnimState[p] == AS2D_MISS ) - m_bgMiss[p]->Update( fDelta ); - if( m_bgGood[p].IsLoaded() && m_i2DAnimState[p] == AS2D_GOOD ) - m_bgGood[p]->Update( fDelta ); - if( m_bgGreat[p].IsLoaded() && m_i2DAnimState[p] == AS2D_GREAT ) - m_bgGreat[p]->Update( fDelta ); - if( m_bgFever[p].IsLoaded() && m_i2DAnimState[p] == AS2D_FEVER ) - m_bgFever[p]->Update( fDelta ); - if( m_bgFail[p].IsLoaded() && m_i2DAnimState[p] == AS2D_FAIL ) - m_bgFail[p]->Update( fDelta ); - if( m_bgWin[p].IsLoaded() && m_i2DAnimState[p] == AS2D_WIN ) - m_bgWin[p]->Update( fDelta ); - if( m_bgWinFever[p].IsLoaded() && m_i2DAnimState[p] == AS2D_WINFEVER ) - m_bgWinFever[p]->Update(fDelta); - - if(m_i2DAnimState[p] != AS2D_IDLE) // if we're not in idle state, start a timer to return us to idle - { - // never return to idle state if we have failed / passed (i.e. completed) the song - if(m_i2DAnimState[p] != AS2D_WINFEVER && m_i2DAnimState[p] != AS2D_FAIL && m_i2DAnimState[p] != AS2D_WIN) - { - if(m_2DIdleTimer[p].IsZero()) - m_2DIdleTimer[p].Touch(); - if(!m_2DIdleTimer[p].IsZero() && m_2DIdleTimer[p].Ago() > 1.0f) - { - m_2DIdleTimer[p].SetZero(); - m_i2DAnimState[p] = AS2D_IDLE; - } - } - } - } - } - */ -} - -void DancingCharacters::Change2DAnimState( PlayerNumber pn, int iState ) -{ - ASSERT( pn < NUM_PLAYERS ); - ASSERT( iState < AS2D_MAXSTATES ); - - m_i2DAnimState[pn] = iState; -} - -void DancingCharacters::DrawPrimitives() -{ - DISPLAY->CameraPushMatrix(); - - float fPercentIntoSweep; - if(m_fThisCameraStartBeat == m_fThisCameraEndBeat) - fPercentIntoSweep = 0; - else - fPercentIntoSweep = SCALE(GAMESTATE->m_Position.m_fSongBeat, m_fThisCameraStartBeat, m_fThisCameraEndBeat, 0.f, 1.f ); - float fCameraPanY = SCALE( fPercentIntoSweep, 0.f, 1.f, m_CameraPanYStart, m_CameraPanYEnd ); - float fCameraHeight = SCALE( fPercentIntoSweep, 0.f, 1.f, m_fCameraHeightStart, m_fCameraHeightEnd ); - - RageVector3 m_CameraPoint( 0, fCameraHeight, -m_CameraDistance ); - RageMatrix CameraRot; - RageMatrixRotationY( &CameraRot, fCameraPanY ); - RageVec3TransformCoord( &m_CameraPoint, &m_CameraPoint, &CameraRot ); - - RageVector3 m_LookAt( 0, m_fLookAtHeight, 0 ); - - DISPLAY->LoadLookAt( CAM_FOV, - m_CameraPoint, - m_LookAt, - RageVector3(0,1,0) ); - - FOREACH_EnabledPlayer( p ) - { - bool bFailed = STATSMAN->m_CurStageStats.m_player[p].m_bFailed; - bool bDanger = m_bDrawDangerLight; - - DISPLAY->SetLighting( true ); - - RageColor ambient = bFailed ? (RageColor)LIGHT_ADANGER_COLOR : (bDanger ? (RageColor)LIGHT_ADANGER_COLOR : (RageColor)LIGHT_AMBIENT_COLOR); - RageColor diffuse = bFailed ? (RageColor)LIGHT_DDANGER_COLOR : (bDanger ? (RageColor)LIGHT_DDANGER_COLOR : (RageColor)LIGHT_DIFFUSE_COLOR); - RageColor specular = (RageColor)LIGHT_AMBIENT_COLOR; - DISPLAY->SetLightDirectional( - 0, - ambient, - diffuse, - specular, - RageVector3(LIGHTING_X, LIGHTING_Y, LIGHTING_Z) ); - - if( PREFSMAN->m_bCelShadeModels ) - { - m_pCharacter[p]->DrawCelShaded(); - - DISPLAY->SetLightOff( 0 ); - DISPLAY->SetLighting( false ); - continue; - } - - m_pCharacter[p]->Draw(); - - DISPLAY->SetLightOff( 0 ); - DISPLAY->SetLighting( false ); - } - - DISPLAY->CameraPopMatrix(); - - /* - // Ugly! -Colby - // now draw any potential 2D stuff - FOREACH_PlayerNumber( p ) - { - if(m_bgIdle[p].IsLoaded() && m_i2DAnimState[p] == AS2D_IDLE) - m_bgIdle[p]->Draw(); - if(m_bgMiss[p].IsLoaded() && m_i2DAnimState[p] == AS2D_MISS) - m_bgMiss[p]->Draw(); - if(m_bgGood[p].IsLoaded() && m_i2DAnimState[p] == AS2D_GOOD) - m_bgGood[p]->Draw(); - if(m_bgGreat[p].IsLoaded() && m_i2DAnimState[p] == AS2D_GREAT) - m_bgGreat[p]->Draw(); - if(m_bgFever[p].IsLoaded() && m_i2DAnimState[p] == AS2D_FEVER) - m_bgFever[p]->Draw(); - if(m_bgWinFever[p].IsLoaded() && m_i2DAnimState[p] == AS2D_WINFEVER) - m_bgWinFever[p]->Draw(); - if(m_bgWin[p].IsLoaded() && m_i2DAnimState[p] == AS2D_WIN) - m_bgWin[p]->Draw(); - if(m_bgFail[p].IsLoaded() && m_i2DAnimState[p] == AS2D_FAIL) - m_bgFail[p]->Draw(); - } - */ -} - -/* 2018 Jose Varela - * (c) 2003-2004 Chris Danford - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "DancingCharacters.h" +#include "GameConstantsAndTypes.h" +#include "RageDisplay.h" +#include "RageUtil.h" +#include "RageMath.h" +#include "GameState.h" +#include "Song.h" +#include "Character.h" +#include "StatsManager.h" +#include "PrefsManager.h" +#include "Model.h" + +int Neg1OrPos1(); + +#define DC_X( choice ) THEME->GetMetricF("DancingCharacters",ssprintf("2DCharacterXP%d",choice+1)) +#define DC_Y( choice ) THEME->GetMetricF("DancingCharacters",ssprintf("2DCharacterYP%d",choice+1)) + +/* + * TODO: + * - Metrics/Lua for lighting and camera sweeping. + * - Ability to load secondary elements i.e. stages. + * - Remove support for 2D characters (Lua can do it). + * - Cleanup! + * + * -- Colby + */ + +#define CAMERA_REST_DISTANCE THEME->GetMetricF("DancingCamera","RestDistance") +#define CAMERA_REST_LOOK_AT_HEIGHT THEME->GetMetricF("DancingCamera","RestHeight") +#define CAMERA_SWEEP_DISTANCE THEME->GetMetricF("DancingCamera","SweepDistance") +#define CAMERA_SWEEP_DISTANCE_VARIANCE THEME->GetMetricF("DancingCamera","SweepDistanceVariable") +#define CAMERA_SWEEP_HEIGHT_VARIANCE THEME->GetMetricF("DancingCamera","SweepHeightVariable") +#define CAMERA_SWEEP_PAN_Y_RANGE_DEGREES THEME->GetMetricF("DancingCamera","SweepPanYRangeDegrees") +#define CAMERA_SWEEP_PAN_Y_VARIANCE_DEGREES THEME->GetMetricF("DancingCamera","SweepPanYVarianceDegrees") +#define CAMERA_SWEEP_LOOK_AT_HEIGHT THEME->GetMetricF("DancingCamera","SweepHeight") +#define CAMERA_STILL_DISTANCE THEME->GetMetricF("DancingCamera","StillDistance") +#define CAMERA_STILL_DISTANCE_VARIANCE THEME->GetMetricF("DancingCamera","StillDistanceVariance") +#define CAMERA_STILL_PAN_Y_RANGE_DEGREES THEME->GetMetricF("DancingCamera","StillPanYRangeDegrees") +#define CAMERA_STILL_HEIGHT_VARIANCE THEME->GetMetricF("DancingCamera","StillHeightVariance") +#define CAMERA_STILL_LOOK_AT_HEIGHT THEME->GetMetricF("DancingCamera","StillHeight") + +// This is to setup the lighting color. +const ThemeMetric LIGHT_AMBIENT_COLOR ( "DancingCamera", "AmbientColor" ); +const ThemeMetric LIGHT_DIFFUSE_COLOR ( "DancingCamera", "DiffuseColor" ); + +// This is for Danger and Failed colors. +const ThemeMetric LIGHT_ADANGER_COLOR ( "DancingCamera", "AmbientDangerColor" ); +const ThemeMetric LIGHT_AFAILED_COLOR ( "DancingCamera", "AmbientFailedColor" ); +const ThemeMetric LIGHT_DDANGER_COLOR ( "DancingCamera", "DiffuseDangerColor" ); +const ThemeMetric LIGHT_DFAILED_COLOR ( "DancingCamera", "DiffuseFailedColor" ); + +// This is to make positioning of said light. +#define LIGHTING_X THEME->GetMetricF("DancingCamera","LightX") +#define LIGHTING_Y THEME->GetMetricF("DancingCamera","LightY") +#define LIGHTING_Z THEME->GetMetricF("DancingCamera","LightZ") + +// Position of the model in X (one player) +#define MODEL_X_ONE_PLAYER THEME->GetMetricF("DancingCharacters","OnePlayerModelX") + +// As the name implies, this sets the ammount of beats that the camera will +// stay in its current state until transitioning to the next camera tween. +#define AMM_BEATS_TIL_NEXTCAMERA THEME->GetMetricF("DancingCamera","BeatsUntilNextCamPos") +#define CAM_FOV THEME->GetMetricF("DancingCamera","CameraFOV") + +const float MODEL_X_TWO_PLAYERS[NUM_PLAYERS] = { +8, -8 }; +const float MODEL_ROTATIONY_TWO_PLAYERS[NUM_PLAYERS] = { -90, 90 }; + +DancingCharacters::DancingCharacters(): m_bDrawDangerLight(false), + m_CameraDistance(0), m_CameraPanYStart(0), m_CameraPanYEnd(0), + m_fLookAtHeight(0), m_fCameraHeightStart(0), m_fCameraHeightEnd(0), + m_fThisCameraStartBeat(0), m_fThisCameraEndBeat(0) +{ + FOREACH_PlayerNumber( p ) + { + m_pCharacter[p] = new Model; + m_2DIdleTimer[p].SetZero(); + m_i2DAnimState[p] = AS2D_IDLE; // start on idle state + if( !GAMESTATE->IsPlayerEnabled(p) ) + continue; + + Character* pChar = GAMESTATE->m_pCurCharacters[p]; + if( !pChar ) + continue; + + // load in any potential 2D stuff + RString sCharacterDirectory = pChar->m_sCharDir; + RString sCurrentAnim; + sCurrentAnim = sCharacterDirectory + "2DIdle"; + if( DoesFileExist(sCurrentAnim + "/BGAnimation.ini") ) // check 2D Idle BGAnim exists + { + m_bgIdle[p].Load( sCurrentAnim ); + m_bgIdle[p]->SetXY(DC_X(p),DC_Y(p)); + } + + sCurrentAnim = sCharacterDirectory + "2DMiss"; + if( DoesFileExist(sCurrentAnim + "/BGAnimation.ini") ) // check 2D Idle BGAnim exists + { + m_bgMiss[p].Load( sCurrentAnim ); + m_bgMiss[p]->SetXY(DC_X(p),DC_Y(p)); + } + + sCurrentAnim = sCharacterDirectory + "2DGood"; + if( DoesFileExist(sCurrentAnim + "/BGAnimation.ini") ) // check 2D Idle BGAnim exists + { + m_bgGood[p].Load( sCurrentAnim ); + m_bgGood[p]->SetXY(DC_X(p),DC_Y(p)); + } + + sCurrentAnim = sCharacterDirectory + "2DGreat"; + if( DoesFileExist(sCurrentAnim + "/BGAnimation.ini") ) // check 2D Idle BGAnim exists + { + m_bgGreat[p].Load( sCurrentAnim ); + m_bgGreat[p]->SetXY(DC_X(p),DC_Y(p)); + } + + sCurrentAnim = sCharacterDirectory + "2DFever"; + if( DoesFileExist(sCurrentAnim + "/BGAnimation.ini") ) // check 2D Idle BGAnim exists + { + m_bgFever[p].Load( sCurrentAnim ); + m_bgFever[p]->SetXY(DC_X(p),DC_Y(p)); + } + + sCurrentAnim = sCharacterDirectory + "2DFail"; + if( DoesFileExist(sCurrentAnim + "/BGAnimation.ini") ) // check 2D Idle BGAnim exists + { + m_bgFail[p].Load( sCurrentAnim ); + m_bgFail[p]->SetXY(DC_X(p),DC_Y(p)); + } + + sCurrentAnim = sCharacterDirectory + "2DWin"; + if( DoesFileExist(sCurrentAnim + "/BGAnimation.ini") ) // check 2D Idle BGAnim exists + { + m_bgWin[p].Load( sCurrentAnim ); + m_bgWin[p]->SetXY(DC_X(p),DC_Y(p)); + } + + sCurrentAnim = sCharacterDirectory + "2DWinFever"; + if( DoesFileExist(sCurrentAnim + "/BGAnimation.ini") ) // check 2D Idle BGAnim exists + { + m_bgWinFever[p].Load( sCurrentAnim ); + m_bgWinFever[p]->SetXY(DC_X(p),DC_Y(p)); + } + + if( pChar->GetModelPath().empty() ) + continue; + + if( GAMESTATE->GetNumPlayersEnabled()==2 ) + m_pCharacter[p]->SetX( MODEL_X_TWO_PLAYERS[p] ); + else + m_pCharacter[p]->SetX( MODEL_X_ONE_PLAYER ); + + switch( GAMESTATE->m_PlayMode ) + { + case PLAY_MODE_BATTLE: + case PLAY_MODE_RAVE: + m_pCharacter[p]->SetRotationY( MODEL_ROTATIONY_TWO_PLAYERS[p] ); + default: + break; + } + + m_pCharacter[p]->LoadMilkshapeAscii( pChar->GetModelPath() ); + m_pCharacter[p]->LoadMilkshapeAsciiBones( "rest", pChar->GetRestAnimationPath() ); + m_pCharacter[p]->LoadMilkshapeAsciiBones( "warmup", pChar->GetWarmUpAnimationPath() ); + m_pCharacter[p]->LoadMilkshapeAsciiBones( "dance", pChar->GetDanceAnimationPath() ); + m_pCharacter[p]->SetCullMode( CULL_NONE ); // many of the models floating around have the vertex order flipped + + m_pCharacter[p]->RunCommands( pChar->m_cmdInit ); + } +} + +DancingCharacters::~DancingCharacters() +{ + FOREACH_PlayerNumber( p ) + delete m_pCharacter[p]; +} + +void DancingCharacters::LoadNextSong() +{ + // initial camera sweep is still + m_CameraDistance = CAMERA_REST_DISTANCE; + m_CameraPanYStart = 0; + m_CameraPanYEnd = 0; + m_fCameraHeightStart = CAMERA_REST_LOOK_AT_HEIGHT; + m_fCameraHeightEnd = CAMERA_REST_LOOK_AT_HEIGHT; + m_fLookAtHeight = CAMERA_REST_LOOK_AT_HEIGHT; + m_fThisCameraStartBeat = 0; + m_fThisCameraEndBeat = 0; + + ASSERT( GAMESTATE->m_pCurSong != nullptr ); + m_fThisCameraEndBeat = GAMESTATE->m_pCurSong->GetFirstBeat(); + + FOREACH_PlayerNumber( p ) + if( GAMESTATE->IsPlayerEnabled(p) ) + m_pCharacter[p]->PlayAnimation( "rest" ); +} + +int Neg1OrPos1() { return RandomInt( 2 ) ? -1 : +1; } + +void DancingCharacters::Update( float fDelta ) +{ + if( GAMESTATE->m_Position.m_bFreeze || GAMESTATE->m_Position.m_bDelay ) + { + // spin the camera Matrix-style + m_CameraPanYStart += fDelta*40; + m_CameraPanYEnd += fDelta*40; + } + else + { + // make the characters move + float fBPM = GAMESTATE->m_Position.m_fCurBPS*60; + float fUpdateScale = SCALE( fBPM, 60.f, 300.f, 0.75f, 1.5f ); + CLAMP( fUpdateScale, 0.75f, 1.5f ); + + /* It's OK for the animation to go slower than natural when we're + * at a very low music rate. */ + fUpdateScale *= GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate; + + FOREACH_PlayerNumber( p ) + { + if( GAMESTATE->IsPlayerEnabled(p) ) + m_pCharacter[p]->Update( fDelta*fUpdateScale ); + } + } + + static bool bWasGameplayStarting = false; + bool bGameplayStarting = GAMESTATE->m_bGameplayLeadIn; + if( !bWasGameplayStarting && bGameplayStarting ) + { + FOREACH_PlayerNumber( p ) + if( GAMESTATE->IsPlayerEnabled(p) ) + m_pCharacter[p]->PlayAnimation( "warmup" ); + } + bWasGameplayStarting = bGameplayStarting; + + static float fLastBeat = GAMESTATE->m_Position.m_fSongBeat; + float firstBeat = GAMESTATE->m_pCurSong->GetFirstBeat(); + float fThisBeat = GAMESTATE->m_Position.m_fSongBeat; + if( fLastBeat < firstBeat && fThisBeat >= firstBeat ) + { + FOREACH_PlayerNumber( p ) + m_pCharacter[p]->PlayAnimation( "dance" ); + } + fLastBeat = fThisBeat; + + // time for a new sweep? + if (GAMESTATE->m_Position.m_fSongBeat > m_fThisCameraEndBeat) + { + if (RandomInt(6) >= 4) + { + // sweeping camera + m_CameraDistance = CAMERA_SWEEP_DISTANCE + RandomInt(-1, 1) * CAMERA_SWEEP_DISTANCE_VARIANCE; + m_CameraPanYStart = m_CameraPanYEnd = RandomInt(-1, 1) * CAMERA_SWEEP_PAN_Y_RANGE_DEGREES; + m_fCameraHeightStart = m_fCameraHeightEnd = CAMERA_STILL_LOOK_AT_HEIGHT; + + m_CameraPanYEnd += RandomInt(-1, 1) * CAMERA_SWEEP_PAN_Y_VARIANCE_DEGREES; + m_fCameraHeightStart = m_fCameraHeightEnd = m_fCameraHeightStart + RandomInt(-1, 1) * CAMERA_SWEEP_HEIGHT_VARIANCE; + + float fCameraHeightVariance = RandomInt(-1, 1) * CAMERA_SWEEP_HEIGHT_VARIANCE; + m_fCameraHeightStart -= fCameraHeightVariance; + m_fCameraHeightEnd += fCameraHeightVariance; + + m_fLookAtHeight = CAMERA_SWEEP_LOOK_AT_HEIGHT; + } + else + { + // still camera + m_CameraDistance = CAMERA_STILL_DISTANCE + RandomInt(-1, 1) * CAMERA_STILL_DISTANCE_VARIANCE; + m_CameraPanYStart = m_CameraPanYEnd = Neg1OrPos1() * CAMERA_STILL_PAN_Y_RANGE_DEGREES; + m_fCameraHeightStart = m_fCameraHeightEnd = CAMERA_SWEEP_LOOK_AT_HEIGHT + Neg1OrPos1() * CAMERA_STILL_HEIGHT_VARIANCE; + + m_fLookAtHeight = CAMERA_STILL_LOOK_AT_HEIGHT; + } + + int iCurBeat = (int)GAMESTATE->m_Position.m_fSongBeat; + // Need to convert it to a int, otherwise it complains. + int NewBeatToSet = (int)AMM_BEATS_TIL_NEXTCAMERA; + iCurBeat -= iCurBeat % NewBeatToSet; + + m_fThisCameraStartBeat = (float)iCurBeat; + m_fThisCameraEndBeat = float(iCurBeat + AMM_BEATS_TIL_NEXTCAMERA); + } + /* + // is there any of this still around? This block of code is _ugly_. -Colby + // update any 2D stuff + FOREACH_PlayerNumber( p ) + { + if( m_bgIdle[p].IsLoaded() ) + { + if( m_bgIdle[p].IsLoaded() && m_i2DAnimState[p] == AS2D_IDLE ) + m_bgIdle[p]->Update( fDelta ); + if( m_bgMiss[p].IsLoaded() && m_i2DAnimState[p] == AS2D_MISS ) + m_bgMiss[p]->Update( fDelta ); + if( m_bgGood[p].IsLoaded() && m_i2DAnimState[p] == AS2D_GOOD ) + m_bgGood[p]->Update( fDelta ); + if( m_bgGreat[p].IsLoaded() && m_i2DAnimState[p] == AS2D_GREAT ) + m_bgGreat[p]->Update( fDelta ); + if( m_bgFever[p].IsLoaded() && m_i2DAnimState[p] == AS2D_FEVER ) + m_bgFever[p]->Update( fDelta ); + if( m_bgFail[p].IsLoaded() && m_i2DAnimState[p] == AS2D_FAIL ) + m_bgFail[p]->Update( fDelta ); + if( m_bgWin[p].IsLoaded() && m_i2DAnimState[p] == AS2D_WIN ) + m_bgWin[p]->Update( fDelta ); + if( m_bgWinFever[p].IsLoaded() && m_i2DAnimState[p] == AS2D_WINFEVER ) + m_bgWinFever[p]->Update(fDelta); + + if(m_i2DAnimState[p] != AS2D_IDLE) // if we're not in idle state, start a timer to return us to idle + { + // never return to idle state if we have failed / passed (i.e. completed) the song + if(m_i2DAnimState[p] != AS2D_WINFEVER && m_i2DAnimState[p] != AS2D_FAIL && m_i2DAnimState[p] != AS2D_WIN) + { + if(m_2DIdleTimer[p].IsZero()) + m_2DIdleTimer[p].Touch(); + if(!m_2DIdleTimer[p].IsZero() && m_2DIdleTimer[p].Ago() > 1.0f) + { + m_2DIdleTimer[p].SetZero(); + m_i2DAnimState[p] = AS2D_IDLE; + } + } + } + } + } + */ +} + +void DancingCharacters::Change2DAnimState( PlayerNumber pn, int iState ) +{ + ASSERT( pn < NUM_PLAYERS ); + ASSERT( iState < AS2D_MAXSTATES ); + + m_i2DAnimState[pn] = iState; +} + +void DancingCharacters::DrawPrimitives() +{ + DISPLAY->CameraPushMatrix(); + + float fPercentIntoSweep; + if(m_fThisCameraStartBeat == m_fThisCameraEndBeat) + fPercentIntoSweep = 0; + else + fPercentIntoSweep = SCALE(GAMESTATE->m_Position.m_fSongBeat, m_fThisCameraStartBeat, m_fThisCameraEndBeat, 0.f, 1.f ); + float fCameraPanY = SCALE( fPercentIntoSweep, 0.f, 1.f, m_CameraPanYStart, m_CameraPanYEnd ); + float fCameraHeight = SCALE( fPercentIntoSweep, 0.f, 1.f, m_fCameraHeightStart, m_fCameraHeightEnd ); + + RageVector3 m_CameraPoint( 0, fCameraHeight, -m_CameraDistance ); + RageMatrix CameraRot; + RageMatrixRotationY( &CameraRot, fCameraPanY ); + RageVec3TransformCoord( &m_CameraPoint, &m_CameraPoint, &CameraRot ); + + RageVector3 m_LookAt( 0, m_fLookAtHeight, 0 ); + + DISPLAY->LoadLookAt( CAM_FOV, + m_CameraPoint, + m_LookAt, + RageVector3(0,1,0) ); + + FOREACH_EnabledPlayer( p ) + { + bool bFailed = STATSMAN->m_CurStageStats.m_player[p].m_bFailed; + bool bDanger = m_bDrawDangerLight; + + DISPLAY->SetLighting( true ); + + RageColor ambient = bFailed ? (RageColor)LIGHT_ADANGER_COLOR : (bDanger ? (RageColor)LIGHT_ADANGER_COLOR : (RageColor)LIGHT_AMBIENT_COLOR); + RageColor diffuse = bFailed ? (RageColor)LIGHT_DDANGER_COLOR : (bDanger ? (RageColor)LIGHT_DDANGER_COLOR : (RageColor)LIGHT_DIFFUSE_COLOR); + RageColor specular = (RageColor)LIGHT_AMBIENT_COLOR; + DISPLAY->SetLightDirectional( + 0, + ambient, + diffuse, + specular, + RageVector3(LIGHTING_X, LIGHTING_Y, LIGHTING_Z) ); + + if( PREFSMAN->m_bCelShadeModels ) + { + m_pCharacter[p]->DrawCelShaded(); + + DISPLAY->SetLightOff( 0 ); + DISPLAY->SetLighting( false ); + continue; + } + + m_pCharacter[p]->Draw(); + + DISPLAY->SetLightOff( 0 ); + DISPLAY->SetLighting( false ); + } + + DISPLAY->CameraPopMatrix(); + + /* + // Ugly! -Colby + // now draw any potential 2D stuff + FOREACH_PlayerNumber( p ) + { + if(m_bgIdle[p].IsLoaded() && m_i2DAnimState[p] == AS2D_IDLE) + m_bgIdle[p]->Draw(); + if(m_bgMiss[p].IsLoaded() && m_i2DAnimState[p] == AS2D_MISS) + m_bgMiss[p]->Draw(); + if(m_bgGood[p].IsLoaded() && m_i2DAnimState[p] == AS2D_GOOD) + m_bgGood[p]->Draw(); + if(m_bgGreat[p].IsLoaded() && m_i2DAnimState[p] == AS2D_GREAT) + m_bgGreat[p]->Draw(); + if(m_bgFever[p].IsLoaded() && m_i2DAnimState[p] == AS2D_FEVER) + m_bgFever[p]->Draw(); + if(m_bgWinFever[p].IsLoaded() && m_i2DAnimState[p] == AS2D_WINFEVER) + m_bgWinFever[p]->Draw(); + if(m_bgWin[p].IsLoaded() && m_i2DAnimState[p] == AS2D_WIN) + m_bgWin[p]->Draw(); + if(m_bgFail[p].IsLoaded() && m_i2DAnimState[p] == AS2D_FAIL) + m_bgFail[p]->Draw(); + } + */ +} + +/* 2018 Jose Varela + * (c) 2003-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/DancingCharacters.h b/src/DancingCharacters.h index 4894b51191..36f5240d90 100644 --- a/src/DancingCharacters.h +++ b/src/DancingCharacters.h @@ -1,95 +1,97 @@ -#ifndef DancingCharacters_H -#define DancingCharacters_H - -#include "ActorFrame.h" -#include "PlayerNumber.h" -#include "ThemeManager.h" -#include "RageTimer.h" -#include "AutoActor.h" -class Model; - -/** @brief The different animation states for the dancer. */ -enum ANIM_STATES_2D -{ - AS2D_IDLE = 0, /**< The dancer is idle. */ - AS2D_MISS, /**< The dancer just missed a note. */ - AS2D_GOOD, /**< The dancer is doing a good job. */ - AS2D_GREAT, /**< The dancer is doing a great job. */ - AS2D_FEVER, /**< The dancer is on fire! */ - AS2D_FAIL, /**< The dancer has failed. */ - AS2D_WIN, /**< The dancer has won. */ - AS2D_WINFEVER, /**< The dancer has won while on fire. */ - AS2D_IGNORE, /**< This is a special case -- so that we can timer to idle again. */ - AS2D_MAXSTATES /**< A count of the maximum number of states. */ -}; - -/** @brief Characters that react to how the players are doing. */ -class DancingCharacters : public ActorFrame -{ -public: - DancingCharacters(); - virtual ~DancingCharacters(); - - void LoadNextSong(); - - virtual void Update( float fDelta ); - virtual void DrawPrimitives(); - bool m_bDrawDangerLight; - void Change2DAnimState( PlayerNumber pn, int iState ); -protected: - - Model *m_pCharacter[NUM_PLAYERS]; - - /** @brief How far away is the camera from the dancer? */ - float m_CameraDistance; - float m_CameraPanYStart; - float m_CameraPanYEnd; - float m_fLookAtHeight; - float m_fCameraHeightStart; - float m_fCameraHeightEnd; - float m_fThisCameraStartBeat; - float m_fThisCameraEndBeat; - - bool m_bHas2DElements[NUM_PLAYERS]; - - AutoActor m_bgIdle[NUM_PLAYERS]; - AutoActor m_bgMiss[NUM_PLAYERS]; - AutoActor m_bgGood[NUM_PLAYERS]; - AutoActor m_bgGreat[NUM_PLAYERS]; - AutoActor m_bgFever[NUM_PLAYERS]; - AutoActor m_bgFail[NUM_PLAYERS]; - AutoActor m_bgWin[NUM_PLAYERS]; - AutoActor m_bgWinFever[NUM_PLAYERS]; - RageTimer m_2DIdleTimer[NUM_PLAYERS]; - - int m_i2DAnimState[NUM_PLAYERS]; -}; - -#endif - -/** - * @file - * @author Chris Danford (c) 2003-2004 - * @section LICENSE - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#ifndef DancingCharacters_H +#define DancingCharacters_H + +#include "ActorFrame.h" +#include "PlayerNumber.h" +#include "ThemeManager.h" +#include "RageTimer.h" +#include "AutoActor.h" +#include +class Model; + +/** @brief The different animation states for the dancer. */ +enum ANIM_STATES_2D +{ + AS2D_IDLE = 0, /**< The dancer is idle. */ + AS2D_MISS, /**< The dancer just missed a note. */ + AS2D_GOOD, /**< The dancer is doing a good job. */ + AS2D_GREAT, /**< The dancer is doing a great job. */ + AS2D_FEVER, /**< The dancer is on fire! */ + AS2D_FAIL, /**< The dancer has failed. */ + AS2D_WIN, /**< The dancer has won. */ + AS2D_WINFEVER, /**< The dancer has won while on fire. */ + AS2D_IGNORE, /**< This is a special case -- so that we can timer to idle again. */ + AS2D_MAXSTATES /**< A count of the maximum number of states. */ +}; + +/** @brief Characters that react to how the players are doing. */ +class DancingCharacters : public ActorFrame +{ +public: + DancingCharacters(); + virtual ~DancingCharacters(); + + void LoadNextSong(); + + virtual void Update( float fDelta ); + virtual void DrawPrimitives(); + bool m_bDrawDangerLight; + void Change2DAnimState( PlayerNumber pn, int iState ); +protected: + + std::array m_pCharacter; + + /** @brief How far away is the camera from the dancer? */ + float m_CameraDistance; + float m_CameraPanYStart; + float m_CameraPanYEnd; + float m_fLookAtHeight; + float m_fCameraHeightStart; + float m_fCameraHeightEnd; + float m_fThisCameraStartBeat; + float m_fThisCameraEndBeat; + + std::array m_bHas2DElements; + + + std::array m_bgIdle; + std::array m_bgMiss; + std::array m_bgGood; + std::array m_bgGreat; + std::array m_bgFever; + std::array m_bgFail; + std::array m_bgWin; + std::array m_bgWinFever; + std::array m_2DIdleTimer; + + std::array m_i2DAnimState; +}; + +#endif + +/** + * @file + * @author Chris Danford (c) 2003-2004 + * @section LICENSE + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/DateTime.cpp b/src/DateTime.cpp index a99230e0cc..722fc109be 100644 --- a/src/DateTime.cpp +++ b/src/DateTime.cpp @@ -1,352 +1,352 @@ -#include "global.h" -#include "DateTime.h" -#include "RageUtil.h" -#include "EnumHelper.h" -#include "LuaManager.h" -#include "LocalizedString.h" - -DateTime::DateTime() -{ - Init(); -} - -void DateTime::Init() -{ - ZERO( *this ); -} - -bool DateTime::operator<( const DateTime& other ) const -{ -#define COMPARE( v ) if(v!=other.v) return v( const DateTime& other ) const -{ -#define COMPARE( v ) if(v!=other.v) return v>other.v; - COMPARE( tm_year ); - COMPARE( tm_mon ); - COMPARE( tm_mday ); - COMPARE( tm_hour ); - COMPARE( tm_min ); - COMPARE( tm_sec ); -#undef COMPARE - // they're equal - return false; -} - -DateTime DateTime::GetNowDateTime() -{ - time_t now = time(NULL); - tm tNow; - localtime_r( &now, &tNow ); - DateTime dtNow; -#define COPY_M( v ) dtNow.v = tNow.v; - COPY_M( tm_year ); - COPY_M( tm_mon ); - COPY_M( tm_mday ); - COPY_M( tm_hour ); - COPY_M( tm_min ); - COPY_M( tm_sec ); -#undef COPY_M - return dtNow; -} - -DateTime DateTime::GetNowDate() -{ - DateTime tNow = GetNowDateTime(); - tNow.StripTime(); - return tNow; -} - -void DateTime::StripTime() -{ - tm_hour = 0; - tm_min = 0; - tm_sec = 0; -} - -// Common SQL/XML format: "YYYY-MM-DD HH:MM:SS" -RString DateTime::GetString() const -{ - RString s = ssprintf( "%d-%02d-%02d", - tm_year+1900, - tm_mon+1, - tm_mday ); - - if( tm_hour != 0 || - tm_min != 0 || - tm_sec != 0 ) - { - s += ssprintf( " %02d:%02d:%02d", - tm_hour, - tm_min, - tm_sec ); - } - - return s; -} - -bool DateTime::FromString( const RString sDateTime ) -{ - Init(); - - int ret; - - ret = sscanf( sDateTime, "%d-%d-%d %d:%d:%d", - &tm_year, - &tm_mon, - &tm_mday, - &tm_hour, - &tm_min, - &tm_sec ); - if( ret != 6 ) - { - ret = sscanf( sDateTime, "%d-%d-%d", - &tm_year, - &tm_mon, - &tm_mday ); - if( ret != 3 ) - { - return false; - } - } - - tm_year -= 1900; - tm_mon -= 1; - return true; -} - - - -RString DayInYearToString( int iDayInYear ) -{ - return ssprintf("DayInYear%03d",iDayInYear); -} - -int StringToDayInYear( RString sDayInYear ) -{ - int iDayInYear; - if( sscanf( sDayInYear, "DayInYear%d", &iDayInYear ) != 1 ) - return -1; - return iDayInYear; -} - -static const RString LAST_DAYS_NAME[NUM_LAST_DAYS] = -{ - "Today", - "Yesterday", - "Day2Ago", - "Day3Ago", - "Day4Ago", - "Day5Ago", - "Day6Ago", -}; - -RString LastDayToString( int iLastDayIndex ) -{ - return LAST_DAYS_NAME[iLastDayIndex]; -} - -static const char *DAY_OF_WEEK_TO_NAME[DAYS_IN_WEEK] = -{ - "Sunday", - "Monday", - "Tuesday", - "Wednesday", - "Thursday", - "Friday", - "Saturday", -}; - -RString DayOfWeekToString( int iDayOfWeekIndex ) -{ - return DAY_OF_WEEK_TO_NAME[iDayOfWeekIndex]; -} - -RString HourInDayToString( int iHourInDayIndex ) -{ - return ssprintf("Hour%02d", iHourInDayIndex); -} - -static const char *MonthNames[] = -{ - "January", - "February", - "March", - "April", - "May", - "June", - "July", - "August", - "September", - "October", - "November", - "December", -}; -XToString( Month ); -XToLocalizedString( Month ); -LuaXType( Month ); - -RString LastWeekToString( int iLastWeekIndex ) -{ - switch( iLastWeekIndex ) - { - case 0: return "ThisWeek"; break; - case 1: return "LastWeek"; break; - default: return ssprintf("Week%02dAgo",iLastWeekIndex); break; - } -} - -RString LastDayToLocalizedString( int iLastDayIndex ) -{ - RString s = LastDayToString( iLastDayIndex ); - s.Replace( "Day", "" ); - s.Replace( "Ago", " Ago" ); - return s; -} - -RString LastWeekToLocalizedString( int iLastWeekIndex ) -{ - RString s = LastWeekToString( iLastWeekIndex ); - s.Replace( "Week", "" ); - s.Replace( "Ago", " Ago" ); - return s; -} - -RString HourInDayToLocalizedString( int iHourIndex ) -{ - int iBeginHour = iHourIndex; - iBeginHour--; - wrap( iBeginHour, 24 ); - iBeginHour++; - - return ssprintf("%02d:00+", iBeginHour ); -} - - -tm AddDays( tm start, int iDaysToMove ) -{ - /* - * This causes problems on OS X, which doesn't correctly handle range that are below - * their normal values (eg. mday = 0). According to the manpage, it should adjust them: - * - * "If structure members are outside their legal interval, they will be normalized (so - * that, e.g., 40 October is changed into 9 November)." - * - * Instead, it appears to simply fail. - * - * Refs: - * http://bugs.php.net/bug.php?id=10686 - * http://sourceforge.net/tracker/download.php?group_id=37892&atid=421366&file_id=79179&aid=91133 - * - * Note "Log starting 2004-03-07 03:50:42"; mday is 7, and PrintCaloriesBurned calls us - * with iDaysToMove = -7, resulting in an out-of-range value 0. This seems legal, but - * OS X chokes on it. - */ -/* start.tm_mday += iDaysToMove; - time_t seconds = mktime( &start ); - ASSERT( seconds != (time_t)-1 ); - */ - - /* This handles DST differently: it returns the time that was exactly n*60*60*24 seconds - * ago, where the above code always returns the same time of day. I prefer the above - * behavior, but I'm not sure that it mattersmatters. */ - time_t seconds = mktime( &start ); - seconds += iDaysToMove*60*60*24; - - tm time; - localtime_r( &seconds, &time ); - return time; -} - -tm GetYesterday( tm start ) -{ - return AddDays( start, -1 ); -} - -int GetDayOfWeek( tm time ) -{ - int iDayOfWeek = time.tm_wday; - ASSERT( iDayOfWeek < DAYS_IN_WEEK ); - return iDayOfWeek; -} - -tm GetNextSunday( tm start ) -{ - return AddDays( start, DAYS_IN_WEEK-GetDayOfWeek(start) ); -} - - -tm GetDayInYearAndYear( int iDayInYearIndex, int iYear ) -{ - /* If iDayInYearIndex is 200, set the date to Jan 200th, and let mktime - * round it. This shouldn't suffer from the OSX mktime() issue described - * above, since we're not giving it negative values. */ - tm when; - ZERO( when ); - when.tm_mon = 0; - when.tm_mday = iDayInYearIndex+1; - when.tm_year = iYear - 1900; - time_t then = mktime( &when ); - - localtime_r( &then, &when ); - return when; -} - -LuaFunction( MonthToString, MonthToString( Enum::Check(L, 1) ) ); -LuaFunction( MonthToLocalizedString, MonthToLocalizedString( Enum::Check(L, 1) ) ); -LuaFunction( MonthOfYear, GetLocalTime().tm_mon ); -LuaFunction( DayOfMonth, GetLocalTime().tm_mday ); -LuaFunction( Hour, GetLocalTime().tm_hour ); -LuaFunction( Minute, GetLocalTime().tm_min ); -LuaFunction( Second, GetLocalTime().tm_sec ); -LuaFunction( Year, GetLocalTime().tm_year+1900 ); -LuaFunction( Weekday, GetLocalTime().tm_wday ); -LuaFunction( DayOfYear, GetLocalTime().tm_yday ); - -/* - * (c) 2001-2004 Chris Danford - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "DateTime.h" +#include "RageUtil.h" +#include "EnumHelper.h" +#include "LuaManager.h" +#include "LocalizedString.h" + +DateTime::DateTime() +{ + Init(); +} + +void DateTime::Init() +{ + ZERO( *this ); +} + +bool DateTime::operator<( const DateTime& other ) const +{ +#define COMPARE( v ) if(v!=other.v) return v( const DateTime& other ) const +{ +#define COMPARE( v ) if(v!=other.v) return v>other.v; + COMPARE( tm_year ); + COMPARE( tm_mon ); + COMPARE( tm_mday ); + COMPARE( tm_hour ); + COMPARE( tm_min ); + COMPARE( tm_sec ); +#undef COMPARE + // they're equal + return false; +} + +DateTime DateTime::GetNowDateTime() +{ + time_t now = time(nullptr); + tm tNow; + localtime_r( &now, &tNow ); + DateTime dtNow; +#define COPY_M( v ) dtNow.v = tNow.v; + COPY_M( tm_year ); + COPY_M( tm_mon ); + COPY_M( tm_mday ); + COPY_M( tm_hour ); + COPY_M( tm_min ); + COPY_M( tm_sec ); +#undef COPY_M + return dtNow; +} + +DateTime DateTime::GetNowDate() +{ + DateTime tNow = GetNowDateTime(); + tNow.StripTime(); + return tNow; +} + +void DateTime::StripTime() +{ + tm_hour = 0; + tm_min = 0; + tm_sec = 0; +} + +// Common SQL/XML format: "YYYY-MM-DD HH:MM:SS" +RString DateTime::GetString() const +{ + RString s = ssprintf( "%d-%02d-%02d", + tm_year+1900, + tm_mon+1, + tm_mday ); + + if( tm_hour != 0 || + tm_min != 0 || + tm_sec != 0 ) + { + s += ssprintf( " %02d:%02d:%02d", + tm_hour, + tm_min, + tm_sec ); + } + + return s; +} + +bool DateTime::FromString( const RString sDateTime ) +{ + Init(); + + int ret; + + ret = sscanf( sDateTime, "%d-%d-%d %d:%d:%d", + &tm_year, + &tm_mon, + &tm_mday, + &tm_hour, + &tm_min, + &tm_sec ); + if( ret != 6 ) + { + ret = sscanf( sDateTime, "%d-%d-%d", + &tm_year, + &tm_mon, + &tm_mday ); + if( ret != 3 ) + { + return false; + } + } + + tm_year -= 1900; + tm_mon -= 1; + return true; +} + + + +RString DayInYearToString( int iDayInYear ) +{ + return ssprintf("DayInYear%03d",iDayInYear); +} + +int StringToDayInYear( RString sDayInYear ) +{ + int iDayInYear; + if( sscanf( sDayInYear, "DayInYear%d", &iDayInYear ) != 1 ) + return -1; + return iDayInYear; +} + +static const RString LAST_DAYS_NAME[NUM_LAST_DAYS] = +{ + "Today", + "Yesterday", + "Day2Ago", + "Day3Ago", + "Day4Ago", + "Day5Ago", + "Day6Ago", +}; + +RString LastDayToString( int iLastDayIndex ) +{ + return LAST_DAYS_NAME[iLastDayIndex]; +} + +static const char *DAY_OF_WEEK_TO_NAME[DAYS_IN_WEEK] = +{ + "Sunday", + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday", +}; + +RString DayOfWeekToString( int iDayOfWeekIndex ) +{ + return DAY_OF_WEEK_TO_NAME[iDayOfWeekIndex]; +} + +RString HourInDayToString( int iHourInDayIndex ) +{ + return ssprintf("Hour%02d", iHourInDayIndex); +} + +static const char *MonthNames[] = +{ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December", +}; +XToString( Month ); +XToLocalizedString( Month ); +LuaXType( Month ); + +RString LastWeekToString( int iLastWeekIndex ) +{ + switch( iLastWeekIndex ) + { + case 0: return "ThisWeek"; break; + case 1: return "LastWeek"; break; + default: return ssprintf("Week%02dAgo",iLastWeekIndex); break; + } +} + +RString LastDayToLocalizedString( int iLastDayIndex ) +{ + RString s = LastDayToString( iLastDayIndex ); + s.Replace( "Day", "" ); + s.Replace( "Ago", " Ago" ); + return s; +} + +RString LastWeekToLocalizedString( int iLastWeekIndex ) +{ + RString s = LastWeekToString( iLastWeekIndex ); + s.Replace( "Week", "" ); + s.Replace( "Ago", " Ago" ); + return s; +} + +RString HourInDayToLocalizedString( int iHourIndex ) +{ + int iBeginHour = iHourIndex; + iBeginHour--; + wrap( iBeginHour, 24 ); + iBeginHour++; + + return ssprintf("%02d:00+", iBeginHour ); +} + + +tm AddDays( tm start, int iDaysToMove ) +{ + /* + * This causes problems on OS X, which doesn't correctly handle range that are below + * their normal values (eg. mday = 0). According to the manpage, it should adjust them: + * + * "If structure members are outside their legal interval, they will be normalized (so + * that, e.g., 40 October is changed into 9 November)." + * + * Instead, it appears to simply fail. + * + * Refs: + * http://bugs.php.net/bug.php?id=10686 + * http://sourceforge.net/tracker/download.php?group_id=37892&atid=421366&file_id=79179&aid=91133 + * + * Note "Log starting 2004-03-07 03:50:42"; mday is 7, and PrintCaloriesBurned calls us + * with iDaysToMove = -7, resulting in an out-of-range value 0. This seems legal, but + * OS X chokes on it. + */ +/* start.tm_mday += iDaysToMove; + time_t seconds = mktime( &start ); + ASSERT( seconds != (time_t)-1 ); + */ + + /* This handles DST differently: it returns the time that was exactly n*60*60*24 seconds + * ago, where the above code always returns the same time of day. I prefer the above + * behavior, but I'm not sure that it mattersmatters. */ + time_t seconds = mktime( &start ); + seconds += iDaysToMove*60*60*24; + + tm time; + localtime_r( &seconds, &time ); + return time; +} + +tm GetYesterday( tm start ) +{ + return AddDays( start, -1 ); +} + +int GetDayOfWeek( tm time ) +{ + int iDayOfWeek = time.tm_wday; + ASSERT( iDayOfWeek < DAYS_IN_WEEK ); + return iDayOfWeek; +} + +tm GetNextSunday( tm start ) +{ + return AddDays( start, DAYS_IN_WEEK-GetDayOfWeek(start) ); +} + + +tm GetDayInYearAndYear( int iDayInYearIndex, int iYear ) +{ + /* If iDayInYearIndex is 200, set the date to Jan 200th, and let mktime + * round it. This shouldn't suffer from the OSX mktime() issue described + * above, since we're not giving it negative values. */ + tm when; + ZERO( when ); + when.tm_mon = 0; + when.tm_mday = iDayInYearIndex+1; + when.tm_year = iYear - 1900; + time_t then = mktime( &when ); + + localtime_r( &then, &when ); + return when; +} + +LuaFunction( MonthToString, MonthToString( Enum::Check(L, 1) ) ); +LuaFunction( MonthToLocalizedString, MonthToLocalizedString( Enum::Check(L, 1) ) ); +LuaFunction( MonthOfYear, GetLocalTime().tm_mon ); +LuaFunction( DayOfMonth, GetLocalTime().tm_mday ); +LuaFunction( Hour, GetLocalTime().tm_hour ); +LuaFunction( Minute, GetLocalTime().tm_min ); +LuaFunction( Second, GetLocalTime().tm_sec ); +LuaFunction( Year, GetLocalTime().tm_year+1900 ); +LuaFunction( Weekday, GetLocalTime().tm_wday ); +LuaFunction( DayOfYear, GetLocalTime().tm_yday ); + +/* + * (c) 2001-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/Difficulty.cpp b/src/Difficulty.cpp index 0201139495..a2d0945985 100644 --- a/src/Difficulty.cpp +++ b/src/Difficulty.cpp @@ -23,13 +23,13 @@ LuaXType( Difficulty ); const RString &CourseDifficultyToLocalizedString( CourseDifficulty x ) { - static auto_ptr g_CourseDifficultyName[NUM_Difficulty]; - if( g_CourseDifficultyName[0].get() == NULL ) + static unique_ptr g_CourseDifficultyName[NUM_Difficulty]; + if( g_CourseDifficultyName[0].get() == nullptr ) { FOREACH_ENUM( Difficulty,i) { - auto_ptr ap( new LocalizedString("CourseDifficulty", DifficultyToString(i)) ); - g_CourseDifficultyName[i] = ap; + unique_ptr ap( new LocalizedString("CourseDifficulty", DifficultyToString(i)) ); + g_CourseDifficultyName[i] = move(ap); } } return g_CourseDifficultyName[x]->GetValue(); @@ -114,18 +114,18 @@ RString GetCustomDifficulty( StepsType st, Difficulty dc, CourseType ct ) // OPTIMIZATION OPPORTUNITY: cache these metrics and cache the splitting vector vsNames; split( NAMES, ",", vsNames ); - FOREACH( RString, vsNames, sName ) + for (RString const &sName: vsNames) { - ThemeMetric STEPS_TYPE("CustomDifficulty",(*sName)+"StepsType"); + ThemeMetric STEPS_TYPE("CustomDifficulty",sName + "StepsType"); if( STEPS_TYPE == StepsType_Invalid || st == STEPS_TYPE ) // match { - ThemeMetric DIFFICULTY("CustomDifficulty",(*sName)+"Difficulty"); + ThemeMetric DIFFICULTY("CustomDifficulty",sName + "Difficulty"); if( DIFFICULTY == Difficulty_Invalid || dc == DIFFICULTY ) // match { - ThemeMetric COURSE_TYPE("CustomDifficulty",(*sName)+"CourseType"); + ThemeMetric COURSE_TYPE("CustomDifficulty",sName + "CourseType"); if( COURSE_TYPE == CourseType_Invalid || ct == COURSE_TYPE ) // match { - ThemeMetric STRING("CustomDifficulty",(*sName)+"String"); + ThemeMetric STRING("CustomDifficulty",sName + "String"); return STRING.GetValue(); } } diff --git a/src/DifficultyIcon.cpp b/src/DifficultyIcon.cpp index 58eead5f75..b2c53d0f2c 100644 --- a/src/DifficultyIcon.cpp +++ b/src/DifficultyIcon.cpp @@ -62,7 +62,7 @@ void DifficultyIcon::SetPlayer( PlayerNumber pn ) void DifficultyIcon::SetFromSteps( PlayerNumber pn, const Steps* pSteps ) { SetPlayer( pn ); - if( pSteps == NULL ) + if( pSteps == nullptr ) Unset(); else SetFromDifficulty( pSteps->GetDifficulty() ); @@ -71,7 +71,7 @@ void DifficultyIcon::SetFromSteps( PlayerNumber pn, const Steps* pSteps ) void DifficultyIcon::SetFromTrail( PlayerNumber pn, const Trail* pTrail ) { SetPlayer( pn ); - if( pTrail == NULL ) + if( pTrail == nullptr ) Unset(); else SetFromDifficulty( pTrail->m_CourseDifficulty ); diff --git a/src/DifficultyList.cpp b/src/DifficultyList.cpp index 1709f4fc8e..d17031e090 100644 --- a/src/DifficultyList.cpp +++ b/src/DifficultyList.cpp @@ -7,7 +7,7 @@ #include "StepsDisplay.h" #include "StepsUtil.h" #include "CommonMetrics.h" -#include "Foreach.h" + #include "SongUtil.h" #include "XmlFile.h" @@ -49,12 +49,12 @@ void StepsDisplayList::LoadFromNode( const XNode* pNode ) MOVE_COMMAND.Load( m_sName, "MoveCommand" ); m_Lines.resize( MAX_METERS ); - m_CurSong = NULL; + m_CurSong = nullptr; FOREACH_ENUM( PlayerNumber, pn ) { const XNode *pChild = pNode->GetChild( ssprintf("CursorP%i",pn+1) ); - if( pChild == NULL ) + if( pChild == nullptr ) { LuaHelpers::ReportScriptErrorFmt("%s: StepsDisplayList: missing the node \"CursorP%d\"", ActorUtil::GetWhere(pNode).c_str(), pn+1); } @@ -70,7 +70,7 @@ void StepsDisplayList::LoadFromNode( const XNode* pNode ) * in separate tweening stacks. This means the Cursor command can't change diffuse * colors; I think we do need a diffuse color stack ... */ pChild = pNode->GetChild( ssprintf("CursorP%iFrame",pn+1) ); - if( pChild == NULL ) + if( pChild == nullptr ) { LuaHelpers::ReportScriptErrorFmt("%s: StepsDisplayList: missing the node \"CursorP%dFrame\"", ActorUtil::GetWhere(pNode).c_str(), pn+1); } @@ -86,7 +86,7 @@ void StepsDisplayList::LoadFromNode( const XNode* pNode ) { // todo: Use Row1, Row2 for names? also m_sName+"Row" -aj m_Lines[m].m_Meter.SetName( "Row" ); - m_Lines[m].m_Meter.Load( "StepsDisplayListRow", NULL ); + m_Lines[m].m_Meter.Load( "StepsDisplayListRow", nullptr ); this->AddChild( &m_Lines[m].m_Meter ); } @@ -102,7 +102,7 @@ int StepsDisplayList::GetCurrentRowIndex( PlayerNumber pn ) const { const Row &row = m_Rows[i]; - if( GAMESTATE->m_pCurSteps[pn] == NULL ) + if( GAMESTATE->m_pCurSteps[pn] == nullptr ) { if( row.m_dc == ClosestDifficulty ) return i; @@ -267,17 +267,17 @@ void StepsDisplayList::SetFromGameState() const Song *pSong = GAMESTATE->m_pCurSong; unsigned i = 0; - if( pSong == NULL ) + if( pSong == nullptr ) { // FIXME: This clamps to between the min and the max difficulty, but // it really should round to the nearest difficulty that's in // DIFFICULTIES_TO_SHOW. const vector& difficulties = CommonMetrics::DIFFICULTIES_TO_SHOW.GetValue(); m_Rows.resize( difficulties.size() ); - FOREACH_CONST( Difficulty, difficulties, d ) + for (Difficulty const &d : difficulties) { - m_Rows[i].m_dc = *d; - m_Lines[i].m_Meter.SetFromStepsTypeAndMeterAndDifficultyAndCourseType( GAMESTATE->GetCurrentStyle(PLAYER_INVALID)->m_StepsType, 0, *d, CourseType_Invalid ); + m_Rows[i].m_dc = d; + m_Lines[i].m_Meter.SetFromStepsTypeAndMeterAndDifficultyAndCourseType( GAMESTATE->GetCurrentStyle(PLAYER_INVALID)->m_StepsType, 0, d, CourseType_Invalid ); ++i; } } @@ -288,11 +288,11 @@ void StepsDisplayList::SetFromGameState() // Should match the sort in ScreenSelectMusic::AfterMusicChange. m_Rows.resize( vpSteps.size() ); - FOREACH_CONST( Steps*, vpSteps, s ) + for (Steps const * s: vpSteps) { //LOG->Trace(ssprintf("setting steps for row %i",i)); - m_Rows[i].m_Steps = *s; - m_Lines[i].m_Meter.SetFromSteps( *s ); + m_Rows[i].m_Steps = s; + m_Lines[i].m_Meter.SetFromSteps( s ); ++i; } } diff --git a/src/DifficultyList.h b/src/DifficultyList.h index 0d0817fa91..a641db6ad9 100644 --- a/src/DifficultyList.h +++ b/src/DifficultyList.h @@ -1,100 +1,100 @@ -/* StepsDisplayList - Shows all available difficulties for a Song/Course. */ -#ifndef DIFFICULTY_LIST_H -#define DIFFICULTY_LIST_H - -#include "ActorFrame.h" -#include "PlayerNumber.h" -#include "StepsDisplay.h" -#include "ThemeMetric.h" - -class Song; -class Steps; - -class StepsDisplayList: public ActorFrame -{ -public: - StepsDisplayList(); - virtual ~StepsDisplayList(); - virtual StepsDisplayList *Copy() const; - virtual void LoadFromNode( const XNode* pNode ); - - void HandleMessage( const Message &msg ); - - void SetFromGameState(); - void TweenOnScreen(); - void TweenOffScreen(); - void Hide(); - void Show(); - - // Lua - void PushSelf( lua_State *L ); - -private: - void UpdatePositions(); - void PositionItems(); - int GetCurrentRowIndex( PlayerNumber pn ) const; - void HideRows(); - - ThemeMetric ITEMS_SPACING_Y; - ThemeMetric NUM_SHOWN_ITEMS; - ThemeMetric CAPITALIZE_DIFFICULTY_NAMES; - ThemeMetric MOVE_COMMAND; - - AutoActor m_Cursors[NUM_PLAYERS]; - ActorFrame m_CursorFrames[NUM_PLAYERS]; // contains Cursor so that color can fade independent of other tweens - - struct Line - { - StepsDisplay m_Meter; - }; - vector m_Lines; - - const Song *m_CurSong; - bool m_bShown; - - struct Row - { - Row() - { - m_Steps = NULL; - m_dc = Difficulty_Invalid; - m_fY = 0; - m_bHidden = false; - } - - const Steps *m_Steps; - Difficulty m_dc; - float m_fY; - bool m_bHidden; // currently off screen - }; - - vector m_Rows; - -}; - -#endif - -/* - * (c) 2003-2004 Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +/* StepsDisplayList - Shows all available difficulties for a Song/Course. */ +#ifndef DIFFICULTY_LIST_H +#define DIFFICULTY_LIST_H + +#include "ActorFrame.h" +#include "PlayerNumber.h" +#include "StepsDisplay.h" +#include "ThemeMetric.h" + +class Song; +class Steps; + +class StepsDisplayList: public ActorFrame +{ +public: + StepsDisplayList(); + virtual ~StepsDisplayList(); + virtual StepsDisplayList *Copy() const; + virtual void LoadFromNode( const XNode* pNode ); + + void HandleMessage( const Message &msg ); + + void SetFromGameState(); + void TweenOnScreen(); + void TweenOffScreen(); + void Hide(); + void Show(); + + // Lua + void PushSelf( lua_State *L ); + +private: + void UpdatePositions(); + void PositionItems(); + int GetCurrentRowIndex( PlayerNumber pn ) const; + void HideRows(); + + ThemeMetric ITEMS_SPACING_Y; + ThemeMetric NUM_SHOWN_ITEMS; + ThemeMetric CAPITALIZE_DIFFICULTY_NAMES; + ThemeMetric MOVE_COMMAND; + + AutoActor m_Cursors[NUM_PLAYERS]; + ActorFrame m_CursorFrames[NUM_PLAYERS]; // contains Cursor so that color can fade independent of other tweens + + struct Line + { + StepsDisplay m_Meter; + }; + vector m_Lines; + + const Song *m_CurSong; + bool m_bShown; + + struct Row + { + Row() + { + m_Steps = nullptr; + m_dc = Difficulty_Invalid; + m_fY = 0; + m_bHidden = false; + } + + const Steps *m_Steps; + Difficulty m_dc; + float m_fY; + bool m_bHidden; // currently off screen + }; + + vector m_Rows; + +}; + +#endif + +/* + * (c) 2003-2004 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/DisplaySpec.cpp b/src/DisplaySpec.cpp index c5e29bfe4b..815a2494fd 100644 --- a/src/DisplaySpec.cpp +++ b/src/DisplaySpec.cpp @@ -37,7 +37,7 @@ public: } static int GetCurrentMode( T *p, lua_State *L ) { - if (p->currentMode() != NULL) { + if (p->currentMode() != nullptr) { DisplayMode *m = const_cast( p->currentMode() ); m->PushSelf( L ); } else { @@ -65,7 +65,7 @@ namespace DisplaySpecs *check_DisplaySpecs(lua_State *L) { void *ud = luaL_checkudata( L, 1, DISPLAYSPECS ); - luaL_argcheck( L, ud != NULL, 1, "`DisplaySpecs` expected" ); + luaL_argcheck( L, ud != nullptr, 1, "`DisplaySpecs` expected" ); return static_cast(ud); } @@ -126,7 +126,7 @@ namespace {"__index", DisplaySpecs_get}, {"__len", DisplaySpecs_len}, {"__tostring", DisplaySpecs_tostring}, - {NULL, NULL} + {nullptr, nullptr} }; diff --git a/src/DisplaySpec.h b/src/DisplaySpec.h index 4ff7a11bdd..546988cded 100644 --- a/src/DisplaySpec.h +++ b/src/DisplaySpec.h @@ -114,7 +114,7 @@ public: } /* - * Return a pointer to the currently active display mode, or NULL if + * Return a pointer to the currently active display mode, or nullptr if * display is inactive * * Note that inactive *does not* necessarily mean unusable. E.g., in X11, diff --git a/src/EditMenu.cpp b/src/EditMenu.cpp index b199a0ec58..40937ff390 100644 --- a/src/EditMenu.cpp +++ b/src/EditMenu.cpp @@ -8,7 +8,7 @@ #include "Steps.h" #include "Song.h" #include "StepsUtil.h" -#include "Foreach.h" + #include "CommonMetrics.h" #include "ImageCache.h" #include "UnlockManager.h" @@ -171,12 +171,12 @@ void EditMenu::Load( const RString &sType ) this->AddChild( &m_SongTextBanner ); m_StepsDisplay.SetName( "StepsDisplay" ); - m_StepsDisplay.Load( "StepsDisplayEdit", NULL ); + m_StepsDisplay.Load( "StepsDisplayEdit", nullptr ); ActorUtil::SetXY( m_StepsDisplay, sType ); this->AddChild( &m_StepsDisplay ); m_StepsDisplaySource.SetName( "StepsDisplaySource" ); - m_StepsDisplaySource.Load( "StepsDisplayEdit", NULL ); + m_StepsDisplaySource.Load( "StepsDisplayEdit", nullptr ); ActorUtil::SetXY( m_StepsDisplaySource, sType ); this->AddChild( &m_StepsDisplaySource ); @@ -411,11 +411,11 @@ void EditMenu::OnRowValueChanged( EditMenuRow row ) vector vtSongs; GetSongsToShowForGroup(GetSelectedGroup(), vtSongs); // Filter out songs that aren't playable. - FOREACH(Song*, vtSongs, s) + for (Song *s :vtSongs) { - if(SongUtil::IsSongPlayable(*s)) + if(SongUtil::IsSongPlayable(s)) { - m_pSongs.push_back(*s); + m_pSongs.push_back(s); } } } @@ -428,7 +428,7 @@ void EditMenu::OnRowValueChanged( EditMenuRow row ) m_iSelection[ROW_SONG] = 0; // fall through case ROW_SONG: - if(GetSelectedSong() == NULL) + if(GetSelectedSong() == nullptr) { m_textValue[ROW_SONG].SetText(""); m_SongBanner.LoadFallback(); @@ -462,13 +462,13 @@ void EditMenu::OnRowValueChanged( EditMenuRow row ) // Only show StepsTypes for which we have valid Steps. vector vSts = CommonMetrics::STEPS_TYPES_TO_SHOW.GetValue(); - FOREACH( StepsType, vSts, st ) + for (StepsType &st : vSts) { - if(SongUtil::GetStepsByDifficulty( GetSelectedSong(), *st, Difficulty_Invalid, false) != NULL) - m_StepsTypes.push_back(*st); + if(SongUtil::GetStepsByDifficulty( GetSelectedSong(), st, Difficulty_Invalid, false) != nullptr) + m_StepsTypes.push_back(st); // Try to preserve the user's StepsType selection. - if(*st == orgSel) + if(st == orgSel) m_iSelection[ROW_STEPS_TYPE] = m_StepsTypes.size() - 1; } } @@ -506,8 +506,8 @@ void EditMenu::OnRowValueChanged( EditMenuRow row ) vector v; SongUtil::GetSteps( GetSelectedSong(), v, GetSelectedStepsType(), Difficulty_Edit ); StepsUtil::SortStepsByDescription( v ); - FOREACH_CONST( Steps*, v, p ) - m_vpSteps.push_back( StepsAndDifficulty(*p,dc) ); + for (Steps *p : v) + m_vpSteps.push_back( StepsAndDifficulty(p,dc) ); } break; case EditMode_Home: @@ -524,7 +524,7 @@ void EditMenu::OnRowValueChanged( EditMenuRow row ) break; case EditMode_Home: case EditMode_Full: - m_vpSteps.push_back( StepsAndDifficulty(NULL,dc) ); // "New Edit" + m_vpSteps.push_back( StepsAndDifficulty(nullptr,dc) ); // "New Edit" break; default: FAIL_M(ssprintf("Invalid edit mode: %i", mode)); @@ -534,7 +534,7 @@ void EditMenu::OnRowValueChanged( EditMenuRow row ) { Steps *pSteps = SongUtil::GetStepsByDifficulty( GetSelectedSong(), GetSelectedStepsType(), dc ); if( pSteps && UNLOCKMAN->StepsIsLocked( GetSelectedSong(), pSteps ) ) - pSteps = NULL; + pSteps = nullptr; switch( mode ) { @@ -558,11 +558,12 @@ void EditMenu::OnRowValueChanged( EditMenuRow row ) } StripLockedStepsAndDifficulty( m_vpSteps ); - FOREACH( StepsAndDifficulty, m_vpSteps, s ) + int i = 0; + for (StepsAndDifficulty const &s : m_vpSteps) { - if( s->dc == dcOld ) + if( s.dc == dcOld ) { - m_iSelection[ROW_STEPS] = s - m_vpSteps.begin(); + m_iSelection[ROW_STEPS] = i; break; } } @@ -570,7 +571,7 @@ void EditMenu::OnRowValueChanged( EditMenuRow row ) } // fall through case ROW_STEPS: - if(GetSelectedSteps() == NULL && mode == EditMode_Practice) + if(GetSelectedSteps() == nullptr && mode == EditMode_Practice) { m_textValue[ROW_STEPS].SetText(THEME->GetString(m_sName, "No Steps selected.")); m_StepsDisplay.Unset(); @@ -602,7 +603,7 @@ void EditMenu::OnRowValueChanged( EditMenuRow row ) m_textValue[ROW_SOURCE_STEPS_TYPE].SetVisible( GetSelectedSteps() ? false : true ); m_textValue[ROW_SOURCE_STEPS_TYPE].SetText( GAMEMAN->GetStepsTypeInfo(GetSelectedSourceStepsType()).GetLocalizedString() ); m_vpSourceSteps.clear(); - m_vpSourceSteps.push_back( StepsAndDifficulty(NULL,Difficulty_Invalid) ); // "blank" + m_vpSourceSteps.push_back( StepsAndDifficulty(nullptr,Difficulty_Invalid) ); // "blank" FOREACH_ENUM( Difficulty, dc ) { @@ -610,7 +611,7 @@ void EditMenu::OnRowValueChanged( EditMenuRow row ) if( dc != Difficulty_Edit ) { Steps *pSteps = SongUtil::GetStepsByDifficulty( GetSelectedSong(), GetSelectedSourceStepsType(), dc ); - if( pSteps != NULL ) + if( pSteps != nullptr ) m_vpSourceSteps.push_back( StepsAndDifficulty(pSteps,dc) ); } else @@ -618,8 +619,8 @@ void EditMenu::OnRowValueChanged( EditMenuRow row ) vector v; SongUtil::GetSteps( GetSelectedSong(), v, GetSelectedSourceStepsType(), dc ); StepsUtil::SortStepsByDescription( v ); - FOREACH_CONST( Steps*, v, pSteps ) - m_vpSourceSteps.push_back( StepsAndDifficulty(*pSteps,dc) ); + for (Steps *pSteps : v) + m_vpSourceSteps.push_back( StepsAndDifficulty(pSteps,dc) ); } } StripLockedStepsAndDifficulty( m_vpSteps ); @@ -662,7 +663,7 @@ void EditMenu::OnRowValueChanged( EditMenuRow row ) m_Actions.clear(); // Stick autosave in the list first so that people will see it. -Kyz Song* cur_song= GetSelectedSong(); - if(cur_song != NULL && cur_song->HasAutosaveFile() && !cur_song->WasLoadedFromAutosave()) + if(cur_song != nullptr && cur_song->HasAutosaveFile() && !cur_song->WasLoadedFromAutosave()) { m_Actions.push_back(EditMenuAction_LoadAutosave); } diff --git a/src/EditMenu.h b/src/EditMenu.h index 1d7b912ed3..9d1ff63f01 100644 --- a/src/EditMenu.h +++ b/src/EditMenu.h @@ -121,7 +121,7 @@ public: Song* GetSelectedSong() const { RETURN_IF_INVALID(m_pSongs.empty() || - m_iSelection[ROW_SONG] >= (int)m_pSongs.size(), NULL); + m_iSelection[ROW_SONG] >= (int)m_pSongs.size(), nullptr); return m_pSongs[m_iSelection[ROW_SONG]]; } /** @brief Retrieve the currently selected steps type. @@ -137,7 +137,7 @@ public: Steps* GetSelectedSteps() const { RETURN_IF_INVALID(m_vpSteps.empty() || - m_iSelection[ROW_STEPS] >= (int)m_vpSteps.size(), NULL); + m_iSelection[ROW_STEPS] >= (int)m_vpSteps.size(), nullptr); return m_vpSteps[m_iSelection[ROW_STEPS]].pSteps; } /** @brief Retrieve the currently selected difficulty. @@ -161,7 +161,7 @@ public: Steps* GetSelectedSourceSteps() const { RETURN_IF_INVALID(m_vpSourceSteps.empty() || - m_iSelection[ROW_SOURCE_STEPS] >= (int)m_vpSourceSteps.size(), NULL); + m_iSelection[ROW_SOURCE_STEPS] >= (int)m_vpSourceSteps.size(), nullptr); return m_vpSourceSteps[m_iSelection[ROW_SOURCE_STEPS]].pSteps; } /** @brief Retrieve the currently selected difficulty. diff --git a/src/EnumHelper.cpp b/src/EnumHelper.cpp index 3391002ce4..06a5139192 100644 --- a/src/EnumHelper.cpp +++ b/src/EnumHelper.cpp @@ -80,18 +80,18 @@ int CheckEnum( lua_State *L, LuaReference &table, int iPos, int iInvalid, const } // szNameArray is of size iMax; pNameCache is of size iMax+2. -const RString &EnumToString( int iVal, int iMax, const char **szNameArray, auto_ptr *pNameCache ) +const RString &EnumToString( int iVal, int iMax, const char **szNameArray, unique_ptr *pNameCache ) { - if( unlikely(pNameCache[0].get() == NULL) ) + if( unlikely(pNameCache[0].get() == nullptr) ) { for( int i = 0; i < iMax; ++i ) { - auto_ptr ap( new RString( szNameArray[i] ) ); - pNameCache[i] = ap; + unique_ptr ap( new RString( szNameArray[i] ) ); + pNameCache[i] = move(ap); } - auto_ptr ap( new RString ); - pNameCache[iMax+1] = ap; + unique_ptr ap( new RString ); + pNameCache[iMax+1] = move(ap); } // iMax+1 is "Invalid". iMax+0 is the NUM_ size value, which can not be converted @@ -140,7 +140,7 @@ namespace static const luaL_Reg EnumLib[] = { { "GetName", GetName }, { "Reverse", Reverse }, - { NULL, NULL } + { nullptr, nullptr } }; static void PushEnumMethodTable( lua_State *L ) diff --git a/src/EnumHelper.h b/src/EnumHelper.h index c5209dc7a3..230e21624b 100644 --- a/src/EnumHelper.h +++ b/src/EnumHelper.h @@ -66,14 +66,14 @@ namespace Enum void SetMetatable( lua_State *L, LuaReference &EnumTable, LuaReference &EnumIndexTable, const char *szName ); }; -const RString &EnumToString( int iVal, int iMax, const char **szNameArray, auto_ptr *pNameCache ); // XToString helper +const RString &EnumToString( int iVal, int iMax, const char **szNameArray, unique_ptr *pNameCache ); // XToString helper #define XToString(X) \ const RString& X##ToString(X x); \ COMPILE_ASSERT( NUM_##X == ARRAYLEN(X##Names) ); \ const RString& X##ToString( X x ) \ { \ - static auto_ptr as_##X##Name[NUM_##X+2]; \ + static unique_ptr as_##X##Name[NUM_##X+2]; \ return EnumToString( x, NUM_##X, X##Names, as_##X##Name ); \ } \ namespace StringConversion { template<> RString ToString( const X &value ) { return X##ToString(value); } } @@ -82,12 +82,12 @@ namespace StringConversion { template<> RString ToString( const X &value ) { const RString &X##ToLocalizedString(X x); \ const RString &X##ToLocalizedString( X x ) \ { \ - static auto_ptr g_##X##Name[NUM_##X]; \ - if( g_##X##Name[0].get() == NULL ) { \ + static unique_ptr g_##X##Name[NUM_##X]; \ + if( g_##X##Name[0].get() == nullptr ) { \ for( unsigned i = 0; i < NUM_##X; ++i ) \ { \ - auto_ptr ap( new LocalizedString(#X, X##ToString((X)i)) ); \ - g_##X##Name[i] = ap; \ + unique_ptr ap( new LocalizedString(#X, X##ToString((X)i)) ); \ + g_##X##Name[i] = move(ap); \ } \ } \ return g_##X##Name[x]->GetValue(); \ diff --git a/src/FadingBanner.cpp b/src/FadingBanner.cpp index ec22d3f758..d5123a9fc4 100644 --- a/src/FadingBanner.cpp +++ b/src/FadingBanner.cpp @@ -166,7 +166,7 @@ bool FadingBanner::LoadFromCachedBanner( const RString &path ) void FadingBanner::LoadFromSong( const Song* pSong ) { - if( pSong == NULL ) + if( pSong == nullptr ) { LoadFallback(); return; @@ -195,7 +195,7 @@ void FadingBanner::LoadFromSongGroup( RString sSongGroup ) void FadingBanner::LoadFromCourse( const Course* pCourse ) { - if( pCourse == NULL ) + if( pCourse == nullptr ) { LoadFallback(); return; @@ -272,25 +272,25 @@ public: static int ScaleToClipped( T* p, lua_State *L ) { p->ScaleToClipped(FArg(1),FArg(2)); COMMON_RETURN_SELF; } static int LoadFromSong( T* p, lua_State *L ) { - if( lua_isnil(L,1) ) { p->LoadFromSong( NULL ); } + if( lua_isnil(L,1) ) { p->LoadFromSong(nullptr); } else { Song *pS = Luna::check(L,1); p->LoadFromSong( pS ); } COMMON_RETURN_SELF; } static int LoadFromCourse( T* p, lua_State *L ) { - if( lua_isnil(L,1) ) { p->LoadFromCourse( NULL ); } + if( lua_isnil(L,1) ) { p->LoadFromCourse(nullptr); } else { Course *pC = Luna::check(L,1); p->LoadFromCourse( pC ); } COMMON_RETURN_SELF; } static int LoadIconFromCharacter( T* p, lua_State *L ) { - if( lua_isnil(L,1) ) { p->LoadIconFromCharacter( NULL ); } + if( lua_isnil(L,1) ) { p->LoadIconFromCharacter(nullptr); } else { Character *pC = Luna::check(L,1); p->LoadIconFromCharacter( pC ); } COMMON_RETURN_SELF; } static int LoadCardFromCharacter( T* p, lua_State *L ) { - if( lua_isnil(L,1) ) { p->LoadIconFromCharacter( NULL ); } + if( lua_isnil(L,1) ) { p->LoadIconFromCharacter(nullptr); } else { Character *pC = Luna::check(L,1); p->LoadIconFromCharacter( pC ); } COMMON_RETURN_SELF; } diff --git a/src/FadingBanner.h b/src/FadingBanner.h index 6caaed458c..fa06e54ac6 100644 --- a/src/FadingBanner.h +++ b/src/FadingBanner.h @@ -18,7 +18,7 @@ public: /* If you previously loaded a cached banner, and are now loading the full- * resolution banner, set bLowResToHighRes to true. */ void Load( RageTextureID ID, bool bLowResToHighRes=false ); - void LoadFromSong( const Song* pSong ); // NULL means no song + void LoadFromSong( const Song* pSong ); // nullptr means no song void LoadMode(); void LoadFromSongGroup( RString sSongGroup ); void LoadFromCourse( const Course* pCourse ); diff --git a/src/FileDownload.cpp b/src/FileDownload.cpp index 26006842a5..c532719969 100644 --- a/src/FileDownload.cpp +++ b/src/FileDownload.cpp @@ -7,7 +7,7 @@ #include "SpecialFiles.h" #include "RageLog.h" #include "Preference.h" -#include "Foreach.h" + FileTransfer::FileTransfer() { @@ -199,8 +199,8 @@ void FileTransfer::StartTransfer( TransferType type, const RString &sURL, const vsHeaders.push_back( "Content-Length: " + ssprintf("%zd",sRequestPayload.size()) ); RString sHeader; - FOREACH_CONST( RString, vsHeaders, h ) - sHeader += *h + "\r\n"; + for (RString const &h : vsHeaders) + sHeader += h + "\r\n"; sHeader += "\r\n"; m_wSocket.SendData( sHeader.c_str(), sHeader.length() ); @@ -267,14 +267,14 @@ void FileTransfer::HTTPUpdate() m_sResponseName = "Malformed response."; return; } - m_iResponseCode = StringToInt(m_sBUFFER.substr(i+1,j-i)); + m_iResponseCode = std::stoi(m_sBUFFER.substr(i+1,j-i)); m_sResponseName = m_sBUFFER.substr( j+1, k-j ); i = m_sBUFFER.find("Content-Length:"); j = m_sBUFFER.find("\n", i+1 ); if( i != string::npos ) - m_iTotalBytes = StringToInt(m_sBUFFER.substr(i+16,j-i)); + m_iTotalBytes = std::stoi(m_sBUFFER.substr(i+16,j-i)); else m_iTotalBytes = -1; // We don't know, so go until disconnect @@ -345,7 +345,7 @@ bool FileTransfer::ParseHTTPAddress( const RString &URL, RString &sProto, RStrin sServer = asMatches[1]; if( asMatches[3] != "" ) { - iPort = StringToInt(asMatches[3]); + iPort = std::stoi(asMatches[3]); if( iPort == 0 ) return false; } diff --git a/src/Font.cpp b/src/Font.cpp index 243d63773a..2587e0f060 100644 --- a/src/Font.cpp +++ b/src/Font.cpp @@ -26,7 +26,7 @@ void FontPage::Load( const FontPageSettings &cfg ) ID1.AdditionalTextureHints = cfg.m_sTextureHints; m_FontPageTextures.m_pTextureMain = TEXTUREMAN->LoadTexture( ID1 ); - if(m_FontPageTextures.m_pTextureMain == NULL) + if(m_FontPageTextures.m_pTextureMain == nullptr) { LuaHelpers::ReportScriptErrorFmt( "Failed to load main texture %s for font page.", @@ -43,7 +43,7 @@ void FontPage::Load( const FontPageSettings &cfg ) if( IsAFile(ID2.filename) ) { m_FontPageTextures.m_pTextureStroke = TEXTUREMAN->LoadTexture( ID2 ); - if(m_FontPageTextures.m_pTextureStroke == NULL) + if(m_FontPageTextures.m_pTextureStroke == nullptr) { LuaHelpers::ReportScriptErrorFmt( "Failed to load stroke texture %s for font page.", @@ -220,15 +220,15 @@ void FontPage::SetExtraPixels( int iDrawExtraPixelsLeft, int iDrawExtraPixelsRig FontPage::~FontPage() { - if( m_FontPageTextures.m_pTextureMain != NULL ) + if( m_FontPageTextures.m_pTextureMain != nullptr ) { TEXTUREMAN->UnloadTexture( m_FontPageTextures.m_pTextureMain ); - m_FontPageTextures.m_pTextureMain = NULL; + m_FontPageTextures.m_pTextureMain = nullptr; } - if( m_FontPageTextures.m_pTextureStroke != NULL ) + if( m_FontPageTextures.m_pTextureStroke != nullptr ) { TEXTUREMAN->UnloadTexture( m_FontPageTextures.m_pTextureStroke ); - m_FontPageTextures.m_pTextureStroke = NULL; + m_FontPageTextures.m_pTextureStroke = nullptr; } } @@ -271,7 +271,7 @@ int Font::GetGlyphsThatFit(const wstring& line, int* width) const return i; } -Font::Font(): m_iRefCount(1), path(""), m_apPages(), m_pDefault(NULL), +Font::Font(): m_iRefCount(1), path(""), m_apPages(), m_pDefault(nullptr), m_iCharToGlyph(), m_bRightToLeft(false), m_bDistanceField(false), // strokes aren't shown by default, hence the Color. m_DefaultStrokeColor(RageColor(0,0,0,0)), m_sChars("") {} @@ -288,7 +288,7 @@ void Font::Unload() m_apPages.clear(); m_iCharToGlyph.clear(); - m_pDefault = NULL; + m_pDefault = nullptr; /* Don't clear the refcount. We've unloaded, but that doesn't mean things * aren't still pointing to us. */ @@ -323,7 +323,7 @@ void Font::MergeFont(Font &f) * page. It'll usually be overridden later on by one of our own font * pages; this will be used only if we don't have any font pages at * all. */ - if( m_pDefault == NULL ) + if( m_pDefault == nullptr ) m_pDefault = f.m_pDefault; for(map::iterator it = f.m_iCharToGlyph.begin(); @@ -400,7 +400,7 @@ void Font::CapsOnly() void Font::SetDefaultGlyph( FontPage *pPage ) { - ASSERT( pPage != NULL ); + ASSERT( pPage != nullptr ); if(pPage->m_aGlyphs.empty()) { LuaHelpers::ReportScriptErrorFmt( @@ -488,7 +488,7 @@ void Font::LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RStr // If val is an integer, it's a width, eg. "10=27". if( IsAnInt(sName) ) { - cfg.m_mapGlyphWidths[StringToInt(sName)] = pValue->GetValue(); + cfg.m_mapGlyphWidths[std::stoi(sName)] = pValue->GetValue(); continue; } @@ -603,7 +603,7 @@ void Font::LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RStr row_str.c_str()); continue; } - const int row = StringToInt(row_str); + const int row = std::stoi(row_str); const int first_frame = row * num_frames_wide; if(row >= num_frames_high) @@ -690,7 +690,7 @@ RString FontPageSettings::MapRange( RString sMapping, int iMapOffset, int iGlyph } const wchar_t *pMapping = FontCharmaps::get_char_map( sMapping ); - if( pMapping == NULL ) + if( pMapping == nullptr ) return "Unknown mapping"; while( *pMapping != 0 && iMapOffset ) diff --git a/src/Font.h b/src/Font.h index 4d8df76b44..88c2a3abbe 100644 --- a/src/Font.h +++ b/src/Font.h @@ -23,7 +23,7 @@ struct FontPageTextures RageTexture *m_pTextureStroke; /** @brief Set up the initial textures. */ - FontPageTextures(): m_pTextureMain(NULL), m_pTextureStroke(NULL) {} + FontPageTextures(): m_pTextureMain(nullptr), m_pTextureStroke(nullptr) {} bool operator == (const struct FontPageTextures& other) const { return m_pTextureMain == other.m_pTextureMain && @@ -59,7 +59,7 @@ struct glyph RectF m_TexRect; /** @brief Set up the glyph with default values. */ - glyph() : m_pPage(NULL), m_FontPageTextures(), m_iHadvance(0), + glyph() : m_pPage(nullptr), m_FontPageTextures(), m_iHadvance(0), m_fWidth(0), m_fHeight(0), m_fHshift(0), m_TexRect() {} }; diff --git a/src/FontCharAliases.cpp b/src/FontCharAliases.cpp index 4130295eda..826680ecc4 100644 --- a/src/FontCharAliases.cpp +++ b/src/FontCharAliases.cpp @@ -347,7 +347,7 @@ static void InitCharAliases() { "auxrt", INTERNAL }, { "auxback", INTERNAL }, - { NULL, 0 } + { nullptr, 0 } }; int iNextInternalUseCodepoint = 0xE000; diff --git a/src/FontCharmaps.cpp b/src/FontCharmaps.cpp index f7cdd9a743..cee6921e7f 100644 --- a/src/FontCharmaps.cpp +++ b/src/FontCharmaps.cpp @@ -226,7 +226,7 @@ const wchar_t *FontCharmaps::get_char_map(RString name) map::const_iterator i = charmaps.find(name); if(i == charmaps.end()) - return NULL; + return nullptr; return i->second; } diff --git a/src/FontManager.cpp b/src/FontManager.cpp index a37d9e6685..a5e0bebb2b 100644 --- a/src/FontManager.cpp +++ b/src/FontManager.cpp @@ -5,7 +5,7 @@ #include "RageLog.h" #include -FontManager* FONT = NULL; // global and accessible from anywhere in our program +FontManager* FONT = nullptr; // global and accessible from anywhere in our program // map from file name to a texture holder typedef pair FontName; diff --git a/src/Foreach.h b/src/Foreach.h deleted file mode 100644 index 35d595c4fb..0000000000 --- a/src/Foreach.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef Foreach_H -#define Foreach_H - -/** @brief General foreach loop iterating over a vector. */ -#define FOREACH( elemType, vect, var ) \ -for( vector::iterator var = (vect).begin(); var != (vect).end(); ++var ) -/** @brief General foreach loop iterating over a vector, using a constant iterator. */ -#define FOREACH_CONST( elemType, vect, var ) \ -for( vector::const_iterator var = (vect).begin(); var != (vect).end(); ++var ) - -/** @brief General foreach loop iterating over a deque. */ -#define FOREACHD( elemType, vect, var ) \ -for( deque::iterator var = (vect).begin(); var != (vect).end(); ++var ) -/** @brief General foreach loop iterating over a deque, using a constant iterator. */ -#define FOREACHD_CONST( elemType, vect, var ) \ -for( deque::const_iterator var = (vect).begin(); var != (vect).end(); ++var ) - -/** @brief General foreach loop iterating over a set. */ -#define FOREACHS( elemType, vect, var ) \ -for( set::iterator var = (vect).begin(); var != (vect).end(); ++var ) -/** @brief General foreach loop iterating over a set, using a constant iterator. */ -#define FOREACHS_CONST( elemType, vect, var ) \ -for( set::const_iterator var = (vect).begin(); var != (vect).end(); ++var ) - -/** @brief General foreach loop iterating over a list. */ -#define FOREACHL( elemType, vect, var ) \ -for( list::iterator var = (vect).begin(); var != (vect).end(); ++var ) -/** @brief General foreach loop iterating over a list, using a constant iterator. */ -#define FOREACHL_CONST( elemType, vect, var ) \ -for( list::const_iterator var = (vect).begin(); var != (vect).end(); ++var ) - -/** @brief General foreach loop iterating over a map. */ -#define FOREACHM( keyType, valType, vect, var ) \ -for( map::iterator var = (vect).begin(); var != (vect).end(); ++var ) -/** @brief General foreach loop iterating over a map, using a constant iterator. */ -#define FOREACHM_CONST( keyType, valType, vect, var ) \ -for( map::const_iterator var = (vect).begin(); var != (vect).end(); ++var ) - -/** @brief General foreach loop iterating over a multimap. */ -#define FOREACHMM( keyType, valType, vect, var ) \ -for( multimap::iterator var = (vect).begin(); var != (vect).end(); ++var ) - -/** @brief General foreach loop iterating over a multimap, using a constant iterator. */ -#define FOREACHMM_CONST( keyType, valType, vect, var ) \ -for( multimap::const_iterator var = (vect).begin(); var != (vect).end(); ++var ) - -#endif - -/** - * @file - * @author Chris Danford (c) 2004-2005 - * @section LICENSE - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ diff --git a/src/Foreground.cpp b/src/Foreground.cpp index 95d3f8fed2..d0026daf9e 100644 --- a/src/Foreground.cpp +++ b/src/Foreground.cpp @@ -7,7 +7,7 @@ #include "ActorUtil.h" #include "Song.h" #include "BackgroundUtil.h" -#include "Foreach.h" + Foreground::~Foreground() { @@ -21,7 +21,7 @@ void Foreground::Unload() m_BGAnimations.clear(); m_SubActors.clear(); m_fLastMusicSeconds = -9999; - m_pSong = NULL; + m_pSong = nullptr; } void Foreground::LoadFromSong( const Song *pSong ) @@ -31,9 +31,8 @@ void Foreground::LoadFromSong( const Song *pSong ) TEXTUREMAN->SetDefaultTexturePolicy( RageTextureID::TEX_VOLATILE ); m_pSong = pSong; - FOREACH_CONST( BackgroundChange, pSong->GetForegroundChanges(), bgc ) + for (BackgroundChange const &change : pSong->GetForegroundChanges()) { - const BackgroundChange &change = *bgc; RString sBGName = change.m_def.m_sFile1, sLuaFile = pSong->GetSongDir() + sBGName + "/default.lua", sXmlFile = pSong->GetSongDir() + sBGName + "/default.xml"; @@ -51,7 +50,7 @@ void Foreground::LoadFromSong( const Song *pSong ) { bga.m_bga = ActorUtil::MakeActor( pSong->GetSongDir() + sBGName, this ); } - if( bga.m_bga == NULL ) + if( bga.m_bga == nullptr ) continue; bga.m_bga->SetName( sBGName ); // ActorUtil::MakeActor calls LoadFromNode to load the actor, and diff --git a/src/GameCommand.cpp b/src/GameCommand.cpp index 4d7d67a58c..c5d638d401 100644 --- a/src/GameCommand.cpp +++ b/src/GameCommand.cpp @@ -14,7 +14,6 @@ #include "PrefsManager.h" #include "Game.h" #include "Style.h" -#include "Foreach.h" #include "GameSoundManager.h" #include "PlayerState.h" #include "SongManager.h" @@ -36,7 +35,7 @@ void GameCommand::Init() m_bInvalid = true; m_iIndex = -1; m_MultiPlayer = MultiPlayer_Invalid; - m_pStyle = NULL; + m_pStyle = nullptr; m_pm = PlayMode_Invalid; m_dc = Difficulty_Invalid; m_CourseDifficulty = Difficulty_Invalid; @@ -45,11 +44,11 @@ void GameCommand::Init() m_sAnnouncer = ""; m_sScreen = ""; m_LuaFunction.Unset(); - m_pSong = NULL; - m_pSteps = NULL; - m_pCourse = NULL; - m_pTrail = NULL; - m_pCharacter = NULL; + m_pSong = nullptr; + m_pSteps = nullptr; + m_pCourse = nullptr; + m_pTrail = nullptr; + m_pCharacter = nullptr; m_SortOrder = SortOrder_Invalid; m_sSoundPath = ""; m_vsScreensToPrepare.clear(); @@ -90,7 +89,7 @@ bool GameCommand::DescribesCurrentMode( PlayerNumber pn ) const // HACK: don't compare m_dc if m_pSteps is set. This causes problems // in ScreenSelectOptionsMaster::ImportOptions if m_PreferredDifficulty // doesn't match the difficulty of m_pCurSteps. - if( m_pSteps == NULL && m_dc != Difficulty_Invalid ) + if( m_pSteps == nullptr && m_dc != Difficulty_Invalid ) { // Why is this checking for all players? FOREACH_HumanPlayer( human ) @@ -158,8 +157,8 @@ void GameCommand::Load( int iIndex, const Commands& cmds ) m_bInvalid = false; m_Commands = cmds; - FOREACH_CONST( Command, cmds.v, cmd ) - LoadOne( *cmd ); + for (Command const &cmd : cmds.v) + LoadOne( cmd ); } void GameCommand::LoadOne( const Command& cmd ) @@ -197,7 +196,7 @@ void GameCommand::LoadOne( const Command& cmd ) if( sName == "style" ) { const Style* style = GAMEMAN->GameAndStringToStyle( GAMESTATE->m_pCurGame, sValue ); - CHECK_INVALID_VALUE(m_pStyle, style, NULL, style); + CHECK_INVALID_VALUE(m_pStyle, style, nullptr, style); } else if( sName == "playmode" ) @@ -278,7 +277,7 @@ void GameCommand::LoadOne( const Command& cmd ) else if( sName == "song" ) { CHECK_INVALID_COND(m_pSong, SONGMAN->FindSong(sValue), - (SONGMAN->FindSong(sValue) == NULL), + (SONGMAN->FindSong(sValue) == nullptr), (ssprintf("Song \"%s\" not found", sValue.c_str()))); } @@ -289,9 +288,9 @@ void GameCommand::LoadOne( const Command& cmd ) // This must be processed after "song" and "style" commands. if( !m_bInvalid ) { - Song *pSong = (m_pSong != NULL)? m_pSong:GAMESTATE->m_pCurSong; + Song *pSong = (m_pSong != nullptr)? m_pSong:GAMESTATE->m_pCurSong; const Style *pStyle = m_pStyle ? m_pStyle : GAMESTATE->GetCurrentStyle(GAMESTATE->GetMasterPlayerNumber()); - if( pSong == NULL || pStyle == NULL ) + if( pSong == nullptr || pStyle == nullptr ) { MAKE_INVALID("Must set Song and Style to set Steps."); } @@ -307,7 +306,7 @@ void GameCommand::LoadOne( const Command& cmd ) { st = SongUtil::GetStepsByDescription( pSong, pStyle->m_StepsType, sSteps ); } - CHECK_INVALID_COND(m_pSteps, st, (st == NULL), + CHECK_INVALID_COND(m_pSteps, st, (st == nullptr), (ssprintf("Steps \"%s\" not found", sSteps.c_str()))); } } @@ -316,7 +315,7 @@ void GameCommand::LoadOne( const Command& cmd ) else if( sName == "course" ) { CHECK_INVALID_COND(m_pCourse, SONGMAN->FindCourse("", sValue), - (SONGMAN->FindCourse("", sValue) == NULL), + (SONGMAN->FindCourse("", sValue) == nullptr), (ssprintf( "Course \"%s\" not found", sValue.c_str()))); } @@ -327,9 +326,9 @@ void GameCommand::LoadOne( const Command& cmd ) // This must be processed after "course" and "style" commands. if( !m_bInvalid ) { - Course *pCourse = (m_pCourse != NULL)? m_pCourse:GAMESTATE->m_pCurCourse; + Course *pCourse = (m_pCourse != nullptr)? m_pCourse:GAMESTATE->m_pCurCourse; const Style *pStyle = m_pStyle ? m_pStyle : GAMESTATE->GetCurrentStyle(GAMESTATE->GetMasterPlayerNumber()); - if( pCourse == NULL || pStyle == NULL ) + if( pCourse == nullptr || pStyle == nullptr ) { MAKE_INVALID("Must set Course and Style to set Trail."); } @@ -343,7 +342,7 @@ void GameCommand::LoadOne( const Command& cmd ) else { Trail* tr = pCourse->GetTrail(pStyle->m_StepsType, cd); - CHECK_INVALID_COND(m_pTrail, tr, (tr == NULL), + CHECK_INVALID_COND(m_pTrail, tr, (tr == nullptr), ("Trail \"" + sTrail + "\" not found.")); } } @@ -378,12 +377,12 @@ void GameCommand::LoadOne( const Command& cmd ) else if( sName == "weight" ) { - m_iWeightPounds = StringToInt( sValue ); + m_iWeightPounds = std::stoi( sValue ); } else if( sName == "goalcalories" ) { - m_iGoalCalories = StringToInt( sValue ); + m_iGoalCalories = std::stoi( sValue ); } else if( sName == "goaltype" ) @@ -450,7 +449,7 @@ void GameCommand::LoadOne( const Command& cmd ) { for(size_t i= 1; i < cmd.m_vsArgs.size(); i+= 2) { - if(IPreference::GetPreferenceByName(cmd.m_vsArgs[i]) == NULL) + if(IPreference::GetPreferenceByName(cmd.m_vsArgs[i]) == nullptr) { MAKE_INVALID("Unknown preference \"" + cmd.m_vsArgs[i] + "\"."); } @@ -526,7 +525,7 @@ int GetCreditsRequiredToPlayStyle( const Style *style ) static bool AreStyleAndPlayModeCompatible( const Style *style, PlayMode pm ) { - if( style == NULL || pm == PlayMode_Invalid ) + if( style == nullptr || pm == PlayMode_Invalid ) return true; switch( pm ) @@ -596,10 +595,10 @@ bool GameCommand::IsPlayable( RString *why ) const /* Don't allow a PlayMode that's incompatible with our current Style (if set), * and vice versa. */ - if( m_pm != PlayMode_Invalid || m_pStyle != NULL ) + if( m_pm != PlayMode_Invalid || m_pStyle != nullptr ) { const PlayMode pm = (m_pm != PlayMode_Invalid) ? m_pm : GAMESTATE->m_PlayMode; - const Style *style = (m_pStyle != NULL)? m_pStyle: GAMESTATE->GetCurrentStyle(GAMESTATE->GetMasterPlayerNumber()); + const Style *style = (m_pStyle != nullptr)? m_pStyle: GAMESTATE->GetCurrentStyle(GAMESTATE->GetMasterPlayerNumber()); if( !AreStyleAndPlayModeCompatible( style, pm ) ) { if( why ) @@ -680,12 +679,12 @@ void GameCommand::Apply( const vector &vpns ) const if( m_Commands.v.size() ) { // We were filled using a GameCommand from metrics. Apply the options in order. - FOREACH_CONST( Command, m_Commands.v, cmd ) + for (Command const &cmd : m_Commands.v) { GameCommand gc; gc.m_bInvalid = false; gc.m_bApplyCommitsScreens = m_bApplyCommitsScreens; - gc.LoadOne( *cmd ); + gc.LoadOne( cmd ); gc.ApplySelf( vpns ); } } @@ -704,7 +703,7 @@ void GameCommand::ApplySelf( const vector &vpns ) const if( m_pm != PlayMode_Invalid ) GAMESTATE->m_PlayMode.Set( m_pm ); - if( m_pStyle != NULL ) + if( m_pStyle != nullptr ) { GAMESTATE->SetCurrentStyle( m_pStyle, GAMESTATE->GetMasterPlayerNumber() ); @@ -720,8 +719,8 @@ void GameCommand::ApplySelf( const vector &vpns ) const LOG->Trace( "Deducted %i coins, %i remaining", iNumCreditsOwed * PREFSMAN->m_iCoinsPerCredit, GAMESTATE->m_iCoins.Get() ); - //Credit Used, make sure to update CoinsFile - BOOKKEEPER->WriteCoinsFile(GAMESTATE->m_iCoins.Get()); + //Credit Used, make sure to update CoinsFile + BOOKKEEPER->WriteCoinsFile(GAMESTATE->m_iCoins.Get()); } // If only one side is joined and we picked a style that requires both @@ -743,25 +742,25 @@ void GameCommand::ApplySelf( const vector &vpns ) const } } if( m_dc != Difficulty_Invalid ) - FOREACH_CONST( PlayerNumber, vpns, pn ) - GAMESTATE->m_PreferredDifficulty[*pn].Set( m_dc ); + for (PlayerNumber const &pn : vpns) + GAMESTATE->m_PreferredDifficulty[pn].Set( m_dc ); if( m_sAnnouncer != "" ) ANNOUNCER->SwitchAnnouncer( m_sAnnouncer ); if( m_sPreferredModifiers != "" ) - FOREACH_CONST( PlayerNumber, vpns, pn ) - GAMESTATE->ApplyPreferredModifiers( *pn, m_sPreferredModifiers ); + for (PlayerNumber const &pn : vpns) + GAMESTATE->ApplyPreferredModifiers( pn, m_sPreferredModifiers ); if( m_sStageModifiers != "" ) - FOREACH_CONST( PlayerNumber, vpns, pn ) - GAMESTATE->ApplyStageModifiers( *pn, m_sStageModifiers ); + for (PlayerNumber const &pn : vpns) + GAMESTATE->ApplyStageModifiers( pn, m_sStageModifiers ); if( m_LuaFunction.IsSet() && !m_LuaFunction.IsNil() ) { Lua *L = LUA->Get(); - FOREACH_CONST( PlayerNumber, vpns, pn ) + for (PlayerNumber const &pn : vpns) { m_LuaFunction.PushSelf( L ); ASSERT( !lua_isnil(L, -1) ); - lua_pushnumber( L, *pn ); // 1st parameter + lua_pushnumber( L, pn ); // 1st parameter RString error= "Lua GameCommand error: "; LuaHelpers::RunScriptOnStack(L, error, 1, 0, true); } @@ -775,22 +774,22 @@ void GameCommand::ApplySelf( const vector &vpns ) const GAMESTATE->m_pPreferredSong = m_pSong; } if( m_pSteps ) - FOREACH_CONST( PlayerNumber, vpns, pn ) - GAMESTATE->m_pCurSteps[*pn].Set( m_pSteps ); + for (PlayerNumber const &pn : vpns) + GAMESTATE->m_pCurSteps[pn].Set( m_pSteps ); if( m_pCourse ) { GAMESTATE->m_pCurCourse.Set( m_pCourse ); GAMESTATE->m_pPreferredCourse = m_pCourse; } if( m_pTrail ) - FOREACH_CONST( PlayerNumber, vpns, pn ) - GAMESTATE->m_pCurTrail[*pn].Set( m_pTrail ); + for (PlayerNumber const &pn : vpns) + GAMESTATE->m_pCurTrail[pn].Set( m_pTrail ); if( m_CourseDifficulty != Difficulty_Invalid ) - FOREACH_CONST( PlayerNumber, vpns, pn ) - GAMESTATE->ChangePreferredCourseDifficulty( *pn, m_CourseDifficulty ); + for (PlayerNumber const &pn : vpns) + GAMESTATE->ChangePreferredCourseDifficulty( pn, m_CourseDifficulty ); if( m_pCharacter ) - FOREACH_CONST( PlayerNumber, vpns, pn ) - GAMESTATE->m_pCurCharacters[*pn] = m_pCharacter; + for (PlayerNumber const &pn : vpns) + GAMESTATE->m_pCurCharacters[pn] = m_pCharacter; for( map::const_iterator i = m_SetEnv.begin(); i != m_SetEnv.end(); i++ ) { Lua *L = LUA->Get(); @@ -804,7 +803,7 @@ void GameCommand::ApplySelf( const vector &vpns ) const for(map::const_iterator setting= m_SetPref.begin(); setting != m_SetPref.end(); ++setting) { IPreference* pref= IPreference::GetPreferenceByName(setting->first); - if(pref != NULL) + if(pref != nullptr) { pref->FromString(setting->second); } @@ -816,17 +815,17 @@ void GameCommand::ApplySelf( const vector &vpns ) const if( m_sSoundPath != "" ) SOUND->PlayOnce( THEME->GetPathS( "", m_sSoundPath ) ); if( m_iWeightPounds != -1 ) - FOREACH_CONST( PlayerNumber, vpns, pn ) - PROFILEMAN->GetProfile(*pn)->m_iWeightPounds = m_iWeightPounds; + for (PlayerNumber const &pn : vpns) + PROFILEMAN->GetProfile(pn)->m_iWeightPounds = m_iWeightPounds; if( m_iGoalCalories != -1 ) - FOREACH_CONST( PlayerNumber, vpns, pn ) - PROFILEMAN->GetProfile(*pn)->m_iGoalCalories = m_iGoalCalories; + for (PlayerNumber const &pn : vpns) + PROFILEMAN->GetProfile(pn)->m_iGoalCalories = m_iGoalCalories; if( m_GoalType != GoalType_Invalid ) - FOREACH_CONST( PlayerNumber, vpns, pn ) - PROFILEMAN->GetProfile(*pn)->m_GoalType = m_GoalType; + for (PlayerNumber const &pn : vpns) + PROFILEMAN->GetProfile(pn)->m_GoalType = m_GoalType; if( !m_sProfileID.empty() ) - FOREACH_CONST( PlayerNumber, vpns, pn ) - ProfileManager::m_sDefaultLocalProfileID[*pn].Set( m_sProfileID ); + for (PlayerNumber const &pn : vpns) + ProfileManager::m_sDefaultLocalProfileID[pn].Set( m_sProfileID ); if( !m_sUrl.empty() ) { if( HOOKS->GoToURL( m_sUrl ) ) @@ -845,8 +844,8 @@ void GameCommand::ApplySelf( const vector &vpns ) const if( m_bFadeMusic ) SOUND->DimMusic(m_fMusicFadeOutVolume, m_fMusicFadeOutSeconds); - FOREACH_CONST( RString, m_vsScreensToPrepare, s ) - SCREENMAN->PrepareScreen( *s ); + for (RString const &s : m_vsScreensToPrepare) + SCREENMAN->PrepareScreen( s ); if( m_bInsertCredit ) { @@ -886,16 +885,16 @@ void GameCommand::ApplySelf( const vector &vpns ) const bool GameCommand::IsZero() const { if( m_pm != PlayMode_Invalid || - m_pStyle != NULL || + m_pStyle != nullptr || m_dc != Difficulty_Invalid || m_sAnnouncer != "" || m_sPreferredModifiers != "" || m_sStageModifiers != "" || - m_pSong != NULL || - m_pSteps != NULL || - m_pCourse != NULL || - m_pTrail != NULL || - m_pCharacter != NULL || + m_pSong != nullptr || + m_pSteps != nullptr || + m_pCourse != nullptr || + m_pTrail != nullptr || + m_pCharacter != nullptr || m_CourseDifficulty != Difficulty_Invalid || !m_sSongGroup.empty() || m_SortOrder != SortOrder_Invalid || @@ -923,14 +922,14 @@ public: static int GetText( T* p, lua_State *L ) { lua_pushstring(L, p->m_sText ); return 1; } static int GetIndex( T* p, lua_State *L ) { lua_pushnumber(L, p->m_iIndex ); return 1; } static int GetMultiPlayer( T* p, lua_State *L ) { lua_pushnumber(L, p->m_MultiPlayer); return 1; } - static int GetStyle( T* p, lua_State *L ) { if(p->m_pStyle==NULL) lua_pushnil(L); else {Style *pStyle = (Style*)p->m_pStyle; pStyle->PushSelf(L);} return 1; } + static int GetStyle( T* p, lua_State *L ) { if(p->m_pStyle== nullptr) lua_pushnil(L); else {Style *pStyle = (Style*)p->m_pStyle; pStyle->PushSelf(L);} return 1; } static int GetScreen( T* p, lua_State *L ) { lua_pushstring(L, p->m_sScreen ); return 1; } static int GetProfileID( T* p, lua_State *L ) { lua_pushstring(L, p->m_sProfileID ); return 1; } - static int GetSong( T* p, lua_State *L ) { if(p->m_pSong==NULL) lua_pushnil(L); else p->m_pSong->PushSelf(L); return 1; } - static int GetSteps( T* p, lua_State *L ) { if(p->m_pSteps==NULL) lua_pushnil(L); else p->m_pSteps->PushSelf(L); return 1; } - static int GetCourse( T* p, lua_State *L ) { if(p->m_pCourse==NULL) lua_pushnil(L); else p->m_pCourse->PushSelf(L); return 1; } - static int GetTrail( T* p, lua_State *L ) { if(p->m_pTrail==NULL) lua_pushnil(L); else p->m_pTrail->PushSelf(L); return 1; } - static int GetCharacter( T* p, lua_State *L ) { if(p->m_pCharacter==NULL) lua_pushnil(L); else p->m_pCharacter->PushSelf(L); return 1; } + static int GetSong( T* p, lua_State *L ) { if(p->m_pSong== nullptr) lua_pushnil(L); else p->m_pSong->PushSelf(L); return 1; } + static int GetSteps( T* p, lua_State *L ) { if(p->m_pSteps== nullptr) lua_pushnil(L); else p->m_pSteps->PushSelf(L); return 1; } + static int GetCourse( T* p, lua_State *L ) { if(p->m_pCourse== nullptr) lua_pushnil(L); else p->m_pCourse->PushSelf(L); return 1; } + static int GetTrail( T* p, lua_State *L ) { if(p->m_pTrail== nullptr) lua_pushnil(L); else p->m_pTrail->PushSelf(L); return 1; } + static int GetCharacter( T* p, lua_State *L ) { if(p->m_pCharacter== nullptr) lua_pushnil(L); else p->m_pCharacter->PushSelf(L); return 1; } static int GetSongGroup( T* p, lua_State *L ) { lua_pushstring(L, p->m_sSongGroup ); return 1; } static int GetUrl( T* p, lua_State *L ) { lua_pushstring(L, p->m_sUrl ); return 1; } static int GetAnnouncer( T* p, lua_State *L ) { lua_pushstring(L, p->m_sAnnouncer ); return 1; } diff --git a/src/GameCommand.h b/src/GameCommand.h index cad1ae9c62..aa7a5d4467 100644 --- a/src/GameCommand.h +++ b/src/GameCommand.h @@ -28,13 +28,13 @@ public: GameCommand(): m_Commands(), m_sName(""), m_sText(""), m_bInvalid(true), m_sInvalidReason(""), m_iIndex(-1), m_MultiPlayer(MultiPlayer_Invalid), - m_pStyle(NULL), m_pm(PlayMode_Invalid), + m_pStyle(nullptr), m_pm(PlayMode_Invalid), m_dc(Difficulty_Invalid), m_CourseDifficulty(Difficulty_Invalid), m_sAnnouncer(""), m_sPreferredModifiers(""), m_sStageModifiers(""), m_sScreen(""), m_LuaFunction(), - m_pSong(NULL), m_pSteps(NULL), m_pCourse(NULL), - m_pTrail(NULL), m_pCharacter(NULL), m_SetEnv(), m_SetPref(), + m_pSong(nullptr), m_pSteps(nullptr), m_pCourse(nullptr), + m_pTrail(nullptr), m_pCharacter(nullptr), m_SetEnv(), m_SetPref(), m_sSongGroup(""), m_SortOrder(SortOrder_Invalid), m_sSoundPath(""), m_vsScreensToPrepare(), m_iWeightPounds(-1), m_iGoalCalories(-1), m_GoalType(GoalType_Invalid), @@ -60,7 +60,7 @@ public: bool DescribesCurrentMode( PlayerNumber pn ) const; bool DescribesCurrentModeForAllPlayers() const; - bool IsPlayable( RString *why = NULL ) const; + bool IsPlayable( RString *why = nullptr ) const; bool IsZero() const; /* If true, Apply() will apply m_sScreen. If false, it won't, and you need diff --git a/src/GameConstantsAndTypes.cpp b/src/GameConstantsAndTypes.cpp index 7c1c7f5e9c..12417ca98e 100644 --- a/src/GameConstantsAndTypes.cpp +++ b/src/GameConstantsAndTypes.cpp @@ -4,7 +4,7 @@ #include "RageUtil.h" #include "ThemeMetric.h" #include "EnumHelper.h" -#include "Foreach.h" + #include "LuaManager.h" #include "GameManager.h" #include "LocalizedString.h" @@ -375,10 +375,10 @@ void DisplayBpms::Add( float f ) float DisplayBpms::GetMin() const { float fMin = FLT_MAX; - FOREACH_CONST( float, vfBpms, f ) + for (float const &f : vfBpms) { - if( *f != -1 ) - fMin = min( fMin, *f ); + if( f != -1 ) + fMin = min( fMin, f ); } if( fMin == FLT_MAX ) return 0; @@ -394,10 +394,10 @@ float DisplayBpms::GetMax() const float DisplayBpms::GetMaxWithin(float highest) const { float fMax = 0; - FOREACH_CONST( float, vfBpms, f ) + for (float const &f : vfBpms) { - if( *f != -1 ) - fMax = clamp(max( fMax, *f ), 0, highest); + if( f != -1 ) + fMax = clamp(max( fMax, f ), 0, highest); } return fMax; } @@ -409,12 +409,7 @@ bool DisplayBpms::BpmIsConstant() const bool DisplayBpms::IsSecret() const { - FOREACH_CONST( float, vfBpms, f ) - { - if( *f == -1 ) - return true; - } - return false; + return std::any_of(vfBpms.begin(), vfBpms.end(), [](float const &f) { return f == -1; }); } static const char *StyleTypeNames[] = { diff --git a/src/GameLoop.cpp b/src/GameLoop.cpp index a19e82d9eb..b2cc84e797 100644 --- a/src/GameLoop.cpp +++ b/src/GameLoop.cpp @@ -76,13 +76,12 @@ static bool ChangeAppPri() if( INPUTMAN ) { INPUTMAN->GetDevicesAndDescriptions(vDevices); - FOREACH_CONST( InputDeviceInfo, vDevices, d ) + if (std::any_of(vDevices.begin(), vDevices.end(), [](InputDeviceInfo const &d) { + return d.sDesc.find("NTPAD") != string::npos; + })) { - if( d->sDesc.find("NTPAD") != string::npos ) - { - LOG->Trace( "Using NTPAD. Don't boost priority." ); - return false; - } + LOG->Trace( "Using NTPAD. Don't boost priority." ); + return false; } } } @@ -181,7 +180,7 @@ namespace void DoChangeGame() { const Game* g= GAMEMAN->StringToGame(g_NewGame); - ASSERT(g != NULL); + ASSERT(g != nullptr); GAMESTATE->SetCurGame(g); bool theme_changing= false; @@ -358,7 +357,7 @@ private: enum State { RENDERING_IDLE, RENDERING_START, RENDERING_ACTIVE, RENDERING_END }; State m_State; }; -static ConcurrentRenderer *g_pConcurrentRenderer = NULL; +static ConcurrentRenderer *g_pConcurrentRenderer = nullptr; ConcurrentRenderer::ConcurrentRenderer(): m_Event("ConcurrentRenderer") @@ -405,7 +404,7 @@ void ConcurrentRenderer::Stop() void ConcurrentRenderer::RenderThread() { - ASSERT( SCREENMAN != NULL ); + ASSERT( SCREENMAN != nullptr ); while( !m_bShutdown ) { @@ -462,7 +461,7 @@ int ConcurrentRenderer::StartRenderThread( void *p ) void GameLoop::StartConcurrentRendering() { - if( g_pConcurrentRenderer == NULL ) + if( g_pConcurrentRenderer == nullptr ) g_pConcurrentRenderer = new ConcurrentRenderer; g_pConcurrentRenderer->Start(); } diff --git a/src/GameManager.cpp b/src/GameManager.cpp index a9a4d37983..86e36c4bd3 100644 --- a/src/GameManager.cpp +++ b/src/GameManager.cpp @@ -13,9 +13,8 @@ #include "LightsManager.h" // for NUM_CabinetLight #include "Game.h" #include "Style.h" -#include "Foreach.h" -GameManager* GAMEMAN = NULL; // global and accessible from anywhere in our program +GameManager* GAMEMAN = nullptr; // global and accessable from anywhere in our program enum { @@ -151,16 +150,16 @@ static const Style g_Style_Dance_Single = 4, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -DANCE_COL_SPACING*1.5f, NULL }, - { TRACK_2, -DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_3, +DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_4, +DANCE_COL_SPACING*1.5f, NULL }, + { TRACK_1, -DANCE_COL_SPACING*1.5f, nullptr }, + { TRACK_2, -DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_3, +DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +DANCE_COL_SPACING*1.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -DANCE_COL_SPACING*1.5f, NULL }, - { TRACK_2, -DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_3, +DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_4, +DANCE_COL_SPACING*1.5f, NULL }, + { TRACK_1, -DANCE_COL_SPACING*1.5f, nullptr }, + { TRACK_2, -DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_3, +DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +DANCE_COL_SPACING*1.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -186,16 +185,16 @@ static const Style g_Style_Dance_Versus = 4, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -DANCE_COL_SPACING*1.5f, NULL }, - { TRACK_2, -DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_3, +DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_4, +DANCE_COL_SPACING*1.5f, NULL }, + { TRACK_1, -DANCE_COL_SPACING*1.5f, nullptr }, + { TRACK_2, -DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_3, +DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +DANCE_COL_SPACING*1.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -DANCE_COL_SPACING*1.5f, NULL }, - { TRACK_2, -DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_3, +DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_4, +DANCE_COL_SPACING*1.5f, NULL }, + { TRACK_1, -DANCE_COL_SPACING*1.5f, nullptr }, + { TRACK_2, -DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_3, +DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +DANCE_COL_SPACING*1.5f, nullptr }, }, }, { @@ -221,24 +220,24 @@ static const Style g_Style_Dance_Double = 8, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -DANCE_COL_SPACING*3.5f, NULL }, - { TRACK_2, -DANCE_COL_SPACING*2.5f, NULL }, - { TRACK_3, -DANCE_COL_SPACING*1.5f, NULL }, - { TRACK_4, -DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_5, +DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_6, +DANCE_COL_SPACING*1.5f, NULL }, - { TRACK_7, +DANCE_COL_SPACING*2.5f, NULL }, - { TRACK_8, +DANCE_COL_SPACING*3.5f, NULL }, + { TRACK_1, -DANCE_COL_SPACING*3.5f, nullptr }, + { TRACK_2, -DANCE_COL_SPACING*2.5f, nullptr }, + { TRACK_3, -DANCE_COL_SPACING*1.5f, nullptr }, + { TRACK_4, -DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_6, +DANCE_COL_SPACING*1.5f, nullptr }, + { TRACK_7, +DANCE_COL_SPACING*2.5f, nullptr }, + { TRACK_8, +DANCE_COL_SPACING*3.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -DANCE_COL_SPACING*3.5f, NULL }, - { TRACK_2, -DANCE_COL_SPACING*2.5f, NULL }, - { TRACK_3, -DANCE_COL_SPACING*1.5f, NULL }, - { TRACK_4, -DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_5, +DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_6, +DANCE_COL_SPACING*1.5f, NULL }, - { TRACK_7, +DANCE_COL_SPACING*2.5f, NULL }, - { TRACK_8, +DANCE_COL_SPACING*3.5f, NULL }, + { TRACK_1, -DANCE_COL_SPACING*3.5f, nullptr }, + { TRACK_2, -DANCE_COL_SPACING*2.5f, nullptr }, + { TRACK_3, -DANCE_COL_SPACING*1.5f, nullptr }, + { TRACK_4, -DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_6, +DANCE_COL_SPACING*1.5f, nullptr }, + { TRACK_7, +DANCE_COL_SPACING*2.5f, nullptr }, + { TRACK_8, +DANCE_COL_SPACING*3.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -264,16 +263,16 @@ static const Style g_Style_Dance_Couple = 4, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -DANCE_COL_SPACING*1.5f, NULL }, - { TRACK_2, -DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_3, +DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_4, +DANCE_COL_SPACING*1.5f, NULL }, + { TRACK_1, -DANCE_COL_SPACING*1.5f, nullptr }, + { TRACK_2, -DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_3, +DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +DANCE_COL_SPACING*1.5f, nullptr }, }, { // PLAYER_2 - { TRACK_5, -DANCE_COL_SPACING*1.5f, NULL }, - { TRACK_6, -DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_7, +DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_8, +DANCE_COL_SPACING*1.5f, NULL }, + { TRACK_5, -DANCE_COL_SPACING*1.5f, nullptr }, + { TRACK_6, -DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_7, +DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_8, +DANCE_COL_SPACING*1.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -299,20 +298,20 @@ static const Style g_Style_Dance_Solo = 6, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -DANCE_COL_SPACING*2.5f, NULL }, - { TRACK_2, -DANCE_COL_SPACING*1.5f, NULL }, - { TRACK_3, -DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_4, +DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_5, +DANCE_COL_SPACING*1.5f, NULL }, - { TRACK_6, +DANCE_COL_SPACING*2.5f, NULL }, + { TRACK_1, -DANCE_COL_SPACING*2.5f, nullptr }, + { TRACK_2, -DANCE_COL_SPACING*1.5f, nullptr }, + { TRACK_3, -DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +DANCE_COL_SPACING*1.5f, nullptr }, + { TRACK_6, +DANCE_COL_SPACING*2.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -DANCE_COL_SPACING*2.5f, NULL }, - { TRACK_2, -DANCE_COL_SPACING*1.5f, NULL }, - { TRACK_3, -DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_4, +DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_5, +DANCE_COL_SPACING*1.5f, NULL }, - { TRACK_6, +DANCE_COL_SPACING*2.5f, NULL }, + { TRACK_1, -DANCE_COL_SPACING*2.5f, nullptr }, + { TRACK_2, -DANCE_COL_SPACING*1.5f, nullptr }, + { TRACK_3, -DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +DANCE_COL_SPACING*1.5f, nullptr }, + { TRACK_6, +DANCE_COL_SPACING*2.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -338,24 +337,24 @@ static const Style g_Style_Dance_Couple_Edit = 8, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -DANCE_COL_SPACING*4.f, NULL }, - { TRACK_2, -DANCE_COL_SPACING*3.f, NULL }, - { TRACK_3, -DANCE_COL_SPACING*2.f, NULL }, - { TRACK_4, -DANCE_COL_SPACING*1.f, NULL }, - { TRACK_5, +DANCE_COL_SPACING*1.f, NULL }, - { TRACK_6, +DANCE_COL_SPACING*2.f, NULL }, - { TRACK_7, +DANCE_COL_SPACING*3.f, NULL }, - { TRACK_8, +DANCE_COL_SPACING*4.f, NULL }, + { TRACK_1, -DANCE_COL_SPACING*4.f, nullptr }, + { TRACK_2, -DANCE_COL_SPACING*3.f, nullptr }, + { TRACK_3, -DANCE_COL_SPACING*2.f, nullptr }, + { TRACK_4, -DANCE_COL_SPACING*1.f, nullptr }, + { TRACK_5, +DANCE_COL_SPACING*1.f, nullptr }, + { TRACK_6, +DANCE_COL_SPACING*2.f, nullptr }, + { TRACK_7, +DANCE_COL_SPACING*3.f, nullptr }, + { TRACK_8, +DANCE_COL_SPACING*4.f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -DANCE_COL_SPACING*4.f, NULL }, - { TRACK_2, -DANCE_COL_SPACING*3.f, NULL }, - { TRACK_3, -DANCE_COL_SPACING*2.f, NULL }, - { TRACK_4, -DANCE_COL_SPACING*1.f, NULL }, - { TRACK_5, +DANCE_COL_SPACING*1.f, NULL }, - { TRACK_6, +DANCE_COL_SPACING*2.f, NULL }, - { TRACK_7, +DANCE_COL_SPACING*3.f, NULL }, - { TRACK_8, +DANCE_COL_SPACING*4.f, NULL }, + { TRACK_1, -DANCE_COL_SPACING*4.f, nullptr }, + { TRACK_2, -DANCE_COL_SPACING*3.f, nullptr }, + { TRACK_3, -DANCE_COL_SPACING*2.f, nullptr }, + { TRACK_4, -DANCE_COL_SPACING*1.f, nullptr }, + { TRACK_5, +DANCE_COL_SPACING*1.f, nullptr }, + { TRACK_6, +DANCE_COL_SPACING*2.f, nullptr }, + { TRACK_7, +DANCE_COL_SPACING*3.f, nullptr }, + { TRACK_8, +DANCE_COL_SPACING*4.f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -381,14 +380,14 @@ static const Style g_Style_Dance_ThreePanel = 3, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -DANCE_COL_SPACING*1.0f, NULL }, - { TRACK_2, +DANCE_COL_SPACING*0.0f, NULL }, - { TRACK_3, +DANCE_COL_SPACING*1.0f, NULL }, + { TRACK_1, -DANCE_COL_SPACING*1.0f, nullptr }, + { TRACK_2, +DANCE_COL_SPACING*0.0f, nullptr }, + { TRACK_3, +DANCE_COL_SPACING*1.0f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -DANCE_COL_SPACING*1.0f, NULL }, - { TRACK_2, +DANCE_COL_SPACING*0.0f, NULL }, - { TRACK_3, +DANCE_COL_SPACING*1.0f, NULL }, + { TRACK_1, -DANCE_COL_SPACING*1.0f, nullptr }, + { TRACK_2, +DANCE_COL_SPACING*0.0f, nullptr }, + { TRACK_3, +DANCE_COL_SPACING*1.0f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -452,24 +451,24 @@ static const Style g_Style_Dance_Routine = 8, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -DANCE_COL_SPACING*3.5f, NULL }, - { TRACK_2, -DANCE_COL_SPACING*2.5f, NULL }, - { TRACK_3, -DANCE_COL_SPACING*1.5f, NULL }, - { TRACK_4, -DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_5, +DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_6, +DANCE_COL_SPACING*1.5f, NULL }, - { TRACK_7, +DANCE_COL_SPACING*2.5f, NULL }, - { TRACK_8, +DANCE_COL_SPACING*3.5f, NULL }, + { TRACK_1, -DANCE_COL_SPACING*3.5f, nullptr }, + { TRACK_2, -DANCE_COL_SPACING*2.5f, nullptr }, + { TRACK_3, -DANCE_COL_SPACING*1.5f, nullptr }, + { TRACK_4, -DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_6, +DANCE_COL_SPACING*1.5f, nullptr }, + { TRACK_7, +DANCE_COL_SPACING*2.5f, nullptr }, + { TRACK_8, +DANCE_COL_SPACING*3.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -DANCE_COL_SPACING*3.5f, NULL }, - { TRACK_2, -DANCE_COL_SPACING*2.5f, NULL }, - { TRACK_3, -DANCE_COL_SPACING*1.5f, NULL }, - { TRACK_4, -DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_5, +DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_6, +DANCE_COL_SPACING*1.5f, NULL }, - { TRACK_7, +DANCE_COL_SPACING*2.5f, NULL }, - { TRACK_8, +DANCE_COL_SPACING*3.5f, NULL }, + { TRACK_1, -DANCE_COL_SPACING*3.5f, nullptr }, + { TRACK_2, -DANCE_COL_SPACING*2.5f, nullptr }, + { TRACK_3, -DANCE_COL_SPACING*1.5f, nullptr }, + { TRACK_4, -DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_6, +DANCE_COL_SPACING*1.5f, nullptr }, + { TRACK_7, +DANCE_COL_SPACING*2.5f, nullptr }, + { TRACK_8, +DANCE_COL_SPACING*3.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -493,7 +492,7 @@ static const Style *g_apGame_Dance_Styles[] = &g_Style_Dance_Couple_Edit, &g_Style_Dance_Routine, &g_Style_Dance_ThreePanel, - NULL + nullptr }; static const Game g_Game_Dance = @@ -570,18 +569,18 @@ static const Style g_Style_Pump_Single = 5, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -PUMP_COL_SPACING*2.0f, NULL }, - { TRACK_2, -PUMP_COL_SPACING*1.0f, NULL }, - { TRACK_3, +PUMP_COL_SPACING*0.0f, NULL }, - { TRACK_4, +PUMP_COL_SPACING*1.0f, NULL }, - { TRACK_5, +PUMP_COL_SPACING*2.0f, NULL }, + { TRACK_1, -PUMP_COL_SPACING*2.0f, nullptr }, + { TRACK_2, -PUMP_COL_SPACING*1.0f, nullptr }, + { TRACK_3, +PUMP_COL_SPACING*0.0f, nullptr }, + { TRACK_4, +PUMP_COL_SPACING*1.0f, nullptr }, + { TRACK_5, +PUMP_COL_SPACING*2.0f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -PUMP_COL_SPACING*2.0f, NULL }, - { TRACK_2, -PUMP_COL_SPACING*1.0f, NULL }, - { TRACK_3, +PUMP_COL_SPACING*0.0f, NULL }, - { TRACK_4, +PUMP_COL_SPACING*1.0f, NULL }, - { TRACK_5, +PUMP_COL_SPACING*2.0f, NULL }, + { TRACK_1, -PUMP_COL_SPACING*2.0f, nullptr }, + { TRACK_2, -PUMP_COL_SPACING*1.0f, nullptr }, + { TRACK_3, +PUMP_COL_SPACING*0.0f, nullptr }, + { TRACK_4, +PUMP_COL_SPACING*1.0f, nullptr }, + { TRACK_5, +PUMP_COL_SPACING*2.0f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -607,18 +606,18 @@ static const Style g_Style_Pump_Versus = 5, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -PUMP_COL_SPACING*2.0f, NULL }, - { TRACK_2, -PUMP_COL_SPACING*1.0f, NULL }, - { TRACK_3, +PUMP_COL_SPACING*0.0f, NULL }, - { TRACK_4, +PUMP_COL_SPACING*1.0f, NULL }, - { TRACK_5, +PUMP_COL_SPACING*2.0f, NULL }, + { TRACK_1, -PUMP_COL_SPACING*2.0f, nullptr }, + { TRACK_2, -PUMP_COL_SPACING*1.0f, nullptr }, + { TRACK_3, +PUMP_COL_SPACING*0.0f, nullptr }, + { TRACK_4, +PUMP_COL_SPACING*1.0f, nullptr }, + { TRACK_5, +PUMP_COL_SPACING*2.0f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -PUMP_COL_SPACING*2.0f, NULL }, - { TRACK_2, -PUMP_COL_SPACING*1.0f, NULL }, - { TRACK_3, +PUMP_COL_SPACING*0.0f, NULL }, - { TRACK_4, +PUMP_COL_SPACING*1.0f, NULL }, - { TRACK_5, +PUMP_COL_SPACING*2.0f, NULL }, + { TRACK_1, -PUMP_COL_SPACING*2.0f, nullptr }, + { TRACK_2, -PUMP_COL_SPACING*1.0f, nullptr }, + { TRACK_3, +PUMP_COL_SPACING*0.0f, nullptr }, + { TRACK_4, +PUMP_COL_SPACING*1.0f, nullptr }, + { TRACK_5, +PUMP_COL_SPACING*2.0f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -644,20 +643,20 @@ static const Style g_Style_Pump_HalfDouble = 6, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -PUMP_COL_SPACING*2.5f-4, NULL }, - { TRACK_2, -PUMP_COL_SPACING*1.5f-4, NULL }, - { TRACK_3, -PUMP_COL_SPACING*0.5f-4, NULL }, - { TRACK_4, +PUMP_COL_SPACING*0.5f+4, NULL }, - { TRACK_5, +PUMP_COL_SPACING*1.5f+4, NULL }, - { TRACK_6, +PUMP_COL_SPACING*2.5f+4, NULL }, + { TRACK_1, -PUMP_COL_SPACING*2.5f-4, nullptr }, + { TRACK_2, -PUMP_COL_SPACING*1.5f-4, nullptr }, + { TRACK_3, -PUMP_COL_SPACING*0.5f-4, nullptr }, + { TRACK_4, +PUMP_COL_SPACING*0.5f+4, nullptr }, + { TRACK_5, +PUMP_COL_SPACING*1.5f+4, nullptr }, + { TRACK_6, +PUMP_COL_SPACING*2.5f+4, nullptr }, }, { // PLAYER_2 - { TRACK_1, -PUMP_COL_SPACING*2.5f-4, NULL }, - { TRACK_2, -PUMP_COL_SPACING*1.5f-4, NULL }, - { TRACK_3, -PUMP_COL_SPACING*0.5f-4, NULL }, - { TRACK_4, +PUMP_COL_SPACING*0.5f+4, NULL }, - { TRACK_5, +PUMP_COL_SPACING*1.5f+4, NULL }, - { TRACK_6, +PUMP_COL_SPACING*2.5f+4, NULL }, + { TRACK_1, -PUMP_COL_SPACING*2.5f-4, nullptr }, + { TRACK_2, -PUMP_COL_SPACING*1.5f-4, nullptr }, + { TRACK_3, -PUMP_COL_SPACING*0.5f-4, nullptr }, + { TRACK_4, +PUMP_COL_SPACING*0.5f+4, nullptr }, + { TRACK_5, +PUMP_COL_SPACING*1.5f+4, nullptr }, + { TRACK_6, +PUMP_COL_SPACING*2.5f+4, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -683,28 +682,28 @@ static const Style g_Style_Pump_Double = 10, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -PUMP_COL_SPACING*4.5f-4, NULL }, - { TRACK_2, -PUMP_COL_SPACING*3.5f-4, NULL }, - { TRACK_3, -PUMP_COL_SPACING*2.5f-4, NULL }, - { TRACK_4, -PUMP_COL_SPACING*1.5f-4, NULL }, - { TRACK_5, -PUMP_COL_SPACING*0.5f-4, NULL }, - { TRACK_6, +PUMP_COL_SPACING*0.5f+4, NULL }, - { TRACK_7, +PUMP_COL_SPACING*1.5f+4, NULL }, - { TRACK_8, +PUMP_COL_SPACING*2.5f+4, NULL }, - { TRACK_9, +PUMP_COL_SPACING*3.5f+4, NULL }, - { TRACK_10, +PUMP_COL_SPACING*4.5f+4, NULL }, + { TRACK_1, -PUMP_COL_SPACING*4.5f-4, nullptr }, + { TRACK_2, -PUMP_COL_SPACING*3.5f-4, nullptr }, + { TRACK_3, -PUMP_COL_SPACING*2.5f-4, nullptr }, + { TRACK_4, -PUMP_COL_SPACING*1.5f-4, nullptr }, + { TRACK_5, -PUMP_COL_SPACING*0.5f-4, nullptr }, + { TRACK_6, +PUMP_COL_SPACING*0.5f+4, nullptr }, + { TRACK_7, +PUMP_COL_SPACING*1.5f+4, nullptr }, + { TRACK_8, +PUMP_COL_SPACING*2.5f+4, nullptr }, + { TRACK_9, +PUMP_COL_SPACING*3.5f+4, nullptr }, + { TRACK_10, +PUMP_COL_SPACING*4.5f+4, nullptr }, }, { // PLAYER_2 - { TRACK_1, -PUMP_COL_SPACING*4.5f-4, NULL }, - { TRACK_2, -PUMP_COL_SPACING*3.5f-4, NULL }, - { TRACK_3, -PUMP_COL_SPACING*2.5f-4, NULL }, - { TRACK_4, -PUMP_COL_SPACING*1.5f-4, NULL }, - { TRACK_5, -PUMP_COL_SPACING*0.5f-4, NULL }, - { TRACK_6, +PUMP_COL_SPACING*0.5f+4, NULL }, - { TRACK_7, +PUMP_COL_SPACING*1.5f+4, NULL }, - { TRACK_8, +PUMP_COL_SPACING*2.5f+4, NULL }, - { TRACK_9, +PUMP_COL_SPACING*3.5f+4, NULL }, - { TRACK_10, +PUMP_COL_SPACING*4.5f+4, NULL }, + { TRACK_1, -PUMP_COL_SPACING*4.5f-4, nullptr }, + { TRACK_2, -PUMP_COL_SPACING*3.5f-4, nullptr }, + { TRACK_3, -PUMP_COL_SPACING*2.5f-4, nullptr }, + { TRACK_4, -PUMP_COL_SPACING*1.5f-4, nullptr }, + { TRACK_5, -PUMP_COL_SPACING*0.5f-4, nullptr }, + { TRACK_6, +PUMP_COL_SPACING*0.5f+4, nullptr }, + { TRACK_7, +PUMP_COL_SPACING*1.5f+4, nullptr }, + { TRACK_8, +PUMP_COL_SPACING*2.5f+4, nullptr }, + { TRACK_9, +PUMP_COL_SPACING*3.5f+4, nullptr }, + { TRACK_10, +PUMP_COL_SPACING*4.5f+4, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -730,18 +729,18 @@ static const Style g_Style_Pump_Couple = 5, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -PUMP_COL_SPACING*2.0f, NULL }, - { TRACK_2, -PUMP_COL_SPACING*1.0f, NULL }, - { TRACK_3, +PUMP_COL_SPACING*0.0f, NULL }, - { TRACK_4, +PUMP_COL_SPACING*1.0f, NULL }, - { TRACK_5, +PUMP_COL_SPACING*2.0f, NULL }, + { TRACK_1, -PUMP_COL_SPACING*2.0f, nullptr }, + { TRACK_2, -PUMP_COL_SPACING*1.0f, nullptr }, + { TRACK_3, +PUMP_COL_SPACING*0.0f, nullptr }, + { TRACK_4, +PUMP_COL_SPACING*1.0f, nullptr }, + { TRACK_5, +PUMP_COL_SPACING*2.0f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -PUMP_COL_SPACING*2.0f, NULL }, - { TRACK_2, -PUMP_COL_SPACING*1.0f, NULL }, - { TRACK_3, +PUMP_COL_SPACING*0.0f, NULL }, - { TRACK_4, +PUMP_COL_SPACING*1.0f, NULL }, - { TRACK_5, +PUMP_COL_SPACING*2.0f, NULL }, + { TRACK_1, -PUMP_COL_SPACING*2.0f, nullptr }, + { TRACK_2, -PUMP_COL_SPACING*1.0f, nullptr }, + { TRACK_3, +PUMP_COL_SPACING*0.0f, nullptr }, + { TRACK_4, +PUMP_COL_SPACING*1.0f, nullptr }, + { TRACK_5, +PUMP_COL_SPACING*2.0f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -767,28 +766,28 @@ static const Style g_Style_Pump_Couple_Edit = 10, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -PUMP_COL_SPACING*5.0f-4, NULL }, - { TRACK_2, -PUMP_COL_SPACING*4.0f-4, NULL }, - { TRACK_3, -PUMP_COL_SPACING*3.0f-4, NULL }, - { TRACK_4, -PUMP_COL_SPACING*2.0f-4, NULL }, - { TRACK_5, -PUMP_COL_SPACING*1.0f-4, NULL }, - { TRACK_6, +PUMP_COL_SPACING*1.0f+4, NULL }, - { TRACK_7, +PUMP_COL_SPACING*2.0f+4, NULL }, - { TRACK_8, +PUMP_COL_SPACING*3.0f+4, NULL }, - { TRACK_9, +PUMP_COL_SPACING*4.0f+4, NULL }, - { TRACK_10, +PUMP_COL_SPACING*5.0f+4, NULL }, + { TRACK_1, -PUMP_COL_SPACING*5.0f-4, nullptr }, + { TRACK_2, -PUMP_COL_SPACING*4.0f-4, nullptr }, + { TRACK_3, -PUMP_COL_SPACING*3.0f-4, nullptr }, + { TRACK_4, -PUMP_COL_SPACING*2.0f-4, nullptr }, + { TRACK_5, -PUMP_COL_SPACING*1.0f-4, nullptr }, + { TRACK_6, +PUMP_COL_SPACING*1.0f+4, nullptr }, + { TRACK_7, +PUMP_COL_SPACING*2.0f+4, nullptr }, + { TRACK_8, +PUMP_COL_SPACING*3.0f+4, nullptr }, + { TRACK_9, +PUMP_COL_SPACING*4.0f+4, nullptr }, + { TRACK_10, +PUMP_COL_SPACING*5.0f+4, nullptr }, }, { // PLAYER_2 - { TRACK_1, -PUMP_COL_SPACING*5.0f-4, NULL }, - { TRACK_2, -PUMP_COL_SPACING*4.0f-4, NULL }, - { TRACK_3, -PUMP_COL_SPACING*3.0f-4, NULL }, - { TRACK_4, -PUMP_COL_SPACING*2.0f-4, NULL }, - { TRACK_5, -PUMP_COL_SPACING*1.0f-4, NULL }, - { TRACK_6, +PUMP_COL_SPACING*1.0f+4, NULL }, - { TRACK_7, +PUMP_COL_SPACING*2.0f+4, NULL }, - { TRACK_8, +PUMP_COL_SPACING*3.0f+4, NULL }, - { TRACK_9, +PUMP_COL_SPACING*4.0f+4, NULL }, - { TRACK_10, +PUMP_COL_SPACING*5.0f+4, NULL }, + { TRACK_1, -PUMP_COL_SPACING*5.0f-4, nullptr }, + { TRACK_2, -PUMP_COL_SPACING*4.0f-4, nullptr }, + { TRACK_3, -PUMP_COL_SPACING*3.0f-4, nullptr }, + { TRACK_4, -PUMP_COL_SPACING*2.0f-4, nullptr }, + { TRACK_5, -PUMP_COL_SPACING*1.0f-4, nullptr }, + { TRACK_6, +PUMP_COL_SPACING*1.0f+4, nullptr }, + { TRACK_7, +PUMP_COL_SPACING*2.0f+4, nullptr }, + { TRACK_8, +PUMP_COL_SPACING*3.0f+4, nullptr }, + { TRACK_9, +PUMP_COL_SPACING*4.0f+4, nullptr }, + { TRACK_10, +PUMP_COL_SPACING*5.0f+4, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -814,28 +813,28 @@ static const Style g_Style_Pump_Routine = 10, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -PUMP_COL_SPACING*4.5f-4, NULL }, - { TRACK_2, -PUMP_COL_SPACING*3.5f-4, NULL }, - { TRACK_3, -PUMP_COL_SPACING*2.5f-4, NULL }, - { TRACK_4, -PUMP_COL_SPACING*1.5f-4, NULL }, - { TRACK_5, -PUMP_COL_SPACING*0.5f-4, NULL }, - { TRACK_6, +PUMP_COL_SPACING*0.5f+4, NULL }, - { TRACK_7, +PUMP_COL_SPACING*1.5f+4, NULL }, - { TRACK_8, +PUMP_COL_SPACING*2.5f+4, NULL }, - { TRACK_9, +PUMP_COL_SPACING*3.5f+4, NULL }, - { TRACK_10, +PUMP_COL_SPACING*4.5f+4, NULL }, + { TRACK_1, -PUMP_COL_SPACING*4.5f-4, nullptr }, + { TRACK_2, -PUMP_COL_SPACING*3.5f-4, nullptr }, + { TRACK_3, -PUMP_COL_SPACING*2.5f-4, nullptr }, + { TRACK_4, -PUMP_COL_SPACING*1.5f-4, nullptr }, + { TRACK_5, -PUMP_COL_SPACING*0.5f-4, nullptr }, + { TRACK_6, +PUMP_COL_SPACING*0.5f+4, nullptr }, + { TRACK_7, +PUMP_COL_SPACING*1.5f+4, nullptr }, + { TRACK_8, +PUMP_COL_SPACING*2.5f+4, nullptr }, + { TRACK_9, +PUMP_COL_SPACING*3.5f+4, nullptr }, + { TRACK_10, +PUMP_COL_SPACING*4.5f+4, nullptr }, }, { // PLAYER_2 - { TRACK_1, -PUMP_COL_SPACING*4.5f-4, NULL }, - { TRACK_2, -PUMP_COL_SPACING*3.5f-4, NULL }, - { TRACK_3, -PUMP_COL_SPACING*2.5f-4, NULL }, - { TRACK_4, -PUMP_COL_SPACING*1.5f-4, NULL }, - { TRACK_5, -PUMP_COL_SPACING*0.5f-4, NULL }, - { TRACK_6, +PUMP_COL_SPACING*0.5f+4, NULL }, - { TRACK_7, +PUMP_COL_SPACING*1.5f+4, NULL }, - { TRACK_8, +PUMP_COL_SPACING*2.5f+4, NULL }, - { TRACK_9, +PUMP_COL_SPACING*3.5f+4, NULL }, - { TRACK_10, +PUMP_COL_SPACING*4.5f+4, NULL }, + { TRACK_1, -PUMP_COL_SPACING*4.5f-4, nullptr }, + { TRACK_2, -PUMP_COL_SPACING*3.5f-4, nullptr }, + { TRACK_3, -PUMP_COL_SPACING*2.5f-4, nullptr }, + { TRACK_4, -PUMP_COL_SPACING*1.5f-4, nullptr }, + { TRACK_5, -PUMP_COL_SPACING*0.5f-4, nullptr }, + { TRACK_6, +PUMP_COL_SPACING*0.5f+4, nullptr }, + { TRACK_7, +PUMP_COL_SPACING*1.5f+4, nullptr }, + { TRACK_8, +PUMP_COL_SPACING*2.5f+4, nullptr }, + { TRACK_9, +PUMP_COL_SPACING*3.5f+4, nullptr }, + { TRACK_10, +PUMP_COL_SPACING*4.5f+4, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -858,7 +857,7 @@ static const Style *g_apGame_Pump_Styles[] = &g_Style_Pump_Couple, &g_Style_Pump_Couple_Edit, &g_Style_Pump_Routine, - NULL + nullptr }; static const Game g_Game_Pump = @@ -921,22 +920,22 @@ static const Style g_Style_KB7_Single = 7, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -KB7_COL_SPACING*3.25f, NULL }, - { TRACK_2, -KB7_COL_SPACING*2.25f, NULL }, - { TRACK_3, -KB7_COL_SPACING*1.25f, NULL }, - { TRACK_4, +KB7_COL_SPACING*0.0f, NULL }, - { TRACK_5, +KB7_COL_SPACING*1.25f, NULL }, - { TRACK_6, +KB7_COL_SPACING*2.25f, NULL }, - { TRACK_7, +KB7_COL_SPACING*3.25f, NULL }, + { TRACK_1, -KB7_COL_SPACING*3.25f, nullptr }, + { TRACK_2, -KB7_COL_SPACING*2.25f, nullptr }, + { TRACK_3, -KB7_COL_SPACING*1.25f, nullptr }, + { TRACK_4, +KB7_COL_SPACING*0.0f, nullptr }, + { TRACK_5, +KB7_COL_SPACING*1.25f, nullptr }, + { TRACK_6, +KB7_COL_SPACING*2.25f, nullptr }, + { TRACK_7, +KB7_COL_SPACING*3.25f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -KB7_COL_SPACING*3.25f, NULL }, - { TRACK_2, -KB7_COL_SPACING*2.25f, NULL }, - { TRACK_3, -KB7_COL_SPACING*1.25f, NULL }, - { TRACK_4, +KB7_COL_SPACING*0.0f, NULL }, - { TRACK_5, +KB7_COL_SPACING*1.25f, NULL }, - { TRACK_6, +KB7_COL_SPACING*2.25f, NULL }, - { TRACK_7, +KB7_COL_SPACING*3.25f, NULL }, + { TRACK_1, -KB7_COL_SPACING*3.25f, nullptr }, + { TRACK_2, -KB7_COL_SPACING*2.25f, nullptr }, + { TRACK_3, -KB7_COL_SPACING*1.25f, nullptr }, + { TRACK_4, +KB7_COL_SPACING*0.0f, nullptr }, + { TRACK_5, +KB7_COL_SPACING*1.25f, nullptr }, + { TRACK_6, +KB7_COL_SPACING*2.25f, nullptr }, + { TRACK_7, +KB7_COL_SPACING*3.25f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -964,22 +963,22 @@ static const Style g_Style_KB7_Small = 7, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -34, NULL }, - { TRACK_2, -24, NULL }, - { TRACK_3, -15, NULL }, - { TRACK_4, 0, NULL }, - { TRACK_5, +15, NULL }, - { TRACK_6, +24, NULL }, - { TRACK_7, +34, NULL }, + { TRACK_1, -34, nullptr }, + { TRACK_2, -24, nullptr }, + { TRACK_3, -15, nullptr }, + { TRACK_4, 0, nullptr }, + { TRACK_5, +15, nullptr }, + { TRACK_6, +24, nullptr }, + { TRACK_7, +34, nullptr }, }, { // PLAYER_2 - { TRACK_1, -34, NULL }, - { TRACK_2, -24, NULL }, - { TRACK_3, -15, NULL }, - { TRACK_4, 0, NULL }, - { TRACK_5, +15, NULL }, - { TRACK_6, +24 NULL }, - { TRACK_7, +34, NULL }, + { TRACK_1, -34, nullptr }, + { TRACK_2, -24, nullptr }, + { TRACK_3, -15, nullptr }, + { TRACK_4, 0, nullptr }, + { TRACK_5, +15, nullptr }, + { TRACK_6, +24 nullptr }, + { TRACK_7, +34, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -1005,22 +1004,22 @@ static const Style g_Style_KB7_Versus = 7, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -KB7_COL_SPACING*3.0f, NULL }, - { TRACK_2, -KB7_COL_SPACING*2.0f, NULL }, - { TRACK_3, -KB7_COL_SPACING*1.0f, NULL }, - { TRACK_4, +KB7_COL_SPACING*0.0f, NULL }, - { TRACK_5, +KB7_COL_SPACING*1.0f, NULL }, - { TRACK_6, +KB7_COL_SPACING*2.0f, NULL }, - { TRACK_7, +KB7_COL_SPACING*3.0f, NULL }, + { TRACK_1, -KB7_COL_SPACING*3.0f, nullptr }, + { TRACK_2, -KB7_COL_SPACING*2.0f, nullptr }, + { TRACK_3, -KB7_COL_SPACING*1.0f, nullptr }, + { TRACK_4, +KB7_COL_SPACING*0.0f, nullptr }, + { TRACK_5, +KB7_COL_SPACING*1.0f, nullptr }, + { TRACK_6, +KB7_COL_SPACING*2.0f, nullptr }, + { TRACK_7, +KB7_COL_SPACING*3.0f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -KB7_COL_SPACING*3.0f, NULL }, - { TRACK_2, -KB7_COL_SPACING*2.0f, NULL }, - { TRACK_3, -KB7_COL_SPACING*1.0f, NULL }, - { TRACK_4, +KB7_COL_SPACING*0.0f, NULL }, - { TRACK_5, +KB7_COL_SPACING*1.0f, NULL }, - { TRACK_6, +KB7_COL_SPACING*2.0f, NULL }, - { TRACK_7, +KB7_COL_SPACING*3.0f, NULL }, + { TRACK_1, -KB7_COL_SPACING*3.0f, nullptr }, + { TRACK_2, -KB7_COL_SPACING*2.0f, nullptr }, + { TRACK_3, -KB7_COL_SPACING*1.0f, nullptr }, + { TRACK_4, +KB7_COL_SPACING*0.0f, nullptr }, + { TRACK_5, +KB7_COL_SPACING*1.0f, nullptr }, + { TRACK_6, +KB7_COL_SPACING*2.0f, nullptr }, + { TRACK_7, +KB7_COL_SPACING*3.0f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -1039,7 +1038,7 @@ static const Style *g_apGame_KB7_Styles[] = &g_Style_KB7_Single, // &g_Style_KB7_Small, &g_Style_KB7_Versus, - NULL + nullptr }; static const Game g_Game_KB7 = @@ -1096,18 +1095,18 @@ static const Style g_Style_Ez2_Single = 5, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -EZ2_COL_SPACING*2.0f, NULL }, - { TRACK_2, -EZ2_COL_SPACING*1.0f, NULL }, - { TRACK_3, +EZ2_COL_SPACING*0.0f, NULL }, - { TRACK_4, +EZ2_COL_SPACING*1.0f, NULL }, - { TRACK_5, +EZ2_COL_SPACING*2.0f, NULL }, + { TRACK_1, -EZ2_COL_SPACING*2.0f, nullptr }, + { TRACK_2, -EZ2_COL_SPACING*1.0f, nullptr }, + { TRACK_3, +EZ2_COL_SPACING*0.0f, nullptr }, + { TRACK_4, +EZ2_COL_SPACING*1.0f, nullptr }, + { TRACK_5, +EZ2_COL_SPACING*2.0f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -EZ2_COL_SPACING*2.0f, NULL }, - { TRACK_2, -EZ2_COL_SPACING*1.0f, NULL }, - { TRACK_3, +EZ2_COL_SPACING*0.0f, NULL }, - { TRACK_4, +EZ2_COL_SPACING*1.0f, NULL }, - { TRACK_5, +EZ2_COL_SPACING*2.0f, NULL }, + { TRACK_1, -EZ2_COL_SPACING*2.0f, nullptr }, + { TRACK_2, -EZ2_COL_SPACING*1.0f, nullptr }, + { TRACK_3, +EZ2_COL_SPACING*0.0f, nullptr }, + { TRACK_4, +EZ2_COL_SPACING*1.0f, nullptr }, + { TRACK_5, +EZ2_COL_SPACING*2.0f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -1133,22 +1132,22 @@ static const Style g_Style_Ez2_Real = 7, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -EZ2_REAL_COL_SPACING*2.3f, NULL }, - { TRACK_2, -EZ2_REAL_COL_SPACING*1.6f, NULL }, - { TRACK_3, -EZ2_REAL_COL_SPACING*0.9f, NULL }, - { TRACK_4, +EZ2_REAL_COL_SPACING*0.0f, NULL }, - { TRACK_5, +EZ2_REAL_COL_SPACING*0.9f, NULL }, - { TRACK_6, +EZ2_REAL_COL_SPACING*1.6f, NULL }, - { TRACK_7, +EZ2_REAL_COL_SPACING*2.3f, NULL }, + { TRACK_1, -EZ2_REAL_COL_SPACING*2.3f, nullptr }, + { TRACK_2, -EZ2_REAL_COL_SPACING*1.6f, nullptr }, + { TRACK_3, -EZ2_REAL_COL_SPACING*0.9f, nullptr }, + { TRACK_4, +EZ2_REAL_COL_SPACING*0.0f, nullptr }, + { TRACK_5, +EZ2_REAL_COL_SPACING*0.9f, nullptr }, + { TRACK_6, +EZ2_REAL_COL_SPACING*1.6f, nullptr }, + { TRACK_7, +EZ2_REAL_COL_SPACING*2.3f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -EZ2_REAL_COL_SPACING*2.3f, NULL }, - { TRACK_2, -EZ2_REAL_COL_SPACING*1.6f, NULL }, - { TRACK_3, -EZ2_REAL_COL_SPACING*0.9f, NULL }, - { TRACK_4, +EZ2_REAL_COL_SPACING*0.0f, NULL }, - { TRACK_5, +EZ2_REAL_COL_SPACING*0.9f, NULL }, - { TRACK_6, +EZ2_REAL_COL_SPACING*1.6f, NULL }, - { TRACK_7, +EZ2_REAL_COL_SPACING*2.3f, NULL }, + { TRACK_1, -EZ2_REAL_COL_SPACING*2.3f, nullptr }, + { TRACK_2, -EZ2_REAL_COL_SPACING*1.6f, nullptr }, + { TRACK_3, -EZ2_REAL_COL_SPACING*0.9f, nullptr }, + { TRACK_4, +EZ2_REAL_COL_SPACING*0.0f, nullptr }, + { TRACK_5, +EZ2_REAL_COL_SPACING*0.9f, nullptr }, + { TRACK_6, +EZ2_REAL_COL_SPACING*1.6f, nullptr }, + { TRACK_7, +EZ2_REAL_COL_SPACING*2.3f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -1174,18 +1173,18 @@ static const Style g_Style_Ez2_Single_Versus = 5, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -EZ2_COL_SPACING*2.0f, NULL }, - { TRACK_2, -EZ2_COL_SPACING*1.0f, NULL }, - { TRACK_3, +EZ2_COL_SPACING*0.0f, NULL }, - { TRACK_4, +EZ2_COL_SPACING*1.0f, NULL }, - { TRACK_5, +EZ2_COL_SPACING*2.0f, NULL }, + { TRACK_1, -EZ2_COL_SPACING*2.0f, nullptr }, + { TRACK_2, -EZ2_COL_SPACING*1.0f, nullptr }, + { TRACK_3, +EZ2_COL_SPACING*0.0f, nullptr }, + { TRACK_4, +EZ2_COL_SPACING*1.0f, nullptr }, + { TRACK_5, +EZ2_COL_SPACING*2.0f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -EZ2_COL_SPACING*2.0f, NULL }, - { TRACK_2, -EZ2_COL_SPACING*1.0f, NULL }, - { TRACK_3, +EZ2_COL_SPACING*0.0f, NULL }, - { TRACK_4, +EZ2_COL_SPACING*1.0f, NULL }, - { TRACK_5, +EZ2_COL_SPACING*2.0f, NULL }, + { TRACK_1, -EZ2_COL_SPACING*2.0f, nullptr }, + { TRACK_2, -EZ2_COL_SPACING*1.0f, nullptr }, + { TRACK_3, +EZ2_COL_SPACING*0.0f, nullptr }, + { TRACK_4, +EZ2_COL_SPACING*1.0f, nullptr }, + { TRACK_5, +EZ2_COL_SPACING*2.0f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -1211,22 +1210,22 @@ static const Style g_Style_Ez2_Real_Versus = 7, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -EZ2_REAL_COL_SPACING*2.3f, NULL }, - { TRACK_2, -EZ2_REAL_COL_SPACING*1.6f, NULL }, - { TRACK_3, -EZ2_REAL_COL_SPACING*0.9f, NULL }, - { TRACK_4, +EZ2_REAL_COL_SPACING*0.0f, NULL }, - { TRACK_5, +EZ2_REAL_COL_SPACING*0.9f, NULL }, - { TRACK_6, +EZ2_REAL_COL_SPACING*1.6f, NULL }, - { TRACK_7, +EZ2_REAL_COL_SPACING*2.3f, NULL }, + { TRACK_1, -EZ2_REAL_COL_SPACING*2.3f, nullptr }, + { TRACK_2, -EZ2_REAL_COL_SPACING*1.6f, nullptr }, + { TRACK_3, -EZ2_REAL_COL_SPACING*0.9f, nullptr }, + { TRACK_4, +EZ2_REAL_COL_SPACING*0.0f, nullptr }, + { TRACK_5, +EZ2_REAL_COL_SPACING*0.9f, nullptr }, + { TRACK_6, +EZ2_REAL_COL_SPACING*1.6f, nullptr }, + { TRACK_7, +EZ2_REAL_COL_SPACING*2.3f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -EZ2_REAL_COL_SPACING*2.3f, NULL }, - { TRACK_2, -EZ2_REAL_COL_SPACING*1.6f, NULL }, - { TRACK_3, -EZ2_REAL_COL_SPACING*0.9f, NULL }, - { TRACK_4, +EZ2_REAL_COL_SPACING*0.0f, NULL }, - { TRACK_5, +EZ2_REAL_COL_SPACING*0.9f, NULL }, - { TRACK_6, +EZ2_REAL_COL_SPACING*1.6f, NULL }, - { TRACK_7, +EZ2_REAL_COL_SPACING*2.3f, NULL }, + { TRACK_1, -EZ2_REAL_COL_SPACING*2.3f, nullptr }, + { TRACK_2, -EZ2_REAL_COL_SPACING*1.6f, nullptr }, + { TRACK_3, -EZ2_REAL_COL_SPACING*0.9f, nullptr }, + { TRACK_4, +EZ2_REAL_COL_SPACING*0.0f, nullptr }, + { TRACK_5, +EZ2_REAL_COL_SPACING*0.9f, nullptr }, + { TRACK_6, +EZ2_REAL_COL_SPACING*1.6f, nullptr }, + { TRACK_7, +EZ2_REAL_COL_SPACING*2.3f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -1252,28 +1251,28 @@ static const Style g_Style_Ez2_Double = 10, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -EZ2_COL_SPACING*4.5f, NULL }, - { TRACK_2, -EZ2_COL_SPACING*3.5f, NULL }, - { TRACK_3, -EZ2_COL_SPACING*2.5f, NULL }, - { TRACK_4, -EZ2_COL_SPACING*1.5f, NULL }, - { TRACK_5, -EZ2_COL_SPACING*0.5f, NULL }, - { TRACK_6, +EZ2_COL_SPACING*0.5f, NULL }, - { TRACK_7, +EZ2_COL_SPACING*1.5f, NULL }, - { TRACK_8, +EZ2_COL_SPACING*2.5f, NULL }, - { TRACK_9, +EZ2_COL_SPACING*3.5f, NULL }, - { TRACK_10, +EZ2_COL_SPACING*4.5f, NULL }, + { TRACK_1, -EZ2_COL_SPACING*4.5f, nullptr }, + { TRACK_2, -EZ2_COL_SPACING*3.5f, nullptr }, + { TRACK_3, -EZ2_COL_SPACING*2.5f, nullptr }, + { TRACK_4, -EZ2_COL_SPACING*1.5f, nullptr }, + { TRACK_5, -EZ2_COL_SPACING*0.5f, nullptr }, + { TRACK_6, +EZ2_COL_SPACING*0.5f, nullptr }, + { TRACK_7, +EZ2_COL_SPACING*1.5f, nullptr }, + { TRACK_8, +EZ2_COL_SPACING*2.5f, nullptr }, + { TRACK_9, +EZ2_COL_SPACING*3.5f, nullptr }, + { TRACK_10, +EZ2_COL_SPACING*4.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -EZ2_COL_SPACING*4.5f, NULL }, - { TRACK_2, -EZ2_COL_SPACING*3.5f, NULL }, - { TRACK_3, -EZ2_COL_SPACING*2.5f, NULL }, - { TRACK_4, -EZ2_COL_SPACING*1.5f, NULL }, - { TRACK_5, -EZ2_COL_SPACING*0.5f, NULL }, - { TRACK_6, +EZ2_COL_SPACING*0.5f, NULL }, - { TRACK_7, +EZ2_COL_SPACING*1.5f, NULL }, - { TRACK_8, +EZ2_COL_SPACING*2.5f, NULL }, - { TRACK_9, +EZ2_COL_SPACING*3.5f, NULL }, - { TRACK_10, +EZ2_COL_SPACING*4.5f, NULL }, + { TRACK_1, -EZ2_COL_SPACING*4.5f, nullptr }, + { TRACK_2, -EZ2_COL_SPACING*3.5f, nullptr }, + { TRACK_3, -EZ2_COL_SPACING*2.5f, nullptr }, + { TRACK_4, -EZ2_COL_SPACING*1.5f, nullptr }, + { TRACK_5, -EZ2_COL_SPACING*0.5f, nullptr }, + { TRACK_6, +EZ2_COL_SPACING*0.5f, nullptr }, + { TRACK_7, +EZ2_COL_SPACING*1.5f, nullptr }, + { TRACK_8, +EZ2_COL_SPACING*2.5f, nullptr }, + { TRACK_9, +EZ2_COL_SPACING*3.5f, nullptr }, + { TRACK_10, +EZ2_COL_SPACING*4.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -1294,7 +1293,7 @@ static const Style *g_apGame_Ez2_Styles[] = &g_Style_Ez2_Single_Versus, &g_Style_Ez2_Real_Versus, &g_Style_Ez2_Double, - NULL + nullptr }; static const AutoMappings g_AutoKeyMappings_Ez2 = AutoMappings ( @@ -1362,18 +1361,18 @@ static const Style g_Style_Para_Single = 5, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -PARA_COL_SPACING*2.0f, NULL }, - { TRACK_2, -PARA_COL_SPACING*1.0f, NULL }, - { TRACK_3, +PARA_COL_SPACING*0.0f, NULL }, - { TRACK_4, +PARA_COL_SPACING*1.0f, NULL }, - { TRACK_5, +PARA_COL_SPACING*2.0f, NULL }, + { TRACK_1, -PARA_COL_SPACING*2.0f, nullptr }, + { TRACK_2, -PARA_COL_SPACING*1.0f, nullptr }, + { TRACK_3, +PARA_COL_SPACING*0.0f, nullptr }, + { TRACK_4, +PARA_COL_SPACING*1.0f, nullptr }, + { TRACK_5, +PARA_COL_SPACING*2.0f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -PARA_COL_SPACING*2.0f, NULL }, - { TRACK_2, -PARA_COL_SPACING*1.0f, NULL }, - { TRACK_3, +PARA_COL_SPACING*0.0f, NULL }, - { TRACK_4, +PARA_COL_SPACING*1.0f, NULL }, - { TRACK_5, +PARA_COL_SPACING*2.0f, NULL }, + { TRACK_1, -PARA_COL_SPACING*2.0f, nullptr }, + { TRACK_2, -PARA_COL_SPACING*1.0f, nullptr }, + { TRACK_3, +PARA_COL_SPACING*0.0f, nullptr }, + { TRACK_4, +PARA_COL_SPACING*1.0f, nullptr }, + { TRACK_5, +PARA_COL_SPACING*2.0f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -1399,18 +1398,18 @@ static const Style g_Style_Para_Versus = 5, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -PARA_COL_SPACING*2.0f, NULL }, - { TRACK_2, -PARA_COL_SPACING*1.0f, NULL }, - { TRACK_3, +PARA_COL_SPACING*0.0f, NULL }, - { TRACK_4, +PARA_COL_SPACING*1.0f, NULL }, - { TRACK_5, +PARA_COL_SPACING*2.0f, NULL }, + { TRACK_1, -PARA_COL_SPACING*2.0f, nullptr }, + { TRACK_2, -PARA_COL_SPACING*1.0f, nullptr }, + { TRACK_3, +PARA_COL_SPACING*0.0f, nullptr }, + { TRACK_4, +PARA_COL_SPACING*1.0f, nullptr }, + { TRACK_5, +PARA_COL_SPACING*2.0f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -PARA_COL_SPACING*2.0f, NULL }, - { TRACK_2, -PARA_COL_SPACING*1.0f, NULL }, - { TRACK_3, +PARA_COL_SPACING*0.0f, NULL }, - { TRACK_4, +PARA_COL_SPACING*1.0f, NULL }, - { TRACK_5, +PARA_COL_SPACING*2.0f, NULL }, + { TRACK_1, -PARA_COL_SPACING*2.0f, nullptr }, + { TRACK_2, -PARA_COL_SPACING*1.0f, nullptr }, + { TRACK_3, +PARA_COL_SPACING*0.0f, nullptr }, + { TRACK_4, +PARA_COL_SPACING*1.0f, nullptr }, + { TRACK_5, +PARA_COL_SPACING*2.0f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -1428,7 +1427,7 @@ static const Style *g_apGame_Para_Styles[] = { &g_Style_Para_Single, &g_Style_Para_Versus, - NULL + nullptr }; static const AutoMappings g_AutoKeyMappings_Para = AutoMappings ( @@ -1489,24 +1488,24 @@ static const Style g_Style_DS3DDX_Single = 8, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -DS3DDX_COL_SPACING*3.0f, NULL }, - { TRACK_2, -DS3DDX_COL_SPACING*2.0f, NULL }, - { TRACK_3, -DS3DDX_COL_SPACING*1.0f, NULL }, - { TRACK_4, -DS3DDX_COL_SPACING*0.0f, NULL }, - { TRACK_5, +DS3DDX_COL_SPACING*0.0f, NULL }, - { TRACK_6, +DS3DDX_COL_SPACING*1.0f, NULL }, - { TRACK_7, +DS3DDX_COL_SPACING*2.0f, NULL }, - { TRACK_8, +DS3DDX_COL_SPACING*3.0f , NULL}, + { TRACK_1, -DS3DDX_COL_SPACING*3.0f, nullptr }, + { TRACK_2, -DS3DDX_COL_SPACING*2.0f, nullptr }, + { TRACK_3, -DS3DDX_COL_SPACING*1.0f, nullptr }, + { TRACK_4, -DS3DDX_COL_SPACING*0.0f, nullptr }, + { TRACK_5, +DS3DDX_COL_SPACING*0.0f, nullptr }, + { TRACK_6, +DS3DDX_COL_SPACING*1.0f, nullptr }, + { TRACK_7, +DS3DDX_COL_SPACING*2.0f, nullptr }, + { TRACK_8, +DS3DDX_COL_SPACING*3.0f , nullptr}, }, { // PLAYER_2 - { TRACK_1, -DS3DDX_COL_SPACING*3.0f, NULL }, - { TRACK_2, -DS3DDX_COL_SPACING*2.0f, NULL }, - { TRACK_3, -DS3DDX_COL_SPACING*1.0f, NULL }, - { TRACK_4, -DS3DDX_COL_SPACING*0.0f, NULL }, - { TRACK_5, +DS3DDX_COL_SPACING*0.0f, NULL }, - { TRACK_6, +DS3DDX_COL_SPACING*1.0f, NULL }, - { TRACK_7, +DS3DDX_COL_SPACING*2.0f, NULL }, - { TRACK_8, +DS3DDX_COL_SPACING*3.0f, NULL }, + { TRACK_1, -DS3DDX_COL_SPACING*3.0f, nullptr }, + { TRACK_2, -DS3DDX_COL_SPACING*2.0f, nullptr }, + { TRACK_3, -DS3DDX_COL_SPACING*1.0f, nullptr }, + { TRACK_4, -DS3DDX_COL_SPACING*0.0f, nullptr }, + { TRACK_5, +DS3DDX_COL_SPACING*0.0f, nullptr }, + { TRACK_6, +DS3DDX_COL_SPACING*1.0f, nullptr }, + { TRACK_7, +DS3DDX_COL_SPACING*2.0f, nullptr }, + { TRACK_8, +DS3DDX_COL_SPACING*3.0f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -1523,7 +1522,7 @@ static const Style g_Style_DS3DDX_Single = static const Style *g_apGame_DS3DDX_Styles[] = { &g_Style_DS3DDX_Single, - NULL + nullptr }; static const AutoMappings g_AutoKeyMappings_DS3DDX = AutoMappings ( @@ -1593,19 +1592,19 @@ static const Style g_Style_Beat_Single5 = 6, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -BEAT_COL_SPACING*2.5f, NULL }, - { TRACK_2, -BEAT_COL_SPACING*1.5f, NULL }, - { TRACK_3, -BEAT_COL_SPACING*0.5f, NULL }, - { TRACK_4, +BEAT_COL_SPACING*0.5f, NULL }, - { TRACK_5, +BEAT_COL_SPACING*1.5f, NULL }, + { TRACK_1, -BEAT_COL_SPACING*2.5f, nullptr }, + { TRACK_2, -BEAT_COL_SPACING*1.5f, nullptr }, + { TRACK_3, -BEAT_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +BEAT_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +BEAT_COL_SPACING*1.5f, nullptr }, { TRACK_6, +BEAT_COL_SPACING*3.0f, "scratch" }, }, { // PLAYER_2 - { TRACK_1, -BEAT_COL_SPACING*2.5f, NULL }, - { TRACK_2, -BEAT_COL_SPACING*1.5f, NULL }, - { TRACK_3, -BEAT_COL_SPACING*0.5f, NULL }, - { TRACK_4, +BEAT_COL_SPACING*0.5f, NULL }, - { TRACK_5, +BEAT_COL_SPACING*1.5f, NULL }, + { TRACK_1, -BEAT_COL_SPACING*2.5f, nullptr }, + { TRACK_2, -BEAT_COL_SPACING*1.5f, nullptr }, + { TRACK_3, -BEAT_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +BEAT_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +BEAT_COL_SPACING*1.5f, nullptr }, { TRACK_6, +BEAT_COL_SPACING*3.0f, "scratch" }, }, }, @@ -1632,19 +1631,19 @@ static const Style g_Style_Beat_Versus5 = 6, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -BEAT_COL_SPACING*2.5f, NULL }, - { TRACK_2, -BEAT_COL_SPACING*1.5f, NULL }, - { TRACK_3, -BEAT_COL_SPACING*0.5f, NULL }, - { TRACK_4, +BEAT_COL_SPACING*0.5f, NULL }, - { TRACK_5, +BEAT_COL_SPACING*1.5f, NULL }, + { TRACK_1, -BEAT_COL_SPACING*2.5f, nullptr }, + { TRACK_2, -BEAT_COL_SPACING*1.5f, nullptr }, + { TRACK_3, -BEAT_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +BEAT_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +BEAT_COL_SPACING*1.5f, nullptr }, { TRACK_6, +BEAT_COL_SPACING*3.0f, "scratch" }, }, { // PLAYER_2 - { TRACK_1, -BEAT_COL_SPACING*2.5f, NULL }, - { TRACK_2, -BEAT_COL_SPACING*1.5f, NULL }, - { TRACK_3, -BEAT_COL_SPACING*0.5f, NULL }, - { TRACK_4, +BEAT_COL_SPACING*0.5f, NULL }, - { TRACK_5, +BEAT_COL_SPACING*1.5f, NULL }, + { TRACK_1, -BEAT_COL_SPACING*2.5f, nullptr }, + { TRACK_2, -BEAT_COL_SPACING*1.5f, nullptr }, + { TRACK_3, -BEAT_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +BEAT_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +BEAT_COL_SPACING*1.5f, nullptr }, { TRACK_6, +BEAT_COL_SPACING*3.0f, "scratch" }, }, }, @@ -1671,31 +1670,31 @@ static const Style g_Style_Beat_Double5 = 12, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -BEAT_COL_SPACING*6.0f, NULL }, - { TRACK_2, -BEAT_COL_SPACING*5.0f, NULL }, - { TRACK_3, -BEAT_COL_SPACING*4.0f, NULL }, - { TRACK_4, -BEAT_COL_SPACING*3.0f, NULL }, - { TRACK_5, -BEAT_COL_SPACING*2.0f, NULL }, + { TRACK_1, -BEAT_COL_SPACING*6.0f, nullptr }, + { TRACK_2, -BEAT_COL_SPACING*5.0f, nullptr }, + { TRACK_3, -BEAT_COL_SPACING*4.0f, nullptr }, + { TRACK_4, -BEAT_COL_SPACING*3.0f, nullptr }, + { TRACK_5, -BEAT_COL_SPACING*2.0f, nullptr }, { TRACK_6, -BEAT_COL_SPACING*1.5f, "scratch" }, - { TRACK_7, +BEAT_COL_SPACING*0.5f, NULL }, - { TRACK_8, +BEAT_COL_SPACING*1.5f, NULL }, - { TRACK_9, +BEAT_COL_SPACING*2.5f, NULL }, - { TRACK_10, +BEAT_COL_SPACING*3.5f, NULL }, - { TRACK_11, +BEAT_COL_SPACING*4.5f, NULL }, + { TRACK_7, +BEAT_COL_SPACING*0.5f, nullptr }, + { TRACK_8, +BEAT_COL_SPACING*1.5f, nullptr }, + { TRACK_9, +BEAT_COL_SPACING*2.5f, nullptr }, + { TRACK_10, +BEAT_COL_SPACING*3.5f, nullptr }, + { TRACK_11, +BEAT_COL_SPACING*4.5f, nullptr }, { TRACK_12, +BEAT_COL_SPACING*6.0f, "scratch" }, }, { // PLAYER_2 - { TRACK_1, -BEAT_COL_SPACING*6.0f, NULL }, - { TRACK_2, -BEAT_COL_SPACING*5.0f, NULL }, - { TRACK_3, -BEAT_COL_SPACING*4.0f, NULL }, - { TRACK_4, -BEAT_COL_SPACING*3.0f, NULL }, - { TRACK_5, -BEAT_COL_SPACING*2.0f, NULL }, + { TRACK_1, -BEAT_COL_SPACING*6.0f, nullptr }, + { TRACK_2, -BEAT_COL_SPACING*5.0f, nullptr }, + { TRACK_3, -BEAT_COL_SPACING*4.0f, nullptr }, + { TRACK_4, -BEAT_COL_SPACING*3.0f, nullptr }, + { TRACK_5, -BEAT_COL_SPACING*2.0f, nullptr }, { TRACK_6, -BEAT_COL_SPACING*1.5f, "scratch" }, - { TRACK_7, +BEAT_COL_SPACING*0.5f, NULL }, - { TRACK_8, +BEAT_COL_SPACING*1.5f, NULL }, - { TRACK_9, +BEAT_COL_SPACING*2.5f, NULL }, - { TRACK_10, +BEAT_COL_SPACING*3.5f, NULL }, - { TRACK_11, +BEAT_COL_SPACING*4.5f, NULL }, + { TRACK_7, +BEAT_COL_SPACING*0.5f, nullptr }, + { TRACK_8, +BEAT_COL_SPACING*1.5f, nullptr }, + { TRACK_9, +BEAT_COL_SPACING*2.5f, nullptr }, + { TRACK_10, +BEAT_COL_SPACING*3.5f, nullptr }, + { TRACK_11, +BEAT_COL_SPACING*4.5f, nullptr }, { TRACK_12, +BEAT_COL_SPACING*6.0f, "scratch" }, }, }, @@ -1723,23 +1722,23 @@ static const Style g_Style_Beat_Single7 = { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 { TRACK_8, -BEAT_COL_SPACING*3.5f, "scratch" }, - { TRACK_1, -BEAT_COL_SPACING*2.0f, NULL }, - { TRACK_2, -BEAT_COL_SPACING*1.0f, NULL }, - { TRACK_3, -BEAT_COL_SPACING*0.0f, NULL }, - { TRACK_4, +BEAT_COL_SPACING*1.0f, NULL }, - { TRACK_5, +BEAT_COL_SPACING*2.0f, NULL }, - { TRACK_6, +BEAT_COL_SPACING*3.0f, NULL }, - { TRACK_7, +BEAT_COL_SPACING*4.0f, NULL }, + { TRACK_1, -BEAT_COL_SPACING*2.0f, nullptr }, + { TRACK_2, -BEAT_COL_SPACING*1.0f, nullptr }, + { TRACK_3, -BEAT_COL_SPACING*0.0f, nullptr }, + { TRACK_4, +BEAT_COL_SPACING*1.0f, nullptr }, + { TRACK_5, +BEAT_COL_SPACING*2.0f, nullptr }, + { TRACK_6, +BEAT_COL_SPACING*3.0f, nullptr }, + { TRACK_7, +BEAT_COL_SPACING*4.0f, nullptr }, }, { // PLAYER_2 { TRACK_8, +BEAT_COL_SPACING*4.0f, "scratch" }, - { TRACK_1, -BEAT_COL_SPACING*3.5f, NULL }, - { TRACK_2, -BEAT_COL_SPACING*2.5f, NULL }, - { TRACK_3, -BEAT_COL_SPACING*1.5f, NULL }, - { TRACK_4, -BEAT_COL_SPACING*0.5f, NULL }, - { TRACK_5, +BEAT_COL_SPACING*0.5f, NULL }, - { TRACK_6, +BEAT_COL_SPACING*1.5f, NULL }, - { TRACK_7, +BEAT_COL_SPACING*2.5f, NULL }, + { TRACK_1, -BEAT_COL_SPACING*3.5f, nullptr }, + { TRACK_2, -BEAT_COL_SPACING*2.5f, nullptr }, + { TRACK_3, -BEAT_COL_SPACING*1.5f, nullptr }, + { TRACK_4, -BEAT_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +BEAT_COL_SPACING*0.5f, nullptr }, + { TRACK_6, +BEAT_COL_SPACING*1.5f, nullptr }, + { TRACK_7, +BEAT_COL_SPACING*2.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -1766,23 +1765,23 @@ static const Style g_Style_Beat_Versus7 = { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 { TRACK_8, -BEAT_COL_SPACING*3.5f, "scratch" }, - { TRACK_1, -BEAT_COL_SPACING*2.0f, NULL }, - { TRACK_2, -BEAT_COL_SPACING*1.0f, NULL }, - { TRACK_3, -BEAT_COL_SPACING*0.0f, NULL }, - { TRACK_4, +BEAT_COL_SPACING*1.0f, NULL }, - { TRACK_5, +BEAT_COL_SPACING*2.0f, NULL }, - { TRACK_6, +BEAT_COL_SPACING*3.0f, NULL }, - { TRACK_7, +BEAT_COL_SPACING*4.0f, NULL }, + { TRACK_1, -BEAT_COL_SPACING*2.0f, nullptr }, + { TRACK_2, -BEAT_COL_SPACING*1.0f, nullptr }, + { TRACK_3, -BEAT_COL_SPACING*0.0f, nullptr }, + { TRACK_4, +BEAT_COL_SPACING*1.0f, nullptr }, + { TRACK_5, +BEAT_COL_SPACING*2.0f, nullptr }, + { TRACK_6, +BEAT_COL_SPACING*3.0f, nullptr }, + { TRACK_7, +BEAT_COL_SPACING*4.0f, nullptr }, }, { // PLAYER_2 { TRACK_8, +BEAT_COL_SPACING*4.0f, "scratch" }, - { TRACK_1, -BEAT_COL_SPACING*3.5f, NULL }, - { TRACK_2, -BEAT_COL_SPACING*2.5f, NULL }, - { TRACK_3, -BEAT_COL_SPACING*1.5f, NULL }, - { TRACK_4, -BEAT_COL_SPACING*0.5f, NULL }, - { TRACK_5, +BEAT_COL_SPACING*0.5f, NULL }, - { TRACK_6, +BEAT_COL_SPACING*1.5f, NULL }, - { TRACK_7, +BEAT_COL_SPACING*2.5f, NULL }, + { TRACK_1, -BEAT_COL_SPACING*3.5f, nullptr }, + { TRACK_2, -BEAT_COL_SPACING*2.5f, nullptr }, + { TRACK_3, -BEAT_COL_SPACING*1.5f, nullptr }, + { TRACK_4, -BEAT_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +BEAT_COL_SPACING*0.5f, nullptr }, + { TRACK_6, +BEAT_COL_SPACING*1.5f, nullptr }, + { TRACK_7, +BEAT_COL_SPACING*2.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -1810,38 +1809,38 @@ static const Style g_Style_Beat_Double7 = { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 { TRACK_8, -BEAT_COL_SPACING*8.0f, "scratch" }, - { TRACK_1, -BEAT_COL_SPACING*6.5f, NULL }, - { TRACK_2, -BEAT_COL_SPACING*5.5f, NULL }, - { TRACK_3, -BEAT_COL_SPACING*4.5f, NULL }, - { TRACK_4, -BEAT_COL_SPACING*3.5f, NULL }, - { TRACK_5, -BEAT_COL_SPACING*2.5f, NULL }, - { TRACK_6, -BEAT_COL_SPACING*1.5f, NULL }, - { TRACK_7, -BEAT_COL_SPACING*0.5f, NULL }, - { TRACK_9, +BEAT_COL_SPACING*0.5f, NULL }, - { TRACK_10, +BEAT_COL_SPACING*1.5f, NULL }, - { TRACK_11, +BEAT_COL_SPACING*2.5f, NULL }, - { TRACK_12, +BEAT_COL_SPACING*3.5f, NULL }, - { TRACK_13, +BEAT_COL_SPACING*4.5f, NULL }, - { TRACK_14, +BEAT_COL_SPACING*5.5f, NULL }, - { TRACK_15, +BEAT_COL_SPACING*6.5f, NULL }, + { TRACK_1, -BEAT_COL_SPACING*6.5f, nullptr }, + { TRACK_2, -BEAT_COL_SPACING*5.5f, nullptr }, + { TRACK_3, -BEAT_COL_SPACING*4.5f, nullptr }, + { TRACK_4, -BEAT_COL_SPACING*3.5f, nullptr }, + { TRACK_5, -BEAT_COL_SPACING*2.5f, nullptr }, + { TRACK_6, -BEAT_COL_SPACING*1.5f, nullptr }, + { TRACK_7, -BEAT_COL_SPACING*0.5f, nullptr }, + { TRACK_9, +BEAT_COL_SPACING*0.5f, nullptr }, + { TRACK_10, +BEAT_COL_SPACING*1.5f, nullptr }, + { TRACK_11, +BEAT_COL_SPACING*2.5f, nullptr }, + { TRACK_12, +BEAT_COL_SPACING*3.5f, nullptr }, + { TRACK_13, +BEAT_COL_SPACING*4.5f, nullptr }, + { TRACK_14, +BEAT_COL_SPACING*5.5f, nullptr }, + { TRACK_15, +BEAT_COL_SPACING*6.5f, nullptr }, { TRACK_16, +BEAT_COL_SPACING*8.0f, "scratch" }, }, { // PLAYER_2 { TRACK_8, -BEAT_COL_SPACING*8.0f, "scratch" }, - { TRACK_1, -BEAT_COL_SPACING*6.5f, NULL }, - { TRACK_2, -BEAT_COL_SPACING*5.5f, NULL }, - { TRACK_3, -BEAT_COL_SPACING*4.5f, NULL }, - { TRACK_4, -BEAT_COL_SPACING*3.5f, NULL }, - { TRACK_5, -BEAT_COL_SPACING*2.5f, NULL }, - { TRACK_6, -BEAT_COL_SPACING*1.5f, NULL }, - { TRACK_7, -BEAT_COL_SPACING*0.5f, NULL }, - { TRACK_9, +BEAT_COL_SPACING*0.5f, NULL }, - { TRACK_10, +BEAT_COL_SPACING*1.5f, NULL }, - { TRACK_11, +BEAT_COL_SPACING*2.5f, NULL }, - { TRACK_12, +BEAT_COL_SPACING*3.5f, NULL }, - { TRACK_13, +BEAT_COL_SPACING*4.5f, NULL }, - { TRACK_14, +BEAT_COL_SPACING*5.5f, NULL }, - { TRACK_15, +BEAT_COL_SPACING*6.5f, NULL }, + { TRACK_1, -BEAT_COL_SPACING*6.5f, nullptr }, + { TRACK_2, -BEAT_COL_SPACING*5.5f, nullptr }, + { TRACK_3, -BEAT_COL_SPACING*4.5f, nullptr }, + { TRACK_4, -BEAT_COL_SPACING*3.5f, nullptr }, + { TRACK_5, -BEAT_COL_SPACING*2.5f, nullptr }, + { TRACK_6, -BEAT_COL_SPACING*1.5f, nullptr }, + { TRACK_7, -BEAT_COL_SPACING*0.5f, nullptr }, + { TRACK_9, +BEAT_COL_SPACING*0.5f, nullptr }, + { TRACK_10, +BEAT_COL_SPACING*1.5f, nullptr }, + { TRACK_11, +BEAT_COL_SPACING*2.5f, nullptr }, + { TRACK_12, +BEAT_COL_SPACING*3.5f, nullptr }, + { TRACK_13, +BEAT_COL_SPACING*4.5f, nullptr }, + { TRACK_14, +BEAT_COL_SPACING*5.5f, nullptr }, + { TRACK_15, +BEAT_COL_SPACING*6.5f, nullptr }, { TRACK_16, +BEAT_COL_SPACING*8.0f, "scratch" }, }, }, @@ -1864,7 +1863,7 @@ static const Style *g_apGame_Beat_Styles[] = &g_Style_Beat_Single7, &g_Style_Beat_Versus7, &g_Style_Beat_Double7, - NULL + nullptr }; static const AutoMappings g_AutoKeyMappings_Beat = AutoMappings ( @@ -1936,16 +1935,16 @@ static const Style g_Style_Maniax_Single = 4, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -MANIAX_COL_SPACING*1.5f, NULL }, - { TRACK_2, -MANIAX_COL_SPACING*0.5f, NULL }, - { TRACK_3, +MANIAX_COL_SPACING*0.5f, NULL }, - { TRACK_4, +MANIAX_COL_SPACING*1.5f, NULL }, + { TRACK_1, -MANIAX_COL_SPACING*1.5f, nullptr }, + { TRACK_2, -MANIAX_COL_SPACING*0.5f, nullptr }, + { TRACK_3, +MANIAX_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +MANIAX_COL_SPACING*1.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -MANIAX_COL_SPACING*1.5f, NULL }, - { TRACK_2, -MANIAX_COL_SPACING*0.5f, NULL }, - { TRACK_3, +MANIAX_COL_SPACING*0.5f, NULL }, - { TRACK_4, +MANIAX_COL_SPACING*1.5f, NULL }, + { TRACK_1, -MANIAX_COL_SPACING*1.5f, nullptr }, + { TRACK_2, -MANIAX_COL_SPACING*0.5f, nullptr }, + { TRACK_3, +MANIAX_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +MANIAX_COL_SPACING*1.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -1971,16 +1970,16 @@ static const Style g_Style_Maniax_Versus = 4, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -MANIAX_COL_SPACING*1.5f, NULL }, - { TRACK_2, -MANIAX_COL_SPACING*0.5f, NULL }, - { TRACK_3, +MANIAX_COL_SPACING*0.5f, NULL }, - { TRACK_4, +MANIAX_COL_SPACING*1.5f, NULL }, + { TRACK_1, -MANIAX_COL_SPACING*1.5f, nullptr }, + { TRACK_2, -MANIAX_COL_SPACING*0.5f, nullptr }, + { TRACK_3, +MANIAX_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +MANIAX_COL_SPACING*1.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -MANIAX_COL_SPACING*1.5f, NULL }, - { TRACK_2, -MANIAX_COL_SPACING*0.5f, NULL }, - { TRACK_3, +MANIAX_COL_SPACING*0.5f, NULL }, - { TRACK_4, +MANIAX_COL_SPACING*1.5f, NULL }, + { TRACK_1, -MANIAX_COL_SPACING*1.5f, nullptr }, + { TRACK_2, -MANIAX_COL_SPACING*0.5f, nullptr }, + { TRACK_3, +MANIAX_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +MANIAX_COL_SPACING*1.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -2006,24 +2005,24 @@ static const Style g_Style_Maniax_Double = 8, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -MANIAX_COL_SPACING*3.5f, NULL }, - { TRACK_2, -MANIAX_COL_SPACING*2.5f, NULL }, - { TRACK_3, -MANIAX_COL_SPACING*1.5f, NULL }, - { TRACK_4, -MANIAX_COL_SPACING*0.5f, NULL }, - { TRACK_5, +MANIAX_COL_SPACING*0.5f, NULL }, - { TRACK_6, +MANIAX_COL_SPACING*1.5f, NULL }, - { TRACK_7, +MANIAX_COL_SPACING*2.5f, NULL }, - { TRACK_8, +MANIAX_COL_SPACING*3.5f, NULL }, + { TRACK_1, -MANIAX_COL_SPACING*3.5f, nullptr }, + { TRACK_2, -MANIAX_COL_SPACING*2.5f, nullptr }, + { TRACK_3, -MANIAX_COL_SPACING*1.5f, nullptr }, + { TRACK_4, -MANIAX_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +MANIAX_COL_SPACING*0.5f, nullptr }, + { TRACK_6, +MANIAX_COL_SPACING*1.5f, nullptr }, + { TRACK_7, +MANIAX_COL_SPACING*2.5f, nullptr }, + { TRACK_8, +MANIAX_COL_SPACING*3.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -MANIAX_COL_SPACING*3.5f, NULL }, - { TRACK_2, -MANIAX_COL_SPACING*2.5f, NULL }, - { TRACK_3, -MANIAX_COL_SPACING*1.5f, NULL }, - { TRACK_4, -MANIAX_COL_SPACING*0.5f, NULL }, - { TRACK_5, +MANIAX_COL_SPACING*0.5f, NULL }, - { TRACK_6, +MANIAX_COL_SPACING*1.5f, NULL }, - { TRACK_7, +MANIAX_COL_SPACING*2.5f, NULL }, - { TRACK_8, +MANIAX_COL_SPACING*3.5f, NULL }, + { TRACK_1, -MANIAX_COL_SPACING*3.5f, nullptr }, + { TRACK_2, -MANIAX_COL_SPACING*2.5f, nullptr }, + { TRACK_3, -MANIAX_COL_SPACING*1.5f, nullptr }, + { TRACK_4, -MANIAX_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +MANIAX_COL_SPACING*0.5f, nullptr }, + { TRACK_6, +MANIAX_COL_SPACING*1.5f, nullptr }, + { TRACK_7, +MANIAX_COL_SPACING*2.5f, nullptr }, + { TRACK_8, +MANIAX_COL_SPACING*3.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -2042,7 +2041,7 @@ static const Style *g_apGame_Maniax_Styles[] = &g_Style_Maniax_Single, &g_Style_Maniax_Versus, &g_Style_Maniax_Double, - NULL + nullptr }; static const AutoMappings g_AutoKeyMappings_Maniax = AutoMappings ( @@ -2107,16 +2106,16 @@ static const Style g_Style_Techno_Single4 = 4, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -TECHNO_COL_SPACING*1.5f, NULL }, - { TRACK_2, -TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_3, +TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_4, +TECHNO_COL_SPACING*1.5f, NULL }, + { TRACK_1, -TECHNO_COL_SPACING*1.5f, nullptr }, + { TRACK_2, -TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_3, +TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +TECHNO_COL_SPACING*1.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -TECHNO_COL_SPACING*1.5f, NULL }, - { TRACK_2, -TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_3, +TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_4, +TECHNO_COL_SPACING*1.5f, NULL }, + { TRACK_1, -TECHNO_COL_SPACING*1.5f, nullptr }, + { TRACK_2, -TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_3, +TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +TECHNO_COL_SPACING*1.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -2142,18 +2141,18 @@ static const Style g_Style_Techno_Single5 = 5, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -TECHNO_COL_SPACING*2.0f, NULL }, - { TRACK_2, -TECHNO_COL_SPACING*1.0f, NULL }, - { TRACK_3, +TECHNO_COL_SPACING*0.0f, NULL }, - { TRACK_4, +TECHNO_COL_SPACING*1.0f, NULL }, - { TRACK_5, +TECHNO_COL_SPACING*2.0f, NULL }, + { TRACK_1, -TECHNO_COL_SPACING*2.0f, nullptr }, + { TRACK_2, -TECHNO_COL_SPACING*1.0f, nullptr }, + { TRACK_3, +TECHNO_COL_SPACING*0.0f, nullptr }, + { TRACK_4, +TECHNO_COL_SPACING*1.0f, nullptr }, + { TRACK_5, +TECHNO_COL_SPACING*2.0f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -TECHNO_COL_SPACING*2.0f, NULL }, - { TRACK_2, -TECHNO_COL_SPACING*1.0f, NULL }, - { TRACK_3, +TECHNO_COL_SPACING*0.0f, NULL }, - { TRACK_4, +TECHNO_COL_SPACING*1.0f, NULL }, - { TRACK_5, +TECHNO_COL_SPACING*2.0f, NULL }, + { TRACK_1, -TECHNO_COL_SPACING*2.0f, nullptr }, + { TRACK_2, -TECHNO_COL_SPACING*1.0f, nullptr }, + { TRACK_3, +TECHNO_COL_SPACING*0.0f, nullptr }, + { TRACK_4, +TECHNO_COL_SPACING*1.0f, nullptr }, + { TRACK_5, +TECHNO_COL_SPACING*2.0f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -2181,24 +2180,24 @@ static const Style g_Style_Techno_Single8 = 8, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -TECHNO_COL_SPACING*3.5f, NULL }, - { TRACK_2, -TECHNO_COL_SPACING*2.5f, NULL }, - { TRACK_3, -TECHNO_COL_SPACING*1.5f, NULL }, - { TRACK_4, -TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_5, +TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_6, +TECHNO_COL_SPACING*1.5f, NULL }, - { TRACK_7, +TECHNO_COL_SPACING*2.5f, NULL }, - { TRACK_8, +TECHNO_COL_SPACING*3.5f, NULL }, + { TRACK_1, -TECHNO_COL_SPACING*3.5f, nullptr }, + { TRACK_2, -TECHNO_COL_SPACING*2.5f, nullptr }, + { TRACK_3, -TECHNO_COL_SPACING*1.5f, nullptr }, + { TRACK_4, -TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_6, +TECHNO_COL_SPACING*1.5f, nullptr }, + { TRACK_7, +TECHNO_COL_SPACING*2.5f, nullptr }, + { TRACK_8, +TECHNO_COL_SPACING*3.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -TECHNO_COL_SPACING*3.5f, NULL }, - { TRACK_2, -TECHNO_COL_SPACING*2.5f, NULL }, - { TRACK_3, -TECHNO_COL_SPACING*1.5f, NULL }, - { TRACK_4, -TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_5, +TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_6, +TECHNO_COL_SPACING*1.5f, NULL }, - { TRACK_7, +TECHNO_COL_SPACING*2.5f, NULL }, - { TRACK_8, +TECHNO_COL_SPACING*3.5f, NULL }, + { TRACK_1, -TECHNO_COL_SPACING*3.5f, nullptr }, + { TRACK_2, -TECHNO_COL_SPACING*2.5f, nullptr }, + { TRACK_3, -TECHNO_COL_SPACING*1.5f, nullptr }, + { TRACK_4, -TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_6, +TECHNO_COL_SPACING*1.5f, nullptr }, + { TRACK_7, +TECHNO_COL_SPACING*2.5f, nullptr }, + { TRACK_8, +TECHNO_COL_SPACING*3.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -2224,16 +2223,16 @@ static const Style g_Style_Techno_Versus4 = 4, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -TECHNO_COL_SPACING*1.5f, NULL }, - { TRACK_2, -TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_3, +TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_4, +TECHNO_COL_SPACING*1.5f, NULL }, + { TRACK_1, -TECHNO_COL_SPACING*1.5f, nullptr }, + { TRACK_2, -TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_3, +TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +TECHNO_COL_SPACING*1.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -TECHNO_COL_SPACING*1.5f, NULL }, - { TRACK_2, -TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_3, +TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_4, +TECHNO_COL_SPACING*1.5f, NULL }, + { TRACK_1, -TECHNO_COL_SPACING*1.5f, nullptr }, + { TRACK_2, -TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_3, +TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +TECHNO_COL_SPACING*1.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -2259,18 +2258,18 @@ static const Style g_Style_Techno_Versus5 = 5, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -TECHNO_COL_SPACING*2.0f, NULL }, - { TRACK_2, -TECHNO_COL_SPACING*1.0f, NULL }, - { TRACK_3, +TECHNO_COL_SPACING*0.0f, NULL }, - { TRACK_4, +TECHNO_COL_SPACING*1.0f, NULL }, - { TRACK_5, +TECHNO_COL_SPACING*2.0f, NULL }, + { TRACK_1, -TECHNO_COL_SPACING*2.0f, nullptr }, + { TRACK_2, -TECHNO_COL_SPACING*1.0f, nullptr }, + { TRACK_3, +TECHNO_COL_SPACING*0.0f, nullptr }, + { TRACK_4, +TECHNO_COL_SPACING*1.0f, nullptr }, + { TRACK_5, +TECHNO_COL_SPACING*2.0f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -TECHNO_COL_SPACING*2.0f, NULL }, - { TRACK_2, -TECHNO_COL_SPACING*1.0f, NULL }, - { TRACK_3, +TECHNO_COL_SPACING*0.0f, NULL }, - { TRACK_4, +TECHNO_COL_SPACING*1.0f, NULL }, - { TRACK_5, +TECHNO_COL_SPACING*2.0f, NULL }, + { TRACK_1, -TECHNO_COL_SPACING*2.0f, nullptr }, + { TRACK_2, -TECHNO_COL_SPACING*1.0f, nullptr }, + { TRACK_3, +TECHNO_COL_SPACING*0.0f, nullptr }, + { TRACK_4, +TECHNO_COL_SPACING*1.0f, nullptr }, + { TRACK_5, +TECHNO_COL_SPACING*2.0f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -2298,24 +2297,24 @@ static const Style g_Style_Techno_Versus8 = 8, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -TECHNO_COL_SPACING*3.5f, NULL }, - { TRACK_2, -TECHNO_COL_SPACING*2.5f, NULL }, - { TRACK_3, -TECHNO_COL_SPACING*1.5f, NULL }, - { TRACK_4, -TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_5, +TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_6, +TECHNO_COL_SPACING*1.5f, NULL }, - { TRACK_7, +TECHNO_COL_SPACING*2.5f, NULL }, - { TRACK_8, +TECHNO_COL_SPACING*3.5f, NULL }, + { TRACK_1, -TECHNO_COL_SPACING*3.5f, nullptr }, + { TRACK_2, -TECHNO_COL_SPACING*2.5f, nullptr }, + { TRACK_3, -TECHNO_COL_SPACING*1.5f, nullptr }, + { TRACK_4, -TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_6, +TECHNO_COL_SPACING*1.5f, nullptr }, + { TRACK_7, +TECHNO_COL_SPACING*2.5f, nullptr }, + { TRACK_8, +TECHNO_COL_SPACING*3.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -TECHNO_COL_SPACING*3.5f, NULL }, - { TRACK_2, -TECHNO_COL_SPACING*2.5f, NULL }, - { TRACK_3, -TECHNO_COL_SPACING*1.5f, NULL }, - { TRACK_4, -TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_5, +TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_6, +TECHNO_COL_SPACING*1.5f, NULL }, - { TRACK_7, +TECHNO_COL_SPACING*2.5f, NULL }, - { TRACK_8, +TECHNO_COL_SPACING*3.5f, NULL }, + { TRACK_1, -TECHNO_COL_SPACING*3.5f, nullptr }, + { TRACK_2, -TECHNO_COL_SPACING*2.5f, nullptr }, + { TRACK_3, -TECHNO_COL_SPACING*1.5f, nullptr }, + { TRACK_4, -TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_6, +TECHNO_COL_SPACING*1.5f, nullptr }, + { TRACK_7, +TECHNO_COL_SPACING*2.5f, nullptr }, + { TRACK_8, +TECHNO_COL_SPACING*3.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -2343,24 +2342,24 @@ static const Style g_Style_Techno_Double4 = 8, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -TECHNO_COL_SPACING*3.5f, NULL }, - { TRACK_2, -TECHNO_COL_SPACING*2.5f, NULL }, - { TRACK_3, -TECHNO_COL_SPACING*1.5f, NULL }, - { TRACK_4, -TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_5, +TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_6, +TECHNO_COL_SPACING*1.5f, NULL }, - { TRACK_7, +TECHNO_COL_SPACING*2.5f, NULL }, - { TRACK_8, +TECHNO_COL_SPACING*3.5f, NULL }, + { TRACK_1, -TECHNO_COL_SPACING*3.5f, nullptr }, + { TRACK_2, -TECHNO_COL_SPACING*2.5f, nullptr }, + { TRACK_3, -TECHNO_COL_SPACING*1.5f, nullptr }, + { TRACK_4, -TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_6, +TECHNO_COL_SPACING*1.5f, nullptr }, + { TRACK_7, +TECHNO_COL_SPACING*2.5f, nullptr }, + { TRACK_8, +TECHNO_COL_SPACING*3.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -TECHNO_COL_SPACING*3.5f, NULL }, - { TRACK_2, -TECHNO_COL_SPACING*2.5f, NULL }, - { TRACK_3, -TECHNO_COL_SPACING*1.5f, NULL }, - { TRACK_4, -TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_5, +TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_6, +TECHNO_COL_SPACING*1.5f, NULL }, - { TRACK_7, +TECHNO_COL_SPACING*2.5f, NULL }, - { TRACK_8, +TECHNO_COL_SPACING*3.5f, NULL }, + { TRACK_1, -TECHNO_COL_SPACING*3.5f, nullptr }, + { TRACK_2, -TECHNO_COL_SPACING*2.5f, nullptr }, + { TRACK_3, -TECHNO_COL_SPACING*1.5f, nullptr }, + { TRACK_4, -TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_6, +TECHNO_COL_SPACING*1.5f, nullptr }, + { TRACK_7, +TECHNO_COL_SPACING*2.5f, nullptr }, + { TRACK_8, +TECHNO_COL_SPACING*3.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -2386,28 +2385,28 @@ static const Style g_Style_Techno_Double5 = 10, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -TECHNO_COL_SPACING*4.5f, NULL }, - { TRACK_2, -TECHNO_COL_SPACING*3.5f, NULL }, - { TRACK_3, -TECHNO_COL_SPACING*2.5f, NULL }, - { TRACK_4, -TECHNO_COL_SPACING*1.5f, NULL }, - { TRACK_5, -TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_6, +TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_7, +TECHNO_COL_SPACING*1.5f, NULL }, - { TRACK_8, +TECHNO_COL_SPACING*2.5f, NULL }, - { TRACK_9, +TECHNO_COL_SPACING*3.5f, NULL }, - { TRACK_10, +TECHNO_COL_SPACING*4.5f, NULL }, + { TRACK_1, -TECHNO_COL_SPACING*4.5f, nullptr }, + { TRACK_2, -TECHNO_COL_SPACING*3.5f, nullptr }, + { TRACK_3, -TECHNO_COL_SPACING*2.5f, nullptr }, + { TRACK_4, -TECHNO_COL_SPACING*1.5f, nullptr }, + { TRACK_5, -TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_6, +TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_7, +TECHNO_COL_SPACING*1.5f, nullptr }, + { TRACK_8, +TECHNO_COL_SPACING*2.5f, nullptr }, + { TRACK_9, +TECHNO_COL_SPACING*3.5f, nullptr }, + { TRACK_10, +TECHNO_COL_SPACING*4.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -TECHNO_COL_SPACING*4.5f, NULL }, - { TRACK_2, -TECHNO_COL_SPACING*3.5f, NULL }, - { TRACK_3, -TECHNO_COL_SPACING*2.5f, NULL }, - { TRACK_4, -TECHNO_COL_SPACING*1.5f, NULL }, - { TRACK_5, -TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_6, +TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_7, +TECHNO_COL_SPACING*1.5f, NULL }, - { TRACK_8, +TECHNO_COL_SPACING*2.5f, NULL }, - { TRACK_9, +TECHNO_COL_SPACING*3.5f, NULL }, - { TRACK_10, +TECHNO_COL_SPACING*4.5f, NULL }, + { TRACK_1, -TECHNO_COL_SPACING*4.5f, nullptr }, + { TRACK_2, -TECHNO_COL_SPACING*3.5f, nullptr }, + { TRACK_3, -TECHNO_COL_SPACING*2.5f, nullptr }, + { TRACK_4, -TECHNO_COL_SPACING*1.5f, nullptr }, + { TRACK_5, -TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_6, +TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_7, +TECHNO_COL_SPACING*1.5f, nullptr }, + { TRACK_8, +TECHNO_COL_SPACING*2.5f, nullptr }, + { TRACK_9, +TECHNO_COL_SPACING*3.5f, nullptr }, + { TRACK_10, +TECHNO_COL_SPACING*4.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -2445,40 +2444,40 @@ static const Style g_Style_Techno_Double8 = 16, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -TECHNO_COL_SPACING*7.5f, NULL }, - { TRACK_2, -TECHNO_COL_SPACING*6.5f, NULL }, - { TRACK_3, -TECHNO_COL_SPACING*5.5f, NULL }, - { TRACK_4, -TECHNO_COL_SPACING*4.5f, NULL }, - { TRACK_5, -TECHNO_COL_SPACING*3.5f, NULL }, - { TRACK_6, -TECHNO_COL_SPACING*2.5f, NULL }, - { TRACK_7, -TECHNO_COL_SPACING*1.5f, NULL }, - { TRACK_8, -TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_9, +TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_10, +TECHNO_COL_SPACING*1.5f, NULL }, - { TRACK_11, +TECHNO_COL_SPACING*2.5f, NULL }, - { TRACK_12, +TECHNO_COL_SPACING*3.5f, NULL }, - { TRACK_13, +TECHNO_COL_SPACING*4.5f, NULL }, - { TRACK_14, +TECHNO_COL_SPACING*5.5f, NULL }, - { TRACK_15, +TECHNO_COL_SPACING*6.5f, NULL }, - { TRACK_16, +TECHNO_COL_SPACING*7.5f, NULL }, + { TRACK_1, -TECHNO_COL_SPACING*7.5f, nullptr }, + { TRACK_2, -TECHNO_COL_SPACING*6.5f, nullptr }, + { TRACK_3, -TECHNO_COL_SPACING*5.5f, nullptr }, + { TRACK_4, -TECHNO_COL_SPACING*4.5f, nullptr }, + { TRACK_5, -TECHNO_COL_SPACING*3.5f, nullptr }, + { TRACK_6, -TECHNO_COL_SPACING*2.5f, nullptr }, + { TRACK_7, -TECHNO_COL_SPACING*1.5f, nullptr }, + { TRACK_8, -TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_9, +TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_10, +TECHNO_COL_SPACING*1.5f, nullptr }, + { TRACK_11, +TECHNO_COL_SPACING*2.5f, nullptr }, + { TRACK_12, +TECHNO_COL_SPACING*3.5f, nullptr }, + { TRACK_13, +TECHNO_COL_SPACING*4.5f, nullptr }, + { TRACK_14, +TECHNO_COL_SPACING*5.5f, nullptr }, + { TRACK_15, +TECHNO_COL_SPACING*6.5f, nullptr }, + { TRACK_16, +TECHNO_COL_SPACING*7.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -TECHNO_COL_SPACING*7.5f, NULL }, - { TRACK_2, -TECHNO_COL_SPACING*6.5f, NULL }, - { TRACK_3, -TECHNO_COL_SPACING*5.5f, NULL }, - { TRACK_4, -TECHNO_COL_SPACING*4.5f, NULL }, - { TRACK_5, -TECHNO_COL_SPACING*3.5f, NULL }, - { TRACK_6, -TECHNO_COL_SPACING*2.5f, NULL }, - { TRACK_7, -TECHNO_COL_SPACING*1.5f, NULL }, - { TRACK_8, -TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_9, +TECHNO_COL_SPACING*0.5f, NULL }, - { TRACK_10, +TECHNO_COL_SPACING*1.5f, NULL }, - { TRACK_11, +TECHNO_COL_SPACING*2.5f, NULL }, - { TRACK_12, +TECHNO_COL_SPACING*3.5f, NULL }, - { TRACK_13, +TECHNO_COL_SPACING*4.5f, NULL }, - { TRACK_14, +TECHNO_COL_SPACING*5.5f, NULL }, - { TRACK_15, +TECHNO_COL_SPACING*6.5f, NULL }, - { TRACK_16, +TECHNO_COL_SPACING*7.5f, NULL }, + { TRACK_1, -TECHNO_COL_SPACING*7.5f, nullptr }, + { TRACK_2, -TECHNO_COL_SPACING*6.5f, nullptr }, + { TRACK_3, -TECHNO_COL_SPACING*5.5f, nullptr }, + { TRACK_4, -TECHNO_COL_SPACING*4.5f, nullptr }, + { TRACK_5, -TECHNO_COL_SPACING*3.5f, nullptr }, + { TRACK_6, -TECHNO_COL_SPACING*2.5f, nullptr }, + { TRACK_7, -TECHNO_COL_SPACING*1.5f, nullptr }, + { TRACK_8, -TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_9, +TECHNO_COL_SPACING*0.5f, nullptr }, + { TRACK_10, +TECHNO_COL_SPACING*1.5f, nullptr }, + { TRACK_11, +TECHNO_COL_SPACING*2.5f, nullptr }, + { TRACK_12, +TECHNO_COL_SPACING*3.5f, nullptr }, + { TRACK_13, +TECHNO_COL_SPACING*4.5f, nullptr }, + { TRACK_14, +TECHNO_COL_SPACING*5.5f, nullptr }, + { TRACK_15, +TECHNO_COL_SPACING*6.5f, nullptr }, + { TRACK_16, +TECHNO_COL_SPACING*7.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -2503,7 +2502,7 @@ static const Style *g_apGame_Techno_Styles[] = &g_Style_Techno_Double4, &g_Style_Techno_Double5, &g_Style_Techno_Double8, - NULL + nullptr }; static const AutoMappings g_AutoKeyMappings_Techno = AutoMappings ( @@ -2588,18 +2587,18 @@ static const Style g_Style_Popn_Five = 5, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -POPN5_COL_SPACING*2.0f, NULL }, - { TRACK_2, -POPN5_COL_SPACING*1.0f, NULL }, - { TRACK_3, +POPN5_COL_SPACING*0.0f, NULL }, - { TRACK_4, +POPN5_COL_SPACING*1.0f, NULL }, - { TRACK_5, +POPN5_COL_SPACING*2.0f, NULL }, + { TRACK_1, -POPN5_COL_SPACING*2.0f, nullptr }, + { TRACK_2, -POPN5_COL_SPACING*1.0f, nullptr }, + { TRACK_3, +POPN5_COL_SPACING*0.0f, nullptr }, + { TRACK_4, +POPN5_COL_SPACING*1.0f, nullptr }, + { TRACK_5, +POPN5_COL_SPACING*2.0f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -POPN5_COL_SPACING*2.0f, NULL }, - { TRACK_2, -POPN5_COL_SPACING*1.0f, NULL }, - { TRACK_3, +POPN5_COL_SPACING*0.0f, NULL }, - { TRACK_4, +POPN5_COL_SPACING*1.0f, NULL }, - { TRACK_5, +POPN5_COL_SPACING*2.0f, NULL }, + { TRACK_1, -POPN5_COL_SPACING*2.0f, nullptr }, + { TRACK_2, -POPN5_COL_SPACING*1.0f, nullptr }, + { TRACK_3, +POPN5_COL_SPACING*0.0f, nullptr }, + { TRACK_4, +POPN5_COL_SPACING*1.0f, nullptr }, + { TRACK_5, +POPN5_COL_SPACING*2.0f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -2625,26 +2624,26 @@ static const Style g_Style_Popn_Nine = 9, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -POPN9_COL_SPACING*4.0f, NULL }, - { TRACK_2, -POPN9_COL_SPACING*3.0f, NULL }, - { TRACK_3, -POPN9_COL_SPACING*2.0f, NULL }, - { TRACK_4, -POPN9_COL_SPACING*1.0f, NULL }, - { TRACK_5, +POPN9_COL_SPACING*0.0f, NULL }, - { TRACK_6, +POPN9_COL_SPACING*1.0f, NULL }, - { TRACK_7, +POPN9_COL_SPACING*2.0f, NULL }, - { TRACK_8, +POPN9_COL_SPACING*3.0f, NULL }, - { TRACK_9, +POPN9_COL_SPACING*4.0f, NULL }, + { TRACK_1, -POPN9_COL_SPACING*4.0f, nullptr }, + { TRACK_2, -POPN9_COL_SPACING*3.0f, nullptr }, + { TRACK_3, -POPN9_COL_SPACING*2.0f, nullptr }, + { TRACK_4, -POPN9_COL_SPACING*1.0f, nullptr }, + { TRACK_5, +POPN9_COL_SPACING*0.0f, nullptr }, + { TRACK_6, +POPN9_COL_SPACING*1.0f, nullptr }, + { TRACK_7, +POPN9_COL_SPACING*2.0f, nullptr }, + { TRACK_8, +POPN9_COL_SPACING*3.0f, nullptr }, + { TRACK_9, +POPN9_COL_SPACING*4.0f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -POPN9_COL_SPACING*4.0f, NULL }, - { TRACK_2, -POPN9_COL_SPACING*3.0f, NULL }, - { TRACK_3, -POPN9_COL_SPACING*2.0f, NULL }, - { TRACK_4, -POPN9_COL_SPACING*1.0f, NULL }, - { TRACK_5, +POPN9_COL_SPACING*0.0f, NULL }, - { TRACK_6, +POPN9_COL_SPACING*1.0f, NULL }, - { TRACK_7, +POPN9_COL_SPACING*2.0f, NULL }, - { TRACK_8, +POPN9_COL_SPACING*3.0f, NULL }, - { TRACK_9, +POPN9_COL_SPACING*4.0f, NULL }, + { TRACK_1, -POPN9_COL_SPACING*4.0f, nullptr }, + { TRACK_2, -POPN9_COL_SPACING*3.0f, nullptr }, + { TRACK_3, -POPN9_COL_SPACING*2.0f, nullptr }, + { TRACK_4, -POPN9_COL_SPACING*1.0f, nullptr }, + { TRACK_5, +POPN9_COL_SPACING*0.0f, nullptr }, + { TRACK_6, +POPN9_COL_SPACING*1.0f, nullptr }, + { TRACK_7, +POPN9_COL_SPACING*2.0f, nullptr }, + { TRACK_8, +POPN9_COL_SPACING*3.0f, nullptr }, + { TRACK_9, +POPN9_COL_SPACING*4.0f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -2662,7 +2661,7 @@ static const Style *g_apGame_Popn_Styles[] = { &g_Style_Popn_Five, &g_Style_Popn_Nine, - NULL + nullptr }; static const AutoMappings g_AutoKeyMappings_Popn = AutoMappings ( @@ -2749,24 +2748,24 @@ static const Style g_Style_Lights_Cabinet = NUM_CabinetLight, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -DANCE_COL_SPACING*3.5f, NULL }, - { TRACK_2, -DANCE_COL_SPACING*2.5f, NULL }, - { TRACK_3, -DANCE_COL_SPACING*1.5f, NULL }, - { TRACK_4, -DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_5, +DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_6, +DANCE_COL_SPACING*1.5f, NULL }, - { TRACK_7, +DANCE_COL_SPACING*2.5f, NULL }, - { TRACK_8, +DANCE_COL_SPACING*3.5f, NULL }, + { TRACK_1, -DANCE_COL_SPACING*3.5f, nullptr }, + { TRACK_2, -DANCE_COL_SPACING*2.5f, nullptr }, + { TRACK_3, -DANCE_COL_SPACING*1.5f, nullptr }, + { TRACK_4, -DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_6, +DANCE_COL_SPACING*1.5f, nullptr }, + { TRACK_7, +DANCE_COL_SPACING*2.5f, nullptr }, + { TRACK_8, +DANCE_COL_SPACING*3.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -DANCE_COL_SPACING*3.5f, NULL }, - { TRACK_2, -DANCE_COL_SPACING*2.5f, NULL }, - { TRACK_3, -DANCE_COL_SPACING*1.5f, NULL }, - { TRACK_4, -DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_5, +DANCE_COL_SPACING*0.5f, NULL }, - { TRACK_6, +DANCE_COL_SPACING*1.5f, NULL }, - { TRACK_7, +DANCE_COL_SPACING*2.5f, NULL }, - { TRACK_8, +DANCE_COL_SPACING*3.5f, NULL }, + { TRACK_1, -DANCE_COL_SPACING*3.5f, nullptr }, + { TRACK_2, -DANCE_COL_SPACING*2.5f, nullptr }, + { TRACK_3, -DANCE_COL_SPACING*1.5f, nullptr }, + { TRACK_4, -DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +DANCE_COL_SPACING*0.5f, nullptr }, + { TRACK_6, +DANCE_COL_SPACING*1.5f, nullptr }, + { TRACK_7, +DANCE_COL_SPACING*2.5f, nullptr }, + { TRACK_8, +DANCE_COL_SPACING*3.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -2783,7 +2782,7 @@ static const Style g_Style_Lights_Cabinet = static const Style *g_apGame_Lights_Styles[] = { &g_Style_Lights_Cabinet, - NULL + nullptr }; static const Game g_Game_Lights = @@ -2868,16 +2867,16 @@ static const Style g_Style_Kickbox_Human= 4, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -KICKBOX_COL_SPACING*1.5f, NULL }, - { TRACK_2, -KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_3, +KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_4, +KICKBOX_COL_SPACING*1.5f, NULL }, + { TRACK_1, -KICKBOX_COL_SPACING*1.5f, nullptr }, + { TRACK_2, -KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_3, +KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +KICKBOX_COL_SPACING*1.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -KICKBOX_COL_SPACING*1.5f, NULL }, - { TRACK_2, -KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_3, +KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_4, +KICKBOX_COL_SPACING*1.5f, NULL }, + { TRACK_1, -KICKBOX_COL_SPACING*1.5f, nullptr }, + { TRACK_2, -KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_3, +KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +KICKBOX_COL_SPACING*1.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -2903,16 +2902,16 @@ static const Style g_Style_Kickbox_Human_Versus= 4, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -KICKBOX_COL_SPACING*1.5f, NULL }, - { TRACK_2, -KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_3, +KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_4, +KICKBOX_COL_SPACING*1.5f, NULL }, + { TRACK_1, -KICKBOX_COL_SPACING*1.5f, nullptr }, + { TRACK_2, -KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_3, +KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +KICKBOX_COL_SPACING*1.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -KICKBOX_COL_SPACING*1.5f, NULL }, - { TRACK_2, -KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_3, +KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_4, +KICKBOX_COL_SPACING*1.5f, NULL }, + { TRACK_1, -KICKBOX_COL_SPACING*1.5f, nullptr }, + { TRACK_2, -KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_3, +KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +KICKBOX_COL_SPACING*1.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -2938,16 +2937,16 @@ static const Style g_Style_Kickbox_Quadarm= 4, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -KICKBOX_COL_SPACING*1.5f, NULL }, - { TRACK_2, -KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_3, +KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_4, +KICKBOX_COL_SPACING*1.5f, NULL }, + { TRACK_1, -KICKBOX_COL_SPACING*1.5f, nullptr }, + { TRACK_2, -KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_3, +KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +KICKBOX_COL_SPACING*1.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -KICKBOX_COL_SPACING*1.5f, NULL }, - { TRACK_2, -KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_3, +KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_4, +KICKBOX_COL_SPACING*1.5f, NULL }, + { TRACK_1, -KICKBOX_COL_SPACING*1.5f, nullptr }, + { TRACK_2, -KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_3, +KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +KICKBOX_COL_SPACING*1.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -2973,16 +2972,16 @@ static const Style g_Style_Kickbox_Quadarm_Versus= 4, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -KICKBOX_COL_SPACING*1.5f, NULL }, - { TRACK_2, -KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_3, +KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_4, +KICKBOX_COL_SPACING*1.5f, NULL }, + { TRACK_1, -KICKBOX_COL_SPACING*1.5f, nullptr }, + { TRACK_2, -KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_3, +KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +KICKBOX_COL_SPACING*1.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -KICKBOX_COL_SPACING*1.5f, NULL }, - { TRACK_2, -KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_3, +KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_4, +KICKBOX_COL_SPACING*1.5f, NULL }, + { TRACK_1, -KICKBOX_COL_SPACING*1.5f, nullptr }, + { TRACK_2, -KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_3, +KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +KICKBOX_COL_SPACING*1.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -3008,20 +3007,20 @@ static const Style g_Style_Kickbox_Insect= 6, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -KICKBOX_COL_SPACING*2.5f, NULL }, - { TRACK_2, -KICKBOX_COL_SPACING*1.5f, NULL }, - { TRACK_3, -KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_4, +KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_5, +KICKBOX_COL_SPACING*1.5f, NULL }, - { TRACK_6, +KICKBOX_COL_SPACING*2.5f, NULL }, + { TRACK_1, -KICKBOX_COL_SPACING*2.5f, nullptr }, + { TRACK_2, -KICKBOX_COL_SPACING*1.5f, nullptr }, + { TRACK_3, -KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +KICKBOX_COL_SPACING*1.5f, nullptr }, + { TRACK_6, +KICKBOX_COL_SPACING*2.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -KICKBOX_COL_SPACING*2.5f, NULL }, - { TRACK_2, -KICKBOX_COL_SPACING*1.5f, NULL }, - { TRACK_3, -KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_4, +KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_5, +KICKBOX_COL_SPACING*1.5f, NULL }, - { TRACK_6, +KICKBOX_COL_SPACING*2.5f, NULL }, + { TRACK_1, -KICKBOX_COL_SPACING*2.5f, nullptr }, + { TRACK_2, -KICKBOX_COL_SPACING*1.5f, nullptr }, + { TRACK_3, -KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +KICKBOX_COL_SPACING*1.5f, nullptr }, + { TRACK_6, +KICKBOX_COL_SPACING*2.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -3047,20 +3046,20 @@ static const Style g_Style_Kickbox_Insect_Versus= 6, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -KICKBOX_COL_SPACING*2.5f, NULL }, - { TRACK_2, -KICKBOX_COL_SPACING*1.5f, NULL }, - { TRACK_3, -KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_4, +KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_5, +KICKBOX_COL_SPACING*1.5f, NULL }, - { TRACK_6, +KICKBOX_COL_SPACING*2.5f, NULL }, + { TRACK_1, -KICKBOX_COL_SPACING*2.5f, nullptr }, + { TRACK_2, -KICKBOX_COL_SPACING*1.5f, nullptr }, + { TRACK_3, -KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +KICKBOX_COL_SPACING*1.5f, nullptr }, + { TRACK_6, +KICKBOX_COL_SPACING*2.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -KICKBOX_COL_SPACING*2.5f, NULL }, - { TRACK_2, -KICKBOX_COL_SPACING*1.5f, NULL }, - { TRACK_3, -KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_4, +KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_5, +KICKBOX_COL_SPACING*1.5f, NULL }, - { TRACK_6, +KICKBOX_COL_SPACING*2.5f, NULL }, + { TRACK_1, -KICKBOX_COL_SPACING*2.5f, nullptr }, + { TRACK_2, -KICKBOX_COL_SPACING*1.5f, nullptr }, + { TRACK_3, -KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_4, +KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +KICKBOX_COL_SPACING*1.5f, nullptr }, + { TRACK_6, +KICKBOX_COL_SPACING*2.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -3086,24 +3085,24 @@ static const Style g_Style_Kickbox_Arachnid= 8, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -KICKBOX_COL_SPACING*3.5f, NULL }, - { TRACK_2, -KICKBOX_COL_SPACING*2.5f, NULL }, - { TRACK_3, -KICKBOX_COL_SPACING*1.5f, NULL }, - { TRACK_4, -KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_5, +KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_6, +KICKBOX_COL_SPACING*1.5f, NULL }, - { TRACK_7, +KICKBOX_COL_SPACING*2.5f, NULL }, - { TRACK_8, +KICKBOX_COL_SPACING*3.5f, NULL }, + { TRACK_1, -KICKBOX_COL_SPACING*3.5f, nullptr }, + { TRACK_2, -KICKBOX_COL_SPACING*2.5f, nullptr }, + { TRACK_3, -KICKBOX_COL_SPACING*1.5f, nullptr }, + { TRACK_4, -KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_6, +KICKBOX_COL_SPACING*1.5f, nullptr }, + { TRACK_7, +KICKBOX_COL_SPACING*2.5f, nullptr }, + { TRACK_8, +KICKBOX_COL_SPACING*3.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -KICKBOX_COL_SPACING*3.5f, NULL }, - { TRACK_2, -KICKBOX_COL_SPACING*2.5f, NULL }, - { TRACK_3, -KICKBOX_COL_SPACING*1.5f, NULL }, - { TRACK_4, -KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_5, +KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_6, +KICKBOX_COL_SPACING*1.5f, NULL }, - { TRACK_7, +KICKBOX_COL_SPACING*2.5f, NULL }, - { TRACK_8, +KICKBOX_COL_SPACING*3.5f, NULL }, + { TRACK_1, -KICKBOX_COL_SPACING*3.5f, nullptr }, + { TRACK_2, -KICKBOX_COL_SPACING*2.5f, nullptr }, + { TRACK_3, -KICKBOX_COL_SPACING*1.5f, nullptr }, + { TRACK_4, -KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_6, +KICKBOX_COL_SPACING*1.5f, nullptr }, + { TRACK_7, +KICKBOX_COL_SPACING*2.5f, nullptr }, + { TRACK_8, +KICKBOX_COL_SPACING*3.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -3129,24 +3128,24 @@ static const Style g_Style_Kickbox_Arachnid_Versus= 8, // m_iColsPerPlayer { // m_ColumnInfo[NUM_PLAYERS][MAX_COLS_PER_PLAYER]; { // PLAYER_1 - { TRACK_1, -KICKBOX_COL_SPACING*3.5f, NULL }, - { TRACK_2, -KICKBOX_COL_SPACING*2.5f, NULL }, - { TRACK_3, -KICKBOX_COL_SPACING*1.5f, NULL }, - { TRACK_4, -KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_5, +KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_6, +KICKBOX_COL_SPACING*1.5f, NULL }, - { TRACK_7, +KICKBOX_COL_SPACING*2.5f, NULL }, - { TRACK_8, +KICKBOX_COL_SPACING*3.5f, NULL }, + { TRACK_1, -KICKBOX_COL_SPACING*3.5f, nullptr }, + { TRACK_2, -KICKBOX_COL_SPACING*2.5f, nullptr }, + { TRACK_3, -KICKBOX_COL_SPACING*1.5f, nullptr }, + { TRACK_4, -KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_6, +KICKBOX_COL_SPACING*1.5f, nullptr }, + { TRACK_7, +KICKBOX_COL_SPACING*2.5f, nullptr }, + { TRACK_8, +KICKBOX_COL_SPACING*3.5f, nullptr }, }, { // PLAYER_2 - { TRACK_1, -KICKBOX_COL_SPACING*3.5f, NULL }, - { TRACK_2, -KICKBOX_COL_SPACING*2.5f, NULL }, - { TRACK_3, -KICKBOX_COL_SPACING*1.5f, NULL }, - { TRACK_4, -KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_5, +KICKBOX_COL_SPACING*0.5f, NULL }, - { TRACK_6, +KICKBOX_COL_SPACING*1.5f, NULL }, - { TRACK_7, +KICKBOX_COL_SPACING*2.5f, NULL }, - { TRACK_8, +KICKBOX_COL_SPACING*3.5f, NULL }, + { TRACK_1, -KICKBOX_COL_SPACING*3.5f, nullptr }, + { TRACK_2, -KICKBOX_COL_SPACING*2.5f, nullptr }, + { TRACK_3, -KICKBOX_COL_SPACING*1.5f, nullptr }, + { TRACK_4, -KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_5, +KICKBOX_COL_SPACING*0.5f, nullptr }, + { TRACK_6, +KICKBOX_COL_SPACING*1.5f, nullptr }, + { TRACK_7, +KICKBOX_COL_SPACING*2.5f, nullptr }, + { TRACK_8, +KICKBOX_COL_SPACING*3.5f, nullptr }, }, }, { // m_iInputColumn[NUM_GameController][NUM_GameButton] @@ -3170,7 +3169,7 @@ static const Style* g_apGame_Kickbox_Styles[] = &g_Style_Kickbox_Quadarm_Versus, &g_Style_Kickbox_Insect_Versus, &g_Style_Kickbox_Arachnid_Versus, - NULL + nullptr }; static const Game g_Game_Kickbox = @@ -3289,7 +3288,7 @@ const Style* GameManager::GetEditorStyleForStepsType( StepsType st ) } ASSERT_M(0, ssprintf("The current game cannot use this Style with the editor!")); - return NULL; + return nullptr; } @@ -3375,14 +3374,14 @@ const Style *GameManager::GetFirstCompatibleStyle( const Game *pGame, int iNumPl { vector vpStyles; GetCompatibleStyles( pGame, iNumPlayers, vpStyles ); - FOREACH_CONST( const Style*, vpStyles, s ) + for (Style const *s : vpStyles) { - if( (*s)->m_StepsType == st ) + if( s->m_StepsType == st ) { - return *s; + return s; } } - return NULL; + return nullptr; } @@ -3398,16 +3397,16 @@ void GameManager::GetEnabledGames( vector& aGamesOut ) const Game* GameManager::GetDefaultGame() { - const Game *pDefault = NULL; - if( pDefault == NULL ) + const Game *pDefault = nullptr; + if( pDefault == nullptr ) { - for( size_t i=0; pDefault == NULL && i < ARRAYLEN(g_Games); ++i ) + for( size_t i=0; pDefault == nullptr && i < ARRAYLEN(g_Games); ++i ) { if( IsGameEnabled(g_Games[i]) ) pDefault = g_Games[i]; } - if( pDefault == NULL ) + if( pDefault == nullptr ) RageException::Throw( "No NoteSkins found" ); } @@ -3470,7 +3469,7 @@ const Game* GameManager::StringToGame( RString sGame ) if( !sGame.CompareNoCase(g_Games[i]->m_szName) ) return g_Games[i]; - return NULL; + return nullptr; } @@ -3483,7 +3482,7 @@ const Style* GameManager::GameAndStringToStyle( const Game *game, RString sStyle return style; } - return NULL; + return nullptr; } // lua start diff --git a/src/GameSoundManager.cpp b/src/GameSoundManager.cpp index 0c9a9ef5ee..b9bed2a861 100644 --- a/src/GameSoundManager.cpp +++ b/src/GameSoundManager.cpp @@ -20,7 +20,7 @@ #include "arch/Sound/RageSoundDriver.h" -GameSoundManager *SOUND = NULL; +GameSoundManager *SOUND = nullptr; /* * When playing music, automatically search for an SM file for timing data. If one is @@ -436,7 +436,7 @@ int MusicThread_start( void *p ) GameSoundManager::GameSoundManager() { /* Init RageSoundMan first: */ - ASSERT( SOUNDMAN != NULL ); + ASSERT( SOUNDMAN != nullptr ); g_Mutex = new RageEvent("GameSoundManager"); g_Playing = new MusicPlaying( new RageSound ); @@ -875,7 +875,7 @@ public: { alignBeat = BArg(8); } - p->PlayMusic(musicPath, NULL, loop, musicStart, musicLength, + p->PlayMusic(musicPath, nullptr, loop, musicStart, musicLength, fadeIn, fadeOut, alignBeat, applyRate); COMMON_RETURN_SELF; } diff --git a/src/GameSoundManager.h b/src/GameSoundManager.h index addd49cea1..5f37e52da3 100644 --- a/src/GameSoundManager.h +++ b/src/GameSoundManager.h @@ -21,7 +21,7 @@ public: { PlayMusicParams() { - pTiming = NULL; + pTiming = nullptr; bForceLoop = false; fStartSecond = 0; fLengthSeconds = -1; @@ -44,7 +44,7 @@ public: void PlayMusic( PlayMusicParams params, PlayMusicParams FallbackMusicParams = PlayMusicParams() ); void PlayMusic( RString sFile, - const TimingData *pTiming = NULL, + const TimingData *pTiming = nullptr, bool force_loop = false, float start_sec = 0, float length_sec = -1, diff --git a/src/GameState.cpp b/src/GameState.cpp index 31dac86aa3..febaf7b235 100644 --- a/src/GameState.cpp +++ b/src/GameState.cpp @@ -10,7 +10,6 @@ #include "CommonMetrics.h" #include "Course.h" #include "CryptManager.h" -#include "Foreach.h" #include "Game.h" #include "GameCommand.h" #include "GameConstantsAndTypes.h" @@ -46,7 +45,7 @@ #include #include -GameState* GAMESTATE = NULL; // global and accessible from anywhere in our program +GameState* GAMESTATE = nullptr; // global and accessible from anywhere in our program #define NAME_BLACKLIST_FILE "/Data/NamesBlacklist.txt" @@ -80,7 +79,7 @@ struct GameStateImpl m_Subscriber.SubscribeToMessage( "RefreshCreditText" ); } }; -static GameStateImpl *g_pImpl = NULL; +static GameStateImpl *g_pImpl = nullptr; ThemeMetric ALLOW_LATE_JOIN("GameState","AllowLateJoin"); ThemeMetric USE_NAME_BLACKLIST("GameState","UseNameBlacklist"); @@ -111,7 +110,7 @@ static Preference g_Premium( "Premium", Premium_DoubleFor1Credit ); Preference GameState::m_bAutoJoin( "AutoJoin", false ); GameState::GameState() : - processedTiming( NULL ), + processedTiming(nullptr), m_pCurGame( Message_CurrentGameChanged ), m_pCurStyle( Message_CurrentStyleChanged ), m_PlayMode( Message_PlayModeChanged ), @@ -139,13 +138,13 @@ GameState::GameState() : { g_pImpl = new GameStateImpl; - m_pCurStyle.Set(NULL); + m_pCurStyle.Set(nullptr); FOREACH_PlayerNumber(rpn) { - m_SeparatedStyles[rpn]= NULL; + m_SeparatedStyles[rpn]= nullptr; } - m_pCurGame.Set( NULL ); + m_pCurGame.Set(nullptr); m_iCoins.Set( 0 ); m_timeGameStarted.SetZero(); m_bDemonstrationOrJukebox = false; @@ -247,7 +246,7 @@ void GameState::ApplyCmdline() RString sPlayer; for( int i = 0; GetCommandlineArgument( "player", &sPlayer, i ); ++i ) { - int pn = StringToInt( sPlayer )-1; + int pn = std::stoi( sPlayer )-1; if( !IsAnInt( sPlayer ) || pn < 0 || pn >= NUM_PLAYERS ) RageException::Throw( "Invalid argument \"--player=%s\".", sPlayer.c_str() ); @@ -268,8 +267,8 @@ void GameState::ResetPlayer( PlayerNumber pn ) m_PreferredCourseDifficulty[pn].Set( Difficulty_Medium ); m_iPlayerStageTokens[pn] = 0; m_iAwardedExtraStages[pn] = 0; - m_pCurSteps[pn].Set( NULL ); - m_pCurTrail[pn].Set( NULL ); + m_pCurSteps[pn].Set(nullptr); + m_pCurTrail[pn].Set(nullptr); m_pPlayerState[pn]->Reset(); PROFILEMAN->UnloadProfile( pn ); ResetPlayerOptions(pn); @@ -289,15 +288,14 @@ void GameState::Reset() FOREACH_PlayerNumber( pn ) UnjoinPlayer( pn ); - ASSERT( THEME != NULL ); + ASSERT( THEME != nullptr ); m_timeGameStarted.SetZero(); - SetCurrentStyle( NULL, PLAYER_INVALID ); + SetCurrentStyle( nullptr, PLAYER_INVALID ); FOREACH_MultiPlayer( p ) m_MultiPlayerStatus[p] = MultiPlayerStatus_NotJoined; FOREACH_PlayerNumber( pn ) MEMCARDMAN->UnlockCard( pn ); - //m_iCoins = 0; // don't reset coin count! m_bMultiplayer = false; m_iNumMultiplayerNoteFields = 1; *m_Environment = LuaTable(); @@ -324,9 +322,9 @@ void GameState::Reset() m_AdjustTokensBySongCostForFinalStageCheck= true; m_pCurSong.Set( GetDefaultSong() ); - m_pPreferredSong = NULL; - m_pCurCourse.Set( NULL ); - m_pPreferredCourse = NULL; + m_pPreferredSong = nullptr; + m_pCurCourse.Set(nullptr); + m_pPreferredCourse = nullptr; FOREACH_MultiPlayer( p ) m_pMultiPlayerState[p]->Reset(); @@ -353,7 +351,7 @@ void GameState::Reset() m_pCurCharacters[p] = CHARMAN->GetRandomCharacter(); else m_pCurCharacters[p] = CHARMAN->GetDefaultCharacter(); - ASSERT( m_pCurCharacters[p] != NULL ); + ASSERT( m_pCurCharacters[p] != nullptr ); } m_bTemporaryEventMode = false; @@ -361,7 +359,7 @@ void GameState::Reset() LIGHTSMAN->SetLightsMode( LIGHTSMODE_ATTRACT ); m_stEdit.Set( StepsType_Invalid ); - m_pEditSourceSteps.Set( NULL ); + m_pEditSourceSteps.Set(nullptr); m_stEditSource.Set( StepsType_Invalid ); m_iEditCourseEntryIndex.Set( -1 ); m_sEditLocalProfileID.Set( "" ); @@ -389,7 +387,7 @@ void GameState::JoinPlayer( PlayerNumber pn ) { const Style* new_style= GAMEMAN->GetFirstCompatibleStyle(m_pCurGame, players_joined + 1, cur_style->m_StepsType); - if(new_style == NULL) + if(new_style == nullptr) { return; } @@ -427,7 +425,7 @@ void GameState::JoinPlayer( PlayerNumber pn ) // assume that the second player will be joined immediately afterwards and // don't try to change the style. -Kyz const Style* cur_style= GetCurrentStyle(PLAYER_INVALID); - if(cur_style != NULL && !(pn == PLAYER_1 && + if(cur_style != nullptr && !(pn == PLAYER_1 && (cur_style->m_StyleType == StyleType_TwoPlayersTwoSides || cur_style->m_StyleType == StyleType_TwoPlayersSharedSides))) { @@ -684,7 +682,7 @@ int GameState::GetNumStagesMultiplierForSong( const Song* pSong ) { int iNumStages = 1; - ASSERT( pSong != NULL ); + ASSERT( pSong != nullptr ); if( pSong->IsMarathon() ) iNumStages *= 3; if( pSong->IsLong() ) @@ -883,9 +881,9 @@ void GameState::LoadCurrentSettingsFromProfile( PlayerNumber pn ) // Only set the PreferredStepsType if it wasn't already set by a GameCommand (or by an earlier profile) if( m_PreferredStepsType == StepsType_Invalid && pProfile->m_LastStepsType != StepsType_Invalid ) m_PreferredStepsType.Set( pProfile->m_LastStepsType ); - if( m_pPreferredSong == NULL ) + if( m_pPreferredSong == nullptr ) m_pPreferredSong = pProfile->m_lastSong.ToSong(); - if( m_pPreferredCourse == NULL ) + if( m_pPreferredCourse == nullptr ) m_pPreferredCourse = pProfile->m_lastCourse.ToCourse(); } @@ -918,35 +916,35 @@ bool GameState::CanSafelyEnterGameplay(RString& reason) if(!IsCourseMode()) { Song const* song= m_pCurSong; - if(song == NULL) + if(song == nullptr) { - reason= "Current song is NULL."; + reason= "Current song is null."; return false; } } else { Course const* song= m_pCurCourse; - if(song == NULL) + if(song == nullptr) { - reason= "Current course is NULL."; + reason= "Current course is null."; return false; } } FOREACH_EnabledPlayer(pn) { Style const* style= GetCurrentStyle(pn); - if(style == NULL) + if(style == nullptr) { - reason= ssprintf("Style for player %d is NULL.", pn+1); + reason= ssprintf("Style for player %d is null.", pn+1); return false; } if(!IsCourseMode()) { Steps const* steps= m_pCurSteps[pn]; - if(steps == NULL) + if(steps == nullptr) { - reason= ssprintf("Steps for player %d is NULL.", pn+1); + reason= ssprintf("Steps for player %d is null.", pn+1); return false; } if(steps->m_StepsType != style->m_StepsType) @@ -975,9 +973,9 @@ bool GameState::CanSafelyEnterGameplay(RString& reason) else { Trail const* steps= m_pCurTrail[pn]; - if(steps == NULL) + if(steps == nullptr) { - reason= ssprintf("Steps for player %d is NULL.", pn+1); + reason= ssprintf("Steps for player %d is null.", pn+1); return false; } if(steps->m_StepsType != style->m_StepsType) @@ -998,16 +996,16 @@ void GameState::SetCompatibleStylesForPlayers() bool style_set= false; if(IsCourseMode()) { - if(m_pCurCourse != NULL) + if(m_pCurCourse != nullptr) { const Style* style= m_pCurCourse->GetCourseStyle(m_pCurGame, GetNumSidesJoined()); - if(style != NULL) + if(style != nullptr) { style_set= true; SetCurrentStyle(style, PLAYER_INVALID); } } - else if(GetCurrentStyle(PLAYER_INVALID) == NULL) + else if(GetCurrentStyle(PLAYER_INVALID) == nullptr) { vector vst; GAMEMAN->GetStepsTypesForGame(m_pCurGame, vst); @@ -1021,11 +1019,11 @@ void GameState::SetCompatibleStylesForPlayers() FOREACH_EnabledPlayer(pn) { StepsType st= StepsType_Invalid; - if(m_pCurSteps[pn] != NULL) + if(m_pCurSteps[pn] != nullptr) { st= m_pCurSteps[pn]->m_StepsType; } - else if(m_pCurTrail[pn] != NULL) + else if(m_pCurTrail[pn] != nullptr) { st= m_pCurTrail[pn]->m_StepsType; } @@ -1045,11 +1043,11 @@ void GameState::SetCompatibleStylesForPlayers() void GameState::ForceSharedSidesMatch() { PlayerNumber pn_with_shared= PLAYER_INVALID; - const Style* shared_style= NULL; + const Style* shared_style= nullptr; FOREACH_EnabledPlayer(pn) { const Style* style= GetCurrentStyle(pn); - ASSERT_M(style != NULL, "Style being null should not be possible."); + ASSERT_M(style != nullptr, "Style being null should not be possible."); if(style->m_StyleType == StyleType_TwoPlayersSharedSides) { pn_with_shared= pn; @@ -1061,7 +1059,7 @@ void GameState::ForceSharedSidesMatch() ASSERT_M(GetNumPlayersEnabled() == 2, "2 players must be enabled for shared sides."); PlayerNumber other_pn= OPPOSITE_PLAYER[pn_with_shared]; const Style* other_style= GetCurrentStyle(other_pn); - ASSERT_M(other_style != NULL, "Other player's style being null should not be possible."); + ASSERT_M(other_style != nullptr, "Other player's style being null should not be possible."); if(other_style->m_StyleType != StyleType_TwoPlayersSharedSides) { SetCurrentStyle(shared_style, other_pn); @@ -1082,7 +1080,7 @@ void GameState::ForceOtherPlayersToCompatibleSteps(PlayerNumber main) if(IsCourseMode()) { Trail* steps_to_match= m_pCurTrail[main].Get(); - if(steps_to_match == NULL) { return; } + if(steps_to_match == nullptr) { return; } int num_players= GAMESTATE->GetNumPlayersEnabled(); StyleType styletype_to_match= GAMEMAN->GetFirstCompatibleStyle( GAMESTATE->GetCurrentGame(), num_players, steps_to_match->m_StepsType) @@ -1090,8 +1088,8 @@ void GameState::ForceOtherPlayersToCompatibleSteps(PlayerNumber main) FOREACH_EnabledPlayer(pn) { Trail* pn_steps= m_pCurTrail[pn].Get(); - bool match_failed= pn_steps == NULL; - if(steps_to_match != pn_steps && pn_steps != NULL) + bool match_failed= pn_steps == nullptr; + if(steps_to_match != pn_steps && pn_steps != nullptr) { StyleType pn_styletype= GAMEMAN->GetFirstCompatibleStyle( GAMESTATE->GetCurrentGame(), num_players, pn_steps->m_StepsType) @@ -1111,7 +1109,7 @@ void GameState::ForceOtherPlayersToCompatibleSteps(PlayerNumber main) else { Steps* steps_to_match= m_pCurSteps[main].Get(); - if(steps_to_match == NULL) { return; } + if(steps_to_match == nullptr) { return; } int num_players= GAMESTATE->GetNumPlayersEnabled(); StyleType styletype_to_match= GAMEMAN->GetFirstCompatibleStyle( GAMESTATE->GetCurrentGame(), num_players, steps_to_match->m_StepsType) @@ -1120,8 +1118,8 @@ void GameState::ForceOtherPlayersToCompatibleSteps(PlayerNumber main) FOREACH_EnabledPlayer(pn) { Steps* pn_steps= m_pCurSteps[pn].Get(); - bool match_failed= pn_steps == NULL; - if(steps_to_match != pn_steps && pn_steps != NULL) + bool match_failed= pn_steps == nullptr; + if(steps_to_match != pn_steps && pn_steps != nullptr) { StyleType pn_styletype= GAMEMAN->GetFirstCompatibleStyle( GAMESTATE->GetCurrentGame(), num_players, pn_steps->m_StepsType) @@ -1315,7 +1313,7 @@ bool GameState::IsFinalStageForAnyHumanPlayer() const bool GameState::IsFinalStageForEveryHumanPlayer() const { int song_cost= 1; - if(m_pCurSong != NULL) + if(m_pCurSong != nullptr) { if(m_pCurSong->IsLong()) { @@ -1434,7 +1432,7 @@ static char const* prepare_song_failures[]= { int GameState::prepare_song_for_gameplay() { Song* curr= m_pCurSong; - if(curr == NULL) + if(curr == nullptr) { return 1; } @@ -1504,9 +1502,9 @@ bool GameState::PlayersCanJoin() const { return true; } - // If we check the style and it comes up NULL, either the style has not been + // If we check the style and it comes up nullptr, either the style has not been // chosen, or we're on ScreenSelectMusic with AutoSetStyle. - // If the style does not come up NULL, we might be on a screen in a custom + // If the style does not come up nullptr, we might be on a screen in a custom // theme that wants to allow joining after the style is set anyway. // Either way, we can't use the existence of a style to decide. // -Kyz @@ -1529,7 +1527,7 @@ bool GameState::PlayersCanJoin() const { const Style* compat_style= GAMEMAN->GetFirstCompatibleStyle( m_pCurGame, 2, style->m_StepsType); - if(compat_style == NULL) + if(compat_style == nullptr) { return false; } @@ -1551,13 +1549,13 @@ int GameState::GetNumSidesJoined() const const Game* GameState::GetCurrentGame() const { - ASSERT( m_pCurGame != NULL ); // the game must be set before calling this + ASSERT( m_pCurGame != nullptr ); // the game must be set before calling this return m_pCurGame; } const Style* GameState::GetCurrentStyle(PlayerNumber pn) const { - if(GetCurrentGame() == NULL) { return NULL; } + if(GetCurrentGame() == nullptr) { return nullptr; } if(!GetCurrentGame()->m_PlayersHaveSeparateStyles) { return m_pCurStyle; @@ -1566,7 +1564,7 @@ const Style* GameState::GetCurrentStyle(PlayerNumber pn) const { if(pn >= NUM_PLAYERS) { - return m_SeparatedStyles[PLAYER_1] == NULL ? m_SeparatedStyles[PLAYER_2] + return m_SeparatedStyles[PLAYER_1] == nullptr ? m_SeparatedStyles[PLAYER_2] : m_SeparatedStyles[PLAYER_1]; } return m_SeparatedStyles[pn]; @@ -1677,7 +1675,7 @@ bool GameState::IsHumanPlayer( PlayerNumber pn ) const if(GetCurrentGame()->m_PlayersHaveSeparateStyles) { - if( GetCurrentStyle(pn) == NULL ) // no style chosen + if( GetCurrentStyle(pn) == nullptr ) // no style chosen { return m_bSideIsJoined[pn]; } @@ -1697,7 +1695,7 @@ bool GameState::IsHumanPlayer( PlayerNumber pn ) const } } } - if( GetCurrentStyle(pn) == NULL ) // no style chosen + if( GetCurrentStyle(pn) == nullptr ) // no style chosen { return m_bSideIsJoined[pn]; // only allow input from sides that have already joined } @@ -1942,12 +1940,12 @@ void GameState::GetAllUsedNoteSkins( vector &out ) const if( IsCourseMode() ) { const Trail *pTrail = m_pCurTrail[pn]; - ASSERT( pTrail != NULL ); + ASSERT( pTrail != nullptr ); - FOREACH_CONST( TrailEntry, pTrail->m_vEntries, e ) + for (TrailEntry const &e : pTrail->m_vEntries) { PlayerOptions po; - po.FromString( e->Modifiers ); + po.FromString( e.Modifiers ); if( !po.m_sNoteSkin.empty() ) out.push_back( po.m_sNoteSkin ); } @@ -2074,11 +2072,11 @@ void GameState::GetRankingFeats( PlayerNumber pn, vector &asFeatsOu SongAndSteps sas; ASSERT( !STATSMAN->m_vPlayedStageStats[i].m_vpPlayedSongs.empty() ); sas.pSong = STATSMAN->m_vPlayedStageStats[i].m_vpPlayedSongs[0]; - ASSERT( sas.pSong != NULL ); + ASSERT( sas.pSong != nullptr ); if( STATSMAN->m_vPlayedStageStats[i].m_player[pn].m_vpPossibleSteps.empty() ) continue; sas.pSteps = STATSMAN->m_vPlayedStageStats[i].m_player[pn].m_vpPossibleSteps[0]; - ASSERT( sas.pSteps != NULL ); + ASSERT( sas.pSteps != nullptr ); vSongAndSteps.push_back( sas ); } CHECKPOINT_M( ssprintf("All songs/steps from %s gathered", modeStr)); @@ -2215,9 +2213,9 @@ void GameState::GetRankingFeats( PlayerNumber pn, vector &asFeatsOu case PLAY_MODE_ENDLESS: { Course* pCourse = m_pCurCourse; - ASSERT( pCourse != NULL ); + ASSERT( pCourse != nullptr ); Trail *pTrail = m_pCurTrail[pn]; - ASSERT( pTrail != NULL ); + ASSERT( pTrail != nullptr ); CourseDifficulty cd = pTrail->m_CourseDifficulty; // Find Machine Records @@ -2336,23 +2334,23 @@ void GameState::StoreRankingName( PlayerNumber pn, RString sName ) if( !PREFSMAN->m_bAllowMultipleHighScoreWithSameName ) { // erase all but the highest score for each name - FOREACHM( SongID, Profile::HighScoresForASong, pProfile->m_SongHighScores, iter ) - FOREACHM( StepsID, Profile::HighScoresForASteps, iter->second.m_StepsHighScores, iter2 ) - iter2->second.hsl.RemoveAllButOneOfEachName(); + for (auto &songIter : pProfile->m_SongHighScores) + for (auto &stepIter : songIter.second.m_StepsHighScores) + stepIter.second.hsl.RemoveAllButOneOfEachName(); - FOREACHM( CourseID, Profile::HighScoresForACourse, pProfile->m_CourseHighScores, iter ) - FOREACHM( TrailID, Profile::HighScoresForATrail, iter->second.m_TrailHighScores, iter2 ) - iter2->second.hsl.RemoveAllButOneOfEachName(); + for (auto &courseIter : pProfile->m_CourseHighScores) + for (auto &trailIter : courseIter.second.m_TrailHighScores) + trailIter.second.hsl.RemoveAllButOneOfEachName(); } // clamp high score sizes - FOREACHM( SongID, Profile::HighScoresForASong, pProfile->m_SongHighScores, iter ) - FOREACHM( StepsID, Profile::HighScoresForASteps, iter->second.m_StepsHighScores, iter2 ) - iter2->second.hsl.ClampSize( true ); + for (auto &songIter : pProfile->m_SongHighScores) + for (auto &stepIter : songIter.second.m_StepsHighScores) + stepIter.second.hsl.ClampSize( true ); - FOREACHM( CourseID, Profile::HighScoresForACourse, pProfile->m_CourseHighScores, iter ) - FOREACHM( TrailID, Profile::HighScoresForATrail, iter->second.m_TrailHighScores, iter2 ) - iter2->second.hsl.ClampSize( true ); + for (auto &courseIter : pProfile->m_CourseHighScores) + for (auto &trailIter : courseIter.second.m_TrailHighScores) + trailIter.second.hsl.ClampSize( true ); } bool GameState::AllAreInDangerOrWorse() const @@ -2452,15 +2450,15 @@ Difficulty GameState::GetClosestShownDifficulty( PlayerNumber pn ) const Difficulty iClosest = (Difficulty) 0; int iClosestDist = -1; - FOREACH_CONST( Difficulty, v, dc ) + for (Difficulty const &dc : v) { - int iDist = m_PreferredDifficulty[pn] - *dc; + int iDist = m_PreferredDifficulty[pn] - dc; if( iDist < 0 ) continue; if( iClosestDist != -1 && iDist > iClosestDist ) continue; iClosestDist = iDist; - iClosest = *dc; + iClosest = dc; } return iClosest; @@ -2516,7 +2514,7 @@ Difficulty GameState::GetEasiestStepsDifficulty() const Difficulty dc = Difficulty_Invalid; FOREACH_HumanPlayer( p ) { - if( m_pCurSteps[p] == NULL ) + if( m_pCurSteps[p] == nullptr ) { LuaHelpers::ReportScriptErrorFmt( "GetEasiestStepsDifficulty called but p%i hasn't chosen notes", p+1 ); continue; @@ -2531,7 +2529,7 @@ Difficulty GameState::GetHardestStepsDifficulty() const Difficulty dc = Difficulty_Beginner; FOREACH_HumanPlayer( p ) { - if( m_pCurSteps[p] == NULL ) + if( m_pCurSteps[p] == nullptr ) { LuaHelpers::ReportScriptErrorFmt( "GetHardestStepsDifficulty called but p%i hasn't chosen notes", p+1 ); continue; @@ -2608,7 +2606,7 @@ bool GameState::PlayerIsUsingModifier( PlayerNumber pn, const RString &sModifier Profile* GameState::GetEditLocalProfile() { if( m_sEditLocalProfileID.Get().empty() ) - return NULL; + return nullptr; return PROFILEMAN->GetLocalProfile( m_sEditLocalProfileID ); } @@ -2714,7 +2712,7 @@ public: static int GetCurrentSong( T* p, lua_State *L ) { if(p->m_pCurSong) p->m_pCurSong->PushSelf(L); else lua_pushnil(L); return 1; } static int SetCurrentSong( T* p, lua_State *L ) { - if( lua_isnil(L,1) ) { p->m_pCurSong.Set( NULL ); } + if( lua_isnil(L,1) ) { p->m_pCurSong.Set(nullptr); } else { Song *pS = Luna::check( L, 1, true ); p->m_pCurSong.Set( pS ); } COMMON_RETURN_SELF; } @@ -2750,7 +2748,7 @@ public: PlayerNumber pn = Enum::Check(L, 1); if(lua_isnil(L,2)) { - p->m_pCurSteps[pn].Set(NULL); + p->m_pCurSteps[pn].Set(nullptr); } else { @@ -2764,7 +2762,7 @@ public: static int GetCurrentCourse( T* p, lua_State *L ) { if(p->m_pCurCourse) p->m_pCurCourse->PushSelf(L); else lua_pushnil(L); return 1; } static int SetCurrentCourse( T* p, lua_State *L ) { - if( lua_isnil(L,1) ) { p->m_pCurCourse.Set( NULL ); } + if( lua_isnil(L,1) ) { p->m_pCurCourse.Set(nullptr); } else { Course *pC = Luna::check(L,1); p->m_pCurCourse.Set( pC ); } COMMON_RETURN_SELF; } @@ -2781,7 +2779,7 @@ public: PlayerNumber pn = Enum::Check(L, 1); if(lua_isnil(L,2)) { - p->m_pCurTrail[pn].Set(NULL); + p->m_pCurTrail[pn].Set(nullptr); } else { @@ -2795,7 +2793,7 @@ public: static int GetPreferredSong( T* p, lua_State *L ) { if(p->m_pPreferredSong) p->m_pPreferredSong->PushSelf(L); else lua_pushnil(L); return 1; } static int SetPreferredSong( T* p, lua_State *L ) { - if( lua_isnil(L,1) ) { p->m_pPreferredSong = NULL; } + if( lua_isnil(L,1) ) { p->m_pPreferredSong = nullptr; } else { Song *pS = Luna::check(L,1); p->m_pPreferredSong = pS; } COMMON_RETURN_SELF; } @@ -2941,7 +2939,7 @@ public: static int GetCurrentStepsCredits( T* t, lua_State *L ) { const Song* pSong = t->m_pCurSong; - if( pSong == NULL ) + if( pSong == nullptr ) return 0; // use a vector and not a set so that ordering is maintained @@ -2949,7 +2947,7 @@ public: FOREACH_HumanPlayer( p ) { const Steps* pSteps = GAMESTATE->m_pCurSteps[p]; - if( pSteps == NULL ) + if( pSteps == nullptr ) return 0; bool bAlreadyAdded = find( vpStepsToShow.begin(), vpStepsToShow.end(), pSteps ) != vpStepsToShow.end(); if( !bAlreadyAdded ) @@ -3127,9 +3125,9 @@ public: { vector vpStyles; GAMEMAN->GetCompatibleStyles( p->m_pCurGame, 2, vpStyles ); - FOREACH_CONST( const Style*, vpStyles, s ) + for (const Style *s : vpStyles) { - if( (*s)->m_StepsType == style->m_StepsType ) + if( s->m_StepsType == style->m_StepsType ) { return true; } @@ -3147,18 +3145,18 @@ public: const Style *style = p->GetCurrentStyle(pn); if( p->m_pCurSteps[pn] && ( !style || style->m_StepsType != p->m_pCurSteps[pn]->m_StepsType ) ) { - p->m_pCurSteps[pn].Set( NULL ); + p->m_pCurSteps[pn].Set( nullptr ); } if( p->m_pCurTrail[pn] && ( !style || style->m_StepsType != p->m_pCurTrail[pn]->m_StepsType ) ) { - p->m_pCurTrail[pn].Set( NULL ); + p->m_pCurTrail[pn].Set( nullptr ); } } } static int SetCurrentStyle( T* p, lua_State *L ) { - const Style* pStyle = NULL; + const Style* pStyle = nullptr; if( lua_isstring(L,1) ) { RString style = SArg(1); @@ -3217,19 +3215,19 @@ public: // 3. Copy steps to new difficulty to edit: // song, steps, stepstype, difficulty Song* song= Luna::check(L, 1); - Steps* steps= NULL; + Steps* steps= nullptr; if(!lua_isnil(L, 2)) { steps= Luna::check(L, 2); } // Form 1. - if(steps != NULL && lua_gettop(L) == 2) + if(steps != nullptr && lua_gettop(L) == 2) { p->m_pCurSong.Set(song); p->m_pCurSteps[PLAYER_1].Set(steps); p->SetCurrentStyle(GAMEMAN->GetEditorStyleForStepsType( steps->m_StepsType), PLAYER_INVALID); - p->m_pCurCourse.Set(NULL); + p->m_pCurCourse.Set(nullptr); return 0; } StepsType stype= Enum::Check(L, 3); @@ -3237,7 +3235,7 @@ public: Steps* new_steps= song->CreateSteps(); RString edit_name; // Form 2. - if(steps == NULL) + if(steps == nullptr) { new_steps->CreateBlank(stype); new_steps->SetMeter(1); @@ -3256,7 +3254,7 @@ public: p->m_pCurSteps[PLAYER_1].Set(steps); p->SetCurrentStyle(GAMEMAN->GetEditorStyleForStepsType( steps->m_StepsType), PLAYER_INVALID); - p->m_pCurCourse.Set(NULL); + p->m_pCurCourse.Set(nullptr); return 0; } diff --git a/src/GameState.h b/src/GameState.h index 35c230b9bc..d8121a2167 100644 --- a/src/GameState.h +++ b/src/GameState.h @@ -246,13 +246,13 @@ public: // State Info used during gameplay - // NULL on ScreenSelectMusic if the currently selected wheel item isn't a Song. + // nullptr on ScreenSelectMusic if the currently selected wheel item isn't a Song. BroadcastOnChangePtr m_pCurSong; // The last Song that the user manually changed to. Song* m_pPreferredSong; BroadcastOnChangePtr1D m_pCurSteps; - // NULL on ScreenSelectMusic if the currently selected wheel item isn't a Course. + // nullptr on ScreenSelectMusic if the currently selected wheel item isn't a Course. BroadcastOnChangePtr m_pCurCourse; // The last Course that the user manually changed to. Course* m_pPreferredCourse; diff --git a/src/GraphDisplay.cpp b/src/GraphDisplay.cpp index a5b8ee4c73..a1431092b8 100644 --- a/src/GraphDisplay.cpp +++ b/src/GraphDisplay.cpp @@ -8,7 +8,6 @@ #include "RageLog.h" #include "RageMath.h" #include "StageStats.h" -#include "Foreach.h" #include "Song.h" #include "XmlFile.h" @@ -126,7 +125,7 @@ public: ~GraphBody() { TEXTUREMAN->UnloadTexture( m_pTexture ); - m_pTexture = NULL; + m_pTexture = nullptr; } void DrawPrimitives() @@ -150,14 +149,16 @@ public: GraphDisplay::GraphDisplay() { - m_pGraphLine = NULL; - m_pGraphBody = NULL; + m_pGraphLine = nullptr; + m_pGraphBody = nullptr; } GraphDisplay::~GraphDisplay() { - FOREACH( Actor*, m_vpSongBoundaries, p ) - SAFE_DELETE( *p ); + for (Actor *p : m_vpSongBoundaries) + { + SAFE_DELETE( p ); + } m_vpSongBoundaries.clear(); SAFE_DELETE( m_pGraphLine ); SAFE_DELETE( m_pGraphBody ); @@ -176,18 +177,17 @@ void GraphDisplay::Set( const StageStats &ss, const PlayerStageStats &pss ) // Show song boundaries float fSec = 0; - FOREACH_CONST( Song*, ss.m_vpPossibleSongs, song ) - { - if( song == ss.m_vpPossibleSongs.end()-1 ) - continue; - fSec += (*song)->GetStepsSeconds(); + vector const &possibleSongs = ss.m_vpPossibleSongs; + + std::for_each(possibleSongs.begin(), possibleSongs.end() - 1, [&](Song *song) { + fSec += song->GetStepsSeconds(); Actor *p = m_sprSongBoundary->Copy(); m_vpSongBoundaries.push_back( p ); float fX = SCALE( fSec, 0, fTotalStepSeconds, m_quadVertices.left, m_quadVertices.right ); p->SetX( fX ); this->AddChild( p ); - } + }); if( !pss.m_bFailed ) { @@ -288,11 +288,11 @@ public: { StageStats *pStageStats = Luna::check( L, 1 ); PlayerStageStats *pPlayerStageStats = Luna::check( L, 2 ); - if(pStageStats == NULL) + if(pStageStats == nullptr) { luaL_error(L, "The StageStats passed to GraphDisplay:Set are nil."); } - if(pPlayerStageStats == NULL) + if(pPlayerStageStats == nullptr) { luaL_error(L, "The PlayerStageStats passed to GraphDisplay:Set are nil."); } diff --git a/src/GrooveRadar.cpp b/src/GrooveRadar.cpp index 93deafef8a..a90a014b65 100644 --- a/src/GrooveRadar.cpp +++ b/src/GrooveRadar.cpp @@ -58,7 +58,7 @@ void GrooveRadar::LoadFromNode( const XNode* pNode ) void GrooveRadar::SetEmpty( PlayerNumber pn ) { - SetFromSteps( pn, NULL ); + SetFromSteps( pn, nullptr ); } void GrooveRadar::SetFromRadarValues( PlayerNumber pn, const RadarValues &rv ) @@ -66,9 +66,9 @@ void GrooveRadar::SetFromRadarValues( PlayerNumber pn, const RadarValues &rv ) m_GrooveRadarValueMap[pn].SetFromSteps( rv ); } -void GrooveRadar::SetFromSteps( PlayerNumber pn, Steps* pSteps ) // NULL means no Song +void GrooveRadar::SetFromSteps( PlayerNumber pn, Steps* pSteps ) // nullptr means no Song { - if( pSteps == NULL ) + if( pSteps == nullptr ) { m_GrooveRadarValueMap[pn].SetEmpty(); return; diff --git a/src/GrooveRadar.h b/src/GrooveRadar.h index b66e58785a..b0f2af53d9 100644 --- a/src/GrooveRadar.h +++ b/src/GrooveRadar.h @@ -24,7 +24,7 @@ public: /** * @brief Give the Player a GrooveRadar based on some Steps. * @param pn the Player to give a GrooveRadar. - * @param pSteps the Steps to use to make the radar. If NULL, there are no Steps. */ + * @param pSteps the Steps to use to make the radar. If nullptr, there are no Steps. */ void SetFromSteps( PlayerNumber pn, Steps* pSteps ); void SetFromValues( PlayerNumber pn, vector vals ); diff --git a/src/HighScore.cpp b/src/HighScore.cpp index cc9e17c0c6..38ce9420b2 100644 --- a/src/HighScore.cpp +++ b/src/HighScore.cpp @@ -5,7 +5,6 @@ #include "PlayerNumber.h" #include "ThemeManager.h" #include "XmlFile.h" -#include "Foreach.h" #include "RadarValues.h" #include @@ -406,7 +405,7 @@ void HighScoreList::LoadFromNode( const XNode* pHighScoreList ) void HighScoreList::RemoveAllButOneOfEachName() { - FOREACH( HighScore, vHighScores, i ) + for (vector::iterator i = vHighScores.begin(); i != vHighScores.end() - 1; ++i) { for( vector::iterator j = i+1; j != vHighScores.end(); j++ ) { diff --git a/src/ImageCache.cpp b/src/ImageCache.cpp index c5fabddd94..5a27c046be 100644 --- a/src/ImageCache.cpp +++ b/src/ImageCache.cpp @@ -1,7 +1,6 @@ #include "global.h" #include "ImageCache.h" -#include "Foreach.h" #include "RageDisplay.h" #include "RageUtil.h" #include "RageLog.h" @@ -79,7 +78,7 @@ void ImageCache::Demand( RString sImageDir ) const RString sCachePath = GetImageCachePath(sImageDir,sImagePath); RageSurface *pImage = RageSurfaceUtils::LoadSurface( sCachePath ); - if( pImage == NULL ) + if( pImage == nullptr ) { continue; /* doesn't exist */ } @@ -123,7 +122,7 @@ void ImageCache::LoadImage( RString sImageDir, RString sImagePath ) CHECKPOINT_M( ssprintf( "ImageCache::LoadImage: %s", sCachePath.c_str() ) ); RageSurface *pImage = RageSurfaceUtils::LoadSurface( sCachePath ); - if( pImage == NULL ) + if( pImage == nullptr ) { if( tries == 0 ) { @@ -150,9 +149,9 @@ void ImageCache::LoadImage( RString sImageDir, RString sImagePath ) void ImageCache::OutputStats() const { int iTotalSize = 0; - FOREACHM_CONST( RString, RageSurface *, g_ImagePathToImage, it ) + for (auto const &it : g_ImagePathToImage) { - const RageSurface *pImage = it->second; + const RageSurface *pImage = it.second; const int iSize = pImage->pitch * pImage->h; iTotalSize += iSize; } @@ -161,8 +160,10 @@ void ImageCache::OutputStats() const void ImageCache::UnloadAllImages() { - FOREACHM( RString, RageSurface *, g_ImagePathToImage, it ) - delete it->second; + for (auto &it: g_ImagePathToImage) + { + delete it.second; + } g_ImagePathToImage.clear(); } @@ -203,7 +204,7 @@ struct ImageTexture: public RageTexture void Create() { - ASSERT( m_pImage != NULL ); + ASSERT( m_pImage != nullptr ); /* The image is preprocessed; do as little work as possible. */ @@ -239,7 +240,7 @@ struct ImageTexture: public RageTexture ASSERT( DISPLAY->SupportsTextureFormat(pf) ); - ASSERT(m_pImage != NULL); + ASSERT(m_pImage != nullptr); m_uTexHandle = DISPLAY->CreateTexture( pf, m_pImage, false ); CreateFrameRects(); @@ -295,7 +296,7 @@ RageTextureID ImageCache::LoadCachedImage( RString sImageDir, RString sImagePath * when converting; this way, the conversion will end up in the map so we * only have to convert once. */ RageSurface *&pImage = g_ImagePathToImage[sImagePath]; - ASSERT( pImage != NULL ); + ASSERT( pImage != nullptr ); int iSourceWidth = 0, iSourceHeight = 0; ImageData.GetValue( sImagePath, "Width", iSourceWidth ); @@ -373,7 +374,7 @@ void ImageCache::CacheImageInternal( RString sImageDir, RString sImagePath ) { RString sError; RageSurface *pImage = RageSurfaceUtils::LoadFile( sImagePath, sError ); - if( pImage == NULL ) + if( pImage == nullptr ) { LOG->UserLog( "Cache file", sImagePath, "couldn't be loaded: %s", sError.c_str() ); return; diff --git a/src/IniFile.cpp b/src/IniFile.cpp index 409224dd48..50478a3822 100644 --- a/src/IniFile.cpp +++ b/src/IniFile.cpp @@ -9,7 +9,7 @@ http://en.wikipedia.org/wiki/INI_file #include "RageUtil.h" #include "RageLog.h" #include "RageFile.h" -#include "Foreach.h" + IniFile::IniFile(): XNode("IniFile") { @@ -35,7 +35,7 @@ bool IniFile::ReadFile( RageFileBasic &f ) { RString keyname; // keychild is used to cache the node that values are being added to. -Kyz - XNode* keychild= NULL; + XNode* keychild= nullptr; for(;;) { RString line; @@ -82,7 +82,7 @@ bool IniFile::ReadFile( RageFileBasic &f ) // New section. keyname = line.substr(1, line.size()-2); keychild= GetChild(keyname); - if(keychild == NULL) + if(keychild == nullptr) { keychild= AppendChild(keyname); } @@ -90,7 +90,7 @@ bool IniFile::ReadFile( RageFileBasic &f ) } default: keyvalue: - if(keychild == NULL) + if(keychild == nullptr) { break; } // New value. size_t iEqualIndex = line.find("="); @@ -164,7 +164,7 @@ bool IniFile::WriteFile( RageFileBasic &f ) const bool IniFile::DeleteValue(const RString &keyname, const RString &valuename) { XNode* pNode = GetChild( keyname ); - if( pNode == NULL ) + if( pNode == nullptr ) return false; return pNode->RemoveAttr( valuename ); } @@ -173,7 +173,7 @@ bool IniFile::DeleteValue(const RString &keyname, const RString &valuename) bool IniFile::DeleteKey(const RString &keyname) { XNode* pNode = GetChild( keyname ); - if( pNode == NULL ) + if( pNode == nullptr ) return false; return RemoveChild( pNode ); } @@ -181,11 +181,11 @@ bool IniFile::DeleteKey(const RString &keyname) bool IniFile::RenameKey(const RString &from, const RString &to) { // If to already exists, do nothing. - if( GetChild(to) != NULL ) + if( GetChild(to) != nullptr ) return false; XNode* pNode = GetChild( from ); - if( pNode == NULL ) + if( pNode == nullptr ) return false; pNode->SetName( to ); diff --git a/src/IniFile.h b/src/IniFile.h index 010dc3a214..88239db3ce 100644 --- a/src/IniFile.h +++ b/src/IniFile.h @@ -32,7 +32,7 @@ public: bool GetValue( const RString &sKey, const RString &sValueName, T& value ) const { const XNode* pNode = GetChild( sKey ); - if( pNode == NULL ) + if( pNode == nullptr ) return false; return pNode->GetAttrValue( sValueName, value ); } @@ -40,7 +40,7 @@ public: void SetValue( const RString &sKey, const RString &sValueName, const T &value ) { XNode* pNode = GetChild( sKey ); - if( pNode == NULL ) + if( pNode == nullptr ) pNode = AppendChild( sKey ); pNode->AppendAttr( sValueName, value ); } diff --git a/src/InputFilter.cpp b/src/InputFilter.cpp index d26c0dfe4e..28f9193af1 100644 --- a/src/InputFilter.cpp +++ b/src/InputFilter.cpp @@ -6,7 +6,6 @@ #include "RageUtil.h" #include "RageThreads.h" #include "Preference.h" -#include "Foreach.h" #include "GameInput.h" #include "InputMapper.h" // for mouse stuff: -aj @@ -111,7 +110,7 @@ namespace * this won't cause timing problems, because the event timestamp is preserved. */ static Preference g_fInputDebounceTime( "InputDebounceTime", 0 ); -InputFilter* INPUTFILTER = NULL; // global and accessible from anywhere in our program +InputFilter* INPUTFILTER = nullptr; // global and accessible from anywhere in our program static const float TIME_BEFORE_REPEATS = 0.375f; @@ -233,9 +232,9 @@ void InputFilter::ResetDevice( InputDevice device ) RageTimer now; const ButtonStateMap ButtonStates( g_ButtonStates ); - FOREACHM_CONST( DeviceButtonPair, ButtonState, ButtonStates, b ) + for (std::pair const &b : ButtonStates) { - const DeviceButtonPair &db = b->first; + const DeviceButtonPair &db = b.first; if( db.device == device ) ButtonPressed( DeviceInput(device, db.button, 0, now) ); } @@ -326,7 +325,7 @@ void InputFilter::Update( float fDeltaTime ) vector ButtonsToErase; - FOREACHM( DeviceButtonPair, ButtonState, g_ButtonStates, b ) + for( map::iterator b = g_ButtonStates.begin(); b != g_ButtonStates.end(); ++b ) { di.device = b->first.device; di.button = b->first.button; @@ -379,8 +378,8 @@ void InputFilter::Update( float fDeltaTime ) ReportButtonChange( di, IET_REPEAT ); } - FOREACH( ButtonStateMap::iterator, ButtonsToErase, it ) - g_ButtonStates.erase( *it ); + for (ButtonStateMap::iterator &it : ButtonsToErase) + g_ButtonStates.erase( it ); } template @@ -388,7 +387,7 @@ const T *FindItemBinarySearch( IT begin, IT end, const T &i ) { IT it = lower_bound( begin, end, i ); if( it == end || *it != i ) - return NULL; + return nullptr; return &*it; } @@ -396,19 +395,19 @@ const T *FindItemBinarySearch( IT begin, IT end, const T &i ) bool InputFilter::IsBeingPressed( const DeviceInput &di, const DeviceInputList *pButtonState ) const { LockMut(*queuemutex); - if( pButtonState == NULL ) + if( pButtonState == nullptr ) pButtonState = &g_CurrentState; const DeviceInput *pDI = FindItemBinarySearch( pButtonState->begin(), pButtonState->end(), di ); - return pDI != NULL && pDI->bDown; + return pDI != nullptr && pDI->bDown; } float InputFilter::GetSecsHeld( const DeviceInput &di, const DeviceInputList *pButtonState ) const { LockMut(*queuemutex); - if( pButtonState == NULL ) + if( pButtonState == nullptr ) pButtonState = &g_CurrentState; const DeviceInput *pDI = FindItemBinarySearch( pButtonState->begin(), pButtonState->end(), di ); - if( pDI == NULL ) + if( pDI == nullptr ) return 0; return pDI->ts.Ago(); } @@ -416,10 +415,10 @@ float InputFilter::GetSecsHeld( const DeviceInput &di, const DeviceInputList *pB float InputFilter::GetLevel( const DeviceInput &di, const DeviceInputList *pButtonState ) const { LockMut(*queuemutex); - if( pButtonState == NULL ) + if( pButtonState == nullptr ) pButtonState = &g_CurrentState; const DeviceInput *pDI = FindItemBinarySearch( pButtonState->begin(), pButtonState->end(), di ); - if( pDI == NULL ) + if( pDI == nullptr ) return 0.0f; return pDI->level; } diff --git a/src/InputFilter.h b/src/InputFilter.h index 8a8b7b2494..5cacc3bd8a 100644 --- a/src/InputFilter.h +++ b/src/InputFilter.h @@ -64,10 +64,10 @@ public: void ResetKeyRepeat( const DeviceInput &di ); void RepeatStopKey( const DeviceInput &di ); - // If aButtonState is NULL, use the last reported state. - bool IsBeingPressed( const DeviceInput &di, const DeviceInputList *pButtonState = NULL ) const; - float GetSecsHeld( const DeviceInput &di, const DeviceInputList *pButtonState = NULL ) const; - float GetLevel( const DeviceInput &di, const DeviceInputList *pButtonState = NULL ) const; + // If aButtonState is nullptr, use the last reported state. + bool IsBeingPressed( const DeviceInput &di, const DeviceInputList *pButtonState = nullptr ) const; + float GetSecsHeld( const DeviceInput &di, const DeviceInputList *pButtonState = nullptr ) const; + float GetLevel( const DeviceInput &di, const DeviceInputList *pButtonState = nullptr ) const; RString GetButtonComment( const DeviceInput &di ) const; void GetInputEvents( vector &aEventOut ); diff --git a/src/InputMapper.cpp b/src/InputMapper.cpp index 873ccc02fe..0fb1f58fd9 100644 --- a/src/InputMapper.cpp +++ b/src/InputMapper.cpp @@ -9,7 +9,6 @@ #include "RageInput.h" #include "SpecialFiles.h" #include "LocalizedString.h" -#include "Foreach.h" #include "arch/Dialog/Dialog.h" #define AUTOMAPPINGS_DIR "/Data/AutoMappings/" @@ -26,12 +25,12 @@ namespace PlayerNumber g_JoinControllers; }; -InputMapper* INPUTMAPPER = NULL; // global and accessible from anywhere in our program +InputMapper* INPUTMAPPER = nullptr; // global and accessible from anywhere in our program InputMapper::InputMapper() { g_JoinControllers = PLAYER_INVALID; - m_pInputScheme = NULL; + m_pInputScheme = nullptr; } InputMapper::~InputMapper() @@ -79,20 +78,20 @@ void InputMapper::AddDefaultMappingsForCurrentGameIfUnmapped() vector aMaps; aMaps.reserve( 32 ); - FOREACH_CONST( AutoMappingEntry, g_DefaultKeyMappings.m_vMaps, iter ) - aMaps.push_back( *iter ); - FOREACH_CONST( AutoMappingEntry, m_pInputScheme->m_pAutoMappings->m_vMaps, iter ) - aMaps.push_back( *iter ); + for (AutoMappingEntry const &iter : g_DefaultKeyMappings.m_vMaps) + aMaps.push_back( iter ); + for (AutoMappingEntry const &iter : m_pInputScheme->m_pAutoMappings->m_vMaps) + aMaps.push_back( iter ); /* There may be duplicate GAME_BUTTON maps. Process the list backwards, * so game-specific mappings override g_DefaultKeyMappings. */ std::reverse( aMaps.begin(), aMaps.end() ); - FOREACH( AutoMappingEntry, aMaps, m ) + for (AutoMappingEntry const &m : aMaps) { - DeviceButton key = m->m_deviceButton; + DeviceButton key = m.m_deviceButton; DeviceInput DeviceI( DEVICE_KEYBOARD, key ); - GameInput GameI( m->m_bSecondController ? GameController_2 : GameController_1, m->m_gb ); + GameInput GameI( m.m_bSecondController ? GameController_2 : GameController_1, m.m_gb ); if( !IsMapped(DeviceI) ) // if this key isn't already being used by another user-made mapping { if( !GameI.IsValid() ) @@ -545,10 +544,10 @@ void InputMapper::Unmap( InputDevice id ) void InputMapper::ApplyMapping( const vector &vMmaps, GameController gc, InputDevice id ) { map MappedButtons; - FOREACH_CONST( AutoMappingEntry, vMmaps, iter ) + for (AutoMappingEntry const &iter : vMmaps) { GameController map_gc = gc; - if( iter->m_bSecondController ) + if( iter.m_bSecondController ) { map_gc = (GameController)(map_gc+1); @@ -559,8 +558,8 @@ void InputMapper::ApplyMapping( const vector &vMmaps, GameCont continue; } - DeviceInput di( id, iter->m_deviceButton ); - GameInput gi( map_gc, iter->m_gb ); + DeviceInput di( id, iter.m_deviceButton ); + GameInput gi( map_gc, iter.m_gb ); int iSlot = MappedButtons[gi]; ++MappedButtons[gi]; SetInputMap( di, gi, iSlot );//maps[k].iSlotIndex ); @@ -578,10 +577,10 @@ void InputMapper::AutoMapJoysticksForCurrentGame() // file automaps - Add these first so that they can match before the hard-coded mappings vector vs; GetDirListing( AUTOMAPPINGS_DIR "*.ini", vs, false, true ); - FOREACH_CONST( RString, vs, sFilePath ) + for (RString const &sFilePath : vs) { InputMappings km; - km.ReadMappings( m_pInputScheme, *sFilePath, true ); + km.ReadMappings( m_pInputScheme, sFilePath, true ); AutoMappings mapping( m_pInputScheme->m_szName, km.m_sDeviceRegex, km.m_sDescription ); @@ -616,13 +615,13 @@ void InputMapper::AutoMapJoysticksForCurrentGame() // apply auto mappings int iNumJoysticksMapped = 0; - FOREACH_CONST( InputDeviceInfo, vDevices, device ) + for (InputDeviceInfo const &device : vDevices) { - InputDevice id = device->id; - const RString &sDescription = device->sDesc; - FOREACH_CONST( AutoMappings, vAutoMappings, mapping ) + InputDevice id = device.id; + const RString &sDescription = device.sDesc; + for (AutoMappings const &mapping : vAutoMappings) { - Regex regex( mapping->m_sDriverRegex ); + Regex regex( mapping.m_sDriverRegex ); if( !regex.Compare(sDescription) ) continue; // driver names don't match @@ -632,10 +631,10 @@ void InputMapper::AutoMapJoysticksForCurrentGame() break; // stop mapping. We already mapped one device for each game controller. LOG->Info( "Applying default joystick mapping #%d for device '%s' (%s)", - iNumJoysticksMapped+1, mapping->m_sDriverRegex.c_str(), mapping->m_sControllerName.c_str() ); + iNumJoysticksMapped+1, mapping.m_sDriverRegex.c_str(), mapping.m_sControllerName.c_str() ); Unmap( id ); - ApplyMapping( mapping->m_vMaps, gc, id ); + ApplyMapping( mapping.m_vMaps, gc, id ); iNumJoysticksMapped++; } @@ -686,16 +685,16 @@ void InputMapper::CheckButtonAndAddToReason(GameButton menu, vector& fu if(!inputs.empty()) { vector device_inputs; - FOREACH(GameInput, inputs, inp) + for(GameInput &inp : inputs) { for(int slot= 0; slot < NUM_GAME_TO_DEVICE_SLOTS; ++slot) { - device_inputs.push_back(m_mappings.m_GItoDI[inp->controller][inp->button][slot]); + device_inputs.push_back(m_mappings.m_GItoDI[inp.controller][inp.button][slot]); } } - FOREACH(DeviceInput, device_inputs, inp) + for(DeviceInput &inp : device_inputs) { - if(!inp->IsValid()) + if(!inp.IsValid()) { continue; } @@ -706,7 +705,7 @@ void InputMapper::CheckButtonAndAddToReason(GameButton menu, vector& fu { for(int slot= 0; slot < NUM_GAME_TO_DEVICE_SLOTS; ++slot) { - use_count+= ((*inp) == m_mappings.m_GItoDI[cont][gb][slot]); + use_count+= (inp == m_mappings.m_GItoDI[cont][gb][slot]); } } } @@ -1096,16 +1095,16 @@ void InputScheme::MenuButtonToGameInputs( GameButton MenuI, PlayerNumber pn, vec vector aGameButtons; MenuButtonToGameButtons( MenuI, aGameButtons ); - FOREACH( GameButton, aGameButtons, gb ) + for (GameButton const &gb : aGameButtons) { if( pn == PLAYER_INVALID ) { - GameIout.push_back( GameInput(GameController_1, *gb) ); - GameIout.push_back( GameInput(GameController_2, *gb) ); + GameIout.push_back( GameInput(GameController_1, gb) ); + GameIout.push_back( GameInput(GameController_2, gb) ); } else { - GameIout.push_back( GameInput((GameController)pn, *gb) ); + GameIout.push_back( GameInput((GameController)pn, gb) ); } } } @@ -1249,7 +1248,7 @@ void InputMappings::WriteMappings( const InputScheme *pInputScheme, RString sFil ini.DeleteKey( pInputScheme->m_szName ); XNode *pKey = ini.GetChild( pInputScheme->m_szName ); - if( pKey != NULL ) + if( pKey != nullptr ) ini.RemoveChild( pKey ); pKey = ini.AppendChild( pInputScheme->m_szName ); diff --git a/src/InputMapper.h b/src/InputMapper.h index afd6e29088..f6280ce30f 100644 --- a/src/InputMapper.h +++ b/src/InputMapper.h @@ -177,9 +177,9 @@ public: float GetSecsHeld( const GameInput &GameI, MultiPlayer mp = MultiPlayer_Invalid ) const; float GetSecsHeld( GameButton MenuI, PlayerNumber pn ) const; - bool IsBeingPressed( const GameInput &GameI, MultiPlayer mp = MultiPlayer_Invalid, const DeviceInputList *pButtonState = NULL ) const; + bool IsBeingPressed( const GameInput &GameI, MultiPlayer mp = MultiPlayer_Invalid, const DeviceInputList *pButtonState = nullptr ) const; bool IsBeingPressed( GameButton MenuI, PlayerNumber pn ) const; - bool IsBeingPressed(const vector& GameI, MultiPlayer mp = MultiPlayer_Invalid, const DeviceInputList *pButtonState = NULL ) const; + bool IsBeingPressed(const vector& GameI, MultiPlayer mp = MultiPlayer_Invalid, const DeviceInputList *pButtonState = nullptr ) const; void ResetKeyRepeat( const GameInput &GameI ); void ResetKeyRepeat( GameButton MenuI, PlayerNumber pn ); diff --git a/src/InputQueue.cpp b/src/InputQueue.cpp index 6fd22a2240..bf8a63eb3e 100644 --- a/src/InputQueue.cpp +++ b/src/InputQueue.cpp @@ -3,10 +3,9 @@ #include "RageTimer.h" #include "RageLog.h" #include "InputEventPlus.h" -#include "Foreach.h" #include "InputMapper.h" -InputQueue* INPUTQUEUE = NULL; // global and accessible from anywhere in our program +InputQueue* INPUTQUEUE = nullptr; // global and accessible from anywhere in our program const unsigned MAX_INPUT_QUEUE_LENGTH = 32; @@ -38,7 +37,7 @@ bool InputQueue::WasPressedRecently( GameController c, const GameButton button, if( iep.GameI.button != button ) continue; - if( pIEP != NULL ) + if( pIEP != nullptr ) *pIEP = iep; return true; @@ -95,7 +94,7 @@ bool InputQueueCode::EnteredCode( GameController controller ) const int iMinSearchIndexUsed = iQueueIndex; for( int b=0; b<(int) Press.m_aButtonsToPress.size(); ++b ) { - const InputEventPlus *pIEP = NULL; + const InputEventPlus *pIEP = nullptr; int iQueueSearchIndex = iQueueIndex; for( ; iQueueSearchIndex>=0; --iQueueSearchIndex ) // iterate newest to oldest { @@ -112,7 +111,7 @@ bool InputQueueCode::EnteredCode( GameController controller ) const break; } } - if( pIEP == NULL ) + if( pIEP == nullptr ) break; // didn't find the button // Check that m_aButtonsToHold were being held when the buttons were pressed. @@ -167,11 +166,11 @@ bool InputQueueCode::Load( RString sButtonsNames ) vector asPresses; split( sButtonsNames, ",", asPresses, false ); - FOREACH( RString, asPresses, sPress ) + for (RString &sPress : asPresses) { vector asButtonNames; - split( *sPress, "-", asButtonNames, false ); + split( sPress, "-", asButtonNames, false ); if( asButtonNames.size() < 1 ) { @@ -181,10 +180,8 @@ bool InputQueueCode::Load( RString sButtonsNames ) } m_aPresses.push_back( ButtonPress() ); - for( unsigned i=0; i &GetQueue( GameController c ) const { return m_aQueue[c]; } void ClearQueue( GameController c ); diff --git a/src/LifeMeterBar.cpp b/src/LifeMeterBar.cpp index f30d8d6801..ff333c3d07 100644 --- a/src/LifeMeterBar.cpp +++ b/src/LifeMeterBar.cpp @@ -29,7 +29,7 @@ LifeMeterBar::LifeMeterBar() EXTRA_STAGE_LIFE_DIFFICULTY.Load ("LifeMeterBar","ExtraStageLifeDifficulty"); m_fLifePercentChange.Load( "LifeMeterBar", LIFE_PERCENT_CHANGE_NAME, NUM_ScoreEvent ); - m_pPlayerState = NULL; + m_pPlayerState = nullptr; const RString sType = "LifeMeterBar"; diff --git a/src/LifeMeterTime.cpp b/src/LifeMeterTime.cpp index 2c144f3bfa..0d287161a7 100644 --- a/src/LifeMeterTime.cpp +++ b/src/LifeMeterTime.cpp @@ -50,7 +50,7 @@ LifeMeterTime::LifeMeterTime() { m_fLifeTotalGainedSeconds = 0; m_fLifeTotalLostSeconds = 0; - m_pStream = NULL; + m_pStream = nullptr; } LifeMeterTime::~LifeMeterTime() @@ -100,7 +100,7 @@ void LifeMeterTime::OnLoadSong() if(GAMESTATE->IsCourseMode()) { Course* pCourse = GAMESTATE->m_pCurCourse; - ASSERT( pCourse != NULL ); + ASSERT( pCourse != nullptr ); fGainSeconds= pCourse->m_vEntries[GAMESTATE->GetCourseSongIndex()].fGainSeconds; } else @@ -108,10 +108,10 @@ void LifeMeterTime::OnLoadSong() // Placeholderish, at least this way it won't crash when someone tries it // out in non-course mode. -Kyz Song* song= GAMESTATE->m_pCurSong; - ASSERT(song != NULL); + ASSERT(song != nullptr); float song_len= song->m_fMusicLengthSeconds; Steps* steps= GAMESTATE->m_pCurSteps[m_pPlayerState->m_PlayerNumber]; - ASSERT(steps != NULL); + ASSERT(steps != nullptr); RadarValues radars= steps->GetRadarValues(m_pPlayerState->m_PlayerNumber); float scorable_things= radars[RadarCategory_TapsAndHolds] + radars[RadarCategory_Lifts]; diff --git a/src/LightsManager.cpp b/src/LightsManager.cpp index 517ab2f117..8713f4d20c 100644 --- a/src/LightsManager.cpp +++ b/src/LightsManager.cpp @@ -10,7 +10,6 @@ #include "PrefsManager.h" #include "Actor.h" #include "Preference.h" -#include "Foreach.h" #include "GameManager.h" #include "CommonMetrics.h" #include "Style.h" @@ -57,9 +56,9 @@ static void GetUsedGameInputs( vector &vGameInputsOut ) split( GAME_BUTTONS_TO_SHOW.GetValue(), ",", asGameButtons ); FOREACH_ENUM( GameController, gc ) { - FOREACH_CONST( RString, asGameButtons, button ) + for (RString const &button : asGameButtons) { - GameButton gb = StringToGameButton( INPUTMAPPER->GetInputScheme(), *button ); + GameButton gb = StringToGameButton( INPUTMAPPER->GetInputScheme(), button ); if( gb != GameButton_Invalid ) { GameInput gi = GameInput( gc, gb ); @@ -71,17 +70,18 @@ static void GetUsedGameInputs( vector &vGameInputsOut ) set vGIs; vector vStyles; GAMEMAN->GetStylesForGame( GAMESTATE->m_pCurGame, vStyles ); - FOREACH( const Style*, vStyles, style ) + auto const &value = CommonMetrics::STEPS_TYPES_TO_SHOW.GetValue(); + for (Style const *style : vStyles) { - bool bFound = find( CommonMetrics::STEPS_TYPES_TO_SHOW.GetValue().begin(), CommonMetrics::STEPS_TYPES_TO_SHOW.GetValue().end(), (*style)->m_StepsType ) != CommonMetrics::STEPS_TYPES_TO_SHOW.GetValue().end(); + bool bFound = find( value.begin(), value.end(), style->m_StepsType ) != value.end(); if( !bFound ) continue; FOREACH_PlayerNumber( pn ) { - for( int iCol=0; iCol<(*style)->m_iColsPerPlayer; ++iCol ) + for( int iCol=0; iCol < style->m_iColsPerPlayer; ++iCol ) { vector gi; - (*style)->StyleInputToGameInput( iCol, pn, gi ); + style->StyleInputToGameInput( iCol, pn, gi ); for(size_t i= 0; i < gi.size(); ++i) { if(gi[i].IsValid()) @@ -93,11 +93,11 @@ static void GetUsedGameInputs( vector &vGameInputsOut ) } } - FOREACHS_CONST( GameInput, vGIs, gi ) - vGameInputsOut.push_back( *gi ); + for (GameInput const &input : vGIs) + vGameInputsOut.push_back( input ); } -LightsManager* LIGHTSMAN = NULL; // global and accessible from anywhere in our program +LightsManager* LIGHTSMAN = nullptr; // global and accessible from anywhere in our program LightsManager::LightsManager() { @@ -119,8 +119,10 @@ LightsManager::LightsManager() LightsManager::~LightsManager() { - FOREACH( LightsDriver*, m_vpDrivers, iter ) - SAFE_DELETE( *iter ); + for (LightsDriver *iter : m_vpDrivers) + { + SAFE_DELETE( iter ); + } m_vpDrivers.clear(); } @@ -438,8 +440,8 @@ void LightsManager::Update( float fDeltaTime ) } // apply new light values we set above - FOREACH( LightsDriver*, m_vpDrivers, iter ) - (*iter)->Set( &m_LightsState ); + for (LightsDriver *iter : m_vpDrivers) + iter->Set( &m_LightsState ); } void LightsManager::BlinkCabinetLight( CabinetLight cl ) @@ -514,8 +516,8 @@ bool LightsManager::IsEnabled() const void LightsManager::TurnOffAllLights() { - FOREACH( LightsDriver*, m_vpDrivers, iter ) - (*iter)->Reset(); + for(LightsDriver *iter : m_vpDrivers) + iter->Reset(); } /* diff --git a/src/LocalizedString.cpp b/src/LocalizedString.cpp index eafe657e01..03eaf719ca 100644 --- a/src/LocalizedString.cpp +++ b/src/LocalizedString.cpp @@ -1,6 +1,6 @@ #include "global.h" #include "LocalizedString.h" -#include "Foreach.h" + #include "RageUtil.h" #include "SubscriptionManager.h" @@ -27,9 +27,8 @@ static LocalizedString::MakeLocalizer g_pMakeLocalizedStringImpl = LocalizedStri void LocalizedString::RegisterLocalizer( MakeLocalizer pFunc ) { g_pMakeLocalizedStringImpl = pFunc; - FOREACHS( LocalizedString*, *m_Subscribers.m_pSubscribers, l ) + for (LocalizedString *pLoc : *m_Subscribers.m_pSubscribers) { - LocalizedString *pLoc = *l; pLoc->CreateImpl(); } } @@ -40,7 +39,7 @@ LocalizedString::LocalizedString( const RString& sGroup, const RString& sName ) m_sGroup = sGroup; m_sName = sName; - m_pImpl = NULL; + m_pImpl = nullptr; CreateImpl(); } @@ -51,7 +50,7 @@ LocalizedString::LocalizedString(LocalizedString const& other) m_sGroup = other.m_sGroup; m_sName = other.m_sName; - m_pImpl = NULL; + m_pImpl = nullptr; CreateImpl(); } diff --git a/src/LuaBinding.cpp b/src/LuaBinding.cpp index 355c6487f9..03264f9e1b 100644 --- a/src/LuaBinding.cpp +++ b/src/LuaBinding.cpp @@ -2,7 +2,7 @@ #include "LuaBinding.h" #include "LuaReference.h" #include "RageUtil.h" -#include "Foreach.h" + #include "SubscriptionManager.h" static SubscriptionManager m_Subscribers; @@ -11,13 +11,13 @@ namespace { void RegisterTypes( lua_State *L ) { - if( m_Subscribers.m_pSubscribers == NULL ) + if( m_Subscribers.m_pSubscribers == nullptr ) return; /* Register base classes first. */ map mapToRegister; - FOREACHS( LuaBinding*, *m_Subscribers.m_pSubscribers, p ) - mapToRegister[(*p)->GetClassName()] = (*p); + for (LuaBinding *binding : *m_Subscribers.m_pSubscribers) + mapToRegister[binding->GetClassName()] = binding; set setRegisteredAlready; @@ -322,7 +322,7 @@ void *LuaBinding::GetPointerFromStack( Lua *L, const RString &sType, int iArg ) return *pData; } else - return NULL; + return nullptr; } /* Tricky: when an instance table is copied, we want to do a deep @@ -354,7 +354,7 @@ LuaClass &LuaClass::operator=( const LuaClass &cpy ) LuaClass::~LuaClass() { - if( LUA == NULL ) + if( LUA == nullptr ) return; Lua *L = LUA->Get(); diff --git a/src/LuaBinding.h b/src/LuaBinding.h index d5b170df57..f073b2196f 100644 --- a/src/LuaBinding.h +++ b/src/LuaBinding.h @@ -156,7 +156,7 @@ public: void T::PushSelf( lua_State *L ) { Luna::PushObject( L, Luna::m_sClassName, this ); } \ static Luna##T registera##T; \ /* Call PushSelf, so we always call the derived Luna::Push. */ \ - namespace LuaHelpers { template<> void Push( lua_State *L, T *const &pObject ) { if( pObject == NULL ) lua_pushnil(L); else pObject->PushSelf( L ); } } + namespace LuaHelpers { template<> void Push( lua_State *L, T *const &pObject ) { if( pObject == nullptr ) lua_pushnil(L); else pObject->PushSelf( L ); } } #define DEFINE_METHOD( method_name, expr ) \ static int method_name( T* p, lua_State *L ) { LuaHelpers::Push( L, p->expr ); return 1; } diff --git a/src/LuaManager.cpp b/src/LuaManager.cpp index 9b3575eba0..2c57145d0b 100644 --- a/src/LuaManager.cpp +++ b/src/LuaManager.cpp @@ -5,7 +5,6 @@ #include "RageLog.h" #include "RageFile.h" #include "RageThreads.h" -#include "Foreach.h" #include "arch/Dialog/Dialog.h" #include "XmlFile.h" #include "Command.h" @@ -19,7 +18,7 @@ #include #include -LuaManager *LUA = NULL; +LuaManager *LUA = nullptr; struct Impl { Impl(): g_pLock("Lua") {} @@ -28,7 +27,7 @@ struct Impl RageMutex g_pLock; }; -static Impl *pImpl = NULL; +static Impl *pImpl = nullptr; #if defined(_MSC_VER) /* "interaction between '_setjmp' and C++ object destruction is non-portable" @@ -96,12 +95,12 @@ namespace LuaHelpers { size_t iLen; const char *pStr = lua_tolstring( L, iOffset, &iLen ); - if( pStr != NULL ) + if( pStr != nullptr ) Object.assign( pStr, iLen ); else Object.clear(); - return pStr != NULL; + return pStr != nullptr; } } @@ -184,7 +183,7 @@ static int GetLuaStack( lua_State *L ) if( !strcmp(ar.what, "C") ) { - for( int i = 1; i <= ar.nups && (name = lua_getupvalue(L, -1, i)) != NULL; ++i ) + for( int i = 1; i <= ar.nups && (name = lua_getupvalue(L, -1, i)) != nullptr; ++i ) { vArgs.push_back( ssprintf("%s = %s", name, lua_tostring(L, -1)) ); lua_pop( L, 1 ); // pop value @@ -192,7 +191,7 @@ static int GetLuaStack( lua_State *L ) } else { - for( int i = 1; (name = lua_getlocal(L, &ar, i)) != NULL; ++i ) + for( int i = 1; (name = lua_getlocal(L, &ar, i)) != nullptr; ++i ) { vArgs.push_back( ssprintf("%s = %s", name, lua_tostring(L, -1)) ); lua_pop( L, 1 ); // pop value @@ -236,11 +235,11 @@ static int LuaPanic( lua_State *L ) } // Actor registration -static vector *g_vRegisterActorTypes = NULL; +static vector *g_vRegisterActorTypes = nullptr; void LuaManager::Register( RegisterWithLuaFn pfn ) { - if( g_vRegisterActorTypes == NULL ) + if( g_vRegisterActorTypes == nullptr ) g_vRegisterActorTypes = new vector; g_vRegisterActorTypes->push_back( pfn ); @@ -253,7 +252,7 @@ LuaManager::LuaManager() LUA = this; // so that LUA is available when we call the Register functions lua_State *L = lua_open(); - ASSERT( L != NULL ); + ASSERT( L != nullptr ); lua_atpanic( L, LuaPanic ); m_pLuaMain = L; @@ -325,7 +324,7 @@ void LuaManager::Release( Lua *&p ) if( bDoUnlock ) pImpl->g_pLock.Unlock(); - p = NULL; + p = nullptr; } /* @@ -680,35 +679,35 @@ XNode *LuaHelpers::GetLuaInformation() /* Globals */ sort( vFunctions.begin(), vFunctions.end() ); - FOREACH_CONST( RString, vFunctions, func ) + for (RString const &func : vFunctions) { XNode *pFunctionNode = pGlobalsNode->AppendChild( "Function" ); - pFunctionNode->AppendAttr( "name", *func ); + pFunctionNode->AppendAttr( "name", func ); } /* Classes */ - FOREACHM_CONST( RString, LClass, mClasses, c ) + for (auto const &c : mClasses) { XNode *pClassNode = pClassesNode->AppendChild( "Class" ); - pClassNode->AppendAttr( "name", c->first ); - if( !c->second.m_sBaseName.empty() ) - pClassNode->AppendAttr( "base", c->second.m_sBaseName ); - FOREACH_CONST( RString, c->second.m_vMethods, m ) + pClassNode->AppendAttr( "name", c.first ); + if( !c.second.m_sBaseName.empty() ) + pClassNode->AppendAttr( "base", c.second.m_sBaseName ); + for (RString const & m : c.second.m_vMethods) { XNode *pMethodNode = pClassNode->AppendChild( "Function" ); - pMethodNode->AppendAttr( "name", *m ); + pMethodNode->AppendAttr( "name", m ); } } /* Singletons */ - FOREACHM_CONST( RString, RString, mSingletons, s ) + for (auto const &s : mSingletons) { - if( mClasses.find(s->first) != mClasses.end() ) + if( mClasses.find(s.first) != mClasses.end() ) continue; XNode *pSingletonNode = pSingletonsNode->AppendChild( "Singleton" ); - pSingletonNode->AppendAttr( "name", s->first ); - pSingletonNode->AppendAttr( "class", s->second ); + pSingletonNode->AppendAttr( "name", s.first ); + pSingletonNode->AppendAttr( "class", s.second ); } /* Namespaces */ @@ -718,10 +717,10 @@ XNode *LuaHelpers::GetLuaInformation() const vector &vNamespace = iter->second; pNamespaceNode->AppendAttr( "name", iter->first ); - FOREACH_CONST( RString, vNamespace, func ) + for (RString const &func: vNamespace) { XNode *pFunctionNode = pNamespaceNode->AppendChild( "Function" ); - pFunctionNode->AppendAttr( "name", *func ); + pFunctionNode->AppendAttr( "name", func ); } } @@ -742,21 +741,21 @@ XNode *LuaHelpers::GetLuaInformation() } /* Constants, String Constants */ - FOREACHM_CONST( RString, float, mConstants, c ) + for (auto const &c : mConstants) { XNode *pConstantNode = pConstantsNode->AppendChild( "Constant" ); - pConstantNode->AppendAttr( "name", c->first ); - if( c->second == truncf(c->second) ) - pConstantNode->AppendAttr( "value", int(c->second) ); + pConstantNode->AppendAttr( "name", c.first ); + if( c.second == truncf(c.second) ) + pConstantNode->AppendAttr( "value", static_cast(c.second) ); else - pConstantNode->AppendAttr( "value", c->second ); + pConstantNode->AppendAttr( "value", c.second ); } - FOREACHM_CONST( RString, RString, mStringConstants, s ) + for (auto const &s : mStringConstants) { XNode *pConstantNode = pConstantsNode->AppendChild( "Constant" ); - pConstantNode->AppendAttr( "name", s->first ); - pConstantNode->AppendAttr( "value", ssprintf("'%s'", s->second.c_str()) ); + pConstantNode->AppendAttr( "name", s.first ); + pConstantNode->AppendAttr( "value", ssprintf("'%s'", s.second.c_str()) ); } return pLuaNode; @@ -924,9 +923,8 @@ void LuaHelpers::ParseCommandList( Lua *L, const RString &sCommands, const RStri if( bLegacy ) s << "\tparent = self:GetParent();\n"; - FOREACH_CONST( Command, cmds.v, c ) + for (Command const &cmd : cmds.v) { - const Command& cmd = (*c); RString sCmdName = cmd.GetName(); if( bLegacy ) sCmdName.MakeLower(); @@ -1137,8 +1135,8 @@ namespace lua_call( L, iArgs, LUA_MULTRET ); int iVals = lua_gettop(L); - FOREACH( LuaThreadVariable *, apVars, v ) - delete *v; + for (LuaThreadVariable *v : apVars) + delete v; return iVals; } @@ -1176,7 +1174,7 @@ namespace LIST_METHOD( RunWithThreadVariables ), LIST_METHOD( GetThreadVariable ), LIST_METHOD( ReportScriptError ), - { NULL, NULL } + { nullptr, nullptr } }; } diff --git a/src/LuaManager.h b/src/LuaManager.h index 79b5f217ee..0b352b5ae6 100644 --- a/src/LuaManager.h +++ b/src/LuaManager.h @@ -240,7 +240,7 @@ inline bool TableContainsOnlyStrings(lua_State* L, int index) { // `key' is at index -2 and `value' at index -1 const char *pValue = lua_tostring(L, -1); - if(pValue == NULL) + if(pValue == nullptr) { // Was going to print an error to the log with the key that failed, // but didn't want to pull in RageLog. -Kyz diff --git a/src/LuaReference.cpp b/src/LuaReference.cpp index 537337ca09..38e386e9d5 100644 --- a/src/LuaReference.cpp +++ b/src/LuaReference.cpp @@ -1,236 +1,236 @@ -#include "global.h" -#include "LuaReference.h" - -REGISTER_CLASS_TRAITS( LuaReference, new LuaReference(*pCopy) ) - -LuaReference::LuaReference() -{ - m_iReference = LUA_NOREF; -} - -LuaReference::~LuaReference() -{ - Unregister(); -} - -LuaReference::LuaReference( const LuaReference &cpy ) -{ - if( cpy.m_iReference == LUA_NOREF || cpy.m_iReference == LUA_REFNIL ) - { - m_iReference = cpy.m_iReference; - } - else - { - /* Make a new reference. */ - Lua *L = LUA->Get(); - lua_rawgeti( L, LUA_REGISTRYINDEX, cpy.m_iReference ); - m_iReference = luaL_ref( L, LUA_REGISTRYINDEX ); - LUA->Release( L ); - } -} - -LuaReference &LuaReference::operator=( const LuaReference &cpy ) -{ - if( this == &cpy ) - return *this; - - Unregister(); - - if( cpy.m_iReference == LUA_NOREF || cpy.m_iReference == LUA_REFNIL ) - { - m_iReference = cpy.m_iReference; - } - else - { - /* Make a new reference. */ - Lua *L = LUA->Get(); - lua_rawgeti( L, LUA_REGISTRYINDEX, cpy.m_iReference ); - m_iReference = luaL_ref( L, LUA_REGISTRYINDEX ); - LUA->Release( L ); - } - - return *this; -} - -void LuaReference::SetFromStack( Lua *L ) -{ - if( m_iReference != LUA_NOREF ) - luaL_unref( L, LUA_REGISTRYINDEX, m_iReference ); - m_iReference = luaL_ref( L, LUA_REGISTRYINDEX ); -} - -void LuaReference::SetFromNil() -{ - Unregister(); - m_iReference = LUA_REFNIL; -} - -void LuaReference::DeepCopy() -{ - /* Call DeepCopy(t, u), where t is our referenced object and u is the new table. */ - Lua *L = LUA->Get(); - - /* Arg 1 (t): */ - this->PushSelf( L ); - - /* Arg 2 (u): */ - lua_newtable( L ); - - lua_pushvalue( L, -1 ); - this->SetFromStack( L ); - - LuaHelpers::DeepCopy( L ); - - LUA->Release( L ); -} - -void LuaReference::PushSelf( lua_State *L ) const -{ - lua_rawgeti( L, LUA_REGISTRYINDEX, m_iReference ); -} - -bool LuaReference::IsSet() const -{ - return m_iReference != LUA_NOREF; -} - -bool LuaReference::IsNil() const -{ - return m_iReference == LUA_REFNIL; -} - -int LuaReference::GetLuaType() const -{ - Lua *L = LUA->Get(); - this->PushSelf( L ); - int iRet = lua_type( L, -1 ); - lua_pop( L, 1 ); - LUA->Release( L ); - - return iRet; -} - -void LuaReference::Unregister() -{ - if( LUA == NULL || m_iReference == LUA_NOREF ) - return; // nothing to do - - Lua *L = LUA->Get(); - luaL_unref( L, LUA_REGISTRYINDEX, m_iReference ); - LUA->Release( L ); - m_iReference = LUA_NOREF; -} - -bool LuaReference::SetFromExpression( const RString &sExpression ) -{ - Lua *L = LUA->Get(); - - bool bSuccess = LuaHelpers::RunExpression( L, sExpression ); - this->SetFromStack( L ); - - LUA->Release( L ); - return bSuccess; -} - -RString LuaReference::Serialize() const -{ - /* Call Serialize(t), where t is our referenced object. */ - Lua *L = LUA->Get(); - lua_getglobal( L, "Serialize" ); - - ASSERT_M( !lua_isnil(L, -1), "Serialize() missing" ); - ASSERT_M( lua_isfunction(L, -1), "Serialize() not a function" ); - - /* Arg 1 (t): */ - this->PushSelf( L ); - - lua_call( L, 1, 1 ); - - /* The return value is a string, which we store in m_sSerializedData. */ - const char *pString = lua_tostring( L, -1 ); - ASSERT_M( pString != NULL, "Serialize() didn't return a string" ); - - RString sRet = pString; - lua_pop( L, 1 ); - - LUA->Release( L ); - - return sRet; -} - -/** @brief Utilities for working with Lua. */ -namespace LuaHelpers -{ - template<> bool FromStack( lua_State *L, LuaReference &Object, int iOffset ) - { - lua_pushvalue( L, iOffset ); - Object.SetFromStack( L ); - return true; - } - - template<> bool FromStack( lua_State *L, apActorCommands &Object, int iOffset ) - { - LuaReference *pRef = new LuaReference; - FromStack( L, *pRef, iOffset ); - Object = apActorCommands( pRef ); - return true; - } -} - -LuaTable::LuaTable() -{ - Lua *L = LUA->Get(); - lua_newtable( L ); - this->SetFromStack(L); - LUA->Release( L ); -} - -void LuaTable::Set( Lua *L, const RString &sKey ) -{ - int iTop = lua_gettop( L ); - this->PushSelf( L ); - lua_pushvalue( L, iTop ); // push the value - lua_setfield( L, -2, sKey ); - lua_settop( L, iTop-1 ); // remove all of the above -} - -void LuaTable::Get( Lua *L, const RString &sKey ) -{ - this->PushSelf( L ); - lua_getfield( L, -1, sKey ); - lua_remove( L, -2 ); // remove self -} - -/** @brief Utilities for working with Lua. */ -namespace LuaHelpers -{ - template<> void Push( lua_State *L, const LuaReference &Object ) - { - Object.PushSelf( L ); - } -} - -/* - * (c) 2005 Glenn Maynard, Chris Danford - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "LuaReference.h" + +REGISTER_CLASS_TRAITS( LuaReference, new LuaReference(*pCopy) ) + +LuaReference::LuaReference() +{ + m_iReference = LUA_NOREF; +} + +LuaReference::~LuaReference() +{ + Unregister(); +} + +LuaReference::LuaReference( const LuaReference &cpy ) +{ + if( cpy.m_iReference == LUA_NOREF || cpy.m_iReference == LUA_REFNIL ) + { + m_iReference = cpy.m_iReference; + } + else + { + /* Make a new reference. */ + Lua *L = LUA->Get(); + lua_rawgeti( L, LUA_REGISTRYINDEX, cpy.m_iReference ); + m_iReference = luaL_ref( L, LUA_REGISTRYINDEX ); + LUA->Release( L ); + } +} + +LuaReference &LuaReference::operator=( const LuaReference &cpy ) +{ + if( this == &cpy ) + return *this; + + Unregister(); + + if( cpy.m_iReference == LUA_NOREF || cpy.m_iReference == LUA_REFNIL ) + { + m_iReference = cpy.m_iReference; + } + else + { + /* Make a new reference. */ + Lua *L = LUA->Get(); + lua_rawgeti( L, LUA_REGISTRYINDEX, cpy.m_iReference ); + m_iReference = luaL_ref( L, LUA_REGISTRYINDEX ); + LUA->Release( L ); + } + + return *this; +} + +void LuaReference::SetFromStack( Lua *L ) +{ + if( m_iReference != LUA_NOREF ) + luaL_unref( L, LUA_REGISTRYINDEX, m_iReference ); + m_iReference = luaL_ref( L, LUA_REGISTRYINDEX ); +} + +void LuaReference::SetFromNil() +{ + Unregister(); + m_iReference = LUA_REFNIL; +} + +void LuaReference::DeepCopy() +{ + /* Call DeepCopy(t, u), where t is our referenced object and u is the new table. */ + Lua *L = LUA->Get(); + + /* Arg 1 (t): */ + this->PushSelf( L ); + + /* Arg 2 (u): */ + lua_newtable( L ); + + lua_pushvalue( L, -1 ); + this->SetFromStack( L ); + + LuaHelpers::DeepCopy( L ); + + LUA->Release( L ); +} + +void LuaReference::PushSelf( lua_State *L ) const +{ + lua_rawgeti( L, LUA_REGISTRYINDEX, m_iReference ); +} + +bool LuaReference::IsSet() const +{ + return m_iReference != LUA_NOREF; +} + +bool LuaReference::IsNil() const +{ + return m_iReference == LUA_REFNIL; +} + +int LuaReference::GetLuaType() const +{ + Lua *L = LUA->Get(); + this->PushSelf( L ); + int iRet = lua_type( L, -1 ); + lua_pop( L, 1 ); + LUA->Release( L ); + + return iRet; +} + +void LuaReference::Unregister() +{ + if( LUA == nullptr || m_iReference == LUA_NOREF ) + return; // nothing to do + + Lua *L = LUA->Get(); + luaL_unref( L, LUA_REGISTRYINDEX, m_iReference ); + LUA->Release( L ); + m_iReference = LUA_NOREF; +} + +bool LuaReference::SetFromExpression( const RString &sExpression ) +{ + Lua *L = LUA->Get(); + + bool bSuccess = LuaHelpers::RunExpression( L, sExpression ); + this->SetFromStack( L ); + + LUA->Release( L ); + return bSuccess; +} + +RString LuaReference::Serialize() const +{ + /* Call Serialize(t), where t is our referenced object. */ + Lua *L = LUA->Get(); + lua_getglobal( L, "Serialize" ); + + ASSERT_M( !lua_isnil(L, -1), "Serialize() missing" ); + ASSERT_M( lua_isfunction(L, -1), "Serialize() not a function" ); + + /* Arg 1 (t): */ + this->PushSelf( L ); + + lua_call( L, 1, 1 ); + + /* The return value is a string, which we store in m_sSerializedData. */ + const char *pString = lua_tostring( L, -1 ); + ASSERT_M( pString != nullptr, "Serialize() didn't return a string" ); + + RString sRet = pString; + lua_pop( L, 1 ); + + LUA->Release( L ); + + return sRet; +} + +/** @brief Utilities for working with Lua. */ +namespace LuaHelpers +{ + template<> bool FromStack( lua_State *L, LuaReference &Object, int iOffset ) + { + lua_pushvalue( L, iOffset ); + Object.SetFromStack( L ); + return true; + } + + template<> bool FromStack( lua_State *L, apActorCommands &Object, int iOffset ) + { + LuaReference *pRef = new LuaReference; + FromStack( L, *pRef, iOffset ); + Object = apActorCommands( pRef ); + return true; + } +} + +LuaTable::LuaTable() +{ + Lua *L = LUA->Get(); + lua_newtable( L ); + this->SetFromStack(L); + LUA->Release( L ); +} + +void LuaTable::Set( Lua *L, const RString &sKey ) +{ + int iTop = lua_gettop( L ); + this->PushSelf( L ); + lua_pushvalue( L, iTop ); // push the value + lua_setfield( L, -2, sKey ); + lua_settop( L, iTop-1 ); // remove all of the above +} + +void LuaTable::Get( Lua *L, const RString &sKey ) +{ + this->PushSelf( L ); + lua_getfield( L, -1, sKey ); + lua_remove( L, -2 ); // remove self +} + +/** @brief Utilities for working with Lua. */ +namespace LuaHelpers +{ + template<> void Push( lua_State *L, const LuaReference &Object ) + { + Object.PushSelf( L ); + } +} + +/* + * (c) 2005 Glenn Maynard, Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/LyricDisplay.cpp b/src/LyricDisplay.cpp index 5454652d3b..f50985c340 100644 --- a/src/LyricDisplay.cpp +++ b/src/LyricDisplay.cpp @@ -1,117 +1,117 @@ -#include "global.h" -#include "LyricDisplay.h" -#include "ScreenDimensions.h" -#include "GameState.h" -#include "ThemeMetric.h" -#include "Song.h" -#include "ActorUtil.h" - -static ThemeMetric IN_LENGTH ("LyricDisplay","InLength"); -static ThemeMetric OUT_LENGTH ("LyricDisplay","OutLength"); - -LyricDisplay::LyricDisplay() -{ - m_textLyrics[0].SetName( "LyricBack" ); - ActorUtil::LoadAllCommands( m_textLyrics[0], "LyricDisplay" ); - m_textLyrics[0].LoadFromFont( THEME->GetPathF("LyricDisplay","text") ); - this->AddChild( &m_textLyrics[0] ); - - m_textLyrics[1].SetName( "LyricFront" ); - ActorUtil::LoadAllCommands( m_textLyrics[1], "LyricDisplay" ); - m_textLyrics[1].LoadFromFont( THEME->GetPathF("LyricDisplay","text") ); - this->AddChild( &m_textLyrics[1] ); - - Init(); -} - -void LyricDisplay::Init() -{ - for( int i=0; i<2; i++ ) - m_textLyrics[i].SetText(""); - m_iCurLyricNumber = 0; - - m_fLastSecond = -500; - m_bStopped = false; -} - -void LyricDisplay::Stop() { - m_bStopped = true; -} - -void LyricDisplay::Update( float fDeltaTime ) -{ - if( m_bStopped ) - return; - - ActorFrame::Update( fDeltaTime ); - - if( GAMESTATE->m_pCurSong == NULL ) - return; - - // If the song has changed (in a course), reset. - if( GAMESTATE->m_Position.m_fMusicSeconds < m_fLastSecond ) - Init(); - m_fLastSecond = GAMESTATE->m_Position.m_fMusicSeconds; - - if( m_iCurLyricNumber >= GAMESTATE->m_pCurSong->m_LyricSegments.size() ) - return; - - const Song *pSong = GAMESTATE->m_pCurSong; - const float fStartTime = (pSong->m_LyricSegments[m_iCurLyricNumber].m_fStartTime) - IN_LENGTH.GetValue(); - - if( GAMESTATE->m_Position.m_fMusicSeconds < fStartTime ) - return; - - // Clamp this lyric to the beginning of the next or the end of the music. - float fEndTime; - if( m_iCurLyricNumber+1 < GAMESTATE->m_pCurSong->m_LyricSegments.size() ) - fEndTime = pSong->m_LyricSegments[m_iCurLyricNumber+1].m_fStartTime; - else - fEndTime = pSong->GetLastSecond(); - - const float fDistance = fEndTime - pSong->m_LyricSegments[m_iCurLyricNumber].m_fStartTime; - const float fTweenBufferTime = IN_LENGTH.GetValue() + OUT_LENGTH.GetValue(); - - /* If it's negative, two lyrics are so close together that there's no time - * to tween properly. Lyrics should never be this brief, anyway, so just - * skip it. */ - float fShowLength = max( fDistance - fTweenBufferTime, 0.0f ); - - // Make lyrics show faster for faster song rates. - fShowLength /= GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate; - - const LyricSegment &seg = GAMESTATE->m_pCurSong->m_LyricSegments[m_iCurLyricNumber]; - - LuaThreadVariable var1( "LyricText", seg.m_sLyric ); - LuaThreadVariable var2( "LyricDuration", LuaReference::Create(fShowLength) ); - LuaThreadVariable var3( "LyricColor", LuaReference::Create(seg.m_Color) ); - - PlayCommand( "Changed" ); - - m_iCurLyricNumber++; -} - -/* - * (c) 2003-2004 Kevin Slaughter, Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "LyricDisplay.h" +#include "ScreenDimensions.h" +#include "GameState.h" +#include "ThemeMetric.h" +#include "Song.h" +#include "ActorUtil.h" + +static ThemeMetric IN_LENGTH ("LyricDisplay","InLength"); +static ThemeMetric OUT_LENGTH ("LyricDisplay","OutLength"); + +LyricDisplay::LyricDisplay() +{ + m_textLyrics[0].SetName( "LyricBack" ); + ActorUtil::LoadAllCommands( m_textLyrics[0], "LyricDisplay" ); + m_textLyrics[0].LoadFromFont( THEME->GetPathF("LyricDisplay","text") ); + this->AddChild( &m_textLyrics[0] ); + + m_textLyrics[1].SetName( "LyricFront" ); + ActorUtil::LoadAllCommands( m_textLyrics[1], "LyricDisplay" ); + m_textLyrics[1].LoadFromFont( THEME->GetPathF("LyricDisplay","text") ); + this->AddChild( &m_textLyrics[1] ); + + Init(); +} + +void LyricDisplay::Init() +{ + for( int i=0; i<2; i++ ) + m_textLyrics[i].SetText(""); + m_iCurLyricNumber = 0; + + m_fLastSecond = -500; + m_bStopped = false; +} + +void LyricDisplay::Stop() { + m_bStopped = true; +} + +void LyricDisplay::Update( float fDeltaTime ) +{ + if( m_bStopped ) + return; + + ActorFrame::Update( fDeltaTime ); + + if( GAMESTATE->m_pCurSong == nullptr ) + return; + + // If the song has changed (in a course), reset. + if( GAMESTATE->m_Position.m_fMusicSeconds < m_fLastSecond ) + Init(); + m_fLastSecond = GAMESTATE->m_Position.m_fMusicSeconds; + + if( m_iCurLyricNumber >= GAMESTATE->m_pCurSong->m_LyricSegments.size() ) + return; + + const Song *pSong = GAMESTATE->m_pCurSong; + const float fStartTime = (pSong->m_LyricSegments[m_iCurLyricNumber].m_fStartTime) - IN_LENGTH.GetValue(); + + if( GAMESTATE->m_Position.m_fMusicSeconds < fStartTime ) + return; + + // Clamp this lyric to the beginning of the next or the end of the music. + float fEndTime; + if( m_iCurLyricNumber+1 < GAMESTATE->m_pCurSong->m_LyricSegments.size() ) + fEndTime = pSong->m_LyricSegments[m_iCurLyricNumber+1].m_fStartTime; + else + fEndTime = pSong->GetLastSecond(); + + const float fDistance = fEndTime - pSong->m_LyricSegments[m_iCurLyricNumber].m_fStartTime; + const float fTweenBufferTime = IN_LENGTH.GetValue() + OUT_LENGTH.GetValue(); + + /* If it's negative, two lyrics are so close together that there's no time + * to tween properly. Lyrics should never be this brief, anyway, so just + * skip it. */ + float fShowLength = max( fDistance - fTweenBufferTime, 0.0f ); + + // Make lyrics show faster for faster song rates. + fShowLength /= GAMESTATE->m_SongOptions.GetCurrent().m_fMusicRate; + + const LyricSegment &seg = GAMESTATE->m_pCurSong->m_LyricSegments[m_iCurLyricNumber]; + + LuaThreadVariable var1( "LyricText", seg.m_sLyric ); + LuaThreadVariable var2( "LyricDuration", LuaReference::Create(fShowLength) ); + LuaThreadVariable var3( "LyricColor", LuaReference::Create(seg.m_Color) ); + + PlayCommand( "Changed" ); + + m_iCurLyricNumber++; +} + +/* + * (c) 2003-2004 Kevin Slaughter, Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/Makefile.am b/src/Makefile.am index 3406974b6a..aa38194675 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -205,7 +205,7 @@ XmlToLua.cpp XmlToLua.h \ XmlFileUtil.cpp XmlFileUtil.h StepMania = CommandLineActions.h CommandLineActions.cpp \ -StdString.h Foreach.h \ +StdString.h \ StepMania.cpp StepMania.h \ GameLoop.cpp GameLoop.h \ global.cpp global.h \ diff --git a/src/MemoryCardManager.cpp b/src/MemoryCardManager.cpp index adf8ef14a9..fc783a875d 100644 --- a/src/MemoryCardManager.cpp +++ b/src/MemoryCardManager.cpp @@ -8,12 +8,11 @@ #include "RageFileDriver.h" #include "RageFileDriverTimeout.h" #include "MessageManager.h" -#include "Foreach.h" #include "RageUtil_WorkerThread.h" #include "arch/MemoryCard/MemoryCardDriver_Null.h" #include "LuaManager.h" -MemoryCardManager* MEMCARDMAN = NULL; // global and accessible from anywhere in our program +MemoryCardManager* MEMCARDMAN = nullptr; // global and accessible from anywhere in our program static void MemoryCardOsMountPointInit( size_t /*PlayerNumber*/ i, RString &sNameOut, RString &defaultValueOut ) { @@ -253,11 +252,11 @@ bool ThreadedMemoryCardWorker::Unmount( const UsbStorageDevice *pDevice ) return true; } -static ThreadedMemoryCardWorker *g_pWorker = NULL; +static ThreadedMemoryCardWorker *g_pWorker = nullptr; MemoryCardManager::MemoryCardManager() { - ASSERT( g_pWorker == NULL ); + ASSERT( g_pWorker == nullptr ); // Register with Lua. { @@ -298,7 +297,7 @@ MemoryCardManager::~MemoryCardManager() // Unregister with Lua. LUA->UnsetGlobal( "MEMCARDMAN" ); - ASSERT( g_pWorker != NULL ); + ASSERT( g_pWorker != nullptr ); SAFE_DELETE(g_pWorker); FOREACH_PlayerNumber( pn ) @@ -337,7 +336,7 @@ void MemoryCardManager::UpdateAssignments() if( assigned_device.IsBlank() ) // no card assigned to this player continue; - FOREACH( UsbStorageDevice, vUnassignedDevices, d ) + for (vector::iterator d = vUnassignedDevices.begin(); d != vUnassignedDevices.end(); ++d) { if( *d == assigned_device ) { @@ -372,8 +371,8 @@ void MemoryCardManager::UpdateAssignments() } LOG->Trace( "Looking for a card for Player %d", p+1 ); - - FOREACH( UsbStorageDevice, vUnassignedDevices, d ) + + for (vector::iterator d = vUnassignedDevices.begin(); d != vUnassignedDevices.end(); ++d) { // search for card dir match if( !m_sMemoryCardOsMountPoint[p].Get().empty() && @@ -608,7 +607,7 @@ bool MemoryCardManager::MountCard( PlayerNumber pn, int iTimeout ) m_bMounted[pn] = true; RageFileDriver *pDriver = FILEMAN->GetFileDriver( MEM_CARD_MOUNT_POINT_INTERNAL[pn] ); - if( pDriver == NULL ) + if( pDriver == nullptr ) { LOG->Warn( "FILEMAN->GetFileDriver(%s) failed", MEM_CARD_MOUNT_POINT_INTERNAL[pn].c_str() ); return true; diff --git a/src/MenuTimer.cpp b/src/MenuTimer.cpp index c90e835612..4dd97774bc 100644 --- a/src/MenuTimer.cpp +++ b/src/MenuTimer.cpp @@ -19,7 +19,7 @@ MenuTimer::MenuTimer() m_fStallSecondsLeft = 0; m_bPaused = false; m_bSilent = false; - WARNING_COMMAND = NULL; + WARNING_COMMAND = nullptr; } MenuTimer::~MenuTimer() diff --git a/src/MessageManager.cpp b/src/MessageManager.cpp index c487973d27..fe539b8474 100644 --- a/src/MessageManager.cpp +++ b/src/MessageManager.cpp @@ -1,6 +1,5 @@ #include "global.h" #include "MessageManager.h" -#include "Foreach.h" #include "RageUtil.h" #include "RageThreads.h" #include "EnumHelper.h" @@ -10,7 +9,7 @@ #include #include -MessageManager* MESSAGEMAN = NULL; // global and accessible from anywhere in our program +MessageManager* MESSAGEMAN = nullptr; // global and accessible from anywhere in our program static const char *MessageIDNames[] = { @@ -219,10 +218,9 @@ void MessageManager::Broadcast( Message &msg ) const if( iter == g_MessageToSubscribers.end() ) return; - FOREACHS_CONST( IMessageSubscriber*, iter->second, p ) + for (IMessageSubscriber *subscriber : iter->second) { - IMessageSubscriber *pSub = *p; - pSub->HandleMessage( msg ); + subscriber->HandleMessage( msg ); } } @@ -251,8 +249,8 @@ void IMessageSubscriber::ClearMessages( const RString sMessage ) MessageSubscriber::MessageSubscriber( const MessageSubscriber &cpy ): IMessageSubscriber(cpy) { - FOREACH_CONST( RString, cpy.m_vsSubscribedTo, msg ) - this->SubscribeToMessage( *msg ); + for (RString const &msg : cpy.m_vsSubscribedTo) + this->SubscribeToMessage( msg ); } MessageSubscriber &MessageSubscriber::operator=(const MessageSubscriber &cpy) @@ -262,8 +260,8 @@ MessageSubscriber &MessageSubscriber::operator=(const MessageSubscriber &cpy) UnsubscribeAll(); - FOREACH_CONST( RString, cpy.m_vsSubscribedTo, msg ) - this->SubscribeToMessage( *msg ); + for (RString const &msg : cpy.m_vsSubscribedTo) + this->SubscribeToMessage( msg ); return *this; } @@ -282,8 +280,8 @@ void MessageSubscriber::SubscribeToMessage( MessageID message ) void MessageSubscriber::UnsubscribeAll() { - FOREACH_CONST( RString, m_vsSubscribedTo, s ) - MESSAGEMAN->Unsubscribe( this, *s ); + for (RString const &s : m_vsSubscribedTo) + MESSAGEMAN->Unsubscribe( this, s ); m_vsSubscribedTo.clear(); } diff --git a/src/MessageManager.h b/src/MessageManager.h index 6d77e1d7e2..e8d5e6fe18 100644 --- a/src/MessageManager.h +++ b/src/MessageManager.h @@ -256,7 +256,7 @@ private: MessageID mSendWhenChanged; T *val; public: - explicit BroadcastOnChangePtr( MessageID m ) { mSendWhenChanged = m; val = NULL; } + explicit BroadcastOnChangePtr( MessageID m ) { mSendWhenChanged = m; val = nullptr; } T* Get() const { return val; } void Set( T* t ) { val = t; if(MESSAGEMAN) MESSAGEMAN->Broadcast( MessageIDToString(mSendWhenChanged) ); } /* This is only intended to be used for setting temporary values; always diff --git a/src/MeterDisplay.cpp b/src/MeterDisplay.cpp index fc485e9014..410496b588 100644 --- a/src/MeterDisplay.cpp +++ b/src/MeterDisplay.cpp @@ -32,7 +32,7 @@ void MeterDisplay::LoadFromNode( const XNode* pNode ) LOG->Trace( "MeterDisplay::LoadFromNode(%s)", ActorUtil::GetWhere(pNode).c_str() ); const XNode *pStream = pNode->GetChild( "Stream" ); - if( pStream == NULL ) + if( pStream == nullptr ) { LuaHelpers::ReportScriptErrorFmt("%s: MeterDisplay: missing the \"Stream\" attribute", ActorUtil::GetWhere(pNode).c_str()); return; @@ -43,7 +43,7 @@ void MeterDisplay::LoadFromNode( const XNode* pNode ) this->AddChild( m_sprStream ); const XNode* pChild = pNode->GetChild( "Tip" ); - if( pChild != NULL ) + if( pChild != nullptr ) { m_sprTip.LoadActorFromNode( pChild, this ); m_sprTip->SetName( "Tip" ); diff --git a/src/ModIconRow.cpp b/src/ModIconRow.cpp index 0bf97c456e..fc91f532ea 100644 --- a/src/ModIconRow.cpp +++ b/src/ModIconRow.cpp @@ -8,7 +8,6 @@ #include "ActorUtil.h" #include "XmlFile.h" #include "LuaManager.h" -#include "Foreach.h" int OptionToPreferredColumn( RString sOptionText ); @@ -23,9 +22,9 @@ ModIconRow::ModIconRow() ModIconRow::~ModIconRow() { - FOREACH( ModIcon*, m_vpModIcon, p ) + for (ModIcon *p : m_vpModIcon) { - SAFE_DELETE( *p ); + SAFE_DELETE( p ); } this->RemoveAllChildren(); } diff --git a/src/Model.cpp b/src/Model.cpp index 4f79646d24..1e49ed8485 100644 --- a/src/Model.cpp +++ b/src/Model.cpp @@ -10,7 +10,6 @@ #include "RageLog.h" #include "ActorUtil.h" #include "ModelManager.h" -#include "Foreach.h" #include "LuaBinding.h" #include "PrefsManager.h" @@ -24,13 +23,13 @@ Model::Model() m_bTextureWrapping = true; SetUseZBuffer( true ); SetCullMode( CULL_BACK ); - m_pGeometry = NULL; - m_pCurAnimation = NULL; + m_pGeometry = nullptr; + m_pCurAnimation = nullptr; m_fDefaultAnimationRate = 1; m_fCurAnimationRate = 1; m_bLoop = true; m_bDrawCelShaded = false; - m_pTempGeometry = NULL; + m_pTempGeometry = nullptr; } Model::~Model() @@ -43,12 +42,12 @@ void Model::Clear() if( m_pGeometry ) { MODELMAN->UnloadModel( m_pGeometry ); - m_pGeometry = NULL; + m_pGeometry = nullptr; } m_vpBones.clear(); m_Materials.clear(); m_mapNameToAnimation.clear(); - m_pCurAnimation = NULL; + m_pCurAnimation = nullptr; RecalcAnimationLengthSeconds(); if( m_pTempGeometry ) @@ -81,7 +80,7 @@ void Model::LoadPieces( const RString &sMeshesPath, const RString &sMaterialsPat // TRICKY: Load materials before geometry so we can figure out whether the materials require normals. LoadMaterialsFromMilkshapeAscii( sMaterialsPath ); - ASSERT( m_pGeometry == NULL ); + ASSERT( m_pGeometry == nullptr ); m_pGeometry = MODELMAN->LoadMilkshapeAscii( sMeshesPath, this->MaterialsNeedNormals() ); // Validate material indices. @@ -288,7 +287,7 @@ bool Model::LoadMilkshapeAsciiBones( const RString &sAniName, const RString &sPa bool Model::EarlyAbortDraw() const { - return m_pGeometry == NULL || m_pGeometry->m_Meshes.empty(); + return m_pGeometry == nullptr || m_pGeometry->m_Meshes.empty(); } void Model::DrawCelShaded() @@ -571,7 +570,7 @@ void Model::SetPosition( float fSeconds ) void Model::AdvanceFrame( float fDeltaTime ) { - if( m_pGeometry == NULL || + if( m_pGeometry == nullptr || m_pGeometry->m_Meshes.empty() || !m_pCurAnimation ) { @@ -611,7 +610,7 @@ void Model::SetBones( const msAnimation* pAnimation, float fFrame, vectorPositionKeys.size(); ++j ) { const msPositionKey *pPositionKey = &pBone->PositionKeys[j]; @@ -624,18 +623,18 @@ void Model::SetBones( const msAnimation* pAnimation, float fFrame, vectorfTime, pThisPositionKey->fTime, 0, 1 ); vPos = pLastPositionKey->Position + (pThisPositionKey->Position - pLastPositionKey->Position) * s; } - else if( pLastPositionKey == NULL ) + else if( pLastPositionKey == nullptr ) vPos = pThisPositionKey->Position; - else if( pThisPositionKey == NULL ) + else if( pThisPositionKey == nullptr ) vPos = pLastPositionKey->Position; // search for the adjacent rotation keys - const msRotationKey *pLastRotationKey = NULL, *pThisRotationKey = NULL; + const msRotationKey *pLastRotationKey = nullptr, *pThisRotationKey = nullptr; for( size_t j = 0; j < pBone->RotationKeys.size(); ++j ) { const msRotationKey *pRotationKey = &pBone->RotationKeys[j]; @@ -648,16 +647,16 @@ void Model::SetBones( const msAnimation* pAnimation, float fFrame, vectorfTime, pThisRotationKey->fTime, 0, 1 ); RageQuatSlerp( &vRot, pLastRotationKey->Rotation, pThisRotationKey->Rotation, s ); } - else if( pLastRotationKey == NULL ) + else if( pLastRotationKey == nullptr ) { vRot = pThisRotationKey->Rotation; } - else if( pThisRotationKey == NULL ) + else if( pThisRotationKey == nullptr ) { vRot = pLastRotationKey->Rotation; } @@ -682,7 +681,7 @@ void Model::SetBones( const msAnimation* pAnimation, float fFrame, vectorm_Meshes.size(); ++i ) @@ -731,47 +730,42 @@ void Model::Update( float fDelta ) int Model::GetNumStates() const { int iMaxStates = 0; - FOREACH_CONST( msMaterial, m_Materials, m ) - iMaxStates = max( iMaxStates, m->diffuse.GetNumStates() ); + for (msMaterial const &m : m_Materials) + iMaxStates = max( iMaxStates, m.diffuse.GetNumStates() ); return iMaxStates; } void Model::SetState( int iNewState ) { - FOREACH( msMaterial, m_Materials, m ) + for (msMaterial &m : m_Materials) { - m->diffuse.SetState( iNewState ); - m->alpha.SetState( iNewState ); + m.diffuse.SetState( iNewState ); + m.alpha.SetState( iNewState ); } } -void Model::RecalcAnimationLengthSeconds() +void Model::RecalcAnimationLengthSeconds() { m_animation_length_seconds= 0; - FOREACH_CONST(msMaterial, m_Materials, m) + for (msMaterial const &m : m_Materials) { m_animation_length_seconds= max(m_animation_length_seconds, - m->diffuse.GetAnimationLengthSeconds()); + m.diffuse.GetAnimationLengthSeconds()); } } void Model::SetSecondsIntoAnimation( float fSeconds ) { - FOREACH( msMaterial, m_Materials, m ) + for (msMaterial &m : m_Materials) { - m->diffuse.SetSecondsIntoAnimation( fSeconds ); - m->alpha.SetSecondsIntoAnimation( fSeconds ); + m.diffuse.SetSecondsIntoAnimation( fSeconds ); + m.alpha.SetSecondsIntoAnimation( fSeconds ); } } bool Model::MaterialsNeedNormals() const { - FOREACH_CONST( msMaterial, m_Materials, m ) - { - if( m->NeedsNormals() ) - return true; - } - return false; + return std::any_of(m_Materials.begin(), m_Materials.end(), [](msMaterial const &m) { return m.NeedsNormals(); }); } // lua start diff --git a/src/ModelManager.cpp b/src/ModelManager.cpp index f587ee4eb5..ba44886c07 100644 --- a/src/ModelManager.cpp +++ b/src/ModelManager.cpp @@ -5,7 +5,7 @@ #include "RageLog.h" #include "RageDisplay.h" -ModelManager* MODELMAN = NULL; // global and accessible from anywhere in our program +ModelManager* MODELMAN = nullptr; // global and accessible from anywhere in our program ModelManager::ModelManager() { diff --git a/src/ModelTypes.cpp b/src/ModelTypes.cpp index f37111dd16..60a9736b29 100644 --- a/src/ModelTypes.cpp +++ b/src/ModelTypes.cpp @@ -8,7 +8,8 @@ #include "RageTextureManager.h" #include "RageLog.h" #include "RageDisplay.h" -#include "Foreach.h" + +#include #define MS_MAX_NAME 32 @@ -30,7 +31,7 @@ AnimatedTexture::~AnimatedTexture() void AnimatedTexture::LoadBlank() { AnimatedTextureState state( - NULL, + nullptr, 1, RageVector2(0,0) ); @@ -54,7 +55,7 @@ void AnimatedTexture::Load( const RString &sTexOrIniPath ) RageException::Throw( "Error reading \"%s\": %s", sTexOrIniPath.c_str(), ini.GetError().c_str() ); const XNode* pAnimatedTexture = ini.GetChild("AnimatedTexture"); - if( pAnimatedTexture == NULL ) + if( pAnimatedTexture == nullptr ) RageException::Throw( "The animated texture file \"%s\" doesn't contain a section called \"AnimatedTexture\".", sTexOrIniPath.c_str() ); pAnimatedTexture->GetAttrValue( "TexVelocityX", m_vTexVelocity.x ); @@ -130,7 +131,7 @@ void AnimatedTexture::Update( float fDelta ) RageTexture* AnimatedTexture::GetCurrentTexture() { if( vFrames.empty() ) - return NULL; + return nullptr; ASSERT( m_iCurState < (int)vFrames.size() ); return vFrames[m_iCurState].pTexture; } @@ -148,10 +149,8 @@ void AnimatedTexture::SetState( int iState ) float AnimatedTexture::GetAnimationLengthSeconds() const { - float fTotalSeconds = 0; - FOREACH_CONST( AnimatedTextureState, vFrames, ats ) - fTotalSeconds += ats->fDelaySecs; - return fTotalSeconds; + return std::accumulate(vFrames.begin(), vFrames.end(), 0.f, + [](float total, AnimatedTextureState const &state) { return total + state.fDelaySecs; }); } void AnimatedTexture::SetSecondsIntoAnimation( float fSeconds ) diff --git a/src/MusicWheel.cpp b/src/MusicWheel.cpp index fa3c96258f..5a94cf75fb 100644 --- a/src/MusicWheel.cpp +++ b/src/MusicWheel.cpp @@ -18,7 +18,6 @@ #include "ActorUtil.h" #include "SongUtil.h" #include "CourseUtil.h" -#include "Foreach.h" #include "Style.h" #include "PlayerState.h" #include "CommonMetrics.h" @@ -154,7 +153,7 @@ void MusicWheel::BeginScreen() const vector &from = getWheelItemsData(SORT_MODE_MENU); for( unsigned i=0; im_pAction != NULL ); + ASSERT( &*from[i]->m_pAction != nullptr ); if( from[i]->m_pAction->DescribesCurrentModeForAllPlayers() ) { m_sLastModeMenuItem = from[i]->m_pAction->m_sName; @@ -223,28 +222,28 @@ void MusicWheel::BeginScreen() /* Invalidate current Song if it can't be played * because there are not enough stages remaining. */ - if(GAMESTATE->m_pCurSong != NULL && + if(GAMESTATE->m_pCurSong != nullptr && GameState::GetNumStagesMultiplierForSong(GAMESTATE->m_pCurSong) > GAMESTATE->GetSmallestNumStagesLeftForAnyHumanPlayer()) { - GAMESTATE->m_pCurSong.Set(NULL); + GAMESTATE->m_pCurSong.Set(nullptr); } /* Invalidate current Steps if it can't be played * because there are not enough stages remaining. */ FOREACH_ENUM(PlayerNumber, p) { - if(GAMESTATE->m_pCurSteps[p] != NULL) + if(GAMESTATE->m_pCurSteps[p] != nullptr) { vector vpPossibleSteps; - if(GAMESTATE->m_pCurSong != NULL) + if(GAMESTATE->m_pCurSong != nullptr) { SongUtil::GetPlayableSteps(GAMESTATE->m_pCurSong, vpPossibleSteps); } bool bStepsIsPossible = find(vpPossibleSteps.begin(), vpPossibleSteps.end(), GAMESTATE->m_pCurSteps[p]) == vpPossibleSteps.end(); if(!bStepsIsPossible) { - GAMESTATE->m_pCurSteps[p].Set(NULL); + GAMESTATE->m_pCurSteps[p].Set(nullptr); } } } @@ -324,7 +323,7 @@ bool MusicWheel::SelectSection( const RString & SectionName ) bool MusicWheel::SelectSong( const Song *p ) { - if( p == NULL ) + if( p == nullptr ) return false; unsigned i; @@ -352,7 +351,7 @@ bool MusicWheel::SelectSong( const Song *p ) bool MusicWheel::SelectCourse( const Course *p ) { - if( p == NULL ) + if( p == nullptr ) return false; unsigned i; @@ -502,9 +501,9 @@ void MusicWheel::GetSongList( vector &arraySongs, SortOrder so ) set vStepsType; SongUtil::GetPlayableStepsTypes( pSong, vStepsType ); - FOREACHS( StepsType, vStepsType, st ) + for (StepsType const &type : vStepsType) { - if(pSong->HasStepsType(*st)) + if(pSong->HasStepsType(type)) { arraySongs.push_back( pSong ); break; @@ -544,7 +543,7 @@ void MusicWheel::BuildWheelItemDatas( vector &arrayWheelIt split( MODE_MENU_CHOICE_NAMES, ",", vsNames ); for( unsigned i=0; i( new GameCommand ); wid.m_pAction->m_sName = vsNames[i]; wid.m_pAction->Load( i, ParseCommands(CHOICE.GetValue(vsNames[i])) ); @@ -719,18 +718,18 @@ void MusicWheel::BuildWheelItemDatas( vector &arrayWheelIt // todo: preferred sort section color handling? -aj RageColor colorSection = (so==SORT_GROUP) ? SONGMAN->GetSongGroupColor(pSong->m_sGroupName) : SECTION_COLORS.GetValue(iSectionColorIndex); iSectionColorIndex = (iSectionColorIndex+1) % NUM_SECTION_COLORS; - arrayWheelItemDatas.push_back( new MusicWheelItemData(WheelItemDataType_Section, NULL, sThisSection, NULL, colorSection, iSectionCount) ); + arrayWheelItemDatas.push_back( new MusicWheelItemData(WheelItemDataType_Section, nullptr, sThisSection, nullptr, colorSection, iSectionCount) ); sLastSection = sThisSection; } } - arrayWheelItemDatas.push_back( new MusicWheelItemData(WheelItemDataType_Song, pSong, sLastSection, NULL, SONGMAN->GetSongColor(pSong), 0) ); + arrayWheelItemDatas.push_back( new MusicWheelItemData(WheelItemDataType_Song, pSong, sLastSection, nullptr, SONGMAN->GetSongColor(pSong), 0) ); } if( so != SORT_ROULETTE ) { // todo: allow themers to change the order of the items. -aj if( SHOW_ROULETTE ) - arrayWheelItemDatas.push_back( new MusicWheelItemData(WheelItemDataType_Roulette, NULL, "", NULL, ROULETTE_COLOR, 0) ); + arrayWheelItemDatas.push_back( new MusicWheelItemData(WheelItemDataType_Roulette, nullptr, "", nullptr, ROULETTE_COLOR, 0) ); // Only add WheelItemDataType_Random and WheelItemDataType_Portal if there's at least // one song on the list. @@ -740,17 +739,17 @@ void MusicWheel::BuildWheelItemDatas( vector &arrayWheelIt bFoundAnySong = true; if( SHOW_RANDOM && bFoundAnySong ) - arrayWheelItemDatas.push_back( new MusicWheelItemData(WheelItemDataType_Random, NULL, "", NULL, RANDOM_COLOR, 0) ); + arrayWheelItemDatas.push_back( new MusicWheelItemData(WheelItemDataType_Random, nullptr, "", nullptr, RANDOM_COLOR, 0) ); if( SHOW_PORTAL && bFoundAnySong ) - arrayWheelItemDatas.push_back( new MusicWheelItemData(WheelItemDataType_Portal, NULL, "", NULL, PORTAL_COLOR, 0) ); + arrayWheelItemDatas.push_back( new MusicWheelItemData(WheelItemDataType_Portal, nullptr, "", nullptr, PORTAL_COLOR, 0) ); // add custom wheel items vector vsNames; split( CUSTOM_WHEEL_ITEM_NAMES, ",", vsNames ); for( unsigned i=0; i( new GameCommand ); wid.m_pAction->m_sName = vsNames[i]; wid.m_pAction->Load( i, ParseCommands(CUSTOM_CHOICES.GetValue(vsNames[i])) ); @@ -810,12 +809,12 @@ void MusicWheel::BuildWheelItemDatas( vector &arrayWheelIt } vector apCourses; - FOREACH_CONST( CourseType, vct, ct ) + for (CourseType const &ct : vct) { if( bOnlyPreferred ) - SONGMAN->GetPreferredSortCourses( *ct, apCourses, PREFSMAN->m_bAutogenGroupCourses ); + SONGMAN->GetPreferredSortCourses( ct, apCourses, PREFSMAN->m_bAutogenGroupCourses ); else - SONGMAN->GetCourses( *ct, apCourses, PREFSMAN->m_bAutogenGroupCourses ); + SONGMAN->GetCourses( ct, apCourses, PREFSMAN->m_bAutogenGroupCourses ); } switch( PREFSMAN->m_CourseSortOrder ) @@ -876,12 +875,12 @@ void MusicWheel::BuildWheelItemDatas( vector &arrayWheelIt { RageColor c = SECTION_COLORS.GetValue(iSectionColorIndex); iSectionColorIndex = (iSectionColorIndex+1) % NUM_SECTION_COLORS; - arrayWheelItemDatas.push_back( new MusicWheelItemData(WheelItemDataType_Section, NULL, sThisSection, NULL, c, 0) ); + arrayWheelItemDatas.push_back( new MusicWheelItemData(WheelItemDataType_Section, nullptr, sThisSection, nullptr, c, 0) ); sLastSection = sThisSection; } RageColor c = ( pCourse->m_sGroupName.size() == 0 ) ? pCourse->GetColor() : SONGMAN->GetCourseColor(pCourse); - arrayWheelItemDatas.push_back( new MusicWheelItemData(WheelItemDataType_Course, NULL, sThisSection, pCourse, c, 0) ); + arrayWheelItemDatas.push_back( new MusicWheelItemData(WheelItemDataType_Course, nullptr, sThisSection, pCourse, c, 0) ); } break; } @@ -890,24 +889,23 @@ void MusicWheel::BuildWheelItemDatas( vector &arrayWheelIt } // init music status icons - for( unsigned i=0; im_pSong != nullptr ) { - WID.m_Flags.bHasBeginnerOr1Meter = WID.m_pSong->IsEasy( GAMESTATE->GetCurrentStyle(PLAYER_INVALID)->m_StepsType ) && SHOW_EASY_FLAG; - WID.m_Flags.bEdits = false; + WID->m_Flags.bHasBeginnerOr1Meter = WID->m_pSong->IsEasy( GAMESTATE->GetCurrentStyle(PLAYER_INVALID)->m_StepsType ) && SHOW_EASY_FLAG; + WID->m_Flags.bEdits = false; set vStepsType; - SongUtil::GetPlayableStepsTypes( WID.m_pSong, vStepsType ); - FOREACHS( StepsType, vStepsType, st ) - WID.m_Flags.bEdits |= WID.m_pSong->HasEdits( *st ); - WID.m_Flags.iStagesForSong = GameState::GetNumStagesMultiplierForSong( WID.m_pSong ); + SongUtil::GetPlayableStepsTypes( WID->m_pSong, vStepsType ); + for (StepsType const &type : vStepsType) + WID->m_Flags.bEdits |= WID->m_pSong->HasEdits( type ); + WID->m_Flags.iStagesForSong = GameState::GetNumStagesMultiplierForSong( WID->m_pSong ); } - else if( WID.m_pCourse != NULL ) + else if( WID->m_pCourse != nullptr ) { - WID.m_Flags.bHasBeginnerOr1Meter = false; - WID.m_Flags.bEdits = WID.m_pCourse->IsAnEdit(); - WID.m_Flags.iStagesForSong = 1; + WID->m_Flags.bHasBeginnerOr1Meter = false; + WID->m_Flags.bEdits = WID->m_pCourse->IsAnEdit(); + WID->m_Flags.iStagesForSong = 1; } } } @@ -955,7 +953,7 @@ void MusicWheel::FilterWheelItemDatas(vector &aUnFilteredD const int iMaxStagesForSong = GAMESTATE->GetSmallestNumStagesLeftForAnyHumanPlayer(); - Song *pExtraStageSong = NULL; + Song *pExtraStageSong = nullptr; if( GAMESTATE->IsAnExtraStage() ) { Steps *pSteps; @@ -1096,7 +1094,7 @@ void MusicWheel::FilterWheelItemDatas(vector &aUnFilteredD // If we've filtered all items, insert a dummy. if( aFilteredData.empty() ) - aFilteredData.push_back( new MusicWheelItemData(WheelItemDataType_Section, NULL, EMPTY_STRING, NULL, EMPTY_COLOR, 0) ); + aFilteredData.push_back( new MusicWheelItemData(WheelItemDataType_Section, nullptr, EMPTY_STRING, nullptr, EMPTY_COLOR, 0) ); } void MusicWheel::UpdateSwitch() @@ -1391,7 +1389,7 @@ void MusicWheel::SetOpenSection( RString group ) if ( REMIND_WHEEL_POSITIONS && HIDE_INACTIVE_SECTIONS ) m_viWheelPositions.resize( SONGMAN->GetNumSongGroups() ); - const WheelItemBaseData *old = NULL; + const WheelItemBaseData *old = nullptr; if( !m_CurWheelItemData.empty() ) old = GetCurWheelItemData(m_iSelection); @@ -1658,14 +1656,9 @@ Song *MusicWheel::GetPreferredSelectionForRandomOrPortal() if( i < 900 && pSong->IsTutorial() ) continue; - FOREACH( Difficulty, vDifficultiesToRequire, d ) - { - if( !pSong->HasStepsTypeAndDifficulty(st,*d) ) - { - isValid = false; - break; - } - } + isValid = std::none_of(vDifficultiesToRequire.begin(), vDifficultiesToRequire.end(), [&](Difficulty const &d) { + return !pSong->HasStepsTypeAndDifficulty(st, d); + }); if (isValid) { diff --git a/src/MusicWheelItem.cpp b/src/MusicWheelItem.cpp index 355e98ca98..fa75be1568 100644 --- a/src/MusicWheelItem.cpp +++ b/src/MusicWheelItem.cpp @@ -75,7 +75,7 @@ MusicWheelItem::MusicWheelItem( RString sType ): FOREACH_ENUM( MusicWheelItemType, i ) { - m_pText[i] = NULL; + m_pText[i] = nullptr; // Don't init text for Type_Song. It uses a TextBanner. if( i == MusicWheelItemType_Song ) @@ -145,9 +145,9 @@ MusicWheelItem::MusicWheelItem( const MusicWheelItem &cpy ): FOREACH_ENUM( MusicWheelItemType, i ) { - if( cpy.m_pText[i] == NULL ) + if( cpy.m_pText[i] == nullptr ) { - m_pText[i] = NULL; + m_pText[i] = nullptr; } else { @@ -308,13 +308,13 @@ void MusicWheelItem::RefreshGrades() if(!IsLoaded()) { return; } const MusicWheelItemData *pWID = dynamic_cast( m_pData ); - if( pWID == NULL ) + if( pWID == nullptr ) return; // LoadFromWheelItemData() hasn't been called yet. FOREACH_HumanPlayer( p ) { m_pGradeDisplay[p]->SetVisible( false ); - if( pWID->m_pSong == NULL && pWID->m_pCourse == NULL ) + if( pWID->m_pSong == nullptr && pWID->m_pCourse == nullptr ) continue; Difficulty dc; @@ -346,19 +346,19 @@ void MusicWheelItem::RefreshGrades() Profile *pProfile = PROFILEMAN->GetProfile(ps); - HighScoreList *pHSL = NULL; + HighScoreList *pHSL = nullptr; if( PROFILEMAN->IsPersistentProfile(ps) && dc != Difficulty_Invalid ) { if( pWID->m_pSong ) { const Steps* pSteps = SongUtil::GetStepsByDifficulty( pWID->m_pSong, st, dc ); - if( pSteps != NULL ) + if( pSteps != nullptr ) pHSL = &pProfile->GetStepsHighScoreList(pWID->m_pSong, pSteps); } else if( pWID->m_pCourse ) { const Trail *pTrail = pWID->m_pCourse->GetTrail( st, dc ); - if( pTrail != NULL ) + if( pTrail != nullptr ) pHSL = &pProfile->GetCourseHighScoreList( pWID->m_pCourse, pTrail ); } } diff --git a/src/MusicWheelItem.h b/src/MusicWheelItem.h index 6155e24d70..bfc94a3abf 100644 --- a/src/MusicWheelItem.h +++ b/src/MusicWheelItem.h @@ -1,110 +1,110 @@ -#ifndef MUSIC_WHEEL_ITEM_H -#define MUSIC_WHEEL_ITEM_H - -#include "ActorFrame.h" -#include "BitmapText.h" -#include "WheelNotifyIcon.h" -#include "TextBanner.h" -#include "GameConstantsAndTypes.h" -#include "GameCommand.h" -#include "WheelItemBase.h" -#include "AutoActor.h" -#include "ThemeMetric.h" - -class Course; -class Song; - -struct MusicWheelItemData; - -enum MusicWheelItemType -{ - MusicWheelItemType_Song, - MusicWheelItemType_SectionExpanded, - MusicWheelItemType_SectionCollapsed, - MusicWheelItemType_Roulette, - MusicWheelItemType_Course, - MusicWheelItemType_Sort, - MusicWheelItemType_Mode, - MusicWheelItemType_Random, - MusicWheelItemType_Portal, - MusicWheelItemType_Custom, - NUM_MusicWheelItemType, - MusicWheelItemType_Invalid, -}; -const RString& MusicWheelItemTypeToString( MusicWheelItemType i ); -/** @brief An item on the MusicWheel. */ -class MusicWheelItem : public WheelItemBase -{ -public: - MusicWheelItem(RString sType = "MusicWheelItem"); - MusicWheelItem( const MusicWheelItem &cpy ); - virtual ~MusicWheelItem(); - virtual MusicWheelItem *Copy() const { return new MusicWheelItem(*this); } - - virtual void LoadFromWheelItemData( const WheelItemBaseData* pWID, int iIndex, bool bHasFocus, int iDrawIndex ); - virtual void HandleMessage( const Message &msg ); - void RefreshGrades(); - -private: - ThemeMetric GRADES_SHOW_MACHINE; - - AutoActor m_sprColorPart[NUM_MusicWheelItemType]; - AutoActor m_sprNormalPart[NUM_MusicWheelItemType]; - AutoActor m_sprOverPart[NUM_MusicWheelItemType]; - - TextBanner m_TextBanner; // used by Type_Song instead of m_pText - BitmapText *m_pText[NUM_MusicWheelItemType]; - BitmapText *m_pTextSectionCount; - - WheelNotifyIcon m_WheelNotifyIcon; - AutoActor m_pGradeDisplay[NUM_PLAYERS]; -}; - -struct MusicWheelItemData : public WheelItemBaseData -{ - MusicWheelItemData() : m_pCourse(NULL), m_pSong(NULL), m_Flags(), - m_iSectionCount(0), m_sLabel(""), m_pAction() { } - MusicWheelItemData( WheelItemDataType type, Song* pSong, - RString sSectionName, Course* pCourse, - RageColor color, int iSectionCount ); - - Course* m_pCourse; - Song* m_pSong; - WheelNotifyIcon::Flags m_Flags; - - // for TYPE_SECTION - int m_iSectionCount; - - // for TYPE_SORT - RString m_sLabel; - HiddenPtr m_pAction; -}; - -#endif - -/** - * @file - * @author Chris Danford, Chris Gomez, Glenn Maynard (c) 2001-2004 - * @section LICENSE - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#ifndef MUSIC_WHEEL_ITEM_H +#define MUSIC_WHEEL_ITEM_H + +#include "ActorFrame.h" +#include "BitmapText.h" +#include "WheelNotifyIcon.h" +#include "TextBanner.h" +#include "GameConstantsAndTypes.h" +#include "GameCommand.h" +#include "WheelItemBase.h" +#include "AutoActor.h" +#include "ThemeMetric.h" + +class Course; +class Song; + +struct MusicWheelItemData; + +enum MusicWheelItemType +{ + MusicWheelItemType_Song, + MusicWheelItemType_SectionExpanded, + MusicWheelItemType_SectionCollapsed, + MusicWheelItemType_Roulette, + MusicWheelItemType_Course, + MusicWheelItemType_Sort, + MusicWheelItemType_Mode, + MusicWheelItemType_Random, + MusicWheelItemType_Portal, + MusicWheelItemType_Custom, + NUM_MusicWheelItemType, + MusicWheelItemType_Invalid, +}; +const RString& MusicWheelItemTypeToString( MusicWheelItemType i ); +/** @brief An item on the MusicWheel. */ +class MusicWheelItem : public WheelItemBase +{ +public: + MusicWheelItem(RString sType = "MusicWheelItem"); + MusicWheelItem( const MusicWheelItem &cpy ); + virtual ~MusicWheelItem(); + virtual MusicWheelItem *Copy() const { return new MusicWheelItem(*this); } + + virtual void LoadFromWheelItemData( const WheelItemBaseData* pWID, int iIndex, bool bHasFocus, int iDrawIndex ); + virtual void HandleMessage( const Message &msg ); + void RefreshGrades(); + +private: + ThemeMetric GRADES_SHOW_MACHINE; + + AutoActor m_sprColorPart[NUM_MusicWheelItemType]; + AutoActor m_sprNormalPart[NUM_MusicWheelItemType]; + AutoActor m_sprOverPart[NUM_MusicWheelItemType]; + + TextBanner m_TextBanner; // used by Type_Song instead of m_pText + BitmapText *m_pText[NUM_MusicWheelItemType]; + BitmapText *m_pTextSectionCount; + + WheelNotifyIcon m_WheelNotifyIcon; + AutoActor m_pGradeDisplay[NUM_PLAYERS]; +}; + +struct MusicWheelItemData : public WheelItemBaseData +{ + MusicWheelItemData() : m_pCourse(nullptr), m_pSong(nullptr), m_Flags(), + m_iSectionCount(0), m_sLabel(""), m_pAction() { } + MusicWheelItemData( WheelItemDataType type, Song* pSong, + RString sSectionName, Course* pCourse, + RageColor color, int iSectionCount ); + + Course* m_pCourse; + Song* m_pSong; + WheelNotifyIcon::Flags m_Flags; + + // for TYPE_SECTION + int m_iSectionCount; + + // for TYPE_SORT + RString m_sLabel; + HiddenPtr m_pAction; +}; + +#endif + +/** + * @file + * @author Chris Danford, Chris Gomez, Glenn Maynard (c) 2001-2004 + * @section LICENSE + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/NetworkSyncManager.cpp b/src/NetworkSyncManager.cpp index 34dd2d6742..a8aeed3407 100644 --- a/src/NetworkSyncManager.cpp +++ b/src/NetworkSyncManager.cpp @@ -67,8 +67,8 @@ int NetworkSyncManager::GetSMOnlineSalt() static LocalizedString INITIALIZING_CLIENT_NETWORK ( "NetworkSyncManager", "Initializing Client Network..." ); NetworkSyncManager::NetworkSyncManager( LoadingWindow *ld ) { - LANserver = NULL; //So we know if it has been created yet - BroadcastReception = NULL; + LANserver = nullptr; //So we know if it has been created yet + BroadcastReception = nullptr; ld->SetText( INITIALIZING_CLIENT_NETWORK ); NetPlayerClient = new EzSockets; @@ -384,11 +384,11 @@ void NetworkSyncManager::StartRequest( short position ) Steps * tSteps; tSteps = GAMESTATE->m_pCurSteps[PLAYER_1]; - if( tSteps!=NULL && GAMESTATE->IsPlayerEnabled(PLAYER_1) ) + if( tSteps!= nullptr && GAMESTATE->IsPlayerEnabled(PLAYER_1) ) ctr = uint8_t(ctr+tSteps->GetMeter()*16); tSteps = GAMESTATE->m_pCurSteps[PLAYER_2]; - if( tSteps!=NULL && GAMESTATE->IsPlayerEnabled(PLAYER_2) ) + if( tSteps!= nullptr && GAMESTATE->IsPlayerEnabled(PLAYER_2) ) ctr = uint8_t( ctr+tSteps->GetMeter() ); m_packet.Write1( ctr ); @@ -396,11 +396,11 @@ void NetworkSyncManager::StartRequest( short position ) ctr=0; tSteps = GAMESTATE->m_pCurSteps[PLAYER_1]; - if( tSteps!=NULL && GAMESTATE->IsPlayerEnabled(PLAYER_1) ) + if( tSteps!= nullptr && GAMESTATE->IsPlayerEnabled(PLAYER_1) ) ctr = uint8_t( ctr + (int)tSteps->GetDifficulty()*16 ); tSteps = GAMESTATE->m_pCurSteps[PLAYER_2]; - if( tSteps!=NULL && GAMESTATE->IsPlayerEnabled(PLAYER_2) ) + if( tSteps!= nullptr && GAMESTATE->IsPlayerEnabled(PLAYER_2) ) ctr = uint8_t( ctr + (int)tSteps->GetDifficulty() ); m_packet.Write1( ctr ); @@ -409,7 +409,7 @@ void NetworkSyncManager::StartRequest( short position ) ctr = char( position*16 ); m_packet.Write1( ctr ); - if( GAMESTATE->m_pCurSong != NULL ) + if( GAMESTATE->m_pCurSong != nullptr ) { m_packet.WriteNT( GAMESTATE->m_pCurSong->m_sMainTitle ); m_packet.WriteNT( GAMESTATE->m_pCurSong->m_sSubTitle ); @@ -422,7 +422,7 @@ void NetworkSyncManager::StartRequest( short position ) m_packet.WriteNT( "" ); } - if( GAMESTATE->m_pCurCourse != NULL ) + if( GAMESTATE->m_pCurCourse != nullptr ) m_packet.WriteNT( GAMESTATE->m_pCurCourse->GetDisplayFullTitle() ); else m_packet.WriteNT( RString() ); @@ -437,12 +437,12 @@ void NetworkSyncManager::StartRequest( short position ) m_packet.WriteNT( GAMESTATE->m_pPlayerState[p]->m_PlayerOptions.GetCurrent().GetString() ); } for (int i=0; i<2-players; ++i) - m_packet.WriteNT(""); //Write a NULL if no player + m_packet.WriteNT(""); //Write a nullptr if no player //Send song hash/chartkey if (m_ServerVersion >= 129) { tSteps = GAMESTATE->m_pCurSteps[PLAYER_1]; - if (tSteps != NULL && GAMESTATE->IsPlayerEnabled(PLAYER_1)) { + if (tSteps != nullptr && GAMESTATE->IsPlayerEnabled(PLAYER_1)) { m_packet.WriteNT(tSteps->GetChartKey()); } else @@ -451,7 +451,7 @@ void NetworkSyncManager::StartRequest( short position ) } tSteps = GAMESTATE->m_pCurSteps[PLAYER_2]; - if (tSteps != NULL && GAMESTATE->IsPlayerEnabled(PLAYER_2)) { + if (tSteps != nullptr && GAMESTATE->IsPlayerEnabled(PLAYER_2)) { m_packet.WriteNT(tSteps->GetChartKey()); } else @@ -998,7 +998,7 @@ unsigned long NetworkSyncManager::GetCurrentSMBuild( LoadingWindow* ld ) { // \r\n\r\n = Separator from HTTP Header and Body char* cBodyStart = strstr(cBuffer, "\r\n\r\n"); - if( cBodyStart != NULL ) + if( cBodyStart != nullptr ) { // Get the HTTP Header only int iHeaderLength = cBodyStart - cBuffer; @@ -1032,13 +1032,13 @@ unsigned long NetworkSyncManager::GetCurrentSMBuild( LoadingWindow* ld ) if( 0 == strcasecmp(sFieldName,"X-SM-Build") ) { bSuccess = true; - uCurrentSMBuild = strtoul( sFieldValue, NULL, 10 ); + uCurrentSMBuild = strtoul( sFieldValue, nullptr, 10 ); break; } } } } // if( svResponse[0].find("200") != RString::npos ) - } // if( cBodyStart != NULL ) + } // if( cBodyStart != nullptr ) } // if( iBytes ) SAFE_DELETE( cBuffer ); } // if( socket->connect(sHost, uPort) ) diff --git a/src/NetworkSyncManager.h b/src/NetworkSyncManager.h index b493c11187..1563b744a5 100644 --- a/src/NetworkSyncManager.h +++ b/src/NetworkSyncManager.h @@ -111,7 +111,7 @@ public: class NetworkSyncManager { public: - NetworkSyncManager( LoadingWindow *ld = NULL ); + NetworkSyncManager( LoadingWindow *ld = nullptr ); ~NetworkSyncManager(); // If "useSMserver" then send score to server diff --git a/src/NoteData.cpp b/src/NoteData.cpp index 129c4c9623..ac363c7aa0 100644 --- a/src/NoteData.cpp +++ b/src/NoteData.cpp @@ -10,7 +10,6 @@ #include "RageLog.h" #include "XmlFile.h" #include "GameState.h" // blame radar calculations. -#include "Foreach.h" #include "RageUtil_AutoPtr.h" REGISTER_CLASS_TRAITS( NoteData, new NoteData(*pCopy) ) @@ -31,8 +30,8 @@ bool NoteData::IsComposite() const { for( int track = 0; track < GetNumTracks(); ++track ) { - FOREACHM_CONST( int, TapNote, m_TapNotes[track], tn ) - if( tn->second.pn != PLAYER_INVALID ) + for (std::pair const &tn : m_TapNotes[track]) + if( tn.second.pn != PLAYER_INVALID ) return true; } return false; @@ -351,13 +350,13 @@ void NoteData::AddHoldNote( int iTrack, int iStartRow, int iEndRow, TapNote tn ) } /* Determine if a hold note lies on the given spot. Return true if so. If - * pHeadRow is non-NULL, return the row of the head. */ + * pHeadRow is non-nullptr, return the row of the head. */ bool NoteData::IsHoldHeadOrBodyAtRow( int iTrack, int iRow, int *pHeadRow ) const { const TapNote &tn = GetTapNote( iTrack, iRow ); if( tn.type == TapNoteType_HoldHead ) { - if( pHeadRow != NULL ) + if( pHeadRow != nullptr ) *pHeadRow = iRow; return true; } @@ -366,13 +365,13 @@ bool NoteData::IsHoldHeadOrBodyAtRow( int iTrack, int iRow, int *pHeadRow ) cons } /* Determine if a hold note lies on the given spot. Return true if so. If - * pHeadRow is non-NULL, return the row of the head. (Note that this returns + * pHeadRow is non-nullptr, return the row of the head. (Note that this returns * false if a hold head lies on iRow itself.) */ /* XXX: rename this to IsHoldBodyAtRow */ bool NoteData::IsHoldNoteAtRow( int iTrack, int iRow, int *pHeadRow ) const { int iDummy; - if( pHeadRow == NULL ) + if( pHeadRow == nullptr ) pHeadRow = &iDummy; /* Starting at iRow, search upwards. If we find a TapNoteType_HoldHead, we're within @@ -1343,7 +1342,7 @@ NoteData::_all_tracks_iterator::_all_tracks_iterator( const _all_t template NoteData::_all_tracks_iterator::~_all_tracks_iterator() { - if(m_pNoteData != NULL) + if(m_pNoteData != nullptr) { m_pNoteData->RemoveATIFromList(this); } diff --git a/src/NoteData.h b/src/NoteData.h index 5f20270ef2..c08ae6e7f9 100644 --- a/src/NoteData.h +++ b/src/NoteData.h @@ -293,7 +293,7 @@ public: void GetTracksHeldAtRow( int row, set& addTo ); int GetNumTracksHeldAtRow( int row ); - bool IsHoldNoteAtRow( int iTrack, int iRow, int *pHeadRow = NULL ) const; + bool IsHoldNoteAtRow( int iTrack, int iRow, int *pHeadRow = nullptr ) const; bool IsHoldHeadOrBodyAtRow( int iTrack, int iRow, int *pHeadRow ) const; // statistics diff --git a/src/NoteDataUtil.cpp b/src/NoteDataUtil.cpp index ad7a607de4..330b3f0b58 100644 --- a/src/NoteDataUtil.cpp +++ b/src/NoteDataUtil.cpp @@ -8,7 +8,6 @@ #include "Style.h" #include "GameState.h" #include "RadarValues.h" -#include "Foreach.h" #include "TimingData.h" #include @@ -351,18 +350,19 @@ void NoteDataUtil::GetSMNoteDataString( const NoteData &in, RString &sRet ) SplitCompositeNoteData( in, parts ); - FOREACH( NoteData, parts, nd ) + for (NoteData &nd : parts) { - InsertHoldTails( *nd ); - fLastBeat = max( fLastBeat, nd->GetLastBeat() ); + InsertHoldTails( nd ); + fLastBeat = max( fLastBeat, nd.GetLastBeat() ); } int iLastMeasure = int( fLastBeat/BEATS_PER_MEASURE ); sRet = ""; - FOREACH( NoteData, parts, nd ) + int partNum = 0; + for (NoteData const &nd : parts) { - if( nd != parts.begin() ) + if( partNum++ != 0 ) sRet.append( "&\n" ); for( int m = 0; m <= iLastMeasure; ++m ) // foreach measure { @@ -370,7 +370,7 @@ void NoteDataUtil::GetSMNoteDataString( const NoteData &in, RString &sRet ) sRet.append( 1, ',' ); sRet += ssprintf(" // measure %d\n", m); - NoteType nt = GetSmallestNoteTypeForMeasure( *nd, m ); + NoteType nt = GetSmallestNoteTypeForMeasure( nd, m ); int iRowSpacing; if( nt == NoteType_Invalid ) iRowSpacing = 1; @@ -384,9 +384,9 @@ void NoteDataUtil::GetSMNoteDataString( const NoteData &in, RString &sRet ) for( int r=iMeasureStartRow; r<=iMeasureLastRow; r+=iRowSpacing ) { - for( int t = 0; t < nd->GetNumTracks(); ++t ) + for( int t = 0; t < nd.GetNumTracks(); ++t ) { - const TapNote &tn = nd->GetTapNote(t, r); + const TapNote &tn = nd.GetTapNote(t, r); char c; switch( tn.type ) { @@ -458,7 +458,7 @@ void NoteDataUtil::SplitCompositeNoteData( const NoteData &in, vector Hopefully this hack can be removed soon. -- Jason "Wolfman2000" Felds */ const Style *curStyle = GAMESTATE->GetCurrentStyle(PLAYER_INVALID); - if( (curStyle == NULL || curStyle->m_StyleType == StyleType_TwoPlayersSharedSides ) + if( (curStyle == nullptr || curStyle->m_StyleType == StyleType_TwoPlayersSharedSides ) && int( tn.pn ) > NUM_PlayerNumber ) { tn.pn = PLAYER_1; @@ -474,13 +474,13 @@ void NoteDataUtil::SplitCompositeNoteData( const NoteData &in, vector void NoteDataUtil::CombineCompositeNoteData( NoteData &out, const vector &in ) { - FOREACH_CONST( NoteData, in, nd ) + for (NoteData const &nd : in) { - const int iMaxTracks = min( out.GetNumTracks(), nd->GetNumTracks() ); + const int iMaxTracks = min( out.GetNumTracks(), nd.GetNumTracks() ); for( int track = 0; track < iMaxTracks; ++track ) { - for( NoteData::const_iterator i = nd->begin(track); i != nd->end(track); ++i ) + for( NoteData::const_iterator i = nd.begin(track); i != nd.end(track); ++i ) { int row = i->first; if( out.IsHoldNoteAtRow(track, i->first) ) @@ -1219,8 +1219,8 @@ void NoteDataUtil::RemoveSimultaneousNotes( NoteData &in, int iMaxSimultaneous, vector vParts; SplitCompositeNoteData( in, vParts ); - FOREACH( NoteData, vParts, nd ) - RemoveSimultaneousNotes( *nd, iMaxSimultaneous, iStartIndex, iEndIndex ); + for (NoteData &nd : vParts) + RemoveSimultaneousNotes( nd, iMaxSimultaneous, iStartIndex, iEndIndex ); in.Init(); in.SetNumTracks( vParts.front().GetNumTracks() ); CombineCompositeNoteData( in, vParts ); @@ -2720,14 +2720,14 @@ void NoteDataUtil::ConvertAdditionsToRegular( NoteData &inout ) void NoteDataUtil::TransformNoteData(NoteData &nd, TimingData const& timing_data, const AttackArray &aa, StepsType st, Song* pSong) { - FOREACH_CONST( Attack, aa, a ) + for (Attack const &a : aa) { PlayerOptions po; - po.FromString( a->sModifiers ); + po.FromString( a.sModifiers ); if( po.ContainsTransformOrTurn() ) { float fStartBeat, fEndBeat; - a->GetAttackBeats( pSong, fStartBeat, fEndBeat ); + a.GetAttackBeats( pSong, fStartBeat, fEndBeat ); NoteDataUtil::TransformNoteData(nd, timing_data, po, st, BeatToNoteRow(fStartBeat), BeatToNoteRow(fEndBeat) ); } diff --git a/src/NoteDisplay.cpp b/src/NoteDisplay.cpp index a4b3d17a60..1d8233c58b 100644 --- a/src/NoteDisplay.cpp +++ b/src/NoteDisplay.cpp @@ -14,7 +14,6 @@ #include "Sprite.h" #include "NoteTypes.h" #include "LuaBinding.h" -#include "Foreach.h" #include "RageMath.h" static const double PI_180= PI / 180.0; @@ -175,7 +174,7 @@ struct NoteResource NoteResource( const NoteSkinAndPath &nsap ): m_nsap(nsap) { m_iRefCount = 0; - m_pActor = NULL; + m_pActor = nullptr; } ~NoteResource() @@ -203,8 +202,8 @@ static NoteResource *MakeNoteResource( const RString &sButton, const RString &sE NOTESKIN->SetPlayerNumber( pn ); NOTESKIN->SetGameController( gc ); - pRes->m_pActor = NOTESKIN->LoadActor( sButton, sElement, NULL, bSpriteOnly ); - ASSERT( pRes->m_pActor != NULL ); + pRes->m_pActor = NOTESKIN->LoadActor( sButton, sElement, nullptr, bSpriteOnly ); + ASSERT( pRes->m_pActor != nullptr ); g_NoteResource[nsap] = pRes; it = g_NoteResource.find( nsap ); @@ -217,7 +216,7 @@ static NoteResource *MakeNoteResource( const RString &sButton, const RString &sE static void DeleteNoteResource( NoteResource *pRes ) { - ASSERT( pRes != NULL ); + ASSERT( pRes != nullptr ); ASSERT_M( pRes->m_iRefCount > 0, ssprintf("RefCount %i > 0", pRes->m_iRefCount) ); --pRes->m_iRefCount; @@ -232,7 +231,7 @@ static void DeleteNoteResource( NoteResource *pRes ) NoteColorActor::NoteColorActor() { - m_p = NULL; + m_p = nullptr; } NoteColorActor::~NoteColorActor() @@ -256,7 +255,7 @@ Actor *NoteColorActor::Get() NoteColorSprite::NoteColorSprite() { - m_p = NULL; + m_p = nullptr; } NoteColorSprite::~NoteColorSprite() @@ -1018,11 +1017,12 @@ void NoteDisplay::DrawHoldPart(vector &vpSpr, * start off the strip again. */ if(!bAllAreTransparent) { - FOREACH(Sprite*, vpSpr, spr) + int i = 0; + for (Sprite *spr : vpSpr) { - RageTexture* pTexture = (*spr)->GetTexture(); + RageTexture* pTexture = spr->GetTexture(); DISPLAY->SetTexture(TextureUnit_1, pTexture->GetTexHandle()); - DISPLAY->SetBlendMode(spr == vpSpr.begin() ? BLEND_NORMAL : BLEND_ADD); + DISPLAY->SetBlendMode((i++ == 0) ? BLEND_NORMAL : BLEND_ADD); DISPLAY->SetCullMode(CULL_NONE); DISPLAY->SetTextureWrapping(TextureUnit_1, part_args.wrapping); queue.Draw(); @@ -1367,7 +1367,7 @@ void NoteDisplay::DrawTap(const TapNote& tn, bool bOnSameRowAsHoldStart, bool bOnSameRowAsRollStart, bool bIsAddition, float fPercentFadeToFail) { - Actor* pActor = NULL; + Actor* pActor = nullptr; NotePart part = NotePart_Tap; /* if( tn.source == TapNoteSource_Addition ) diff --git a/src/NoteField.cpp b/src/NoteField.cpp index becf648081..d05c3ec49b 100644 --- a/src/NoteField.cpp +++ b/src/NoteField.cpp @@ -38,8 +38,8 @@ static ThemeMetric1D ROUTINE_NOTESKIN( "NoteField", RoutineNoteSkinName NoteField::NoteField() { - m_pNoteData = NULL; - m_pCurDisplay = NULL; + m_pNoteData = nullptr; + m_pCurDisplay = nullptr; m_drawing_board_primitive= false; m_textMeasureNumber.LoadFromFont( THEME->GetPathF("NoteField","MeasureNumber") ); @@ -87,7 +87,7 @@ void NoteField::Unload() it != m_NoteDisplays.end(); ++it ) delete it->second; m_NoteDisplays.clear(); - m_pCurDisplay = NULL; + m_pCurDisplay = nullptr; memset( m_pDisplays, 0, sizeof(m_pDisplays) ); } @@ -137,10 +137,10 @@ void NoteField::CacheAllUsedNoteSkins() vector asSkinsLower; GAMESTATE->GetAllUsedNoteSkins( asSkinsLower ); asSkinsLower.push_back( m_pPlayerState->m_PlayerOptions.GetStage().m_sNoteSkin ); - FOREACH( RString, asSkinsLower, s ) + for (RString &s : asSkinsLower) { - NOTESKIN->ValidateNoteSkinName(*s); - s->MakeLower(); + NOTESKIN->ValidateNoteSkinName(s); + s.MakeLower(); } for( unsigned i=0; i < asSkinsLower.size(); ++i ) @@ -149,14 +149,14 @@ void NoteField::CacheAllUsedNoteSkins() /* If we're changing note skins in the editor, we can have old note skins lying * around. Remove them so they don't accumulate. */ set setNoteSkinsToUnload; - FOREACHM( RString, NoteDisplayCols *, m_NoteDisplays, d ) + for (std::pair d : m_NoteDisplays) { - bool unused = find(asSkinsLower.begin(), asSkinsLower.end(), d->first) == asSkinsLower.end(); + bool unused = find(asSkinsLower.begin(), asSkinsLower.end(), d.first) == asSkinsLower.end(); if( unused ) - setNoteSkinsToUnload.insert( d->first ); + setNoteSkinsToUnload.insert( d.first ); } - FOREACHS( RString, setNoteSkinsToUnload, s ) - UncacheNoteSkin( *s ); + for (RString const & skin : setNoteSkinsToUnload) + UncacheNoteSkin( skin ); RString sCurrentNoteSkinLower = m_pPlayerState->m_PlayerOptions.GetCurrent().m_sNoteSkin; NOTESKIN->ValidateNoteSkinName(sCurrentNoteSkinLower); @@ -208,7 +208,7 @@ void NoteField::Load( int iDrawDistanceAfterTargetsPixels, int iDrawDistanceBeforeTargetsPixels ) { - ASSERT( pNoteData != NULL ); + ASSERT( pNoteData != nullptr ); m_pNoteData = pNoteData; m_iDrawDistanceAfterTargetsPixels = iDrawDistanceAfterTargetsPixels; m_iDrawDistanceBeforeTargetsPixels = iDrawDistanceBeforeTargetsPixels; @@ -445,7 +445,7 @@ void NoteField::DrawBoard( int iDrawDistanceAfterTargetsPixels, int iDrawDistanc { // todo: make this an AutoActor instead? -aj Sprite *pSprite = dynamic_cast( (Actor*)m_sprBoard ); - if( pSprite == NULL ) + if( pSprite == nullptr ) { m_sprBoard->Draw(); } @@ -749,7 +749,7 @@ void NoteField::DrawPrimitives() //LOG->Trace( "NoteField::DrawPrimitives()" ); // This should be filled in on the first update. - ASSERT( m_pCurDisplay != NULL ); + ASSERT( m_pCurDisplay != nullptr ); // ArrowEffects::Update call moved because having it happen once per // NoteField (which means twice in two player) seemed wasteful. -Kyz @@ -796,7 +796,7 @@ void NoteField::DrawPrimitives() unsigned i = 0; // Draw beat bars - if( ( GAMESTATE->IsEditing() || SHOW_BEAT_BARS ) && pTiming != NULL ) + if( ( GAMESTATE->IsEditing() || SHOW_BEAT_BARS ) && pTiming != nullptr ) { const vector &tSigs = *segs[SEGMENT_TIME_SIG]; int iMeasureIndex = 0; @@ -836,9 +836,9 @@ void NoteField::DrawPrimitives() } } - if( GAMESTATE->IsEditing() && pTiming != NULL ) + if( GAMESTATE->IsEditing() && pTiming != nullptr ) { - ASSERT(GAMESTATE->m_pCurSong != NULL); + ASSERT(GAMESTATE->m_pCurSong != nullptr); const TimingData &timing = *pTiming; const RageColor text_glow= RageColor(1,1,1,RageFastCos(RageTimer::GetTimeSinceStartFast()*2)/2+0.5f); @@ -860,11 +860,11 @@ void NoteField::DrawPrimitives() } \ } - draw_all_segments(FloatToString(seg->GetRatio()), Scroll, SCROLL); - draw_all_segments(FloatToString(seg->GetBPM()), BPM, BPM); - draw_all_segments(FloatToString(seg->GetPause()), Stop, STOP); - draw_all_segments(FloatToString(seg->GetPause()), Delay, DELAY); - draw_all_segments(FloatToString(seg->GetLength()), Warp, WARP); + draw_all_segments(std::to_string(seg->GetRatio()), Scroll, SCROLL); + draw_all_segments(std::to_string(seg->GetBPM()), BPM, BPM); + draw_all_segments(std::to_string(seg->GetPause()), Stop, STOP); + draw_all_segments(std::to_string(seg->GetPause()), Delay, DELAY); + draw_all_segments(std::to_string(seg->GetLength()), Warp, WARP); draw_all_segments(ssprintf("%d\n--\n%d", seg->GetNum(), seg->GetDen()), TimeSignature, TIME_SIG); draw_all_segments(ssprintf("%d", seg->GetTicks()), Tickcount, TICKCOUNT); @@ -872,10 +872,10 @@ void NoteField::DrawPrimitives() ssprintf("%d/%d", seg->GetCombo(), seg->GetMissCombo()), Combo, COMBO); draw_all_segments(seg->GetLabel(), Label, LABEL); draw_all_segments(ssprintf("%s\n%s\n%s", - FloatToString(seg->GetRatio()).c_str(), + std::to_string(seg->GetRatio()).c_str(), (seg->GetUnit() == 1 ? "S" : "B"), - FloatToString(seg->GetDelay()).c_str()), Speed, SPEED); - draw_all_segments(FloatToString(seg->GetLength()), Fake, FAKE); + std::to_string(seg->GetDelay()).c_str()), Speed, SPEED); + draw_all_segments(std::to_string(seg->GetLength()), Fake, FAKE); #undef draw_all_segments // Course mods text @@ -885,16 +885,16 @@ void NoteField::DrawPrimitives() ASSERT_M( GAMESTATE->m_iEditCourseEntryIndex >= 0 && GAMESTATE->m_iEditCourseEntryIndex < (int)pCourse->m_vEntries.size(), ssprintf("%i",GAMESTATE->m_iEditCourseEntryIndex.Get()) ); const CourseEntry &ce = pCourse->m_vEntries[GAMESTATE->m_iEditCourseEntryIndex]; - FOREACH_CONST( Attack, ce.attacks, a ) + for (Attack const &a : ce.attacks) { - float fSecond = a->fStartSecond; + float fSecond = a.fStartSecond; float fBeat = timing.GetBeatFromElapsedTime( fSecond ); if( BeatToNoteRow(fBeat) >= m_FieldRenderArgs.first_row && BeatToNoteRow(fBeat) <= m_FieldRenderArgs.last_row && IS_ON_SCREEN(fBeat)) { - DrawAttackText(fBeat, *a, text_glow); + DrawAttackText(fBeat, a, text_glow); } } } @@ -906,14 +906,14 @@ void NoteField::DrawPrimitives() // XXX: We're somehow getting here when attacks is null. Find the actual cause later. if (&attacks) { - FOREACH_CONST(Attack, attacks, a) + for (Attack const &a : attacks) { - float fBeat = timing.GetBeatFromElapsedTime(a->fStartSecond); + float fBeat = timing.GetBeatFromElapsedTime(a.fStartSecond); if (BeatToNoteRow(fBeat) >= m_FieldRenderArgs.first_row && BeatToNoteRow(fBeat) <= m_FieldRenderArgs.last_row && IS_ON_SCREEN(fBeat)) { - this->DrawAttackText(fBeat, *a, text_glow); + this->DrawAttackText(fBeat, a, text_glow); } } } @@ -971,22 +971,22 @@ void NoteField::DrawPrimitives() if( IS_ON_SCREEN(fLowestBeat) ) { vector vsBGChanges; - FOREACH_CONST( BackgroundLayer, viLowestIndex, bl ) + for (BackgroundLayer const &bl : viLowestIndex) { - ASSERT( iter[*bl] != GAMESTATE->m_pCurSong->GetBackgroundChanges(*bl).end() ); - const BackgroundChange& change = *iter[*bl]; + ASSERT( iter[bl] != GAMESTATE->m_pCurSong->GetBackgroundChanges(bl).end() ); + const BackgroundChange& change = *iter[bl]; RString s = change.GetTextDescription(); - if( *bl!=0 ) + if( bl!=0 ) { - s = ssprintf("%d: ",*bl) + s; + s = ssprintf("%d: ",bl) + s; } vsBGChanges.push_back( s ); } DrawBGChangeText(fLowestBeat, join("\n",vsBGChanges), text_glow); } - FOREACH_CONST( BackgroundLayer, viLowestIndex, bl ) + for (BackgroundLayer const &bl : viLowestIndex) { - iter[*bl]++; + iter[bl]++; } } } diff --git a/src/NoteSkinManager.cpp b/src/NoteSkinManager.cpp index f1d14524d5..5f72784dc8 100644 --- a/src/NoteSkinManager.cpp +++ b/src/NoteSkinManager.cpp @@ -10,7 +10,6 @@ #include "RageDisplay.h" #include "arch/Dialog/Dialog.h" #include "PrefsManager.h" -#include "Foreach.h" #include "ActorUtil.h" #include "XmlFileUtil.h" #include "Sprite.h" @@ -18,7 +17,7 @@ #include "SpecialFiles.h" /** @brief Have the NoteSkinManager available throughout the program. */ -NoteSkinManager* NOTESKIN = NULL; // global and accessible from anywhere in our program +NoteSkinManager* NOTESKIN = nullptr; // global and accessible from anywhere in our program const RString GAME_COMMON_NOTESKIN_NAME = "common"; const RString GAME_BASE_NOTESKIN_NAME = "default"; @@ -47,7 +46,7 @@ namespace NoteSkinManager::NoteSkinManager() { - m_pCurGame = NULL; + m_pCurGame = nullptr; m_PlayerNumber = PlayerNumber_Invalid; m_GameController = GameController_Invalid; @@ -311,7 +310,7 @@ RString NoteSkinManager::GetMetric( const RString &sButtonName, const RString &s int NoteSkinManager::GetMetricI( const RString &sButtonName, const RString &sValueName ) { - return StringToInt( GetMetric(sButtonName,sValueName) ); + return std::stoi( GetMetric(sButtonName,sValueName) ); } float NoteSkinManager::GetMetricF( const RString &sButtonName, const RString &sValueName ) @@ -322,7 +321,7 @@ float NoteSkinManager::GetMetricF( const RString &sButtonName, const RString &sV bool NoteSkinManager::GetMetricB( const RString &sButtonName, const RString &sValueName ) { // Could also call GetMetricI here...hmm. - return StringToInt( GetMetric(sButtonName,sValueName) ) != 0; + return std::stoi( GetMetric(sButtonName,sValueName) ) != 0; } apActorCommands NoteSkinManager::GetMetricA( const RString &sButtonName, const RString &sValueName ) @@ -349,22 +348,22 @@ RString NoteSkinManager::GetPath( const RString &sButtonName, const RString &sEl const NoteSkinData &data = iter->second; RString sPath; // fill this in below - FOREACH_CONST( RString, data.vsDirSearchOrder, lIter ) + for (RString const &directory : data.vsDirSearchOrder) { if( sButtonName.empty() ) - sPath = GetPathFromDirAndFile( *lIter, sElement ); + sPath = GetPathFromDirAndFile( directory, sElement ); else - sPath = GetPathFromDirAndFile( *lIter, sButtonName+" "+sElement ); + sPath = GetPathFromDirAndFile( directory, sButtonName+" "+sElement ); if( !sPath.empty() ) break; // done searching } if( sPath.empty() ) { - FOREACH_CONST( RString, data.vsDirSearchOrder, lIter ) + for (RString const &directory : data.vsDirSearchOrder) { if( !sButtonName.empty() ) - sPath = GetPathFromDirAndFile( *lIter, "Fallback "+sElement ); + sPath = GetPathFromDirAndFile( directory, "Fallback "+sElement ); if( !sPath.empty() ) break; // done searching } @@ -373,12 +372,14 @@ RString NoteSkinManager::GetPath( const RString &sButtonName, const RString &sEl if( sPath.empty() ) { RString sPaths; - FOREACH_CONST( RString, data.vsDirSearchOrder, dir ) + + // TODO: Find a more elegant way of doing this. + for (RString const &dir : data.vsDirSearchOrder) { if( !sPaths.empty() ) sPaths += ", "; - sPaths += *dir; + sPaths += dir; } RString message = ssprintf( @@ -389,8 +390,8 @@ RString NoteSkinManager::GetPath( const RString &sButtonName, const RString &sEl switch(LuaHelpers::ReportScriptError(message, "NOTESKIN_ERROR", true)) { case Dialog::retry: - FOREACH_CONST(RString, data.vsDirSearchOrder, dir) - FILEMAN->FlushDirCache(*dir); + for (RString const &dir : data.vsDirSearchOrder) + FILEMAN->FlushDirCache(dir); g_PathCache.clear(); return GetPath(sButtonName, sElement); case Dialog::abort: @@ -416,9 +417,9 @@ RString NoteSkinManager::GetPath( const RString &sButtonName, const RString &sEl GetFileContents( sPath, sNewFileName, true ); RString sRealPath; - FOREACH_CONST( RString, data.vsDirSearchOrder, lIter ) + for (RString const &directory : data.vsDirSearchOrder) { - sRealPath = GetPathFromDirAndFile( *lIter, sNewFileName ); + sRealPath = GetPathFromDirAndFile( directory, sNewFileName ); if( !sRealPath.empty() ) break; // done searching } @@ -433,8 +434,8 @@ RString NoteSkinManager::GetPath( const RString &sButtonName, const RString &sEl switch(LuaHelpers::ReportScriptError(message, "NOTESKIN_ERROR", true)) { case Dialog::retry: - FOREACH_CONST(RString, data.vsDirSearchOrder, dir) - FILEMAN->FlushDirCache(*dir); + for (RString const &dir : data.vsDirSearchOrder) + FILEMAN->FlushDirCache(dir); g_PathCache.clear(); return GetPath(sButtonName, sElement); case Dialog::abort: @@ -492,8 +493,8 @@ Actor *NoteSkinManager::LoadActor( const RString &sButton, const RString &sEleme return Sprite::NewBlankSprite(); } - auto_ptr pNode( XmlFileUtil::XNodeFromTable(L) ); - if( pNode.get() == NULL ) + unique_ptr pNode( XmlFileUtil::XNodeFromTable(L) ); + if( pNode.get() == nullptr ) { LUA->Release( L ); // XNode will warn about the error @@ -508,7 +509,7 @@ Actor *NoteSkinManager::LoadActor( const RString &sButton, const RString &sEleme { // Make sure pActor is a Sprite (or something derived from Sprite). Sprite *pSprite = dynamic_cast( pRet ); - if( pSprite == NULL ) + if( pSprite == nullptr ) { LuaHelpers::ReportScriptErrorFmt("%s: %s %s must be a Sprite", m_sCurrentNoteSkin.c_str(), sButton.c_str(), sElement.c_str()); delete pRet; diff --git a/src/NoteSkinManager.h b/src/NoteSkinManager.h index 0bcd96eb43..f870c9746e 100644 --- a/src/NoteSkinManager.h +++ b/src/NoteSkinManager.h @@ -33,7 +33,7 @@ public: void SetGameController( GameController gc ) { m_GameController = gc; } RString GetPath( const RString &sButtonName, const RString &sElement ); bool PushActorTemplate( Lua *L, const RString &sButton, const RString &sElement, bool bSpriteOnly ); - Actor *LoadActor( const RString &sButton, const RString &sElement, Actor *pParent = NULL, bool bSpriteOnly = false ); + Actor *LoadActor( const RString &sButton, const RString &sElement, Actor *pParent = nullptr, bool bSpriteOnly = false ); RString GetMetric( const RString &sButtonName, const RString &sValue ); int GetMetricI( const RString &sButtonName, const RString &sValueName ); diff --git a/src/NotesLoaderBMS.cpp b/src/NotesLoaderBMS.cpp index b33e337c71..b74ec6a595 100644 --- a/src/NotesLoaderBMS.cpp +++ b/src/NotesLoaderBMS.cpp @@ -237,16 +237,16 @@ struct bmsCommandTree bmsNodeS() { - parent = NULL; + parent = nullptr; conditionValue = 0; conditionType = CT_NULL; } ~bmsNodeS() { - FOREACH(bmsNodeS*, branches, b) + for (bmsNodeS *b : branches) { - delete *b; + delete b; } } }; @@ -264,7 +264,7 @@ struct bmsCommandTree root.branchHeight = 0; root.conditionValue = 0; root.conditionTriggerValue = -1; - root.parent = NULL; + root.parent = nullptr; root.conditionType = bmsNodeS::CT_NULL; currentNode = &root; @@ -354,8 +354,8 @@ struct bmsCommandTree bool triggerBranches(bmsNodeS* node, BMSHeaders &headersOut, vector &linesOut) { - FOREACH(bmsNodeS*, node->branches, b) - if (evaluateNode(*b, headersOut, linesOut)) + for (bmsNodeS *b : node->branches) + if (evaluateNode(b, headersOut, linesOut)) { return true; } @@ -438,7 +438,7 @@ struct bmsCommandTree } else if (name == "#else") { - if (currentNode->parent != NULL) // Not the root node. + if (currentNode->parent != nullptr) // Not the root node. { if (currentNode->parent->conditionType == bmsNodeS::CT_CONDITIONALCHAIN) { @@ -452,7 +452,7 @@ struct bmsCommandTree } else if (name == "#elseif") { - if (currentNode->parent != NULL) // Not the root node. + if (currentNode->parent != nullptr) // Not the root node. { if (currentNode->parent->conditionType == bmsNodeS::CT_CONDITIONALCHAIN) { @@ -464,7 +464,7 @@ struct bmsCommandTree } else if (name == "#endif" || name == "#end") { - if (currentNode->parent != NULL) // not the root node + if (currentNode->parent != nullptr) // not the root node { currentNode = currentNode->parent; } @@ -483,7 +483,7 @@ struct bmsCommandTree while (randomStack.size() < currentNode->branchHeight + 1) // if we're on branch level N we need N+1 values. randomStack.push_back(0); - randomStack[currentNode->branchHeight] = rand() % StringToInt(value) + 1; + randomStack[currentNode->branchHeight] = rand() % std::stoi(value) + 1; } else { @@ -886,12 +886,12 @@ void BMSChartReader::ReadHeaders() } else if( it->first == "#playlevel" ) { - out->SetMeter( StringToInt(it->second) ); + out->SetMeter( std::stoi(it->second) ); } else if( it->first == "#difficulty") { // only set the difficulty if the #difficulty tag is between 1 and 6 (beginner~edit) - int diff = StringToInt(it->second)-1; // BMS uses 1 to 6, SM uses 0 to 5 + int diff = std::stoi(it->second)-1; // BMS uses 1 to 6, SM uses 0 to 5 if(diff>=0 && diffSetDifficulty( (Difficulty)diff ); } diff --git a/src/NotesLoaderDWI.cpp b/src/NotesLoaderDWI.cpp index ece1b5fe1f..b94ce49763 100644 --- a/src/NotesLoaderDWI.cpp +++ b/src/NotesLoaderDWI.cpp @@ -430,7 +430,7 @@ static bool LoadFromDWITokens( if( sNumFeet.empty() ) sNumFeet = "1"; - out.SetMeter(StringToInt(sNumFeet)); + out.SetMeter(std::stoi(sNumFeet)); out.SetDifficulty( DwiCompatibleStringToDifficulty(sDescription) ); @@ -508,7 +508,7 @@ bool DWILoader::LoadNoteDataFromSimfile( const RString &path, Steps &out ) continue; if (out.GetDifficulty() != DwiCompatibleStringToDifficulty(params[1])) continue; - if (out.GetMeter() != StringToInt(params[2])) + if (out.GetMeter() != std::stoi(params[2])) continue; RString step1 = params[3]; RString step2 = (iNumParams==5) ? params[4] : RString(""); @@ -626,7 +626,7 @@ bool DWILoader::LoadFromDir( const RString &sPath_, Song &out, set &Bla else if( sValueName.EqualsNoCase("GAP") ) // the units of GAP is 1/1000 second - out.m_SongTiming.m_fBeat0OffsetInSeconds = -StringToInt(sParams[1]) / 1000.0f; + out.m_SongTiming.m_fBeat0OffsetInSeconds = -std::stoi(sParams[1]) / 1000.0f; else if( sValueName.EqualsNoCase("SAMPLESTART") ) out.m_fMusicSampleStartSeconds = ParseBrokenDWITimestamp(sParams[1], sParams[2], sParams[3]); diff --git a/src/NotesLoaderJson.cpp b/src/NotesLoaderJson.cpp index 847e329856..18d2486bb8 100644 --- a/src/NotesLoaderJson.cpp +++ b/src/NotesLoaderJson.cpp @@ -219,8 +219,8 @@ static void Deserialize( Song &out, const Json::Value &root ) { vector vpSteps; JsonUtil::DeserializeVectorPointersParam( vpSteps, Deserialize, root["Charts"], &out ); - FOREACH( Steps*, vpSteps, iter ) - out.AddSteps( *iter ); + for (Steps *step : vpSteps) + out.AddSteps( step ); } } diff --git a/src/NotesLoaderKSF.cpp b/src/NotesLoaderKSF.cpp index 35a9d0d433..e75665a529 100644 --- a/src/NotesLoaderKSF.cpp +++ b/src/NotesLoaderKSF.cpp @@ -1,810 +1,810 @@ -#include "global.h" -#include "NotesLoaderKSF.h" -#include "RageUtil_CharConversions.h" -#include "MsdFile.h" -#include "RageLog.h" -#include "RageUtil.h" -#include "NoteData.h" -#include "NoteTypes.h" -#include "Song.h" -#include "Steps.h" - -static void HandleBunki( TimingData &timing, const float fEarlyBPM, - const float fCurBPM, const float fGap, - const float fPos ) -{ - const float BeatsPerSecond = fEarlyBPM / 60.0f; - const float beat = (fPos + fGap) * BeatsPerSecond; - LOG->Trace( "BPM %f, BPS %f, BPMPos %f, beat %f", - fEarlyBPM, BeatsPerSecond, fPos, beat ); - timing.AddSegment( BPMSegment(BeatToNoteRow(beat), fCurBPM) ); -} - -static bool LoadFromKSFFile( const RString &sPath, Steps &out, Song &song, bool bKIUCompliant ) -{ - LOG->Trace( "Steps::LoadFromKSFFile( '%s' )", sPath.c_str() ); - - MsdFile msd; - if( !msd.ReadFile( sPath, false ) ) // don't unescape - { - LOG->UserLog( "Song file", sPath, "couldn't be opened: %s", msd.GetError().c_str() ); - return false; - } - - // this is the value we read for TICKCOUNT - int iTickCount = -1; - // used to adapt weird tickcounts - //float fScrollRatio = 1.0f; -- uncomment when ready to use. - vector vNoteRows; - - // According to Aldo_MX, there is a default BPM and it's 60. -aj - bool bDoublesChart = false; - - TimingData stepsTiming; - float SMGap1 = 0, SMGap2 = 0, BPM1 = -1, BPMPos2 = -1, BPM2 = -1, BPMPos3 = -1, BPM3 = -1; - - for( unsigned i=0; iUserLog( "Song file", sPath, "has an invalid tick count: %d.", iTickCount ); - return false; - } - stepsTiming.AddSegment( TickcountSegment(0, iTickCount)); - } - - else if( sValueName=="DIFFICULTY" ) - { - out.SetMeter( max(StringToInt(sParams[1]), 1) ); - } - // new cases from Aldo_MX's fork: - else if( sValueName=="PLAYER" ) - { - RString sPlayer = sParams[1]; - sPlayer.MakeLower(); - if( sPlayer.find( "double" ) != string::npos ) - bDoublesChart = true; - } - // This should always be last. - else if( sValueName=="STEP" ) - { - RString theSteps = sParams[1]; - TrimLeft( theSteps ); - split( theSteps, "\n", vNoteRows, true ); - } - } - - if( iTickCount == -1 ) - { - iTickCount = 4; - LOG->UserLog( "Song file", sPath, "doesn't have a TICKCOUNT. Defaulting to %i.", iTickCount ); - } - - // Prepare BPM stuff already if the file uses KSF syntax. - if( bKIUCompliant ) - { - if( BPM2 > 0 && BPMPos2 > 0 ) - { - HandleBunki( stepsTiming, BPM1, BPM2, SMGap1, BPMPos2 ); - } - - if( BPM3 > 0 && BPMPos3 > 0 ) - { - HandleBunki( stepsTiming, BPM2, BPM3, SMGap2, BPMPos3 ); - } - } - - NoteData notedata; // read it into here - - { - RString sDir, sFName, sExt; - splitpath( sPath, sDir, sFName, sExt ); - sFName.MakeLower(); - - out.SetDescription(sFName); - // Check another before anything else... is this okay? -DaisuMaster - if( sFName.find("another") != string::npos ) - { - out.SetDifficulty( Difficulty_Edit ); - if( !out.GetMeter() ) out.SetMeter( 25 ); - } - else if(sFName.find("wild") != string::npos || - sFName.find("wd") != string::npos || - sFName.find("crazy+") != string::npos || - sFName.find("cz+") != string::npos || - sFName.find("hardcore") != string::npos ) - { - out.SetDifficulty( Difficulty_Challenge ); - if( !out.GetMeter() ) out.SetMeter( 20 ); - } - else if(sFName.find("crazy") != string::npos || - sFName.find("cz") != string::npos || - sFName.find("nightmare") != string::npos || - sFName.find("nm") != string::npos || - sFName.find("crazydouble") != string::npos ) - { - out.SetDifficulty( Difficulty_Hard ); - if( !out.GetMeter() ) out.SetMeter( 14 ); // Set the meters to the Pump scale, not DDR. - } - else if(sFName.find("hard") != string::npos || - sFName.find("hd") != string::npos || - sFName.find("freestyle") != string::npos || - sFName.find("fs") != string::npos || - sFName.find("double") != string::npos ) - { - out.SetDifficulty( Difficulty_Medium ); - if( !out.GetMeter() ) out.SetMeter( 8 ); - } - else if(sFName.find("easy") != string::npos || - sFName.find("ez") != string::npos || - sFName.find("normal") != string::npos ) - { - // I wonder if I should leave easy fall into the Beginner difficulty... -DaisuMaster - out.SetDifficulty( Difficulty_Easy ); - if( !out.GetMeter() ) out.SetMeter( 4 ); - } - else if(sFName.find("beginner") != string::npos || - sFName.find("practice") != string::npos || sFName.find("pr") != string::npos ) - { - out.SetDifficulty( Difficulty_Beginner ); - if( !out.GetMeter() ) out.SetMeter( 4 ); - } - else - { - out.SetDifficulty( Difficulty_Hard ); - if( !out.GetMeter() ) out.SetMeter( 10 ); - } - - out.m_StepsType = StepsType_pump_single; - - // Check for "halfdouble" before "double". - if(sFName.find("halfdouble") != string::npos || - sFName.find("half-double") != string::npos || - sFName.find("h_double") != string::npos || - sFName.find("hdb") != string::npos ) - out.m_StepsType = StepsType_pump_halfdouble; - // Handle bDoublesChart from above as well. -aj - else if(sFName.find("double") != string::npos || - sFName.find("nightmare") != string::npos || - sFName.find("freestyle") != string::npos || - sFName.find("db") != string::npos || - sFName.find("nm") != string::npos || - sFName.find("fs") != string::npos || bDoublesChart ) - out.m_StepsType = StepsType_pump_double; - else if( sFName.find("_1") != string::npos ) - out.m_StepsType = StepsType_pump_single; - else if( sFName.find("_2") != string::npos ) - out.m_StepsType = StepsType_pump_couple; - } - - switch( out.m_StepsType ) - { - case StepsType_pump_single: notedata.SetNumTracks( 5 ); break; - case StepsType_pump_couple: notedata.SetNumTracks( 10 ); break; - case StepsType_pump_double: notedata.SetNumTracks( 10 ); break; - case StepsType_pump_routine: notedata.SetNumTracks( 10 ); break; // future files may have this? - case StepsType_pump_halfdouble: notedata.SetNumTracks( 6 ); break; - default: FAIL_M( ssprintf("%i", out.m_StepsType) ); - } - - int t = 0; - int iHoldStartRow[13]; - for( t=0; t<13; t++ ) - iHoldStartRow[t] = -1; - - bool bTickChangeNeeded = false; - int newTick = -1; - float fCurBeat = 0.0f; - float prevBeat = 0.0f; // Used for hold tails. - - for( unsigned r=0; r song.GetSpecifiedLastSecond()) - //{ - // song.SetSpecifiedLastSecond(curTime); - //} - - song.SetSpecifiedLastSecond( song.GetSpecifiedLastSecond() + 4 ); - - break; - } - - else if( BeginsWith(sRowString, "|") ) - { - /* - if (bKIUCompliant) - { - // Log an error, ignore the line. - continue; - } - */ - // gotta do something tricky here: if the bpm is below one then a couple of calculations - // for scrollsegments will be made, example, bpm 0.2, tick 4000, the scrollsegment will - // be 0. if the tickcount is non a stepmania standard then it will be adapted, a scroll - // segment will then be added based on approximations. -DaisuMaster - // eh better do it considering the tickcount (high tickcounts) - - // I'm making some experiments, please spare me... - //continue; - - RString temp = sRowString.substr(2,sRowString.size()-3); - float numTemp = StringToFloat(temp); - if (BeginsWith(sRowString, "|T")) - { - // duh - iTickCount = static_cast(numTemp); - // I have been owned by the man -DaisuMaster - stepsTiming.SetTickcountAtBeat( fCurBeat, clamp(iTickCount, 0, ROWS_PER_BEAT) ); - } - else if (BeginsWith(sRowString, "|B")) - { - // BPM - stepsTiming.SetBPMAtBeat( fCurBeat, numTemp ); - } - else if (BeginsWith(sRowString, "|E")) - { - // DelayBeat - float fCurDelay = 60 / stepsTiming.GetBPMAtBeat(fCurBeat) * numTemp / iTickCount; - fCurDelay += stepsTiming.GetDelayAtRow(BeatToNoteRow(fCurBeat) ); - stepsTiming.SetDelayAtBeat( fCurBeat, fCurDelay ); - } - else if (BeginsWith(sRowString, "|D")) - { - // Delays - float fCurDelay = stepsTiming.GetStopAtRow(BeatToNoteRow(fCurBeat) ); - fCurDelay += numTemp / 1000; - stepsTiming.SetDelayAtBeat( fCurBeat, fCurDelay ); - } - else if (BeginsWith(sRowString, "|M") || BeginsWith(sRowString, "|C")) - { - // multipliers/combo - ComboSegment seg( BeatToNoteRow(fCurBeat), int(numTemp) ); - stepsTiming.AddSegment( seg ); - } - else if (BeginsWith(sRowString, "|S")) - { - // speed segments - } - else if (BeginsWith(sRowString, "|F")) - { - // fakes - } - else if (BeginsWith(sRowString, "|X")) - { - // scroll segments - ScrollSegment seg = ScrollSegment( BeatToNoteRow(fCurBeat), numTemp ); - stepsTiming.AddSegment( seg ); - //return true; - } - - continue; - } - - // Half-doubles is offset; "0011111100000". - if( out.m_StepsType == StepsType_pump_halfdouble ) - sRowString.erase( 0, 2 ); - - // Update TICKCOUNT for Direct Move files. - if( bTickChangeNeeded ) - { - iTickCount = newTick; - bTickChangeNeeded = false; - } - - for( t=0; t < notedata.GetNumTracks(); t++ ) - { - if( sRowString[t] == '4' ) - { - /* Remember when each hold starts; ignore the middle. */ - if( iHoldStartRow[t] == -1 ) - iHoldStartRow[t] = BeatToNoteRow(fCurBeat); - continue; - } - - if( iHoldStartRow[t] != -1 ) // this ends the hold - { - int iEndRow = BeatToNoteRow(prevBeat); - if( iHoldStartRow[t] == iEndRow ) - notedata.SetTapNote( t, iHoldStartRow[t], TAP_ORIGINAL_TAP ); - else - { - //notedata.AddHoldNote( t, iHoldStartRow[t], iEndRow , TAP_ORIGINAL_PUMP_HEAD ); - notedata.AddHoldNote( t, iHoldStartRow[t], iEndRow , TAP_ORIGINAL_HOLD_HEAD ); - } - iHoldStartRow[t] = -1; - } - - TapNote tap; - switch( sRowString[t] ) - { - case '0': tap = TAP_EMPTY; break; - case '1': tap = TAP_ORIGINAL_TAP; break; - //allow setting more notetypes on ksf files, this may come in handy (it should) -DaisuMaster - case 'M': - case 'm': - tap = TAP_ORIGINAL_MINE; - break; - case 'F': - case 'f': - tap = TAP_ORIGINAL_FAKE; - break; - case 'L': - case 'l': - tap = TAP_ORIGINAL_LIFT; - break; - default: - LOG->UserLog( "Song file", sPath, "has an invalid row \"%s\"; corrupt notes ignored.", - sRowString.c_str() ); - //return false; - tap = TAP_EMPTY; - break; - } - - notedata.SetTapNote(t, BeatToNoteRow(fCurBeat), tap); - } - prevBeat = fCurBeat; - fCurBeat = prevBeat + 1.0f / iTickCount; - } - - out.SetNoteData( notedata ); - out.m_Timing = stepsTiming; - - out.TidyUpData(); - - out.SetSavedToDisk( true ); // we're loading from disk, so this is by definintion already saved - - return true; -} - -static void LoadTags( const RString &str, Song &out ) -{ - /* str is either a #TITLE or a directory component. Fill in missing information. - * str is either "title", "artist - title", or "artist - title - difficulty". */ - vector asBits; - split( str, " - ", asBits, false ); - // Ignore the difficulty, since we get that elsewhere. - if( asBits.size() == 3 && ( - asBits[2].EqualsNoCase("double") || - asBits[2].EqualsNoCase("easy") || - asBits[2].EqualsNoCase("normal") || - asBits[2].EqualsNoCase("hard") || - asBits[2].EqualsNoCase("crazy") || - asBits[2].EqualsNoCase("nightmare")) - ) - { - asBits.erase( asBits.begin()+2, asBits.begin()+3 ); - } - - RString title, artist; - if( asBits.size() == 2 ) - { - artist = asBits[0]; - title = asBits[1]; - } - else if( asBits.size() == 1 ) - { - title = asBits[0]; - } - - // Convert, if possible. Most KSFs are in Korean encodings (CP942/EUC-KR). - if( !ConvertString( title, "korean" ) ) - title = ""; - if( !ConvertString( artist, "korean" ) ) - artist = ""; - - if( out.m_sMainTitle == "" ) - out.m_sMainTitle = title; - if( out.m_sArtist == "" ) - out.m_sArtist = artist; -} - -static void ProcessTickcounts( const RString & value, int & ticks, TimingData & timing ) -{ - /* TICKCOUNT will be used below if there are DM compliant BPM changes - * and stops. It will be called again in LoadFromKSFFile for the - * actual steps. */ - ticks = StringToInt( value ); - CLAMP( ticks, 0, ROWS_PER_BEAT ); - - if( ticks == 0 ) - ticks = TickcountSegment::DEFAULT_TICK_COUNT; - - timing.AddSegment( TickcountSegment(0, ticks) ); -} - -static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant ) -{ - MsdFile msd; - if( !msd.ReadFile( sPath, false ) ) // don't unescape - { - LOG->UserLog( "Song file", sPath, "couldn't be opened: %s", msd.GetError().c_str() ); - return false; - } - - // changed up there in case of something is found inside the SONGFILE tag in the head ksf -DaisuMaster - // search for music with song in the file name - vector arrayPossibleMusic; - GetDirListing( out.GetSongDir() + RString("song.mp3"), arrayPossibleMusic ); - GetDirListing( out.GetSongDir() + RString("song.oga"), arrayPossibleMusic ); - GetDirListing( out.GetSongDir() + RString("song.ogg"), arrayPossibleMusic ); - GetDirListing( out.GetSongDir() + RString("song.wav"), arrayPossibleMusic ); - - if( !arrayPossibleMusic.empty() ) // we found a match - out.m_sMusicFile = arrayPossibleMusic[0]; - // ^this was below, at the end - - float SMGap1 = 0, SMGap2 = 0, BPM1 = -1, BPMPos2 = -1, BPM2 = -1, BPMPos3 = -1, BPM3 = -1; - int iTickCount = -1; - bKIUCompliant = false; - vector vNoteRows; - - for( unsigned i=0; i < msd.GetNumValues(); i++ ) - { - const MsdFile::value_t &sParams = msd.GetValue(i); - RString sValueName = sParams[0]; - sValueName.MakeUpper(); - - // handle the data - if( sValueName=="TITLE" ) - LoadTags(sParams[1], out); - else if( sValueName=="BPM" ) - { - BPM1 = StringToFloat(sParams[1]); - out.m_SongTiming.AddSegment( BPMSegment(0, BPM1) ); - } - else if( sValueName=="BPM2" ) - { - bKIUCompliant = true; - BPM2 = StringToFloat( sParams[1] ); - } - else if( sValueName=="BPM3" ) - { - bKIUCompliant = true; - BPM3 = StringToFloat( sParams[1] ); - } - else if( sValueName=="BUNKI" ) - { - bKIUCompliant = true; - BPMPos2 = StringToFloat( sParams[1] ) / 100.0f; - } - else if( sValueName=="BUNKI2" ) - { - bKIUCompliant = true; - BPMPos3 = StringToFloat( sParams[1] ) / 100.0f; - } - else if( sValueName=="STARTTIME" ) - { - SMGap1 = -StringToFloat( sParams[1] )/100; - out.m_SongTiming.m_fBeat0OffsetInSeconds = SMGap1; - } - // This is currently required for more accurate KIU BPM changes. - else if( sValueName=="STARTTIME2" ) - { - bKIUCompliant = true; - SMGap2 = -StringToFloat( sParams[1] )/100; - } - else if ( sValueName=="STARTTIME3" ) - { - // STARTTIME3 only ensures this is a KIU compliant simfile. - //bKIUCompliant = true; - } - else if ( sValueName=="TICKCOUNT" ) - { - ProcessTickcounts(sParams[1], iTickCount, out.m_SongTiming); - } - else if ( sValueName=="STEP" ) - { - /* STEP will always be the last header in a KSF file by design. Due to - * the Direct Move syntax, it is best to get the rows of notes here. */ - RString theSteps = sParams[1]; - TrimLeft( theSteps ); - split( theSteps, "\n", vNoteRows, true ); - } - else if( sValueName=="DIFFICULTY" || sValueName=="PLAYER" ) - { - /* DIFFICULTY and PLAYER are handled only in LoadFromKSFFile. - Ignore those here. */ - continue; - } - // New cases noted in Aldo_MX's code: - else if( sValueName=="MUSICINTRO" || sValueName=="INTRO" ) - { - out.m_fMusicSampleStartSeconds = HHMMSSToSeconds( sParams[1] ); - } - else if( sValueName=="TITLEFILE" ) - { - out.m_sBackgroundFile = sParams[1]; - } - else if( sValueName=="DISCFILE" ) - { - out.m_sBannerFile = sParams[1]; - } - else if( sValueName=="SONGFILE" ) - { - out.m_sMusicFile = sParams[1]; - } - //else if( sValueName=="INTROFILE" ) - //{ - // nothing to add... - //} - // end new cases - else - { - LOG->UserLog( "Song file", sPath, "has an unexpected value named \"%s\".", - sValueName.c_str() ); - } - } - - //intro length in piu mixes is generally 7 seconds - out.m_fMusicSampleLengthSeconds = 7.0f; - - /* BPM Change checks are done here. If bKIUCompliant, it's short and sweet. - * Otherwise, the whole file has to be processed. Right now, this is only - * called once, for the initial file (often the Crazy steps). Hopefully that - * will end up changing soon. */ - if( bKIUCompliant ) - { - if( BPM2 > 0 && BPMPos2 > 0 ) - { - HandleBunki( out.m_SongTiming, BPM1, BPM2, SMGap1, BPMPos2 ); - } - - if( BPM3 > 0 && BPMPos3 > 0 ) - { - HandleBunki( out.m_SongTiming, BPM2, BPM3, SMGap2, BPMPos3 ); - } - } - else - { - float fCurBeat = 0.0f; - bool bDMRequired = false; - - for( unsigned i=0; i < vNoteRows.size(); ++i ) - { - RString& NoteRowString = vNoteRows[i]; - StripCrnl( NoteRowString ); - - if( NoteRowString == "" ) - continue; // ignore empty rows. - - if( NoteRowString == "2222222222222" ) // Row of 2s = end. Confirm KIUCompliency here. - { - if (!bDMRequired) - bKIUCompliant = true; - break; - } - - // This is where the DMRequired test will take place. - if ( BeginsWith( NoteRowString, "|" ) ) - { - // have a static timing for everything - bDMRequired = true; - continue; - } - else - { - // ignore whatever else... - //continue; - } - - fCurBeat += 1.0f / iTickCount; - } - } - - // Try to fill in missing bits of information from the pathname. - { - vector asBits; - split( sPath, "/", asBits, true); - - ASSERT( asBits.size() > 1 ); - LoadTags( asBits[asBits.size()-2], out ); - } - - return true; -} - -void KSFLoader::GetApplicableFiles( const RString &sPath, vector &out ) -{ - GetDirListing( sPath + RString("*.ksf"), out ); -} - -bool KSFLoader::LoadNoteDataFromSimfile( const RString & cachePath, Steps &out ) -{ - bool KIUCompliant = false; - Song dummy; - if (!LoadGlobalData(cachePath, dummy, KIUCompliant)) - return false; - Steps *notes = dummy.CreateSteps(); - if (LoadFromKSFFile(cachePath, *notes, dummy, KIUCompliant)) - { - KIUCompliant = true; // yeah, reusing a variable. - out.SetNoteData(notes->GetNoteData()); - } - delete notes; - return KIUCompliant; -} - -bool KSFLoader::LoadFromDir( const RString &sDir, Song &out ) -{ - LOG->Trace( "KSFLoader::LoadFromDir(%s)", sDir.c_str() ); - - vector arrayKSFFileNames; - GetDirListing( sDir + RString("*.ksf"), arrayKSFFileNames ); - - // We shouldn't have been called to begin with if there were no KSFs. - ASSERT( arrayKSFFileNames.size() != 0 ); - - bool bKIUCompliant = false; - /* With Split Timing, there has to be a backup Song Timing in case - * anything goes wrong. As these files are kept in alphabetical - * order (hopefully), it is best to use the LAST file for timing - * purposes, for that is the "normal", or easiest difficulty. - * Usually. */ - // Nevermind, kiu compilancy is screwing things up: - // IE, I have two simfiles, oh wich each have four ksf files, the first one has - // the first ksf with directmove timing changes, and the rest are not, everything - // goes fine. In the other hand I have my second simfile with the first ksf file - // without directmove timing changes and the rest have changes, changes are not - // loaded due to kiucompilancy in the first ksf file. - // About the "normal" thing, my simfiles' ksfs uses non-standard naming so - // the last chart is usually nightmare or normal, I use easy and normal - // indistinctly for SM so it shouldn't matter, I use piu fiesta/ex naming - // for directmove though, and we're just gathering basic info anyway, and - // most of the time all the KSF files have the same info in the #TITLE:; section - unsigned files = arrayKSFFileNames.size(); - RString dir = out.GetSongDir(); - if( !LoadGlobalData(dir + arrayKSFFileNames[files - 1], out, bKIUCompliant) ) - return false; - - out.m_sSongFileName = dir + arrayKSFFileNames[files - 1]; - // load the Steps from the rest of the KSF files - for( unsigned i=0; iSetFilename(dir + arrayKSFFileNames[i]); - out.AddSteps( pNewNotes ); - } - return true; -} - -/* - * (c) 2001-2006 Chris Danford, Glenn Maynard, Jason Felds - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "NotesLoaderKSF.h" +#include "RageUtil_CharConversions.h" +#include "MsdFile.h" +#include "RageLog.h" +#include "RageUtil.h" +#include "NoteData.h" +#include "NoteTypes.h" +#include "Song.h" +#include "Steps.h" + +static void HandleBunki( TimingData &timing, const float fEarlyBPM, + const float fCurBPM, const float fGap, + const float fPos ) +{ + const float BeatsPerSecond = fEarlyBPM / 60.0f; + const float beat = (fPos + fGap) * BeatsPerSecond; + LOG->Trace( "BPM %f, BPS %f, BPMPos %f, beat %f", + fEarlyBPM, BeatsPerSecond, fPos, beat ); + timing.AddSegment( BPMSegment(BeatToNoteRow(beat), fCurBPM) ); +} + +static bool LoadFromKSFFile( const RString &sPath, Steps &out, Song &song, bool bKIUCompliant ) +{ + LOG->Trace( "Steps::LoadFromKSFFile( '%s' )", sPath.c_str() ); + + MsdFile msd; + if( !msd.ReadFile( sPath, false ) ) // don't unescape + { + LOG->UserLog( "Song file", sPath, "couldn't be opened: %s", msd.GetError().c_str() ); + return false; + } + + // this is the value we read for TICKCOUNT + int iTickCount = -1; + // used to adapt weird tickcounts + //float fScrollRatio = 1.0f; -- uncomment when ready to use. + vector vNoteRows; + + // According to Aldo_MX, there is a default BPM and it's 60. -aj + bool bDoublesChart = false; + + TimingData stepsTiming; + float SMGap1 = 0, SMGap2 = 0, BPM1 = -1, BPMPos2 = -1, BPM2 = -1, BPMPos3 = -1, BPM3 = -1; + + for( unsigned i=0; iUserLog( "Song file", sPath, "has an invalid tick count: %d.", iTickCount ); + return false; + } + stepsTiming.AddSegment( TickcountSegment(0, iTickCount)); + } + + else if( sValueName=="DIFFICULTY" ) + { + out.SetMeter( max(std::stoi(sParams[1]), 1) ); + } + // new cases from Aldo_MX's fork: + else if( sValueName=="PLAYER" ) + { + RString sPlayer = sParams[1]; + sPlayer.MakeLower(); + if( sPlayer.find( "double" ) != string::npos ) + bDoublesChart = true; + } + // This should always be last. + else if( sValueName=="STEP" ) + { + RString theSteps = sParams[1]; + TrimLeft( theSteps ); + split( theSteps, "\n", vNoteRows, true ); + } + } + + if( iTickCount == -1 ) + { + iTickCount = 4; + LOG->UserLog( "Song file", sPath, "doesn't have a TICKCOUNT. Defaulting to %i.", iTickCount ); + } + + // Prepare BPM stuff already if the file uses KSF syntax. + if( bKIUCompliant ) + { + if( BPM2 > 0 && BPMPos2 > 0 ) + { + HandleBunki( stepsTiming, BPM1, BPM2, SMGap1, BPMPos2 ); + } + + if( BPM3 > 0 && BPMPos3 > 0 ) + { + HandleBunki( stepsTiming, BPM2, BPM3, SMGap2, BPMPos3 ); + } + } + + NoteData notedata; // read it into here + + { + RString sDir, sFName, sExt; + splitpath( sPath, sDir, sFName, sExt ); + sFName.MakeLower(); + + out.SetDescription(sFName); + // Check another before anything else... is this okay? -DaisuMaster + if( sFName.find("another") != string::npos ) + { + out.SetDifficulty( Difficulty_Edit ); + if( !out.GetMeter() ) out.SetMeter( 25 ); + } + else if(sFName.find("wild") != string::npos || + sFName.find("wd") != string::npos || + sFName.find("crazy+") != string::npos || + sFName.find("cz+") != string::npos || + sFName.find("hardcore") != string::npos ) + { + out.SetDifficulty( Difficulty_Challenge ); + if( !out.GetMeter() ) out.SetMeter( 20 ); + } + else if(sFName.find("crazy") != string::npos || + sFName.find("cz") != string::npos || + sFName.find("nightmare") != string::npos || + sFName.find("nm") != string::npos || + sFName.find("crazydouble") != string::npos ) + { + out.SetDifficulty( Difficulty_Hard ); + if( !out.GetMeter() ) out.SetMeter( 14 ); // Set the meters to the Pump scale, not DDR. + } + else if(sFName.find("hard") != string::npos || + sFName.find("hd") != string::npos || + sFName.find("freestyle") != string::npos || + sFName.find("fs") != string::npos || + sFName.find("double") != string::npos ) + { + out.SetDifficulty( Difficulty_Medium ); + if( !out.GetMeter() ) out.SetMeter( 8 ); + } + else if(sFName.find("easy") != string::npos || + sFName.find("ez") != string::npos || + sFName.find("normal") != string::npos ) + { + // I wonder if I should leave easy fall into the Beginner difficulty... -DaisuMaster + out.SetDifficulty( Difficulty_Easy ); + if( !out.GetMeter() ) out.SetMeter( 4 ); + } + else if(sFName.find("beginner") != string::npos || + sFName.find("practice") != string::npos || sFName.find("pr") != string::npos ) + { + out.SetDifficulty( Difficulty_Beginner ); + if( !out.GetMeter() ) out.SetMeter( 4 ); + } + else + { + out.SetDifficulty( Difficulty_Hard ); + if( !out.GetMeter() ) out.SetMeter( 10 ); + } + + out.m_StepsType = StepsType_pump_single; + + // Check for "halfdouble" before "double". + if(sFName.find("halfdouble") != string::npos || + sFName.find("half-double") != string::npos || + sFName.find("h_double") != string::npos || + sFName.find("hdb") != string::npos ) + out.m_StepsType = StepsType_pump_halfdouble; + // Handle bDoublesChart from above as well. -aj + else if(sFName.find("double") != string::npos || + sFName.find("nightmare") != string::npos || + sFName.find("freestyle") != string::npos || + sFName.find("db") != string::npos || + sFName.find("nm") != string::npos || + sFName.find("fs") != string::npos || bDoublesChart ) + out.m_StepsType = StepsType_pump_double; + else if( sFName.find("_1") != string::npos ) + out.m_StepsType = StepsType_pump_single; + else if( sFName.find("_2") != string::npos ) + out.m_StepsType = StepsType_pump_couple; + } + + switch( out.m_StepsType ) + { + case StepsType_pump_single: notedata.SetNumTracks( 5 ); break; + case StepsType_pump_couple: notedata.SetNumTracks( 10 ); break; + case StepsType_pump_double: notedata.SetNumTracks( 10 ); break; + case StepsType_pump_routine: notedata.SetNumTracks( 10 ); break; // future files may have this? + case StepsType_pump_halfdouble: notedata.SetNumTracks( 6 ); break; + default: FAIL_M( ssprintf("%i", out.m_StepsType) ); + } + + int t = 0; + int iHoldStartRow[13]; + for( t=0; t<13; t++ ) + iHoldStartRow[t] = -1; + + bool bTickChangeNeeded = false; + int newTick = -1; + float fCurBeat = 0.0f; + float prevBeat = 0.0f; // Used for hold tails. + + for( unsigned r=0; r song.GetSpecifiedLastSecond()) + //{ + // song.SetSpecifiedLastSecond(curTime); + //} + + song.SetSpecifiedLastSecond( song.GetSpecifiedLastSecond() + 4 ); + + break; + } + + else if( BeginsWith(sRowString, "|") ) + { + /* + if (bKIUCompliant) + { + // Log an error, ignore the line. + continue; + } + */ + // gotta do something tricky here: if the bpm is below one then a couple of calculations + // for scrollsegments will be made, example, bpm 0.2, tick 4000, the scrollsegment will + // be 0. if the tickcount is non a stepmania standard then it will be adapted, a scroll + // segment will then be added based on approximations. -DaisuMaster + // eh better do it considering the tickcount (high tickcounts) + + // I'm making some experiments, please spare me... + //continue; + + RString temp = sRowString.substr(2,sRowString.size()-3); + float numTemp = StringToFloat(temp); + if (BeginsWith(sRowString, "|T")) + { + // duh + iTickCount = static_cast(numTemp); + // I have been owned by the man -DaisuMaster + stepsTiming.SetTickcountAtBeat( fCurBeat, clamp(iTickCount, 0, ROWS_PER_BEAT) ); + } + else if (BeginsWith(sRowString, "|B")) + { + // BPM + stepsTiming.SetBPMAtBeat( fCurBeat, numTemp ); + } + else if (BeginsWith(sRowString, "|E")) + { + // DelayBeat + float fCurDelay = 60 / stepsTiming.GetBPMAtBeat(fCurBeat) * numTemp / iTickCount; + fCurDelay += stepsTiming.GetDelayAtRow(BeatToNoteRow(fCurBeat) ); + stepsTiming.SetDelayAtBeat( fCurBeat, fCurDelay ); + } + else if (BeginsWith(sRowString, "|D")) + { + // Delays + float fCurDelay = stepsTiming.GetStopAtRow(BeatToNoteRow(fCurBeat) ); + fCurDelay += numTemp / 1000; + stepsTiming.SetDelayAtBeat( fCurBeat, fCurDelay ); + } + else if (BeginsWith(sRowString, "|M") || BeginsWith(sRowString, "|C")) + { + // multipliers/combo + ComboSegment seg( BeatToNoteRow(fCurBeat), int(numTemp) ); + stepsTiming.AddSegment( seg ); + } + else if (BeginsWith(sRowString, "|S")) + { + // speed segments + } + else if (BeginsWith(sRowString, "|F")) + { + // fakes + } + else if (BeginsWith(sRowString, "|X")) + { + // scroll segments + ScrollSegment seg = ScrollSegment( BeatToNoteRow(fCurBeat), numTemp ); + stepsTiming.AddSegment( seg ); + //return true; + } + + continue; + } + + // Half-doubles is offset; "0011111100000". + if( out.m_StepsType == StepsType_pump_halfdouble ) + sRowString.erase( 0, 2 ); + + // Update TICKCOUNT for Direct Move files. + if( bTickChangeNeeded ) + { + iTickCount = newTick; + bTickChangeNeeded = false; + } + + for( t=0; t < notedata.GetNumTracks(); t++ ) + { + if( sRowString[t] == '4' ) + { + /* Remember when each hold starts; ignore the middle. */ + if( iHoldStartRow[t] == -1 ) + iHoldStartRow[t] = BeatToNoteRow(fCurBeat); + continue; + } + + if( iHoldStartRow[t] != -1 ) // this ends the hold + { + int iEndRow = BeatToNoteRow(prevBeat); + if( iHoldStartRow[t] == iEndRow ) + notedata.SetTapNote( t, iHoldStartRow[t], TAP_ORIGINAL_TAP ); + else + { + //notedata.AddHoldNote( t, iHoldStartRow[t], iEndRow , TAP_ORIGINAL_PUMP_HEAD ); + notedata.AddHoldNote( t, iHoldStartRow[t], iEndRow , TAP_ORIGINAL_HOLD_HEAD ); + } + iHoldStartRow[t] = -1; + } + + TapNote tap; + switch( sRowString[t] ) + { + case '0': tap = TAP_EMPTY; break; + case '1': tap = TAP_ORIGINAL_TAP; break; + //allow setting more notetypes on ksf files, this may come in handy (it should) -DaisuMaster + case 'M': + case 'm': + tap = TAP_ORIGINAL_MINE; + break; + case 'F': + case 'f': + tap = TAP_ORIGINAL_FAKE; + break; + case 'L': + case 'l': + tap = TAP_ORIGINAL_LIFT; + break; + default: + LOG->UserLog( "Song file", sPath, "has an invalid row \"%s\"; corrupt notes ignored.", + sRowString.c_str() ); + //return false; + tap = TAP_EMPTY; + break; + } + + notedata.SetTapNote(t, BeatToNoteRow(fCurBeat), tap); + } + prevBeat = fCurBeat; + fCurBeat = prevBeat + 1.0f / iTickCount; + } + + out.SetNoteData( notedata ); + out.m_Timing = stepsTiming; + + out.TidyUpData(); + + out.SetSavedToDisk( true ); // we're loading from disk, so this is by definintion already saved + + return true; +} + +static void LoadTags( const RString &str, Song &out ) +{ + /* str is either a #TITLE or a directory component. Fill in missing information. + * str is either "title", "artist - title", or "artist - title - difficulty". */ + vector asBits; + split( str, " - ", asBits, false ); + // Ignore the difficulty, since we get that elsewhere. + if( asBits.size() == 3 && ( + asBits[2].EqualsNoCase("double") || + asBits[2].EqualsNoCase("easy") || + asBits[2].EqualsNoCase("normal") || + asBits[2].EqualsNoCase("hard") || + asBits[2].EqualsNoCase("crazy") || + asBits[2].EqualsNoCase("nightmare")) + ) + { + asBits.erase( asBits.begin()+2, asBits.begin()+3 ); + } + + RString title, artist; + if( asBits.size() == 2 ) + { + artist = asBits[0]; + title = asBits[1]; + } + else if( asBits.size() == 1 ) + { + title = asBits[0]; + } + + // Convert, if possible. Most KSFs are in Korean encodings (CP942/EUC-KR). + if( !ConvertString( title, "korean" ) ) + title = ""; + if( !ConvertString( artist, "korean" ) ) + artist = ""; + + if( out.m_sMainTitle == "" ) + out.m_sMainTitle = title; + if( out.m_sArtist == "" ) + out.m_sArtist = artist; +} + +static void ProcessTickcounts( const RString & value, int & ticks, TimingData & timing ) +{ + /* TICKCOUNT will be used below if there are DM compliant BPM changes + * and stops. It will be called again in LoadFromKSFFile for the + * actual steps. */ + ticks = std::stoi( value ); + CLAMP( ticks, 0, ROWS_PER_BEAT ); + + if( ticks == 0 ) + ticks = TickcountSegment::DEFAULT_TICK_COUNT; + + timing.AddSegment( TickcountSegment(0, ticks) ); +} + +static bool LoadGlobalData( const RString &sPath, Song &out, bool &bKIUCompliant ) +{ + MsdFile msd; + if( !msd.ReadFile( sPath, false ) ) // don't unescape + { + LOG->UserLog( "Song file", sPath, "couldn't be opened: %s", msd.GetError().c_str() ); + return false; + } + + // changed up there in case of something is found inside the SONGFILE tag in the head ksf -DaisuMaster + // search for music with song in the file name + vector arrayPossibleMusic; + GetDirListing( out.GetSongDir() + RString("song.mp3"), arrayPossibleMusic ); + GetDirListing( out.GetSongDir() + RString("song.oga"), arrayPossibleMusic ); + GetDirListing( out.GetSongDir() + RString("song.ogg"), arrayPossibleMusic ); + GetDirListing( out.GetSongDir() + RString("song.wav"), arrayPossibleMusic ); + + if( !arrayPossibleMusic.empty() ) // we found a match + out.m_sMusicFile = arrayPossibleMusic[0]; + // ^this was below, at the end + + float SMGap1 = 0, SMGap2 = 0, BPM1 = -1, BPMPos2 = -1, BPM2 = -1, BPMPos3 = -1, BPM3 = -1; + int iTickCount = -1; + bKIUCompliant = false; + vector vNoteRows; + + for( unsigned i=0; i < msd.GetNumValues(); i++ ) + { + const MsdFile::value_t &sParams = msd.GetValue(i); + RString sValueName = sParams[0]; + sValueName.MakeUpper(); + + // handle the data + if( sValueName=="TITLE" ) + LoadTags(sParams[1], out); + else if( sValueName=="BPM" ) + { + BPM1 = StringToFloat(sParams[1]); + out.m_SongTiming.AddSegment( BPMSegment(0, BPM1) ); + } + else if( sValueName=="BPM2" ) + { + bKIUCompliant = true; + BPM2 = StringToFloat( sParams[1] ); + } + else if( sValueName=="BPM3" ) + { + bKIUCompliant = true; + BPM3 = StringToFloat( sParams[1] ); + } + else if( sValueName=="BUNKI" ) + { + bKIUCompliant = true; + BPMPos2 = StringToFloat( sParams[1] ) / 100.0f; + } + else if( sValueName=="BUNKI2" ) + { + bKIUCompliant = true; + BPMPos3 = StringToFloat( sParams[1] ) / 100.0f; + } + else if( sValueName=="STARTTIME" ) + { + SMGap1 = -StringToFloat( sParams[1] )/100; + out.m_SongTiming.m_fBeat0OffsetInSeconds = SMGap1; + } + // This is currently required for more accurate KIU BPM changes. + else if( sValueName=="STARTTIME2" ) + { + bKIUCompliant = true; + SMGap2 = -StringToFloat( sParams[1] )/100; + } + else if ( sValueName=="STARTTIME3" ) + { + // STARTTIME3 only ensures this is a KIU compliant simfile. + //bKIUCompliant = true; + } + else if ( sValueName=="TICKCOUNT" ) + { + ProcessTickcounts(sParams[1], iTickCount, out.m_SongTiming); + } + else if ( sValueName=="STEP" ) + { + /* STEP will always be the last header in a KSF file by design. Due to + * the Direct Move syntax, it is best to get the rows of notes here. */ + RString theSteps = sParams[1]; + TrimLeft( theSteps ); + split( theSteps, "\n", vNoteRows, true ); + } + else if( sValueName=="DIFFICULTY" || sValueName=="PLAYER" ) + { + /* DIFFICULTY and PLAYER are handled only in LoadFromKSFFile. + Ignore those here. */ + continue; + } + // New cases noted in Aldo_MX's code: + else if( sValueName=="MUSICINTRO" || sValueName=="INTRO" ) + { + out.m_fMusicSampleStartSeconds = HHMMSSToSeconds( sParams[1] ); + } + else if( sValueName=="TITLEFILE" ) + { + out.m_sBackgroundFile = sParams[1]; + } + else if( sValueName=="DISCFILE" ) + { + out.m_sBannerFile = sParams[1]; + } + else if( sValueName=="SONGFILE" ) + { + out.m_sMusicFile = sParams[1]; + } + //else if( sValueName=="INTROFILE" ) + //{ + // nothing to add... + //} + // end new cases + else + { + LOG->UserLog( "Song file", sPath, "has an unexpected value named \"%s\".", + sValueName.c_str() ); + } + } + + //intro length in piu mixes is generally 7 seconds + out.m_fMusicSampleLengthSeconds = 7.0f; + + /* BPM Change checks are done here. If bKIUCompliant, it's short and sweet. + * Otherwise, the whole file has to be processed. Right now, this is only + * called once, for the initial file (often the Crazy steps). Hopefully that + * will end up changing soon. */ + if( bKIUCompliant ) + { + if( BPM2 > 0 && BPMPos2 > 0 ) + { + HandleBunki( out.m_SongTiming, BPM1, BPM2, SMGap1, BPMPos2 ); + } + + if( BPM3 > 0 && BPMPos3 > 0 ) + { + HandleBunki( out.m_SongTiming, BPM2, BPM3, SMGap2, BPMPos3 ); + } + } + else + { + float fCurBeat = 0.0f; + bool bDMRequired = false; + + for( unsigned i=0; i < vNoteRows.size(); ++i ) + { + RString& NoteRowString = vNoteRows[i]; + StripCrnl( NoteRowString ); + + if( NoteRowString == "" ) + continue; // ignore empty rows. + + if( NoteRowString == "2222222222222" ) // Row of 2s = end. Confirm KIUCompliency here. + { + if (!bDMRequired) + bKIUCompliant = true; + break; + } + + // This is where the DMRequired test will take place. + if ( BeginsWith( NoteRowString, "|" ) ) + { + // have a static timing for everything + bDMRequired = true; + continue; + } + else + { + // ignore whatever else... + //continue; + } + + fCurBeat += 1.0f / iTickCount; + } + } + + // Try to fill in missing bits of information from the pathname. + { + vector asBits; + split( sPath, "/", asBits, true); + + ASSERT( asBits.size() > 1 ); + LoadTags( asBits[asBits.size()-2], out ); + } + + return true; +} + +void KSFLoader::GetApplicableFiles( const RString &sPath, vector &out ) +{ + GetDirListing( sPath + RString("*.ksf"), out ); +} + +bool KSFLoader::LoadNoteDataFromSimfile( const RString & cachePath, Steps &out ) +{ + bool KIUCompliant = false; + Song dummy; + if (!LoadGlobalData(cachePath, dummy, KIUCompliant)) + return false; + Steps *notes = dummy.CreateSteps(); + if (LoadFromKSFFile(cachePath, *notes, dummy, KIUCompliant)) + { + KIUCompliant = true; // yeah, reusing a variable. + out.SetNoteData(notes->GetNoteData()); + } + delete notes; + return KIUCompliant; +} + +bool KSFLoader::LoadFromDir( const RString &sDir, Song &out ) +{ + LOG->Trace( "KSFLoader::LoadFromDir(%s)", sDir.c_str() ); + + vector arrayKSFFileNames; + GetDirListing( sDir + RString("*.ksf"), arrayKSFFileNames ); + + // We shouldn't have been called to begin with if there were no KSFs. + ASSERT( arrayKSFFileNames.size() != 0 ); + + bool bKIUCompliant = false; + /* With Split Timing, there has to be a backup Song Timing in case + * anything goes wrong. As these files are kept in alphabetical + * order (hopefully), it is best to use the LAST file for timing + * purposes, for that is the "normal", or easiest difficulty. + * Usually. */ + // Nevermind, kiu compilancy is screwing things up: + // IE, I have two simfiles, oh wich each have four ksf files, the first one has + // the first ksf with directmove timing changes, and the rest are not, everything + // goes fine. In the other hand I have my second simfile with the first ksf file + // without directmove timing changes and the rest have changes, changes are not + // loaded due to kiucompilancy in the first ksf file. + // About the "normal" thing, my simfiles' ksfs uses non-standard naming so + // the last chart is usually nightmare or normal, I use easy and normal + // indistinctly for SM so it shouldn't matter, I use piu fiesta/ex naming + // for directmove though, and we're just gathering basic info anyway, and + // most of the time all the KSF files have the same info in the #TITLE:; section + unsigned files = arrayKSFFileNames.size(); + RString dir = out.GetSongDir(); + if( !LoadGlobalData(dir + arrayKSFFileNames[files - 1], out, bKIUCompliant) ) + return false; + + out.m_sSongFileName = dir + arrayKSFFileNames[files - 1]; + // load the Steps from the rest of the KSF files + for( unsigned i=0; iSetFilename(dir + arrayKSFFileNames[i]); + out.AddSteps( pNewNotes ); + } + return true; +} + +/* + * (c) 2001-2006 Chris Danford, Glenn Maynard, Jason Felds + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/NotesLoaderSM.cpp b/src/NotesLoaderSM.cpp index 2300a3095a..cd6ca59d90 100644 --- a/src/NotesLoaderSM.cpp +++ b/src/NotesLoaderSM.cpp @@ -155,7 +155,7 @@ void SMSetSelectable(SMSongTagInfo& info) * used 3.9+ features are not excluded here */ else if((*info.params)[1].EqualsNoCase("ES") || (*info.params)[1].EqualsNoCase("OMES")) { info.song->m_SelectionDisplay = info.song->SHOW_ALWAYS; } - else if(StringToInt((*info.params)[1]) > 0) + else if(std::stoi((*info.params)[1]) > 0) { info.song->m_SelectionDisplay = info.song->SHOW_ALWAYS; } else { LOG->UserLog("Song file", info.path, "has an unknown #SELECTABLE value, \"%s\"; ignored.", (*info.params)[1].c_str()); } @@ -336,7 +336,7 @@ void SMLoader::LoadFromTokens( // have a meter on certain steps. Make the meter 1 in these instances. sMeter = "1"; } - out.SetMeter( StringToInt(sMeter) ); + out.SetMeter( std::stoi(sMeter) ); out.SetSMNoteData( sNoteData ); @@ -396,11 +396,11 @@ void SMLoader::ProcessAttacks( AttackArray &attacks, MsdFile::value_t params ) Trim( sBits[0] ); if( !sBits[0].CompareNoCase("TIME") ) - attack.fStartSecond = strtof( sBits[1], NULL ); + attack.fStartSecond = strtof( sBits[1], nullptr ); else if( !sBits[0].CompareNoCase("LEN") ) - attack.fSecsRemaining = strtof( sBits[1], NULL ); + attack.fSecsRemaining = strtof( sBits[1], nullptr ); else if( !sBits[0].CompareNoCase("END") ) - end = strtof( sBits[1], NULL ); + end = strtof( sBits[1], nullptr ); else if( !sBits[0].CompareNoCase("MODS") ) { Trim(sBits[1]); @@ -424,10 +424,10 @@ void SMLoader::ProcessInstrumentTracks( Song &out, const RString &sParam ) { vector vs1; split( sParam, ",", vs1 ); - FOREACH_CONST( RString, vs1, s ) + for (RString const &s : vs1) { vector vs2; - split( *s, "=", vs2 ); + split( s, "=", vs2 ); if( vs2.size() >= 2 ) { InstrumentTrack it = StringToInstrumentTrack( vs2[0] ); @@ -770,10 +770,10 @@ void SMLoader::ProcessTimeSignatures( TimingData &out, const RString line, const vector vs1; split( line, ",", vs1 ); - FOREACH_CONST( RString, vs1, s1 ) + for (RString const &s1 : vs1) { vector vs2; - split( *s1, "=", vs2 ); + split( s1, "=", vs2 ); if( vs2.size() < 3 ) { @@ -785,8 +785,8 @@ void SMLoader::ProcessTimeSignatures( TimingData &out, const RString line, const } const float fBeat = RowToBeat( vs2[0], rowsPerBeat ); - const int iNumerator = StringToInt( vs2[1] ); - const int iDenominator = StringToInt( vs2[2] ); + const int iNumerator = std::stoi( vs2[1] ); + const int iDenominator = std::stoi( vs2[2] ); if( fBeat < 0 ) { @@ -849,10 +849,10 @@ void SMLoader::ProcessSpeeds( TimingData &out, const RString line, const int row vector vs1; split( line, ",", vs1 ); - FOREACH_CONST( RString, vs1, s1 ) + for (RString const &s1 : vs1) { vector vs2; - split( *s1, "=", vs2 ); + split( s1, "=", vs2 ); if( vs2[0] == 0 && vs2.size() == 2 ) // First one always seems to have 2. { @@ -878,7 +878,7 @@ void SMLoader::ProcessSpeeds( TimingData &out, const RString line, const int row const float fDelay = StringToFloat( vs2[2] ); // XXX: ugly... - int iUnit = StringToInt(vs2[3]); + int iUnit = std::stoi(vs2[3]); SpeedSegment::BaseUnit unit = (iUnit == 0) ? SpeedSegment::UNIT_BEATS : SpeedSegment::UNIT_SECONDS; @@ -979,7 +979,7 @@ bool SMLoader::LoadFromBGChangesString( BackgroundChange &change, const RString // Backward compatibility: if( change.m_def.m_sEffect.empty() ) { - bool bLoop = StringToInt( aBGChangeValues[5] ) != 0; + bool bLoop = std::stoi( aBGChangeValues[5] ) != 0; if( !bLoop ) change.m_def.m_sEffect = SBE_StretchNoLoop; } @@ -989,7 +989,7 @@ bool SMLoader::LoadFromBGChangesString( BackgroundChange &change, const RString // Backward compatibility: if( change.m_def.m_sEffect.empty() ) { - bool bRewindMovie = StringToInt( aBGChangeValues[4] ) != 0; + bool bRewindMovie = std::stoi( aBGChangeValues[4] ) != 0; if( bRewindMovie ) change.m_def.m_sEffect = SBE_StretchRewind; } @@ -998,7 +998,7 @@ bool SMLoader::LoadFromBGChangesString( BackgroundChange &change, const RString // param 9 overrides this. // Backward compatibility: if( change.m_sTransition.empty() ) - change.m_sTransition = (StringToInt( aBGChangeValues[3] ) != 0) ? "CrossFade" : ""; + change.m_sTransition = (std::stoi( aBGChangeValues[3] ) != 0) ? "CrossFade" : ""; // fall through case 3: change.m_fRate = StringToFloat( aBGChangeValues[2] ); @@ -1170,7 +1170,7 @@ bool SMLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCache return true; } -bool SMLoader::LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong, Song *givenSong /* =NULL */ ) +bool SMLoader::LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong, Song *givenSong /* =nullptr */ ) { LOG->Trace( "SMLoader::LoadEditFromFile(%s)", sEditFilePath.c_str() ); @@ -1198,7 +1198,7 @@ bool SMLoader::LoadEditFromBuffer( const RString &sBuffer, const RString &sEditF return LoadEditFromMsd( msd, sEditFilePath, slot, true, givenSong ); } -bool SMLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong, Song *givenSong /* =NULL */ ) +bool SMLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong, Song *givenSong /* = nullptr */ ) { Song* pSong = givenSong; @@ -1225,7 +1225,7 @@ bool SMLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath sSongFullTitle.Replace( '\\', '/' ); pSong = SONGMAN->FindSong( sSongFullTitle ); - if( pSong == NULL ) + if( pSong == nullptr ) { LOG->UserLog( "Edit file", sEditFilePath, "requires a song \"%s\" that isn't present.", sSongFullTitle.c_str() ); return false; @@ -1240,7 +1240,7 @@ bool SMLoader::LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath else if( sValueName=="NOTES" ) { - if( pSong == NULL ) + if( pSong == nullptr ) { LOG->UserLog( "Edit file", sEditFilePath, "doesn't have a #SONG tag preceeding the first #NOTES tag, and is not in a valid song-specific folder." ); return false; diff --git a/src/NotesLoaderSM.h b/src/NotesLoaderSM.h index 56f44062ba..9d6ea557da 100644 --- a/src/NotesLoaderSM.h +++ b/src/NotesLoaderSM.h @@ -62,9 +62,9 @@ struct SMLoader * @param out a vector of files found in the path. */ virtual void GetApplicableFiles( const RString &sPath, vector &out, bool load_autosave= false ); - virtual bool LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong, Song *givenSong=NULL ); - virtual bool LoadEditFromBuffer( const RString &sBuffer, const RString &sEditFilePath, ProfileSlot slot, Song *givenSong=NULL ); - virtual bool LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong, Song *givenSong=NULL ); + virtual bool LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong, Song *givenSong=nullptr ); + virtual bool LoadEditFromBuffer( const RString &sBuffer, const RString &sEditFilePath, ProfileSlot slot, Song *givenSong=nullptr ); + virtual bool LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong, Song *givenSong=nullptr ); virtual bool LoadFromBGChangesString(BackgroundChange &change, const RString &sBGChangeExpression ); diff --git a/src/NotesLoaderSMA.cpp b/src/NotesLoaderSMA.cpp index 57216c60be..1179163d7c 100644 --- a/src/NotesLoaderSMA.cpp +++ b/src/NotesLoaderSMA.cpp @@ -33,11 +33,11 @@ void SMALoader::ProcessMultipliers( TimingData &out, const int iRowsPerBeat, con continue; } const float fComboBeat = RowToBeat( arrayMultiplierValues[0], iRowsPerBeat ); - const int iCombos = StringToInt( arrayMultiplierValues[1] ); // always true. + const int iCombos = std::stoi( arrayMultiplierValues[1] ); // always true. // hoping I'm right here: SMA files can use 6 values after the row/beat. const int iMisses = (size == 2 || size == 4 ? iCombos : - StringToInt(arrayMultiplierValues[2])); + std::stoi(arrayMultiplierValues[2])); out.AddSegment( ComboSegment(BeatToNoteRow(fComboBeat), iCombos, iMisses) ); } } @@ -47,10 +47,10 @@ void SMALoader::ProcessBeatsPerMeasure( TimingData &out, const RString sParam ) vector vs1; split( sParam, ",", vs1 ); - FOREACH_CONST( RString, vs1, s1 ) + for (RString const &s1 : vs1) { vector vs2; - split( *s1, "=", vs2 ); + split( s1, "=", vs2 ); if( vs2.size() < 2 ) { @@ -61,7 +61,7 @@ void SMALoader::ProcessBeatsPerMeasure( TimingData &out, const RString sParam ) continue; } const float fBeat = StringToFloat( vs2[0] ); - const int iNumerator = StringToInt( vs2[1] ); + const int iNumerator = std::stoi( vs2[1] ); if( fBeat < 0 ) { @@ -89,7 +89,7 @@ void SMALoader::ProcessSpeeds( TimingData &out, const RString line, const int ro vector vs1; split( line, ",", vs1 ); - FOREACH_CONST( RString, vs1, s1 ) + for (std::vector::const_iterator s1 = vs1.begin(); s1 != vs1.end(); ++s1) { vector vs2; vs2.clear(); // trying something. @@ -161,7 +161,7 @@ bool SMALoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach out.m_SongTiming.m_sFile = sPath; // songs still have their fallback timing. out.m_sSongFileName = sPath; - Steps* pNewNotes = NULL; + Steps* pNewNotes = nullptr; int iRowsPerBeat = -1; // Start with an invalid value: needed for checking. vector< pair > vBPMChanges, vStops; @@ -296,7 +296,7 @@ bool SMALoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach vector arrayBeatChangeValues; split( arrayBeatChangeExpressions[0], "=", arrayBeatChangeValues ); - iRowsPerBeat = StringToInt(arrayBeatChangeValues[1]); + iRowsPerBeat = std::stoi(arrayBeatChangeValues[1]); } else { @@ -328,7 +328,7 @@ bool SMALoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach * used 3.9+ features are not excluded here */ else if(sParams[1].EqualsNoCase("ES") || sParams[1].EqualsNoCase("OMES")) out.m_SelectionDisplay = out.SHOW_ALWAYS; - else if( StringToInt(sParams[1]) > 0 ) + else if( std::stoi(sParams[1]) > 0 ) out.m_SelectionDisplay = out.SHOW_ALWAYS; else LOG->UserLog("Song file", diff --git a/src/NotesLoaderSSC.cpp b/src/NotesLoaderSSC.cpp index 384b565346..943f4d9ccc 100644 --- a/src/NotesLoaderSSC.cpp +++ b/src/NotesLoaderSSC.cpp @@ -70,7 +70,7 @@ typedef void (*song_tag_func_t)(SongTagInfo& info); /****************************************************************/ void SetVersion(SongTagInfo& info) { - info.song->m_fVersion = StringToFloat((*info.params)[1]); + info.song->m_fVersion = std::stof((*info.params)[1]); } void SetTitle(SongTagInfo& info) { @@ -157,11 +157,11 @@ void SetInstrumentTrack(SongTagInfo& info) void SetMusicLength(SongTagInfo& info) { if(info.from_cache) - info.song->m_fMusicLengthSeconds = StringToFloat((*info.params)[1]); + info.song->m_fMusicLengthSeconds = std::stof((*info.params)[1]); } void SetLastSecondHint(SongTagInfo& info) { - info.song->SetSpecifiedLastSecond(StringToFloat((*info.params)[1])); + info.song->SetSpecifiedLastSecond(std::stof((*info.params)[1])); } void SetSampleStart(SongTagInfo& info) { @@ -179,11 +179,11 @@ void SetDisplayBPM(SongTagInfo& info) else { info.song->m_DisplayBPMType = DISPLAY_BPM_SPECIFIED; - info.song->m_fSpecifiedBPMMin = StringToFloat((*info.params)[1]); + info.song->m_fSpecifiedBPMMin = std::stof((*info.params)[1]); if((*info.params)[2].empty()) { info.song->m_fSpecifiedBPMMax = info.song->m_fSpecifiedBPMMin; } else - { info.song->m_fSpecifiedBPMMax = StringToFloat((*info.params)[2]); } + { info.song->m_fSpecifiedBPMMax = std::stof((*info.params)[2]); } } } void SetSelectable(SongTagInfo& info) @@ -199,7 +199,7 @@ void SetSelectable(SongTagInfo& info) * used 3.9+ features are not excluded here */ else if((*info.params)[1].EqualsNoCase("ES") || (*info.params)[1].EqualsNoCase("OMES")) { info.song->m_SelectionDisplay = info.song->SHOW_ALWAYS; } - else if(StringToInt((*info.params)[1]) > 0) + else if(std::stoi((*info.params)[1]) > 0) { info.song->m_SelectionDisplay = info.song->SHOW_ALWAYS; } else { LOG->UserLog("Song file", info.path, "has an unknown #SELECTABLE value, \"%s\"; ignored.", (*info.params)[1].c_str()); } @@ -234,7 +234,7 @@ void SetAttacks(SongTagInfo& info) } void SetOffset(SongTagInfo& info) { - info.song->m_SongTiming.m_fBeat0OffsetInSeconds = StringToFloat((*info.params)[1]); + info.song->m_SongTiming.m_fBeat0OffsetInSeconds = std::stof((*info.params)[1]); } void SetSongStops(SongTagInfo& info) { @@ -283,12 +283,12 @@ void SetSongFakes(SongTagInfo& info) void SetFirstSecond(SongTagInfo& info) { if(info.from_cache) - { info.song->SetFirstSecond(StringToFloat((*info.params)[1])); } + { info.song->SetFirstSecond(std::stof((*info.params)[1])); } } void SetLastSecond(SongTagInfo& info) { if(info.from_cache) - { info.song->SetLastSecond(StringToFloat((*info.params)[1])); } + { info.song->SetLastSecond(std::stof((*info.params)[1])); } } void SetSongFilename(SongTagInfo& info) { @@ -298,19 +298,19 @@ void SetSongFilename(SongTagInfo& info) void SetHasMusic(SongTagInfo& info) { if(info.from_cache) - { info.song->m_bHasMusic = StringToInt((*info.params)[1]) != 0; } + { info.song->m_bHasMusic = std::stoi((*info.params)[1]) != 0; } } void SetHasBanner(SongTagInfo& info) { if(info.from_cache) - { info.song->m_bHasBanner = StringToInt((*info.params)[1]) != 0; } + { info.song->m_bHasBanner = std::stoi((*info.params)[1]) != 0; } } // Functions for steps tags go below this line. -Kyz /****************************************************************/ void SetStepsVersion(StepsTagInfo& info) { - info.song->m_fVersion = StringToFloat((*info.params)[1]); + info.song->m_fVersion = std::stof((*info.params)[1]); } void SetChartName(StepsTagInfo& info) { @@ -350,7 +350,7 @@ void SetDifficulty(StepsTagInfo& info) } void SetMeter(StepsTagInfo& info) { - info.steps->SetMeter(StringToInt((*info.params)[1])); + info.steps->SetMeter(std::stoi((*info.params)[1])); info.ssc_format= true; } void SetRadarValues(StepsTagInfo& info) @@ -368,7 +368,7 @@ void SetRadarValues(StepsTagInfo& info) { for(size_t i= 0; i < cats_per_player; ++i) { - v[pn][i]= StringToFloat(values[pn * cats_per_player + i]); + v[pn][i]= std::stof(values[pn * cats_per_player + i]); } } info.steps->SetCachedRadarValues(v); @@ -499,7 +499,7 @@ void SetStepsOffset(StepsTagInfo& info) { if(info.song->m_fVersion >= VERSION_SPLIT_TIMING || info.for_load_edit) { - info.timing->m_fBeat0OffsetInSeconds = StringToFloat((*info.params)[1]); + info.timing->m_fBeat0OffsetInSeconds = std::stof((*info.params)[1]); info.has_own_timing = true; } } @@ -511,12 +511,12 @@ void SetStepsDisplayBPM(StepsTagInfo& info) else { info.steps->SetDisplayBPM(DISPLAY_BPM_SPECIFIED); - float min = StringToFloat((*info.params)[1]); + float min = std::stof((*info.params)[1]); info.steps->SetMinBPM(min); if((*info.params)[2].empty()) { info.steps->SetMaxBPM(min); } else - { info.steps->SetMaxBPM(StringToFloat((*info.params)[2])); } + { info.steps->SetMaxBPM(std::stof((*info.params)[2])); } } } @@ -659,8 +659,8 @@ void SSCLoader::ProcessBPMs( TimingData &out, const RString sParam ) continue; } - const float fBeat = StringToFloat( arrayBPMValues[0] ); - const float fNewBPM = StringToFloat( arrayBPMValues[1] ); + const float fBeat = std::stof( arrayBPMValues[0] ); + const float fNewBPM = std::stof( arrayBPMValues[1] ); if( fBeat >= 0 && fNewBPM > 0 ) { out.AddSegment( BPMSegment(BeatToNoteRow(fBeat), fNewBPM) ); @@ -693,8 +693,8 @@ void SSCLoader::ProcessStops( TimingData &out, const RString sParam ) continue; } - const float fBeat = StringToFloat( arrayStopValues[0] ); - const float fNewStop = StringToFloat( arrayStopValues[1] ); + const float fBeat = std::stof( arrayStopValues[0] ); + const float fNewStop = std::stof( arrayStopValues[1] ); if( fBeat >= 0 && fNewStop > 0 ) out.AddSegment( StopSegment(BeatToNoteRow(fBeat), fNewStop) ); else @@ -725,8 +725,8 @@ void SSCLoader::ProcessWarps( TimingData &out, const RString sParam, const float continue; } - const float fBeat = StringToFloat( arrayWarpValues[0] ); - const float fNewBeat = StringToFloat( arrayWarpValues[1] ); + const float fBeat = std::stof( arrayWarpValues[0] ); + const float fNewBeat = std::stof( arrayWarpValues[1] ); // Early versions were absolute in beats. They should be relative. if( ( fVersion < VERSION_SPLIT_TIMING && fNewBeat > fBeat ) ) { @@ -762,7 +762,7 @@ void SSCLoader::ProcessLabels( TimingData &out, const RString sParam ) continue; } - const float fBeat = StringToFloat( arrayLabelValues[0] ); + const float fBeat = std::stof( arrayLabelValues[0] ); RString sLabel = arrayLabelValues[1]; TrimRight(sLabel); if( fBeat >= 0.0f ) @@ -796,9 +796,9 @@ void SSCLoader::ProcessCombos( TimingData &out, const RString line, const int ro arrayComboExpressions[f].c_str() ); continue; } - const float fComboBeat = StringToFloat( arrayComboValues[0] ); - const int iCombos = StringToInt( arrayComboValues[1] ); - const int iMisses = (size == 2 ? iCombos : StringToInt(arrayComboValues[2])); + const float fComboBeat = std::stof( arrayComboValues[0] ); + const int iCombos = std::stoi( arrayComboValues[1] ); + const int iMisses = (size == 2 ? iCombos : std::stoi(arrayComboValues[2])); out.AddSegment( ComboSegment( BeatToNoteRow(fComboBeat), iCombos, iMisses ) ); } } @@ -808,10 +808,10 @@ void SSCLoader::ProcessScrolls( TimingData &out, const RString sParam ) vector vs1; split( sParam, ",", vs1 ); - FOREACH_CONST( RString, vs1, s1 ) + for (RString const &s1 : vs1) { vector vs2; - split( *s1, "=", vs2 ); + split( s1, "=", vs2 ); if( vs2.size() < 2 ) { @@ -822,8 +822,8 @@ void SSCLoader::ProcessScrolls( TimingData &out, const RString sParam ) continue; } - const float fBeat = StringToFloat( vs2[0] ); - const float fRatio = StringToFloat( vs2[1] ); + const float fBeat = std::stof( vs2[0] ); + const float fRatio = std::stof( vs2[1] ); if( fBeat < 0 ) { @@ -875,7 +875,7 @@ bool SSCLoader::LoadNoteDataFromSimfile( const RString & cachePath, Steps &out ) case LNDID_version: // Note that version is in both switches. Formerly, it was // checked before the tryingSteps condition. -Kyz - storedVersion = StringToFloat(matcher); + storedVersion = std::stof(matcher); break; case LNDID_stepstype: if(out.m_StepsType != GAMEMAN->StringToStepsType(matcher)) @@ -905,7 +905,7 @@ bool SSCLoader::LoadNoteDataFromSimfile( const RString & cachePath, Steps &out ) { tryingSteps = false; } break; case LNDID_meter: - if(out.GetMeter() != StringToInt(matcher)) + if(out.GetMeter() != std::stoi(matcher)) { tryingSteps = false; } break; case LNDID_credit: @@ -928,7 +928,7 @@ bool SSCLoader::LoadNoteDataFromSimfile( const RString & cachePath, Steps &out ) case LNDID_version: // Note that version is in both switches. Formerly, it was // checked before the tryingSteps condition. -Kyz - storedVersion = StringToFloat(matcher); + storedVersion = std::stof(matcher); break; case LNDID_notedata: tryingSteps = true; @@ -962,7 +962,7 @@ bool SSCLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach int state = GETTING_SONG_INFO; const unsigned values = msd.GetNumValues(); - Steps* pNewNotes = NULL; + Steps* pNewNotes = nullptr; TimingData stepsTiming; SongTagInfo reused_song_info(&*this, &out, sPath, bFromCache); @@ -1047,7 +1047,7 @@ bool SSCLoader::LoadFromSimfile( const RString &sPath, Song &out, bool bFromCach return true; } -bool SSCLoader::LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong, Song *givenSong /* =NULL */ ) +bool SSCLoader::LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong, Song *givenSong /* = nullptr */ ) { LOG->Trace( "SSCLoader::LoadEditFromFile(%s)", sEditFilePath.c_str() ); @@ -1076,10 +1076,10 @@ bool SSCLoader::LoadEditFromMsd(const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong, - Song *givenSong /* =NULL */ ) + Song *givenSong /* = nullptr */ ) { Song* pSong = givenSong; - Steps* pNewNotes = NULL; + Steps* pNewNotes = nullptr; TimingData stepsTiming; StepsTagInfo reused_steps_info(&*this, pSong, sEditFilePath, false); @@ -1093,12 +1093,12 @@ bool SSCLoader::LoadEditFromMsd(const MsdFile &msd, RString sValueName = sParams[0]; sValueName.MakeUpper(); - if(pSong != NULL) + if(pSong != nullptr) { reused_steps_info.params= &sParams; steps_handler_map_t::iterator handler= parser_helper.steps_tag_handlers.find(sValueName); - if(pNewNotes != NULL && handler != parser_helper.steps_tag_handlers.end()) + if(pNewNotes != nullptr && handler != parser_helper.steps_tag_handlers.end()) { handler->second(reused_steps_info); } @@ -1110,7 +1110,7 @@ bool SSCLoader::LoadEditFromMsd(const MsdFile &msd, } else if(sValueName=="NOTES") { - if(pSong == NULL) + if(pSong == nullptr) { LOG->UserLog("Edit file", sEditFilePath, "doesn't have a #SONG tag preceeding the first #NOTES tag," @@ -1137,7 +1137,7 @@ bool SSCLoader::LoadEditFromMsd(const MsdFile &msd, // Force the difficulty to edit in case the edit set its own // difficulty because IsEditAlreadyLoaded has an assert and edits // shouldn't be able to add charts of other difficulties. -Kyz - if(pNewNotes != NULL) + if(pNewNotes != nullptr) { pNewNotes->SetDifficulty(Difficulty_Edit); if(pSong->IsEditAlreadyLoaded(pNewNotes)) @@ -1197,7 +1197,7 @@ bool SSCLoader::LoadEditFromMsd(const MsdFile &msd, sSongFullTitle.Replace('\\', '/'); pSong = SONGMAN->FindSong(sSongFullTitle); reused_steps_info.song= pSong; - if(pSong == NULL) + if(pSong == nullptr) { LOG->UserLog("Edit file", sEditFilePath, "requires a song \"%s\" that isn't present.", diff --git a/src/NotesLoaderSSC.h b/src/NotesLoaderSSC.h index 7a63914dac..2ede6aacbd 100644 --- a/src/NotesLoaderSSC.h +++ b/src/NotesLoaderSSC.h @@ -58,7 +58,7 @@ struct SSCLoader : public SMLoader * @param bAddStepsToSong a flag to determine if we add the edit steps to the song file. * @return its success or failure. */ - bool LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong, Song *givenSong=NULL ); + bool LoadEditFromFile( RString sEditFilePath, ProfileSlot slot, bool bAddStepsToSong, Song *givenSong=nullptr ); /** * @brief Attempt to parse the edit file in question. * @param msd the edit file itself. @@ -67,7 +67,7 @@ struct SSCLoader : public SMLoader * @param bAddStepsToSong a flag to determine if we add the edit steps to the song file. * @return its success or failure. */ - bool LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong, Song *givenSong=NULL ); + bool LoadEditFromMsd( const MsdFile &msd, const RString &sEditFilePath, ProfileSlot slot, bool bAddStepsToSong, Song *givenSong=nullptr ); /** * @brief Retrieve the specific NoteData from the file. diff --git a/src/NotesWriterJson.cpp b/src/NotesWriterJson.cpp index 0c2c9710ca..9cc5b08d4e 100644 --- a/src/NotesWriterJson.cpp +++ b/src/NotesWriterJson.cpp @@ -79,8 +79,6 @@ static void Serialize( const NoteData &o, Json::Value &root ) { NoteData::TrackMap::const_iterator begin, end; o.GetTapNoteRange( t, 0, MAX_NOTE_ROW, begin, end ); - //NoteData::TrackMap tm = o.GetTrack(t); - //FOREACHM_CONST( int, TapNote, tm, iter ) for( ; begin != end; ++begin ) { int iRow = begin->first; @@ -185,11 +183,11 @@ bool NotesWriterJson::WriteSong( const RString &sFile, const Song &out, bool bWr if( bWriteSteps ) { vector vpSteps; - FOREACH_CONST( Steps*, out.GetAllSteps(), iter ) + for (Steps * iter : out.GetAllSteps()) { - if( (*iter)->IsAutogen() ) + if( iter->IsAutogen() ) continue; - vpSteps.push_back( *iter ); + vpSteps.push_back( iter ); } JsonUtil::SerializeVectorPointers( vpSteps, Serialize, root["Charts"] ); } diff --git a/src/NotesWriterSM.cpp b/src/NotesWriterSM.cpp index 60515927d9..f5fff6e254 100644 --- a/src/NotesWriterSM.cpp +++ b/src/NotesWriterSM.cpp @@ -3,7 +3,6 @@ #include #include "NotesWriterSM.h" #include "BackgroundUtil.h" -#include "Foreach.h" #include "GameManager.h" #include "LocalizedString.h" #include "NoteTypes.h" @@ -123,10 +122,10 @@ static void WriteGlobalTags( RageFileBasic &f, Song &out ) } } // Delays can't be negative: thus, no effect. - FOREACH_CONST(TimingSegment *, delays, ss) + for (TimingSegment const *ss : delays) { - float fBeat = NoteRowToBeat( (*ss)->GetRow()-1 ); - float fPause = ToDelay(*ss)->GetPause(); + float fBeat = NoteRowToBeat( ss->GetRow()-1 ); + float fPause = ToDelay(ss)->GetPause(); map::iterator already_exists= allPauses.find(fBeat); if(already_exists != allPauses.end()) { @@ -140,9 +139,9 @@ static void WriteGlobalTags( RageFileBasic &f, Song &out ) f.Write( "#STOPS:" ); vector stopLines; - FOREACHM(float, float, allPauses, ap) + for (std::pair ap : allPauses) { - stopLines.push_back(ssprintf("%.6f=%.6f", ap->first, ap->second)); + stopLines.push_back(ssprintf("%.6f=%.6f", ap.first, ap.second)); } f.PutLine(join(",\n", stopLines)); @@ -157,8 +156,8 @@ static void WriteGlobalTags( RageFileBasic &f, Song &out ) else f.Write( ssprintf("#BGCHANGES%d:", b+1) ); - FOREACH_CONST( BackgroundChange, out.GetBackgroundChanges(b), bgc ) - f.PutLine( (*bgc).ToString() +"," ); + for (BackgroundChange const &bgc : out.GetBackgroundChanges(b)) + f.PutLine( bgc.ToString() +"," ); /* If there's an animation plan at all, add a dummy "-nosongbg-" tag to indicate that * this file doesn't want a song BG entry added at the end. See SMLoader::TidyUpData. @@ -172,9 +171,9 @@ static void WriteGlobalTags( RageFileBasic &f, Song &out ) if( out.GetForegroundChanges().size() ) { f.Write( "#FGCHANGES:" ); - FOREACH_CONST( BackgroundChange, out.GetForegroundChanges(), bgc ) + for (BackgroundChange const &bgc : out.GetForegroundChanges()) { - f.PutLine( (*bgc).ToString() +"," ); + f.PutLine( bgc.ToString() +"," ); } f.PutLine( ";" ); } @@ -272,9 +271,8 @@ bool NotesWriterSM::Write( RageFileBasic &f, Song &out, const vector& vp { WriteGlobalTags( f, out ); - FOREACH_CONST( Steps*, vpStepsToSave, s ) + for (Steps const *pSteps : vpStepsToSave) { - const Steps* pSteps = *s; RString sTag = GetSMNotesTag( out, *pSteps ); f.PutLine( sTag ); } diff --git a/src/NotesWriterSSC.cpp b/src/NotesWriterSSC.cpp index fbc564f36b..2abe6376fd 100644 --- a/src/NotesWriterSSC.cpp +++ b/src/NotesWriterSSC.cpp @@ -3,7 +3,6 @@ #include #include "NotesWriterSSC.h" #include "BackgroundUtil.h" -#include "Foreach.h" #include "GameManager.h" #include "LocalizedString.h" #include "NoteTypes.h" @@ -289,8 +288,8 @@ static void WriteGlobalTags( RageFile &f, const Song &out ) else f.Write( ssprintf("#BGCHANGES%d:", b+1) ); - FOREACH_CONST( BackgroundChange, out.GetBackgroundChanges(b), bgc ) - f.PutLine( (*bgc).ToString() +"," ); + for (BackgroundChange const &bgc : out.GetBackgroundChanges(b)) + f.PutLine( bgc.ToString() +"," ); /* If there's an animation plan at all, add a dummy "-nosongbg-" tag to * indicate that this file doesn't want a song BG entry added at the end. @@ -304,9 +303,9 @@ static void WriteGlobalTags( RageFile &f, const Song &out ) if( out.GetForegroundChanges().size() ) { f.Write( "#FGCHANGES:" ); - FOREACH_CONST( BackgroundChange, out.GetForegroundChanges(), bgc ) + for (BackgroundChange const &bgc : out.GetForegroundChanges()) { - f.PutLine( (*bgc).ToString() +"," ); + f.PutLine( bgc.ToString() +"," ); } f.PutLine( ";" ); } @@ -464,9 +463,8 @@ bool NotesWriterSSC::Write( RString sPath, const Song &out, const vector } // Save specified Steps to this file - FOREACH_CONST( Steps*, vpStepsToSave, s ) + for (Steps const *pSteps : vpStepsToSave) { - const Steps* pSteps = *s; RString sTag = GetSSCNoteData( out, *pSteps, bSavingCache ); f.PutLine( sTag ); } diff --git a/src/OptionRow.cpp b/src/OptionRow.cpp index 189a665b31..824a40bb17 100644 --- a/src/OptionRow.cpp +++ b/src/OptionRow.cpp @@ -2,7 +2,7 @@ #include "OptionRow.h" #include "RageUtil.h" #include "RageLog.h" -#include "Foreach.h" + #include "OptionRowHandler.h" #include "CommonMetrics.h" #include "GameState.h" @@ -33,9 +33,9 @@ RString MOD_ICON_X_NAME( size_t p ) { return ssprintf("ModIconP%dX",int(p+1)); OptionRow::OptionRow( const OptionRowType *pSource ) { m_pParentType = pSource; - m_pHand = NULL; + m_pHand = nullptr; - m_textTitle = NULL; + m_textTitle = nullptr; ZERO( m_ModIcons ); Clear(); @@ -61,10 +61,10 @@ void OptionRow::Clear() FOREACH_PlayerNumber( p ) m_Underline[p].clear(); - if( m_pHand != NULL ) + if( m_pHand != nullptr ) { - FOREACH_CONST( RString, m_pHand->m_vsReloadRowMessages, m ) - MESSAGEMAN->Unsubscribe( this, *m ); + for (RString const &m : m_pHand->m_vsReloadRowMessages) + MESSAGEMAN->Unsubscribe( this, m ); } SAFE_DELETE( m_pHand ); @@ -108,7 +108,7 @@ void OptionRowType::Load( const RString &sMetricsGroup, Actor *pParent ) ActorUtil::LoadAllCommandsAndSetXY( m_textTitle, sMetricsGroup ); Actor *pActor = ActorUtil::MakeActor( THEME->GetPathG(sMetricsGroup,"Frame"), pParent ); - if( pActor == NULL ) + if( pActor == nullptr ) pActor = new Actor; m_sprFrame.Load( pActor ); m_sprFrame->SetName( "Frame" ); @@ -128,8 +128,8 @@ void OptionRow::LoadNormal( OptionRowHandler *pHand, bool bFirstItemGoesDown ) m_pHand = pHand; m_bFirstItemGoesDown = bFirstItemGoesDown; - FOREACH_CONST( RString, m_pHand->m_vsReloadRowMessages, m ) - MESSAGEMAN->Subscribe( this, *m ); + for (RString const &m : m_pHand->m_vsReloadRowMessages) + MESSAGEMAN->Subscribe( this, m ); ChoicesChanged( RowType_Normal ); } @@ -204,7 +204,7 @@ RString OptionRow::GetRowTitle() const if( GAMESTATE->m_pCurCourse ) { const Trail* pTrail = GAMESTATE->m_pCurTrail[GAMESTATE->GetMasterPlayerNumber()]; - ASSERT( pTrail != NULL ); + ASSERT( pTrail != nullptr ); const int iNumCourseEntries = pTrail->m_vEntries.size(); if( iNumCourseEntries > CommonMetrics::MAX_COURSE_ENTRIES_BEFORE_VARIOUS ) bShowBpmInSpeedTitle = false; @@ -223,7 +223,7 @@ RString OptionRow::GetRowTitle() const const Course *pCourse = GAMESTATE->m_pCurCourse; StepsType st = GAMESTATE->GetCurrentStyle(GAMESTATE->GetMasterPlayerNumber())->m_StepsType; const Trail* pTrail = pCourse->GetTrail( st ); - ASSERT( pTrail != NULL ); + ASSERT( pTrail != nullptr ); pTrail->GetDisplayBpms( bpms ); } @@ -503,7 +503,7 @@ void OptionRow::PositionUnderlines( PlayerNumber pn ) void OptionRow::PositionIcons( PlayerNumber pn ) { ModIcon *pIcon = m_ModIcons[pn]; - if( pIcon == NULL ) + if( pIcon == nullptr ) return; pIcon->SetX( m_pParentType->MOD_ICON_X.GetValue(pn) ); @@ -650,7 +650,7 @@ void OptionRow::SetModIcon( PlayerNumber pn, const RString &sText, GameCommand & msg.SetParam( "GameCommand", &gc ); msg.SetParam( "Text", sText ); m_sprFrame->HandleMessage( msg ); - if( m_ModIcons[pn] != NULL ) + if( m_ModIcons[pn] != nullptr ) m_ModIcons[pn]->Set( sText ); } @@ -706,8 +706,7 @@ void OptionRow::SetOneSelection( PlayerNumber pn, int iChoice ) vector &vb = m_vbSelected[pn]; if( vb.empty() ) return; - FOREACH( bool, vb, b ) - *b = false; + std::fill_n(vb.begin(), vb.size(), false); vb[iChoice] = true; NotifyHandlerOfSelection(pn, iChoice); } @@ -882,10 +881,13 @@ void OptionRow::Reload() void OptionRow::HandleMessage( const Message &msg ) { bool bReload = false; - FOREACH_CONST( RString, m_pHand->m_vsReloadRowMessages, m ) + for (RString const &m : m_pHand->m_vsReloadRowMessages) { - if( *m == msg.GetName() ) + if( m == msg.GetName() ) + { bReload = true; + break; + } } if( bReload ) Reload(); @@ -907,12 +909,9 @@ void OptionRow::ImportOptions( const vector &vpns ) { ASSERT( m_pHand->m_Def.m_vsChoices.size() > 0 ); - FOREACH_CONST( PlayerNumber, vpns, iter ) + for (PlayerNumber const &p : vpns) { - PlayerNumber p = *iter; - - FOREACH( bool, m_vbSelected[p], b ) - *b = false; + std::fill_n(m_vbSelected[p].begin(), m_vbSelected[p].size(), false); ASSERT( m_vbSelected[p].size() == m_pHand->m_Def.m_vsChoices.size() ); ERASE_ONE_BOOL_AT_FRONT_IF_NEEDED( m_vbSelected[p] ); @@ -920,10 +919,8 @@ void OptionRow::ImportOptions( const vector &vpns ) m_pHand->ImportOption( this, vpns, m_vbSelected ); - FOREACH_CONST( PlayerNumber, vpns, iter ) + for (PlayerNumber const &p : vpns) { - PlayerNumber p = *iter; - INSERT_ONE_BOOL_AT_FRONT_IF_NEEDED( m_vbSelected[p] ); VerifySelected( m_pHand->m_Def.m_selectType, m_vbSelected[p], m_pHand->m_Def.m_sName ); } @@ -935,9 +932,8 @@ int OptionRow::ExportOptions( const vector &vpns, bool bRowHasFocu int iChangeMask = 0; - FOREACH_CONST( PlayerNumber, vpns, iter ) + for (PlayerNumber const &p : vpns) { - PlayerNumber p = *iter; bool bFocus = bRowHasFocus[p]; VerifySelected( m_pHand->m_Def.m_selectType, m_vbSelected[p], m_pHand->m_Def.m_sName ); @@ -952,9 +948,8 @@ int OptionRow::ExportOptions( const vector &vpns, bool bRowHasFocu iChangeMask |= m_pHand->ExportOption( vpns, m_vbSelected ); - FOREACH_CONST( PlayerNumber, vpns, iter ) + for (PlayerNumber const &p : vpns) { - PlayerNumber p = *iter; bool bFocus = bRowHasFocus[p]; int iChoice = GetChoiceInRowWithFocus( p ); diff --git a/src/OptionRow.h b/src/OptionRow.h index 2992d97f5b..71f184e1e8 100644 --- a/src/OptionRow.h +++ b/src/OptionRow.h @@ -9,6 +9,7 @@ #include "ModIcon.h" #include "ThemeMetric.h" #include "AutoActor.h" +#include class OptionRowHandler; class GameCommand; @@ -141,7 +142,7 @@ protected: ModIcon *m_ModIcons[NUM_PLAYERS]; bool m_bFirstItemGoesDown; - bool m_bRowHasFocus[NUM_PLAYERS]; + std::array m_bRowHasFocus; int m_iChoiceInRowWithFocus[NUM_PLAYERS]; // this choice has input focus // Only one will true at a time if m_pHand->m_Def.bMultiSelect diff --git a/src/OptionRowHandler.cpp b/src/OptionRowHandler.cpp index 0821f7057d..d066a0ad54 100644 --- a/src/OptionRowHandler.cpp +++ b/src/OptionRowHandler.cpp @@ -16,7 +16,6 @@ #include "SongUtil.h" #include "StepsUtil.h" #include "GameManager.h" -#include "Foreach.h" #include "GameSoundManager.h" #include "CommonMetrics.h" #include "CharacterManager.h" @@ -163,7 +162,7 @@ public: m_Def.m_bOneChoiceForAllPlayers = false; ROW_INVALID_IF(lCmds.v[0].m_vsArgs.size() != 1, "Row command has invalid args to number of entries.", false); - const int NumCols = StringToInt( lCmds.v[0].m_vsArgs[0] ); + const int NumCols = std::stoi( lCmds.v[0].m_vsArgs[0] ); ROW_INVALID_IF(NumCols < 1, "Not enough entries in list.", false); for( unsigned i=1; i= 0 && pn < NUM_PLAYERS ); m_Def.m_vEnabledForPlayers.insert( pn ); } @@ -229,7 +228,6 @@ public: } m_aListEntries.push_back( mc ); - RString sChoice = mc.m_sName; m_Def.m_vsChoices.push_back( sChoice ); } @@ -248,9 +246,8 @@ public: } void ImportOption( OptionRow *pRow, const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const { - FOREACH_CONST( PlayerNumber, vpns, pn ) + for (PlayerNumber const &p : vpns) { - PlayerNumber p = *pn; vector &vbSelOut = vbSelectedOut[p]; bool bUseFallbackOption = true; @@ -314,9 +311,8 @@ public: int ExportOption( const vector &vpns, const vector vbSelected[NUM_PLAYERS] ) const { - FOREACH_CONST( PlayerNumber, vpns, pn ) + for (PlayerNumber const &p : vpns) { - PlayerNumber p = *pn; const vector &vbSel = vbSelected[p]; m_Default.Apply( p ); @@ -326,8 +322,8 @@ public: m_aListEntries[i].Apply( p ); } } - FOREACH_CONST( RString, m_vsBroadcastOnExport, s ) - MESSAGEMAN->Broadcast( *s ); + for (RString const &s : m_vsBroadcastOnExport) + MESSAGEMAN->Broadcast( s ); return 0; } @@ -371,12 +367,12 @@ static void SortNoteSkins( vector &asSkinNames ) set setUnusedSkinNames( setSkinNames ); asSkinNames.clear(); - FOREACH( RString, asSorted, sSkin ) + for (RString const &sSkin : asSorted) { - if( setSkinNames.find(*sSkin) == setSkinNames.end() ) + if( setSkinNames.find(sSkin) == setSkinNames.end() ) continue; - asSkinNames.push_back( *sSkin ); - setUnusedSkinNames.erase( *sSkin ); + asSkinNames.push_back( sSkin ); + setUnusedSkinNames.erase( sSkin ); } asSkinNames.insert( asSkinNames.end(), setUnusedSkinNames.begin(), setUnusedSkinNames.end() ); @@ -528,8 +524,8 @@ public: void Init() { OptionRowHandler::Init(); - m_ppStepsToFill = NULL; - m_pDifficultyToFill = NULL; + m_ppStepsToFill = nullptr; + m_pDifficultyToFill = nullptr; m_vSteps.clear(); m_vDifficulties.clear(); } @@ -553,7 +549,7 @@ public: m_ppStepsToFill = &GAMESTATE->m_pEditSourceSteps; m_pst = &GAMESTATE->m_stEditSource; m_vsReloadRowMessages.push_back( MessageIDToString(Message_EditSourceStepsTypeChanged) ); - if( GAMESTATE->m_pCurSteps[0].Get() != NULL ) + if( GAMESTATE->m_pCurSteps[0].Get() != nullptr ) m_Def.m_vEnabledForPlayers.clear(); // hide row } else @@ -586,7 +582,7 @@ public: if( sParam == "EditSteps" ) { - m_vSteps.push_back( NULL ); + m_vSteps.push_back(nullptr); m_vDifficulties.push_back( Difficulty_Edit ); } @@ -613,7 +609,7 @@ public: else { m_vDifficulties.push_back( Difficulty_Edit ); - m_vSteps.push_back( NULL ); + m_vSteps.push_back(nullptr); m_Def.m_vsChoices.push_back( "none" ); } @@ -624,9 +620,8 @@ public: } virtual void ImportOption( OptionRow *pRow, const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const { - FOREACH_CONST( PlayerNumber, vpns, pn ) + for (PlayerNumber const &p : vpns) { - PlayerNumber p = *pn; vector &vbSelOut = vbSelectedOut[p]; ASSERT( m_vSteps.size() == vbSelOut.size() ); @@ -643,7 +638,8 @@ public: bool matched= false; if( m_pDifficultyToFill ) { - FOREACH_CONST( Difficulty, m_vDifficulties, d ) + // use the old style for now. + for (vector::const_iterator d = m_vDifficulties.begin(); d != m_vDifficulties.end(); ++d) { unsigned i = d - m_vDifficulties.begin(); if( *d == GAMESTATE->m_PreferredDifficulty[p] ) @@ -666,9 +662,8 @@ public: } virtual int ExportOption( const vector &vpns, const vector vbSelected[NUM_PLAYERS] ) const { - FOREACH_CONST( PlayerNumber, vpns, pn ) + for (PlayerNumber const &p : vpns) { - PlayerNumber p = *pn; const vector &vbSel = vbSelected[p]; int index = OptionRowHandlerUtil::GetOneSelection( vbSel ); @@ -696,7 +691,7 @@ class OptionRowHandlerListCharacters: public OptionRowHandlerList { m_Def.m_vsChoices.push_back( OFF ); GameCommand mc; - mc.m_pCharacter = NULL; + mc.m_pCharacter = nullptr; m_aListEntries.push_back( mc ); } @@ -728,11 +723,11 @@ class OptionRowHandlerListStyles: public OptionRowHandlerList vector vStyles; GAMEMAN->GetStylesForGame( GAMESTATE->m_pCurGame, vStyles ); ASSERT( vStyles.size() != 0 ); - FOREACH_CONST( const Style*, vStyles, s ) + for (Style const *s : vStyles) { - m_Def.m_vsChoices.push_back( GAMEMAN->StyleToLocalizedString(*s) ); + m_Def.m_vsChoices.push_back( GAMEMAN->StyleToLocalizedString(s) ); GameCommand mc; - mc.m_pStyle = *s; + mc.m_pStyle = s; m_aListEntries.push_back( mc ); } @@ -761,11 +756,11 @@ class OptionRowHandlerListGroups: public OptionRowHandlerList m_aListEntries.push_back( mc ); } - FOREACH_CONST( RString, vSongGroups, g ) + for (RString const &g : vSongGroups) { - m_Def.m_vsChoices.push_back( *g ); + m_Def.m_vsChoices.push_back( g ); GameCommand mc; - mc.m_sSongGroup = *g; + mc.m_sSongGroup = g; m_aListEntries.push_back( mc ); } return true; @@ -788,15 +783,15 @@ class OptionRowHandlerListDifficulties: public OptionRowHandlerList m_aListEntries.push_back( mc ); } - FOREACH_CONST( Difficulty, CommonMetrics::DIFFICULTIES_TO_SHOW.GetValue(), d ) + for (Difficulty const &d : CommonMetrics::DIFFICULTIES_TO_SHOW.GetValue()) { // TODO: Is this the best thing we can do here? StepsType st = GAMEMAN->GetHowToPlayStyleForGame( GAMESTATE->m_pCurGame )->m_StepsType; - RString s = CustomDifficultyToLocalizedString( GetCustomDifficulty(st, *d, CourseType_Invalid) ); + RString s = CustomDifficultyToLocalizedString( GetCustomDifficulty(st, d, CourseType_Invalid) ); m_Def.m_vsChoices.push_back( s ); GameCommand mc; - mc.m_dc = *d; + mc.m_dc = d; m_aListEntries.push_back( mc ); } return true; @@ -810,7 +805,7 @@ class OptionRowHandlerListSongsInCurrentSongGroup: public OptionRowHandlerList { const vector &vpSongs = SONGMAN->GetSongs( GAMESTATE->m_sPreferredSongGroup ); - if( GAMESTATE->m_pCurSong == NULL ) + if( GAMESTATE->m_pCurSong == nullptr ) GAMESTATE->m_pCurSong.Set( vpSongs[0] ); m_Def.m_sName = "SongsInCurrentSongGroup"; @@ -818,11 +813,11 @@ class OptionRowHandlerListSongsInCurrentSongGroup: public OptionRowHandlerList m_Def.m_layoutType = LAYOUT_SHOW_ONE_IN_ROW; m_Def.m_bExportOnChange = true; - FOREACH_CONST( Song*, vpSongs, p ) + for (Song *p : vpSongs) { - m_Def.m_vsChoices.push_back( (*p)->GetTranslitFullTitle() ); + m_Def.m_vsChoices.push_back( p->GetTranslitFullTitle() ); GameCommand mc; - mc.m_pSong = *p; + mc.m_pSong = p; m_aListEntries.push_back( mc ); } return true; @@ -858,7 +853,7 @@ public: m_pLuaTable->PushSelf(L); lua_getfield(L, -1, "Name"); const char *pStr = lua_tostring(L, -1); - if( pStr == NULL ) + if( pStr == nullptr ) { LuaHelpers::ReportScriptErrorFmt("LUA_ERROR: \"%s\" \"Name\" entry is not a string.", RowName.c_str()); return false; @@ -867,7 +862,7 @@ public: lua_getfield(L, -1, "LayoutType"); pStr = lua_tostring(L, -1); - if(pStr == NULL || StringToLayoutType(pStr) == LayoutType_Invalid) + if(pStr == nullptr || StringToLayoutType(pStr) == LayoutType_Invalid) { LuaHelpers::ReportScriptErrorFmt("LUA_ERROR: \"%s\" \"LayoutType\" entry is not a string.", RowName.c_str()); return false; @@ -876,7 +871,7 @@ public: lua_getfield(L, -1, "SelectType"); pStr = lua_tostring(L, -1); - if(pStr == NULL || StringToSelectType(pStr) == SelectType_Invalid) + if(pStr == nullptr || StringToSelectType(pStr) == SelectType_Invalid) { LuaHelpers::ReportScriptErrorFmt("LUA_ERROR: \"%s\" \"SelectType\" entry is not a string.", RowName.c_str()); return false; @@ -1176,9 +1171,8 @@ public: ASSERT( lua_gettop(L) == 0 ); - FOREACH_CONST( PlayerNumber, vpns, pn ) + for (PlayerNumber const &p : vpns) { - PlayerNumber p = *pn; vector &vbSelOut = vbSelectedOut[p]; /* Evaluate the LoadSelections(self,array,pn) function, where @@ -1235,9 +1229,8 @@ public: ASSERT( lua_gettop(L) == 0 ); int effects = 0; - FOREACH_CONST( PlayerNumber, vpns, pn ) + for (PlayerNumber const &p : vpns) { - PlayerNumber p = *pn; const vector &vbSel = vbSelected[p]; /* Evaluate SaveSelections(self,array,pn) function, where array is @@ -1341,7 +1334,7 @@ public: void Init() { OptionRowHandler::Init(); - m_pOpt = NULL; + m_pOpt = nullptr; } virtual bool LoadInternal( const Commands &cmds ) { @@ -1356,7 +1349,7 @@ public: m_Def.m_bOneChoiceForAllPlayers = true; ConfOption *pConfOption = ConfOption::Find( sParam ); - ROW_INVALID_IF(pConfOption == NULL, "Invalid Conf type \"" + sParam + "\".", false); + ROW_INVALID_IF(pConfOption == nullptr, "Invalid Conf type \"" + sParam + "\".", false); pConfOption->UpdateAvailableOptions(); @@ -1370,9 +1363,8 @@ public: } virtual void ImportOption( OptionRow *, const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const { - FOREACH_CONST( PlayerNumber, vpns, pn ) + for (PlayerNumber const &p : vpns) { - PlayerNumber p = *pn; vector &vbSelOut = vbSelectedOut[p]; int iSelection = m_pOpt->Get(); @@ -1383,9 +1375,8 @@ public: { bool bChanged = false; - FOREACH_CONST( PlayerNumber, vpns, pn ) + for (PlayerNumber const &p : vpns) { - PlayerNumber p = *pn; const vector &vbSel = vbSelected[p]; int iSel = OptionRowHandlerUtil::GetOneSelection(vbSel); @@ -1418,7 +1409,7 @@ public: void Init() { OptionRowHandler::Init(); - m_pstToFill = NULL; + m_pstToFill = nullptr; m_vStepsTypesToShow.clear(); } @@ -1438,7 +1429,7 @@ public: m_pstToFill = &GAMESTATE->m_stEditSource; m_vsReloadRowMessages.push_back( MessageIDToString(Message_CurrentStepsP1Changed) ); m_vsReloadRowMessages.push_back( MessageIDToString(Message_EditStepsTypeChanged) ); - if( GAMESTATE->m_pCurSteps[0].Get() != NULL ) + if( GAMESTATE->m_pCurSteps[0].Get() != nullptr ) m_Def.m_vEnabledForPlayers.clear(); // hide row } else @@ -1456,9 +1447,9 @@ public: m_vStepsTypesToShow = CommonMetrics::STEPS_TYPES_TO_SHOW.GetValue(); m_Def.m_vsChoices.clear(); - FOREACH_CONST( StepsType, m_vStepsTypesToShow, st ) + for (StepsType const &st : m_vStepsTypesToShow) { - RString s = GAMEMAN->GetStepsTypeInfo( *st ).GetLocalizedString(); + RString s = GAMEMAN->GetStepsTypeInfo( st ).GetLocalizedString(); m_Def.m_vsChoices.push_back( s ); } @@ -1469,9 +1460,8 @@ public: virtual void ImportOption( OptionRow *pRow, const vector &vpns, vector vbSelectedOut[NUM_PLAYERS] ) const { - FOREACH_CONST( PlayerNumber, vpns, pn ) + for (PlayerNumber const &p : vpns) { - PlayerNumber p = *pn; vector &vbSelOut = vbSelectedOut[p]; if( GAMESTATE->m_pCurSteps[0] ) @@ -1490,9 +1480,8 @@ public: } virtual int ExportOption( const vector &vpns, const vector vbSelected[NUM_PLAYERS] ) const { - FOREACH_CONST( PlayerNumber, vpns, pn ) + for (PlayerNumber const &p : vpns) { - PlayerNumber p = *pn; const vector &vbSel = vbSelected[p]; int index = OptionRowHandlerUtil::GetOneSelection( vbSel ); @@ -1561,12 +1550,12 @@ public: OptionRowHandler* OptionRowHandlerUtil::Make( const Commands &cmds ) { - OptionRowHandler* pHand = NULL; + OptionRowHandler* pHand = nullptr; - ROW_INVALID_IF(cmds.v.size() == 0, "No commands for constructing row.", NULL); + ROW_INVALID_IF(cmds.v.size() == 0, "No commands for constructing row.", nullptr); const RString &name = cmds.v[0].GetName(); ROW_INVALID_IF(name != "gamecommand" && cmds.v.size() != 1, - "Row must be constructed from single command.", NULL); + "Row must be constructed from single command.", nullptr); bool load_succeeded= false; #define MAKE( type ) { type *p = new type; load_succeeded= p->Load( cmds ); pHand = p; } @@ -1577,7 +1566,7 @@ OptionRowHandler* OptionRowHandlerUtil::Make( const Commands &cmds ) const Command &command = cmds.v[0]; RString sParam = command.GetArg(1).s; ROW_INVALID_IF(command.m_vsArgs.size() != 2 || !sParam.size(), - "list row command must be 'list,name' or 'list,type'.", NULL); + "list row command must be 'list,name' or 'list,type'.", nullptr); if( sParam.CompareNoCase("NoteSkins")==0 ) MAKE( OptionRowHandlerListNoteSkins ) else if( sParam.CompareNoCase("Steps")==0 ) MAKE( OptionRowHandlerListSteps ) @@ -1600,19 +1589,19 @@ OptionRowHandler* OptionRowHandlerUtil::Make( const Commands &cmds ) else if( name == "gamecommand" ) MAKE( OptionRowHandlerGameCommand ) else { - ROW_INVALID_IF(true, "Invalid row type.", NULL); + ROW_INVALID_IF(true, "Invalid row type.", nullptr); } if(load_succeeded) { return pHand; } - return NULL; + return nullptr; } OptionRowHandler* OptionRowHandlerUtil::MakeNull() { - OptionRowHandler* pHand = NULL; + OptionRowHandler* pHand = nullptr; bool load_succeeded= false; // Part of the MAKE macro, but unused. Commands cmds; MAKE( OptionRowHandlerNull ) @@ -1620,7 +1609,7 @@ OptionRowHandler* OptionRowHandlerUtil::MakeNull() { return pHand; } - return NULL; + return nullptr; } OptionRowHandler* OptionRowHandlerUtil::MakeSimple( const MenuRowDef &mr ) @@ -1652,8 +1641,8 @@ OptionRowHandler* OptionRowHandlerUtil::MakeSimple( const MenuRowDef &mr ) pHand->m_Def.m_bAllowThemeTitle = mr.bThemeTitle; pHand->m_Def.m_bAllowThemeItems = mr.bThemeItems; - FOREACH( RString, pHand->m_Def.m_vsChoices, c ) - FontCharAliases::ReplaceMarkers( *c ); // Allow special characters + for (RString &c : pHand->m_Def.m_vsChoices) + FontCharAliases::ReplaceMarkers( c ); // Allow special characters return pHand; } diff --git a/src/OptionRowHandler.h b/src/OptionRowHandler.h index b126634114..9937e93ef6 100644 --- a/src/OptionRowHandler.h +++ b/src/OptionRowHandler.h @@ -112,17 +112,17 @@ struct OptionRowDefinition m_bShowChoicesListOnSelect = false; } - OptionRowDefinition( const char *n, bool b, const char *c0=NULL, - const char *c1=NULL, const char *c2=NULL, - const char *c3=NULL, const char *c4=NULL, - const char *c5=NULL, const char *c6=NULL, - const char *c7=NULL, const char *c8=NULL, - const char *c9=NULL, const char *c10=NULL, - const char *c11=NULL, const char *c12=NULL, - const char *c13=NULL, const char *c14=NULL, - const char *c15=NULL, const char *c16=NULL, - const char *c17=NULL, const char *c18=NULL, - const char *c19=NULL ): m_sName(n), + OptionRowDefinition( const char *n, bool b, const char *c0=nullptr, + const char *c1=nullptr, const char *c2=nullptr, + const char *c3=nullptr, const char *c4=nullptr, + const char *c5=nullptr, const char *c6=nullptr, + const char *c7=nullptr, const char *c8=nullptr, + const char *c9=nullptr, const char *c10=nullptr, + const char *c11=nullptr, const char *c12=nullptr, + const char *c13=nullptr, const char *c14=nullptr, + const char *c15=nullptr, const char *c16=nullptr, + const char *c17=nullptr, const char *c18=nullptr, + const char *c19=nullptr ): m_sName(n), m_sExplanationName(""), m_bOneChoiceForAllPlayers(b), m_selectType(SELECT_ONE), m_layoutType(LAYOUT_SHOW_ALL_IN_ROW), m_vsChoices(), diff --git a/src/OptionsList.cpp b/src/OptionsList.cpp index 109cfecbad..8130a6a6b5 100644 --- a/src/OptionsList.cpp +++ b/src/OptionsList.cpp @@ -47,7 +47,7 @@ void OptionListRow::SetFromHandler( const OptionRowHandler *pHandler ) this->FinishTweening(); this->RemoveAllChildren(); - if( pHandler == NULL ) + if( pHandler == nullptr ) return; int iNum = max( pHandler->m_Def.m_vsChoices.size(), m_Text.size() )+1; @@ -101,7 +101,7 @@ void OptionListRow::SetFromHandler( const OptionRowHandler *pHandler ) void OptionListRow::SetTextFromHandler( const OptionRowHandler *pHandler ) { - ASSERT( pHandler != NULL ); + ASSERT( pHandler != nullptr ); for( unsigned i = 0; i < pHandler->m_Def.m_vsChoices.size(); ++i ) { // init text @@ -172,13 +172,13 @@ void OptionListRow::PositionCursor( Actor *pCursor, int iSelection ) OptionsList::OptionsList() { m_iCurrentRow = 0; - m_pLinked = NULL; + m_pLinked = nullptr; } OptionsList::~OptionsList() { - FOREACHM( RString, OptionRowHandler *, m_Rows, hand ) - delete hand->second; + for (std::pair hand : m_Rows) + delete hand.second; } //This is the initialization function. @@ -200,8 +200,8 @@ void OptionsList::Load( RString sType, PlayerNumber pn ) vector asDirectLines; split( DIRECT_LINES, ",", asDirectLines, true ); - FOREACH( RString, asDirectLines, s ) - m_setDirectRows.insert( *s ); + for (RString &s : asDirectLines) + m_setDirectRows.insert(s); vector setToLoad; split( TOP_MENUS, ",", setToLoad ); @@ -220,7 +220,7 @@ void OptionsList::Load( RString sType, PlayerNumber pn ) ParseCommands( sRowCommands, cmds, false ); OptionRowHandler *pHand = OptionRowHandlerUtil::Make( cmds ); - if( pHand == NULL ) + if( pHand == nullptr ) { LuaHelpers::ReportScriptErrorFmt("Invalid OptionRowHandler '%s' in %s::Line%s", cmds.GetOriginalCommandString().c_str(), m_sName.c_str(), sLineName.c_str()); continue; @@ -252,10 +252,9 @@ void OptionsList::Load( RString sType, PlayerNumber pn ) void OptionsList::Reset() { /* Import options. */ - FOREACHM( RString, OptionRowHandler *, m_Rows, hand ) + for (std::pair hand : m_Rows) { - RString sLineName = hand->first; - ImportRow( sLineName ); + ImportRow(hand.first); } } @@ -272,7 +271,7 @@ void OptionsList::Open() Push( TOP_MENU ); this->FinishTweening(); - m_Row[!m_iCurrentRow].SetFromHandler( NULL ); + m_Row[!m_iCurrentRow].SetFromHandler(nullptr); this->PlayCommand( "TweenOn" ); } @@ -532,7 +531,7 @@ void OptionsList::ImportRow( RString sRow ) vpns.push_back( m_pn ); OptionRowHandler *pHandler = m_Rows[sRow]; aSelections[ m_pn ].resize( pHandler->m_Def.m_vsChoices.size() ); - pHandler->ImportOption( NULL, vpns, aSelections ); + pHandler->ImportOption( nullptr, vpns, aSelections ); m_bSelections[sRow] = aSelections[ m_pn ]; if( m_setTopMenus.find(sRow) != m_setTopMenus.end() ) @@ -641,7 +640,7 @@ void OptionsList::SelectionsChanged( const RString &sRowName ) const OptionRowHandler *pHandler = m_Rows[sRowName]; vector &bSelections = m_bSelections[sRowName]; - if( pHandler->m_Def.m_bOneChoiceForAllPlayers && m_pLinked != NULL ) + if( pHandler->m_Def.m_bOneChoiceForAllPlayers && m_pLinked != nullptr ) { vector &bLinkedSelections = m_pLinked->m_bSelections[sRowName]; bLinkedSelections = bSelections; @@ -688,10 +687,10 @@ bool OptionsList::Start() GAMESTATE->ResetToDefaultSongOptions( ModsLevel_Preferred ); /* Import options. */ - FOREACHM( RString, OptionRowHandler *, m_Rows, hand ) + for (std::pair hand : m_Rows) { - ImportRow( hand->first ); - SelectionsChanged( hand->first ); + ImportRow( hand.first ); + SelectionsChanged( hand.first ); } UpdateMenuFromSelections(); diff --git a/src/PaneDisplay.cpp b/src/PaneDisplay.cpp index 226797f96e..918cbda56b 100644 --- a/src/PaneDisplay.cpp +++ b/src/PaneDisplay.cpp @@ -10,7 +10,6 @@ #include "Course.h" #include "Style.h" #include "ActorUtil.h" -#include "Foreach.h" #include "LuaManager.h" #include "XmlFile.h" #include "PlayerStageStats.h" @@ -131,7 +130,7 @@ void PaneDisplay::GetPaneTextAndLevel( PaneCategory c, RString & sTextOut, float const Steps *pSteps = GAMESTATE->m_pCurSteps[m_PlayerNumber]; const Course *pCourse = GAMESTATE->m_pCurCourse; const Trail *pTrail = GAMESTATE->m_pCurTrail[m_PlayerNumber]; - const Profile *pProfile = PROFILEMAN->IsPersistentProfile(m_PlayerNumber) ? PROFILEMAN->GetProfile(m_PlayerNumber) : NULL; + const Profile *pProfile = PROFILEMAN->IsPersistentProfile(m_PlayerNumber) ? PROFILEMAN->GetProfile(m_PlayerNumber) : nullptr; bool bIsPlayerEdit = pSteps && pSteps->IsAPlayerEdit(); // Defaults, will be filled in later @@ -191,7 +190,7 @@ void PaneDisplay::GetPaneTextAndLevel( PaneCategory c, RString & sTextOut, float { RadarValues rv; - HighScoreList *pHSL = NULL; + HighScoreList *pHSL = nullptr; ProfileSlot slot = ProfileSlot_Machine; switch( c ) { diff --git a/src/PercentageDisplay.cpp b/src/PercentageDisplay.cpp index 5eacb0952b..b67bdd9cc4 100644 --- a/src/PercentageDisplay.cpp +++ b/src/PercentageDisplay.cpp @@ -16,8 +16,8 @@ REGISTER_ACTOR_CLASS( PercentageDisplay ); PercentageDisplay::PercentageDisplay() { - m_pPlayerState = NULL; - m_pPlayerStageStats = NULL; + m_pPlayerState = nullptr; + m_pPlayerStageStats = nullptr; m_Last = -1; m_LastMax = -1; @@ -53,7 +53,7 @@ void PercentageDisplay::LoadFromNode( const XNode* pNode ) } const XNode *pChild = pNode->GetChild( "Percent" ); - if( pChild == NULL ) + if( pChild == nullptr ) { LuaHelpers::ReportScriptError(ActorUtil::GetWhere(pNode) + ": PercentageDisplay: missing the node \"Percent\""); // Make a BitmapText just so we don't crash. @@ -66,7 +66,7 @@ void PercentageDisplay::LoadFromNode( const XNode* pNode ) this->AddChild( &m_textPercent ); pChild = pNode->GetChild( "PercentRemainder" ); - if( !ShowDancePointsNotPercentage() && pChild != NULL ) + if( !ShowDancePointsNotPercentage() && pChild != nullptr ) { m_bUseRemainder = true; m_textPercentRemainder.LoadFromNode( pChild ); diff --git a/src/Player.cpp b/src/Player.cpp index e1c6579d45..37fbf0cc6a 100644 --- a/src/Player.cpp +++ b/src/Player.cpp @@ -238,27 +238,27 @@ Player::Player( NoteData &nd, bool bVisibleParts ) : m_NoteData(nd) m_inside_lua_set_life= false; m_oitg_zoom_mode= false; - m_pPlayerState = NULL; - m_pPlayerStageStats = NULL; + m_pPlayerState = nullptr; + m_pPlayerStageStats = nullptr; m_fNoteFieldHeight = 0; - m_pLifeMeter = NULL; - m_pCombinedLifeMeter = NULL; - m_pScoreDisplay = NULL; - m_pSecondaryScoreDisplay = NULL; - m_pPrimaryScoreKeeper = NULL; - m_pSecondaryScoreKeeper = NULL; - m_pInventory = NULL; - m_pIterNeedsTapJudging = NULL; - m_pIterNeedsHoldJudging = NULL; - m_pIterUncrossedRows = NULL; - m_pIterUnjudgedRows = NULL; - m_pIterUnjudgedMineRows = NULL; + m_pLifeMeter = nullptr; + m_pCombinedLifeMeter = nullptr; + m_pScoreDisplay = nullptr; + m_pSecondaryScoreDisplay = nullptr; + m_pPrimaryScoreKeeper = nullptr; + m_pSecondaryScoreKeeper = nullptr; + m_pInventory = nullptr; + m_pIterNeedsTapJudging = nullptr; + m_pIterNeedsHoldJudging = nullptr; + m_pIterUncrossedRows = nullptr; + m_pIterUnjudgedRows = nullptr; + m_pIterUnjudgedMineRows = nullptr; m_bPaused = false; m_bDelay = false; - m_pAttackDisplay = NULL; + m_pAttackDisplay = nullptr; if( bVisibleParts ) { m_pAttackDisplay = new AttackDisplay; @@ -267,7 +267,7 @@ Player::Player( NoteData &nd, bool bVisibleParts ) : m_NoteData(nd) PlayerAI::InitFromDisk(); - m_pNoteField = NULL; + m_pNoteField = nullptr; if( bVisibleParts ) { m_pNoteField = new NoteField; @@ -432,12 +432,12 @@ void Player::Init( if( GAMESTATE->IsCourseMode() ) { - ASSERT( GAMESTATE->m_pCurTrail[pn] != NULL ); + ASSERT( GAMESTATE->m_pCurTrail[pn] != nullptr ); GAMESTATE->m_pCurTrail[pn]->GetDisplayBpms( bpms ); } else { - ASSERT( GAMESTATE->m_pCurSong != NULL ); + ASSERT( GAMESTATE->m_pCurSong != nullptr ); GAMESTATE->m_pCurSong->GetDisplayBpms( bpms ); } @@ -468,13 +468,13 @@ void Player::Init( if( GAMESTATE->IsCourseMode() ) { - FOREACH_CONST( TrailEntry, GAMESTATE->m_pCurTrail[pn]->m_vEntries, e ) + for (TrailEntry const &e : GAMESTATE->m_pCurTrail[pn]->m_vEntries) { float fMaxForEntry; if (M_MOD_HIGH_CAP > 0) - e->pSong->m_SongTiming.GetActualBPM( fThrowAway, fMaxForEntry, M_MOD_HIGH_CAP ); + e.pSong->m_SongTiming.GetActualBPM( fThrowAway, fMaxForEntry, M_MOD_HIGH_CAP ); else - e->pSong->m_SongTiming.GetActualBPM( fThrowAway, fMaxForEntry ); + e.pSong->m_SongTiming.GetActualBPM( fThrowAway, fMaxForEntry ); fMaxBPM = max( fMaxForEntry, fMaxBPM ); } } @@ -517,14 +517,14 @@ void Player::Init( } else { - m_pActorWithComboPosition = NULL; - m_pActorWithJudgmentPosition = NULL; + m_pActorWithComboPosition = nullptr; + m_pActorWithJudgmentPosition = nullptr; } // Load HoldJudgments m_vpHoldJudgment.resize( GAMESTATE->GetCurrentStyle(GetPlayerState()->m_PlayerNumber)->m_iColsPerPlayer ); for( int i = 0; i < GAMESTATE->GetCurrentStyle(GetPlayerState()->m_PlayerNumber)->m_iColsPerPlayer; ++i ) - m_vpHoldJudgment[i] = NULL; + m_vpHoldJudgment[i] = nullptr; if( HasVisibleParts() ) { @@ -547,8 +547,7 @@ void Player::Init( } m_vbFretIsDown.resize( GAMESTATE->GetCurrentStyle(GetPlayerState()->m_PlayerNumber)->m_iColsPerPlayer ); - FOREACH( bool, m_vbFretIsDown, b ) - *b = false; + std::fill_n(m_vbFretIsDown.begin(), m_vbFretIsDown.size(), false); m_fActiveRandomAttackStart = -1.0f; } @@ -651,7 +650,7 @@ void Player::Load() PlayerNumber pn = m_pPlayerState->m_PlayerNumber; bool bOniDead = m_pPlayerState->m_PlayerOptions.GetStage().m_LifeType == LifeType_Battery && - (m_pPlayerStageStats == NULL || m_pPlayerStageStats->m_bFailed); + (m_pPlayerStageStats == nullptr || m_pPlayerStageStats->m_bFailed); /* The editor reuses Players ... so we really need to make sure everything * is reset and not tweening. Perhaps ActorFrame should recurse to subactors; @@ -817,7 +816,7 @@ void Player::Update( float fDeltaTime ) //LOG->Trace( "Player::Update(%f)", fDeltaTime ); - if( GAMESTATE->m_pCurSong==NULL || IsOniDead() ) + if( GAMESTATE->m_pCurSong== nullptr || IsOniDead() ) return; ActorFrame::Update( fDeltaTime ); @@ -909,14 +908,14 @@ void Player::Update( float fDeltaTime ) const bool bReverse = m_pPlayerState->m_PlayerOptions.GetCurrent().GetReversePercentForColumn(0) == 1; float fPercentCentered = m_pPlayerState->m_PlayerOptions.GetCurrent().m_fScrolls[PlayerOptions::SCROLL_CENTERED]; - if( m_pActorWithJudgmentPosition != NULL ) + if( m_pActorWithJudgmentPosition != nullptr ) { const Actor::TweenState &ts1 = m_tsJudgment[bReverse?1:0][0]; const Actor::TweenState &ts2 = m_tsJudgment[bReverse?1:0][1]; Actor::TweenState::MakeWeightedAverage( m_pActorWithJudgmentPosition->DestTweenState(), ts1, ts2, fPercentCentered ); } - if( m_pActorWithComboPosition != NULL ) + if( m_pActorWithComboPosition != nullptr ) { const Actor::TweenState &ts1 = m_tsCombo[bReverse?1:0][0]; const Actor::TweenState &ts2 = m_tsCombo[bReverse?1:0][1]; @@ -936,9 +935,9 @@ void Player::Update( float fDeltaTime ) m_pNoteField->SetZoom(field_zoom); } } - if( m_pActorWithJudgmentPosition != NULL ) + if( m_pActorWithJudgmentPosition != nullptr ) m_pActorWithJudgmentPosition->SetZoom( m_pActorWithJudgmentPosition->GetZoom() * fJudgmentZoom ); - if( m_pActorWithComboPosition != NULL ) + if( m_pActorWithComboPosition != nullptr ) m_pActorWithComboPosition->SetZoom( m_pActorWithComboPosition->GetZoom() * fJudgmentZoom ); } @@ -952,7 +951,7 @@ void Player::Update( float fDeltaTime ) ASSERT_M( iNumCols <= MAX_COLS_PER_PLAYER, ssprintf("%i > %i", iNumCols, MAX_COLS_PER_PLAYER) ); for( int col=0; col < iNumCols; ++col ) { - ASSERT( m_pPlayerState != NULL ); + ASSERT( m_pPlayerState != nullptr ); // TODO: Remove use of PlayerNumber. vector GameI; @@ -1119,11 +1118,11 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vectoriTrack; - ASSERT( iStartRow == trtn->iRow ); - TapNote &tn = *trtn->pTN; + int iTrack = trtn.iTrack; + ASSERT( iStartRow == trtn.iRow ); + TapNote &tn = *trtn.pTN; int iEndRow = iStartRow + tn.iDuration; if( subType == TapNoteSubType_Invalid ) subType = tn.subType; @@ -1144,15 +1143,15 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vectorTrace( ssprintf("first track with max end row = %i",iFirstTrackWithMaxEndRow) ); //LOG->Trace( ssprintf("max end row - start row (in beats) = %f",NoteRowToBeat(iMaxEndRow)-NoteRowToBeat(iStartRow)) ); - FOREACH( TrackRowTapNote, vTN, trtn ) + for (TrackRowTapNote const &trtn : vTN) { - TapNote &tn = *trtn->pTN; + TapNote &tn = *trtn.pTN; // set hold flags so NoteField can do intelligent drawing tn.HoldResult.bHeld = false; tn.HoldResult.bActive = false; - int iRow = trtn->iRow; + int iRow = trtn.iRow; //LOG->Trace( ssprintf("this row: %i",iRow) ); // If the song beat is in the range of this hold: @@ -1185,9 +1184,9 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vectorpTN; + TapNote &tn = *trtn.pTN; TapNoteScore tns = tn.result.tns; //LOG->Trace( ssprintf("[C++] tap note score: %s",StringConversion::ToString(tns).c_str()) ); @@ -1225,15 +1224,15 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vectorpTN->iDuration) > iSongRow ) + if( !IMMEDIATE_HOLD_LET_GO || (iStartRow + trtn.pTN->iDuration) > iSongRow ) { - int iTrack = trtn->iTrack; + int iTrack = trtn.iTrack; // TODO: Remove use of PlayerNumber. PlayerNumber pn = m_pPlayerState->m_PlayerNumber; @@ -1244,7 +1243,7 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vectorm_PlayerController == PC_AUTOPLAY ) { STATSMAN->m_CurStageStats.m_bUsedAutoplay = true; - if( m_pPlayerStageStats != NULL ) + if( m_pPlayerStageStats != nullptr ) m_pPlayerStageStats->m_bDisqualified = true; } } @@ -1265,13 +1264,13 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vectorpTN; + TapNote &tn = *trtn.pTN; int iEndRow = iStartRow + tn.iDuration; //LOG->Trace(ssprintf("trying for min between iSongRow (%i) and iEndRow (%i) (duration %i)",iSongRow,iEndRow,tn.iDuration)); - trtn->pTN->HoldResult.iLastHeldRow = min( iSongRow, iEndRow ); + tn.HoldResult.iLastHeldRow = min( iSongRow, iEndRow ); } } @@ -1281,9 +1280,9 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vectorpTN; + TapNote &tn = *trtn.pTN; // set hold flag so NoteField can do intelligent drawing tn.HoldResult.bHeld = bIsHoldingButton && bInitiatedNote; @@ -1320,9 +1319,9 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vectorpTN; + TapNote &tn = *trtn.pTN; tn.HoldResult.bHeld = true; tn.HoldResult.bActive = bInitiatedNote; } @@ -1394,10 +1393,10 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vectorTrace("(hold checkpoints are allowed and enabled.)"); int iCheckpointsHit = 0; int iCheckpointsMissed = 0; - FOREACH( TrackRowTapNote, vTN, v ) + for (TrackRowTapNote const &v : vTN) { - iCheckpointsHit += v->pTN->HoldResult.iCheckpointsHit; - iCheckpointsMissed += v->pTN->HoldResult.iCheckpointsMissed; + iCheckpointsHit += v.pTN->HoldResult.iCheckpointsHit; + iCheckpointsMissed += v.pTN->HoldResult.iCheckpointsMissed; } bLetGoOfHoldNote = iCheckpointsMissed > 0 || iCheckpointsHit == 0; @@ -1435,9 +1434,9 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vectorm_iCurCombo>(unsigned int)BRIGHT_GHOST_COMBO_THRESHOLD; if( m_pNoteField ) { - FOREACH( TrackRowTapNote, vTN, trtn ) + for (TrackRowTapNote const &trtn : vTN) { - int iTrack = trtn->iTrack; + int iTrack = trtn.iTrack; m_pNoteField->DidHoldNote( iTrack, HNS_Held, bBright ); // bright ghost flash } } @@ -1460,9 +1459,9 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vectorpTN; + TapNote &tn = *trtn.pTN; tn.HoldResult.fLife = fLife; tn.HoldResult.hns = hns; // Stop the playing keysound for the hold note. @@ -1471,7 +1470,7 @@ void Player::UpdateHoldNotes( int iSongRow, float fDeltaTime, vector *pVolume = Preference::GetPreferenceByName("SoundVolume"); - if (pVolume != NULL) + if (pVolume != nullptr) { float fVol = pVolume->Get(); @@ -2175,7 +2174,7 @@ void Player::Step( int col, int row, const RageTimer &tm, bool bHeld, bool bRele const float fSecondsFromExact = fabsf( fNoteOffset ); TapNote tnDummy = TAP_ORIGINAL_TAP; - TapNote *pTN = NULL; + TapNote *pTN = nullptr; NoteData::iterator iter = m_NoteData.FindTapNote( col, iRowOfOverlappingNoteOrRow ); DEBUG_ASSERT( iter!= m_NoteData.end(col) ); pTN = &iter->second; @@ -2652,11 +2651,11 @@ void Player::UpdateJudgedRows() *m_pIterUnjudgedMineRows= iter; } - FOREACHS( RageSound *, setSounds, s ) + for (RageSound *sound : setSounds) { // Only play one copy of each mine sound at a time per player. - (*s)->Stop(); - (*s)->Play(false); + sound->Stop(); + sound->Play(false); } } } @@ -2896,9 +2895,9 @@ void Player::HandleTapRowScore( unsigned row ) m_pSecondaryScoreKeeper->HandleTapScore( tn ); } - if( m_pPrimaryScoreKeeper != NULL ) + if( m_pPrimaryScoreKeeper != nullptr ) m_pPrimaryScoreKeeper->HandleTapRowScore( m_NoteData, row ); - if( m_pSecondaryScoreKeeper != NULL ) + if( m_pSecondaryScoreKeeper != nullptr ) m_pSecondaryScoreKeeper->HandleTapRowScore( m_NoteData, row ); const unsigned int iCurCombo = m_pPlayerStageStats ? m_pPlayerStageStats->m_iCurCombo : 0; @@ -2999,14 +2998,14 @@ void Player::HandleHoldCheckpoint(int iRow, if( iNumHoldsMissedThisRow == 0 ) { // added for http://ssc.ajworld.net/sm-ssc/bugtracker/view.php?id=16 -aj - if( CHECKPOINTS_FLASH_ON_HOLD ) + if( CHECKPOINTS_FLASH_ON_HOLD && m_pNoteField != nullptr) { - FOREACH_CONST( int, viColsWithHold, i ) + for (int const &i : viColsWithHold) { bool bBright = m_pPlayerStageStats && m_pPlayerStageStats->m_iCurCombo>(unsigned int)BRIGHT_GHOST_COMBO_THRESHOLD; if( m_pNoteField ) - m_pNoteField->DidHoldNote( *i, HNS_Held, bBright ); + m_pNoteField->DidHoldNote( i, HNS_Held, bBright ); } } } diff --git a/src/Player.h b/src/Player.h index 04459beaa4..4c5b310a54 100644 --- a/src/Player.h +++ b/src/Player.h @@ -117,7 +117,7 @@ public: static float GetMaxStepDistanceSeconds(); static float GetWindowSeconds( TimingWindow tw ); const NoteData &GetNoteData() const { return m_NoteData; } - bool HasVisibleParts() const { return m_pNoteField != NULL; } + bool HasVisibleParts() const { return m_pNoteField != nullptr; } void SetActorWithJudgmentPosition( Actor *pActor ) { m_pActorWithJudgmentPosition = pActor; } void SetActorWithComboPosition( Actor *pActor ) { m_pActorWithComboPosition = pActor; } diff --git a/src/PlayerAI.cpp b/src/PlayerAI.cpp index 29b73a9bf7..44cf43e706 100644 --- a/src/PlayerAI.cpp +++ b/src/PlayerAI.cpp @@ -72,7 +72,7 @@ void PlayerAI::InitFromDisk() RString sKey = ssprintf("Skill%d", i); XNode* pNode = ini.GetChild(sKey); TapScoreDistribution& dist = g_Distributions[i]; - if( pNode == NULL ) + if( pNode == nullptr ) { LuaHelpers::ReportScriptErrorFmt("AI.ini: \"%s\" section doesn't exist.", sKey.c_str()); dist.SetDefaultWeights(); diff --git a/src/PlayerOptions.cpp b/src/PlayerOptions.cpp index de5efedf86..f886cb8888 100644 --- a/src/PlayerOptions.cpp +++ b/src/PlayerOptions.cpp @@ -7,7 +7,6 @@ #include "Course.h" #include "Steps.h" #include "ThemeManager.h" -#include "Foreach.h" #include "Style.h" #include "CommonMetrics.h" #include @@ -564,18 +563,18 @@ void PlayerOptions::FromString( const RString &sMultipleMods ) vector vs; split( sTemp, ",", vs, true ); RString sThrowAway; - FOREACH( RString, vs, s ) + for (RString &s : vs) { - if (!FromOneModString( *s, sThrowAway )) + if (!FromOneModString( s, sThrowAway )) { - LOG->Trace( "Attempted to load a non-existing mod \'%s\' for the Player. Ignoring.", (*s).c_str() ); + LOG->Trace( "Attempted to load a non-existing mod \'%s\' for the Player. Ignoring.", s.c_str() ); } } } bool PlayerOptions::FromOneModString( const RString &sOneMod, RString &sErrorOut ) { - ASSERT_M( NOTESKIN != NULL, "The Noteskin Manager must be loaded in order to process mods." ); + ASSERT_M( NOTESKIN != nullptr, "The Noteskin Manager must be loaded in order to process mods." ); RString sBit = sOneMod; RString sMod = ""; @@ -592,31 +591,31 @@ bool PlayerOptions::FromOneModString( const RString &sOneMod, RString &sErrorOut vector asParts; split( sBit, " ", asParts, true ); - FOREACH_CONST( RString, asParts, s ) + for (RString const &s : asParts) { - if( *s == "no" ) + if( s == "no" ) { level = 0; } - else if( isdigit((*s)[0]) || (*s)[0] == '-' ) + else if( isdigit(s[0]) || s[0] == '-' ) { /* If the last character is a *, they probably said "123*" when * they meant "*123". */ - if( s->Right(1) == "*" ) + if( s.Right(1) == "*" ) { // XXX: We know what they want, is there any reason not to handle it? // Yes. We should be strict in handling the format. -Chris - sErrorOut = ssprintf("Invalid player options \"%s\"; did you mean '*%d'?", s->c_str(), StringToInt(*s) ); + sErrorOut = ssprintf("Invalid player options \"%s\"; did you mean '*%d'?", s.c_str(), std::stoi(s) ); return false; } else { - level = StringToFloat( *s ) / 100.0f; + level = StringToFloat( s ) / 100.0f; } } - else if( *s[0]=='*' ) + else if( s[0]=='*' ) { - sscanf( *s, "*%f", &speed ); + sscanf( s, "*%f", &speed ); if( !isfinite(speed) ) speed = 1.0f; } @@ -1313,7 +1312,7 @@ float PlayerOptions::GetReversePercentForColumn( int iCol ) const { float f = 0; ASSERT(m_pn == PLAYER_1 || m_pn == PLAYER_2); - ASSERT(GAMESTATE->GetCurrentStyle(m_pn) != NULL); + ASSERT(GAMESTATE->GetCurrentStyle(m_pn) != nullptr); int iNumCols = GAMESTATE->GetCurrentStyle(m_pn)->m_iColsPerPlayer; f += m_fScrolls[SCROLL_REVERSE]; @@ -1599,25 +1598,20 @@ bool PlayerOptions::IsEasierForSongAndSteps( Song* pSong, Steps* pSteps, PlayerN bool PlayerOptions::IsEasierForCourseAndTrail( Course* pCourse, Trail* pTrail ) const { - ASSERT( pCourse != NULL ); - ASSERT( pTrail != NULL ); + ASSERT( pCourse != nullptr ); + ASSERT( pTrail != nullptr ); - FOREACH_CONST( TrailEntry, pTrail->m_vEntries, e ) - { - if( e->pSong && IsEasierForSongAndSteps(e->pSong, e->pSteps, PLAYER_1) ) - return true; - } - return false; + return std::any_of(pTrail->m_vEntries.begin(), pTrail->m_vEntries.end(), [&](TrailEntry const &e) { + return e.pSong && IsEasierForSongAndSteps(e.pSong, e.pSteps, PLAYER_1); + }); } void PlayerOptions::GetLocalizedMods( vector &AddTo ) const { vector vMods; GetMods( vMods ); - FOREACH_CONST( RString, vMods, s ) + for (RString const &sOneMod : vMods) { - const RString& sOneMod = *s; - ASSERT( !sOneMod.empty() ); vector asTokens; diff --git a/src/PlayerStageStats.cpp b/src/PlayerStageStats.cpp index 7178216ea2..247f4cd4d1 100644 --- a/src/PlayerStageStats.cpp +++ b/src/PlayerStageStats.cpp @@ -2,7 +2,6 @@ #include "PlayerStageStats.h" #include "RageLog.h" #include "ThemeManager.h" -#include "Foreach.h" #include "LuaManager.h" #include #include "GameState.h" @@ -27,7 +26,7 @@ Grade GetGradeFromPercent( float fPercent ); void PlayerStageStats::InternalInit() { - m_pStyle= NULL; + m_pStyle= nullptr; m_for_multiplayer= false; m_player_number= PLAYER_1; m_multiplayer_number= MultiPlayer_P1; @@ -88,8 +87,8 @@ void PlayerStageStats::AddStats( const PlayerStageStats& other ) { m_pStyle= other.m_pStyle; m_bJoined = other.m_bJoined; - FOREACH_CONST( Steps*, other.m_vpPossibleSteps, s ) - m_vpPossibleSteps.push_back( *s ); + for (Steps *s : other.m_vpPossibleSteps) + m_vpPossibleSteps.push_back( s ); m_iStepsPlayed += other.m_iStepsPlayed; m_fAliveSeconds += other.m_fAliveSeconds; m_bFailed |= other.m_bFailed; @@ -335,13 +334,8 @@ int PlayerStageStats::GetLessonScoreActual() const int PlayerStageStats::GetLessonScoreNeeded() const { - float fScore = 0; - - FOREACH_CONST( Steps*, m_vpPossibleSteps, steps ) - { - fScore += (*steps)->GetRadarValues(PLAYER_1)[RadarCategory_TapsAndHolds]; - } - + float fScore = std::accumulate(m_vpPossibleSteps.begin(), m_vpPossibleSteps.end(), 0.f, + [](float total, Steps const *steps) { return total + steps->GetRadarValues(PLAYER_1)[RadarCategory_TapsAndHolds]; }); return lrintf( fScore * LESSON_PASS_THRESHOLD ); } diff --git a/src/PlayerState.cpp b/src/PlayerState.cpp index ae1403888b..5ed8c66210 100644 --- a/src/PlayerState.cpp +++ b/src/PlayerState.cpp @@ -1,6 +1,5 @@ #include "global.h" #include "PlayerState.h" -#include "Foreach.h" #include "GameState.h" #include "RageLog.h" #include "RadarValues.h" @@ -142,8 +141,8 @@ void PlayerState::RemoveActiveAttacks( AttackLevel al ) void PlayerState::EndActiveAttacks() { - FOREACH( Attack, m_ActiveAttacks, a ) - a->fSecsRemaining = 0; + for (Attack &a : m_ActiveAttacks) + a.fSecsRemaining = 0; } void PlayerState::RemoveAllInventory() @@ -205,7 +204,7 @@ const SongPosition &PlayerState::GetDisplayedPosition() const const TimingData &PlayerState::GetDisplayedTiming() const { Steps *steps = GAMESTATE->m_pCurSteps[m_PlayerNumber]; - if( steps == NULL ) + if( steps == nullptr ) return GAMESTATE->m_pCurSong->m_SongTiming; return *steps->GetTimingData(); } diff --git a/src/Preference.cpp b/src/Preference.cpp index 50792ed0b5..0c68f9b907 100644 --- a/src/Preference.cpp +++ b/src/Preference.cpp @@ -5,7 +5,7 @@ #include "LuaManager.h" #include "MessageManager.h" #include "SubscriptionManager.h" -#include "Foreach.h" + static SubscriptionManager m_Subscribers; @@ -23,40 +23,40 @@ IPreference::~IPreference() IPreference *IPreference::GetPreferenceByName( const RString &sName ) { - FOREACHS( IPreference*, *m_Subscribers.m_pSubscribers, p ) + for (IPreference *p : *m_Subscribers.m_pSubscribers) { - if( !(*p)->GetName().CompareNoCase( sName ) ) - return *p; + if( !p->GetName().CompareNoCase( sName ) ) + return p; } - return NULL; + return nullptr; } void IPreference::LoadAllDefaults() { - FOREACHS_CONST( IPreference*, *m_Subscribers.m_pSubscribers, p ) - (*p)->LoadDefault(); + for (IPreference *p : *m_Subscribers.m_pSubscribers) + p->LoadDefault(); } void IPreference::ReadAllPrefsFromNode( const XNode* pNode, bool bIsStatic ) { - ASSERT( pNode != NULL ); - FOREACHS_CONST( IPreference*, *m_Subscribers.m_pSubscribers, p ) - (*p)->ReadFrom( pNode, bIsStatic ); + ASSERT( pNode != nullptr ); + for (IPreference *p : *m_Subscribers.m_pSubscribers) + p->ReadFrom( pNode, bIsStatic ); } void IPreference::SavePrefsToNode( XNode* pNode ) { - FOREACHS_CONST( IPreference*, *m_Subscribers.m_pSubscribers, p ) - (*p)->WriteTo( pNode ); + for (IPreference *p : *m_Subscribers.m_pSubscribers) + p->WriteTo( pNode ); } void IPreference::ReadAllDefaultsFromNode( const XNode* pNode ) { - if( pNode == NULL ) + if( pNode == nullptr ) return; - FOREACHS_CONST( IPreference*, *m_Subscribers.m_pSubscribers, p ) - (*p)->ReadDefaultFrom( pNode ); + for (IPreference *p : *m_Subscribers.m_pSubscribers) + p->ReadDefaultFrom( pNode ); } void IPreference::PushValue( lua_State *L ) const diff --git a/src/Preference.h b/src/Preference.h index a1f7cc6186..91c6f69006 100644 --- a/src/Preference.h +++ b/src/Preference.h @@ -1,185 +1,185 @@ -/* Preference - Holds user-chosen preferences that are saved between sessions. */ - -#ifndef PREFERENCE_H -#define PREFERENCE_H - -#include "EnumHelper.h" -#include "LuaManager.h" -#include "RageUtil.h" -class XNode; - -struct lua_State; -class IPreference -{ -public: - IPreference( const RString& sName ); - virtual ~IPreference(); - void ReadFrom( const XNode* pNode, bool bIsStatic ); - void WriteTo( XNode* pNode ) const; - void ReadDefaultFrom( const XNode* pNode ); - - virtual void LoadDefault() = 0; - virtual void SetDefaultFromString( const RString &s ) = 0; - - virtual RString ToString() const = 0; - virtual void FromString( const RString &s ) = 0; - - virtual void SetFromStack( lua_State *L ); - virtual void PushValue( lua_State *L ) const; - - const RString &GetName() const { return m_sName; } - - static IPreference *GetPreferenceByName( const RString &sName ); - static void LoadAllDefaults(); - static void ReadAllPrefsFromNode( const XNode* pNode, bool bIsStatic ); - static void SavePrefsToNode( XNode* pNode ); - static void ReadAllDefaultsFromNode( const XNode* pNode ); - - RString GetName() { return m_sName; } - void SetStatic( bool b ) { m_bIsStatic = b; } -private: - RString m_sName; - bool m_bIsStatic; // loaded from Static.ini? If so, don't write to Preferences.ini -}; - -void BroadcastPreferenceChanged( const RString& sPreferenceName ); - -template -class Preference : public IPreference -{ -public: - Preference( const RString& sName, const T& defaultValue, void (pfnValidate)(T& val) = NULL ): - IPreference( sName ), - m_currentValue( defaultValue ), - m_defaultValue( defaultValue ), - m_pfnValidate( pfnValidate ) - { - LoadDefault(); - } - - RString ToString() const { return StringConversion::ToString( m_currentValue ); } - void FromString( const RString &s ) - { - if( !StringConversion::FromString(s, m_currentValue) ) - m_currentValue = m_defaultValue; - if( m_pfnValidate ) - m_pfnValidate( m_currentValue ); - } - void SetFromStack( lua_State *L ) - { - LuaHelpers::Pop( L, m_currentValue ); - if( m_pfnValidate ) - m_pfnValidate( m_currentValue ); - } - void PushValue( lua_State *L ) const - { - LuaHelpers::Push( L, m_currentValue ); - } - - void LoadDefault() - { - m_currentValue = m_defaultValue; - } - void SetDefaultFromString( const RString &s ) - { - T def = m_defaultValue; - if( !StringConversion::FromString(s, m_defaultValue) ) - m_defaultValue = def; - } - - const T &Get() const - { - return m_currentValue; - } - - const T &GetDefault() const - { - return m_defaultValue; - } - - operator const T () const - { - return Get(); - } - - void Set( const T& other ) - { - m_currentValue = other; - BroadcastPreferenceChanged( GetName() ); - } - - static Preference *GetPreferenceByName( const RString &sName ) - { - IPreference *pPreference = IPreference::GetPreferenceByName( sName ); - Preference *pRet = dynamic_cast *>(pPreference); - return pRet; - } - -private: - T m_currentValue; - T m_defaultValue; - void (*m_pfnValidate)(T& val); -}; - -/** @brief Utilities for working with Lua. */ -namespace LuaHelpers { template void Push( lua_State *L, const Preference &Object ) { LuaHelpers::Push( L, Object.Get() ); } } - -template -class Preference1D -{ -public: - typedef Preference PreferenceT; - vector m_v; - - Preference1D( void pfn(size_t i, RString &sNameOut, T &defaultValueOut ), size_t N ) - { - for( size_t i=0; i(sName, defaultValue) ); - } - } - - ~Preference1D() - { - for( size_t i=0; i& operator[]( size_t i ) const - { - return *m_v[i]; - } - Preference& operator[]( size_t i ) - { - return *m_v[i]; - } -}; - -#endif - -/* - * (c) 2001-2004 Chris Danford, Chris Gomez - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +/* Preference - Holds user-chosen preferences that are saved between sessions. */ + +#ifndef PREFERENCE_H +#define PREFERENCE_H + +#include "EnumHelper.h" +#include "LuaManager.h" +#include "RageUtil.h" +class XNode; + +struct lua_State; +class IPreference +{ +public: + IPreference( const RString& sName ); + virtual ~IPreference(); + void ReadFrom( const XNode* pNode, bool bIsStatic ); + void WriteTo( XNode* pNode ) const; + void ReadDefaultFrom( const XNode* pNode ); + + virtual void LoadDefault() = 0; + virtual void SetDefaultFromString( const RString &s ) = 0; + + virtual RString ToString() const = 0; + virtual void FromString( const RString &s ) = 0; + + virtual void SetFromStack( lua_State *L ); + virtual void PushValue( lua_State *L ) const; + + const RString &GetName() const { return m_sName; } + + static IPreference *GetPreferenceByName( const RString &sName ); + static void LoadAllDefaults(); + static void ReadAllPrefsFromNode( const XNode* pNode, bool bIsStatic ); + static void SavePrefsToNode( XNode* pNode ); + static void ReadAllDefaultsFromNode( const XNode* pNode ); + + RString GetName() { return m_sName; } + void SetStatic( bool b ) { m_bIsStatic = b; } +private: + RString m_sName; + bool m_bIsStatic; // loaded from Static.ini? If so, don't write to Preferences.ini +}; + +void BroadcastPreferenceChanged( const RString& sPreferenceName ); + +template +class Preference : public IPreference +{ +public: + Preference( const RString& sName, const T& defaultValue, void (pfnValidate)(T& val) = nullptr ): + IPreference( sName ), + m_currentValue( defaultValue ), + m_defaultValue( defaultValue ), + m_pfnValidate( pfnValidate ) + { + LoadDefault(); + } + + RString ToString() const { return StringConversion::ToString( m_currentValue ); } + void FromString( const RString &s ) + { + if( !StringConversion::FromString(s, m_currentValue) ) + m_currentValue = m_defaultValue; + if( m_pfnValidate ) + m_pfnValidate( m_currentValue ); + } + void SetFromStack( lua_State *L ) + { + LuaHelpers::Pop( L, m_currentValue ); + if( m_pfnValidate ) + m_pfnValidate( m_currentValue ); + } + void PushValue( lua_State *L ) const + { + LuaHelpers::Push( L, m_currentValue ); + } + + void LoadDefault() + { + m_currentValue = m_defaultValue; + } + void SetDefaultFromString( const RString &s ) + { + T def = m_defaultValue; + if( !StringConversion::FromString(s, m_defaultValue) ) + m_defaultValue = def; + } + + const T &Get() const + { + return m_currentValue; + } + + const T &GetDefault() const + { + return m_defaultValue; + } + + operator const T () const + { + return Get(); + } + + void Set( const T& other ) + { + m_currentValue = other; + BroadcastPreferenceChanged( GetName() ); + } + + static Preference *GetPreferenceByName( const RString &sName ) + { + IPreference *pPreference = IPreference::GetPreferenceByName( sName ); + Preference *pRet = dynamic_cast *>(pPreference); + return pRet; + } + +private: + T m_currentValue; + T m_defaultValue; + void (*m_pfnValidate)(T& val); +}; + +/** @brief Utilities for working with Lua. */ +namespace LuaHelpers { template void Push( lua_State *L, const Preference &Object ) { LuaHelpers::Push( L, Object.Get() ); } } + +template +class Preference1D +{ +public: + typedef Preference PreferenceT; + vector m_v; + + Preference1D( void pfn(size_t i, RString &sNameOut, T &defaultValueOut ), size_t N ) + { + for( size_t i=0; i(sName, defaultValue) ); + } + } + + ~Preference1D() + { + for( size_t i=0; i& operator[]( size_t i ) const + { + return *m_v[i]; + } + Preference& operator[]( size_t i ) + { + return *m_v[i]; + } +}; + +#endif + +/* + * (c) 2001-2004 Chris Danford, Chris Gomez + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/PrefsManager.cpp b/src/PrefsManager.cpp index 9806269056..3d46b89de8 100644 --- a/src/PrefsManager.cpp +++ b/src/PrefsManager.cpp @@ -1,6 +1,5 @@ #include "global.h" #include "PrefsManager.h" -#include "Foreach.h" #include "IniFile.h" #include "LuaManager.h" #include "Preference.h" @@ -20,7 +19,7 @@ //STATIC_INI_PATH = "Data/Static.ini"; // overlay on the 2 above, can't be overridden //TYPE_TXT_FILE = "Data/Type.txt"; -PrefsManager* PREFSMAN = NULL; // global and accessible from anywhere in our program +PrefsManager* PREFSMAN = nullptr; // global and accessible from anywhere in our program static const char *MusicWheelUsesSectionsNames[] = { "Never", @@ -371,7 +370,7 @@ void PrefsManager::StoreGamePrefs() ASSERT( !m_sCurrentGame.Get().empty() ); // save off old values - GamePrefs &gp = m_mapGameNameToGamePrefs[m_sCurrentGame.Get()]; + GamePrefs &gp = m_mapGameNameToGamePrefs.at(m_sCurrentGame.Get()); gp.m_sAnnouncer = m_sAnnouncer; gp.m_sTheme = m_sTheme; gp.m_sDefaultModifiers = m_sDefaultModifiers; @@ -446,7 +445,7 @@ void PrefsManager::ReadPrefsFromIni( const IniFile &ini, const RString &sSection /* IPreference *pPref = PREFSMAN->GetPreferenceByName( *sName ); - if( pPref == NULL ) + if( pPref == nullptr ) { LOG->Warn( "Unknown preference in [%s]: %s", sClassName.c_str(), sName->c_str() ); continue; @@ -514,18 +513,18 @@ void PrefsManager::SavePrefsToIni( IniFile &ini ) StoreGamePrefs(); XNode* pNode = ini.GetChild( "Options" ); - if( pNode == NULL ) + if( pNode == nullptr ) pNode = ini.AppendChild( "Options" ); IPreference::SavePrefsToNode( pNode ); - FOREACHM_CONST( RString, GamePrefs, m_mapGameNameToGamePrefs, iter ) + for (auto const &iter : m_mapGameNameToGamePrefs) { - RString sSection = "Game-" + RString( iter->first ); + RString sSection = "Game-" + RString( iter.first ); // todo: write more values here? -aj - ini.SetValue( sSection, "Announcer", iter->second.m_sAnnouncer ); - ini.SetValue( sSection, "Theme", iter->second.m_sTheme ); - ini.SetValue( sSection, "DefaultModifiers", iter->second.m_sDefaultModifiers ); + ini.SetValue( sSection, "Announcer", iter.second.m_sAnnouncer ); + ini.SetValue( sSection, "Theme", iter.second.m_sTheme ); + ini.SetValue( sSection, "DefaultModifiers", iter.second.m_sDefaultModifiers ); } } @@ -555,7 +554,7 @@ public: { RString sName = SArg(1); IPreference *pPref = IPreference::GetPreferenceByName( sName ); - if( pPref == NULL ) + if( pPref == nullptr ) { LuaHelpers::ReportScriptErrorFmt( "GetPreference: unknown preference \"%s\"", sName.c_str() ); lua_pushnil( L ); @@ -570,7 +569,7 @@ public: RString sName = SArg(1); IPreference *pPref = IPreference::GetPreferenceByName( sName ); - if( pPref == NULL ) + if( pPref == nullptr ) { LuaHelpers::ReportScriptErrorFmt( "SetPreference: unknown preference \"%s\"", sName.c_str() ); COMMON_RETURN_SELF; @@ -585,7 +584,7 @@ public: RString sName = SArg(1); IPreference *pPref = IPreference::GetPreferenceByName( sName ); - if( pPref == NULL ) + if( pPref == nullptr ) { LuaHelpers::ReportScriptErrorFmt( "SetPreferenceToDefault: unknown preference \"%s\"", sName.c_str() ); COMMON_RETURN_SELF; @@ -600,7 +599,7 @@ public: RString sName = SArg(1); IPreference *pPref = IPreference::GetPreferenceByName( sName ); - if( pPref == NULL ) + if( pPref == nullptr ) { lua_pushboolean( L, false ); return 1; diff --git a/src/Profile.cpp b/src/Profile.cpp index 97a7704448..f5837bf4c9 100644 --- a/src/Profile.cpp +++ b/src/Profile.cpp @@ -21,7 +21,6 @@ #include "UnlockManager.h" #include "XmlFile.h" #include "XmlFileUtil.h" -#include "Foreach.h" #include "Bookkeeper.h" #include "Game.h" #include "CharacterManager.h" @@ -91,7 +90,7 @@ void Profile::ClearSongs() Song* curr_song= m_songs[i]; if(curr_song == gamestate_curr_song) { - GAMESTATE->m_pCurSong.Set(NULL); + GAMESTATE->m_pCurSong.Set(nullptr); } delete curr_song; } @@ -101,9 +100,9 @@ void Profile::ClearSongs() int Profile::HighScoresForASong::GetNumTimesPlayed() const { int iCount = 0; - FOREACHM_CONST( StepsID, HighScoresForASteps, m_StepsHighScores, i ) + for (std::pair const &i : m_StepsHighScores) { - iCount += i->second.hsl.GetNumTimesPlayed(); + iCount += i.second.hsl.GetNumTimesPlayed(); } return iCount; } @@ -111,9 +110,9 @@ int Profile::HighScoresForASong::GetNumTimesPlayed() const int Profile::HighScoresForACourse::GetNumTimesPlayed() const { int iCount = 0; - FOREACHM_CONST( TrailID, HighScoresForATrail, m_TrailHighScores, i ) + for (std::pair const &i : m_TrailHighScores) { - iCount += i->second.hsl.GetNumTimesPlayed(); + iCount += i.second.hsl.GetNumTimesPlayed(); } return iCount; } @@ -238,10 +237,10 @@ Character *Profile::GetCharacter() const { vector vpCharacters; CHARMAN->GetCharacters( vpCharacters ); - FOREACH_CONST( Character*, vpCharacters, c ) + for (Character *c : vpCharacters) { - if( (*c)->m_sCharacterID.CompareNoCase(m_sCharacterID)==0 ) - return *c; + if( c->m_sCharacterID.CompareNoCase(m_sCharacterID)==0 ) + return c; } return CHARMAN->GetDefaultCharacter(); } @@ -303,20 +302,20 @@ int Profile::GetTotalStepsWithTopGrade( StepsType st, Difficulty d, Grade g ) co { int iCount = 0; - FOREACH_CONST( Song*, SONGMAN->GetAllSongs(), pSong ) + for (Song *pSong : SONGMAN->GetAllSongs()) { - if( !(*pSong)->NormallyDisplayed() ) + if( !pSong->NormallyDisplayed() ) continue; // skip - FOREACH_CONST( Steps*, (*pSong)->GetAllSteps(), pSteps ) + for (Steps *pSteps : pSong->GetAllSteps()) { - if( (*pSteps)->m_StepsType != st ) + if( pSteps->m_StepsType != st ) continue; // skip - if( (*pSteps)->GetDifficulty() != d ) + if( pSteps->GetDifficulty() != d ) continue; // skip - const HighScoreList &hsl = GetStepsHighScoreList( *pSong, *pSteps ); + const HighScoreList &hsl = GetStepsHighScoreList( pSong, pSteps ); if( hsl.vHighScores.empty() ) continue; // skip @@ -335,18 +334,18 @@ int Profile::GetTotalTrailsWithTopGrade( StepsType st, CourseDifficulty d, Grade // add course high scores vector vCourses; SONGMAN->GetAllCourses( vCourses, false ); - FOREACH_CONST( Course*, vCourses, pCourse ) + for (Course const *pCourse : vCourses) { // Don't count any course that has any entries that change over time. - if( !(*pCourse)->AllSongsAreFixed() ) + if( !pCourse->AllSongsAreFixed() ) continue; vector vTrails; - Trail* pTrail = (*pCourse)->GetTrail( st, d ); - if( pTrail == NULL ) + Trail* pTrail = pCourse->GetTrail( st, d ); + if( pTrail == nullptr ) continue; - const HighScoreList &hsl = GetCourseHighScoreList( *pCourse, pTrail ); + const HighScoreList &hsl = GetCourseHighScoreList( pCourse, pTrail ); if( hsl.vHighScores.empty() ) continue; // skip @@ -395,33 +394,32 @@ float Profile::GetSongsActual( StepsType st, Difficulty dc ) const float fTotalPercents = 0; // add steps high scores - FOREACHM_CONST( SongID, HighScoresForASong, m_SongHighScores, i ) + for (std::pair const &id : m_SongHighScores) { - const SongID &id = i->first; - Song* pSong = id.ToSong(); + Song* pSong = id.first.ToSong(); CHECKPOINT_M( ssprintf("Profile::GetSongsActual: %p", pSong) ); // If the Song isn't loaded on the current machine, then we can't // get radar values to compute dance points. - if( pSong == NULL ) + if( pSong == nullptr ) continue; if( !pSong->NormallyDisplayed() ) continue; // skip CHECKPOINT_M( ssprintf("Profile::GetSongsActual: song %s", pSong->GetSongDir().c_str()) ); - const HighScoresForASong &hsfas = i->second; + const HighScoresForASong &hsfas = id.second; - FOREACHM_CONST( StepsID, HighScoresForASteps, hsfas.m_StepsHighScores, j ) + for (std::pair const &j : hsfas.m_StepsHighScores) { - const StepsID &sid = j->first; + const StepsID &sid = j.first; Steps* pSteps = sid.ToSteps( pSong, true ); CHECKPOINT_M( ssprintf("Profile::GetSongsActual: song %p, steps %p", pSong, pSteps) ); // If the Steps isn't loaded on the current machine, then we can't // get radar values to compute dance points. - if( pSteps == NULL ) + if( pSteps == nullptr ) continue; if( pSteps->m_StepsType != st ) @@ -435,7 +433,7 @@ float Profile::GetSongsActual( StepsType st, Difficulty dc ) const CHECKPOINT_M( ssprintf("Profile::GetSongsActual: difficulty %s is correct", DifficultyToString(dc).c_str())); - const HighScoresForASteps& h = j->second; + const HighScoresForASteps& h = j.second; const HighScoreList& hsl = h.hsl; fTotalPercents += hsl.GetTopScore().GetPercentDP(); @@ -456,32 +454,24 @@ static void GetHighScoreCourses( vector &vpCoursesOut ) vector vpCourses; SONGMAN->GetAllCourses( vpCourses, false ); - FOREACH_CONST( Course*, vpCourses, c ) + + for (Course *c : vpCourses) { // Don't count any course that has any entries that change over time. - if( !(*c)->AllSongsAreFixed() ) + if( !c->AllSongsAreFixed() ) continue; - vpCoursesOut.push_back( *c ); + vpCoursesOut.push_back( c ); } } float Profile::GetCoursesPossible( StepsType st, CourseDifficulty cd ) const { - int iTotalTrails = 0; - vector vpCourses; GetHighScoreCourses( vpCourses ); - FOREACH_CONST( Course*, vpCourses, c ) - { - Trail* pTrail = (*c)->GetTrail(st,cd); - if( pTrail == NULL ) - continue; - - iTotalTrails++; - } - - return (float) iTotalTrails; + return std::count_if(vpCourses.begin(), vpCourses.end(), [&](Course const *c) { + return c->GetTrail(st, cd) != nullptr; + }); } float Profile::GetCoursesActual( StepsType st, CourseDifficulty cd ) const @@ -490,13 +480,13 @@ float Profile::GetCoursesActual( StepsType st, CourseDifficulty cd ) const vector vpCourses; GetHighScoreCourses( vpCourses ); - FOREACH_CONST( Course*, vpCourses, c ) + for (Course const *c : vpCourses) { - Trail *pTrail = (*c)->GetTrail( st, cd ); - if( pTrail == NULL ) + Trail *pTrail = c->GetTrail( st, cd ); + if( pTrail == nullptr ) continue; - const HighScoreList& hsl = GetCourseHighScoreList( *c, pTrail ); + const HighScoreList& hsl = GetCourseHighScoreList( c, pTrail ); fTotalPercents += hsl.GetTopScore().GetPercentDP(); } @@ -535,13 +525,13 @@ int Profile::GetSongNumTimesPlayed( const Song* pSong ) const int Profile::GetSongNumTimesPlayed( const SongID& songID ) const { const HighScoresForASong *hsSong = GetHighScoresForASong( songID ); - if( hsSong == NULL ) + if( hsSong == nullptr ) return 0; int iTotalNumTimesPlayed = 0; - FOREACHM_CONST( StepsID, HighScoresForASteps, hsSong->m_StepsHighScores, j ) + for (std::pair const &j : hsSong->m_StepsHighScores) { - const HighScoresForASteps &hsSteps = j->second; + const HighScoresForASteps &hsSteps = j.second; iTotalNumTimesPlayed += hsSteps.hsl.GetNumTimesPlayed(); } @@ -585,12 +575,12 @@ Song *Profile::GetMostPopularSong() const { int iMaxNumTimesPlayed = 0; SongID id; - FOREACHM_CONST( SongID, HighScoresForASong, m_SongHighScores, i ) + for (std::pair const &i : m_SongHighScores) { - int iNumTimesPlayed = i->second.GetNumTimesPlayed(); - if(i->first.ToSong() != NULL && iNumTimesPlayed > iMaxNumTimesPlayed) + int iNumTimesPlayed = i.second.GetNumTimesPlayed(); + if(i.first.ToSong() != nullptr && iNumTimesPlayed > iMaxNumTimesPlayed) { - id = i->first; + id = i.first; iMaxNumTimesPlayed = iNumTimesPlayed; } } @@ -602,12 +592,12 @@ Course *Profile::GetMostPopularCourse() const { int iMaxNumTimesPlayed = 0; CourseID id; - FOREACHM_CONST( CourseID, HighScoresForACourse, m_CourseHighScores, i ) + for (std::pair const &i : m_CourseHighScores) { - int iNumTimesPlayed = i->second.GetNumTimesPlayed(); - if(i->first.ToCourse() != NULL && iNumTimesPlayed > iMaxNumTimesPlayed) + int iNumTimesPlayed = i.second.GetNumTimesPlayed(); + if(i.first.ToCourse() != nullptr && iNumTimesPlayed > iMaxNumTimesPlayed) { - id = i->first; + id = i.first; iMaxNumTimesPlayed = iNumTimesPlayed; } } @@ -656,9 +646,9 @@ DateTime Profile::GetSongLastPlayedDateTime( const Song* pSong ) const ASSERT( !iter->second.m_StepsHighScores.empty() ); DateTime dtLatest; // starts out zeroed - FOREACHM_CONST( StepsID, HighScoresForASteps, iter->second.m_StepsHighScores, i ) + for (std::pair const &i : iter->second.m_StepsHighScores) { - const HighScoreList &hsl = i->second.hsl; + const HighScoreList &hsl = i.second.hsl; if( hsl.GetNumTimesPlayed() == 0 ) continue; if( dtLatest < hsl.GetLastPlayed() ) @@ -683,12 +673,10 @@ bool Profile::HasPassedSteps( const Song* pSong, const Steps* pSteps ) const bool Profile::HasPassedAnyStepsInSong( const Song* pSong ) const { - FOREACH_CONST( Steps*, pSong->GetAllSteps(), steps ) - { - if( HasPassedSteps( pSong, *steps ) ) - return true; - } - return false; + auto const &steps = pSong->GetAllSteps(); + return std::any_of(steps.begin(), steps.end(), [&](Steps const *s) { + return HasPassedSteps(pSong, s); + }); } void Profile::IncrementStepsPlayCount( const Song* pSong, const Steps* pSteps ) @@ -704,18 +692,18 @@ void Profile::GetGrades( const Song* pSong, StepsType st, int iCounts[NUM_Grade] memset( iCounts, 0, sizeof(int)*NUM_Grade ); const HighScoresForASong *hsSong = GetHighScoresForASong( songID ); - if( hsSong == NULL ) + if( hsSong == nullptr ) return; FOREACH_ENUM( Grade,g) { - FOREACHM_CONST( StepsID, HighScoresForASteps, hsSong->m_StepsHighScores, it ) + for (std::pair const &it : hsSong->m_StepsHighScores) { - const StepsID &id = it->first; + const StepsID &id = it.first; if( !id.MatchesStepsType(st) ) continue; - const HighScoresForASteps &hsSteps = it->second; + const HighScoresForASteps &hsSteps = it.second; if( hsSteps.hsl.GetTopScore().GetGrade() == g ) iCounts[g]++; } @@ -758,13 +746,13 @@ int Profile::GetCourseNumTimesPlayed( const Course* pCourse ) const int Profile::GetCourseNumTimesPlayed( const CourseID &courseID ) const { const HighScoresForACourse *hsCourse = GetHighScoresForACourse( courseID ); - if( hsCourse == NULL ) + if( hsCourse == nullptr ) return 0; int iTotalNumTimesPlayed = 0; - FOREACHM_CONST( TrailID, HighScoresForATrail, hsCourse->m_TrailHighScores, j ) + for (std::pair const &j : hsCourse->m_TrailHighScores) { - const HighScoresForATrail &hsTrail = j->second; + const HighScoresForATrail &hsTrail = j.second; iTotalNumTimesPlayed += hsTrail.hsl.GetNumTimesPlayed(); } @@ -782,9 +770,9 @@ DateTime Profile::GetCourseLastPlayedDateTime( const Course* pCourse ) const ASSERT( !iter->second.m_TrailHighScores.empty() ); DateTime dtLatest; // starts out zeroed - FOREACHM_CONST( TrailID, HighScoresForATrail, iter->second.m_TrailHighScores, i ) + for (std::pair const &i : iter->second.m_TrailHighScores) { - const HighScoreList &hsl = i->second.hsl; + const HighScoreList &hsl = i.second.hsl; if( hsl.GetNumTimesPlayed() == 0 ) continue; if( dtLatest < hsl.GetLastPlayed() ) @@ -1067,7 +1055,7 @@ void Profile::IncrementCategoryPlayCount( StepsType st, RankingCategory rc ) #define WARN_AND_BREAK_M(m) { WARN_M(m); break; } #define LOAD_NODE(X) { \ const XNode* X = xml->GetChild(#X); \ - if( X==NULL ) LOG->Warn("Failed to read section " #X); \ + if( X== nullptr ) LOG->Warn("Failed to read section " #X); \ else Load##X##FromNode(X); } void Profile::LoadCustomFunction(RString sDir, PlayerNumber pn) @@ -1259,8 +1247,8 @@ ProfileLoadResult Profile::LoadStatsFromDir(RString dir, bool require_signature) } int iError; - auto_ptr pFile(FILEMAN->Open(fn, RageFile::READ, iError)); - if(pFile.get() == NULL) + unique_ptr pFile(FILEMAN->Open(fn, RageFile::READ, iError)); + if(pFile.get() == nullptr) { LOG->Trace("Error opening %s: %s", fn.c_str(), strerror(iError)); return ProfileLoadResult_FailedTampered; @@ -1271,7 +1259,7 @@ ProfileLoadResult Profile::LoadStatsFromDir(RString dir, bool require_signature) RString sError; uint32_t iCRC32; RageFileObjInflate *pInflate = GunzipFile(pFile.release(), sError, &iCRC32); - if(pInflate == NULL) + if(pInflate == nullptr) { LOG->Trace("Error opening %s: %s", fn.c_str(), sError.c_str()); return ProfileLoadResult_FailedTampered; @@ -1335,7 +1323,7 @@ void Profile::LoadTypeFromDir(RString dir) if(ini.ReadFile(fn)) { XNode const* data= ini.GetChild("ListPosition"); - if(data != NULL) + if(data != nullptr) { RString type_str; if(data->GetAttrValue("Type", type_str)) @@ -1459,7 +1447,7 @@ XNode *Profile::SaveStatsXmlCreateNode() const bool Profile::SaveStatsXmlToDir( RString sDir, bool bSignData ) const { LOG->Trace( "SaveStatsXmlToDir: %s", sDir.c_str() ); - auto_ptr xml( SaveStatsXmlCreateNode() ); + unique_ptr xml( SaveStatsXmlCreateNode() ); sDir= sDir + PROFILEMAN->GetStatsPrefix(); // Save stats.xml @@ -1590,20 +1578,19 @@ XNode* Profile::SaveGeneralDataCreateNode() const { XNode* pDefaultModifiers = pGeneralDataNode->AppendChild("DefaultModifiers"); - FOREACHM_CONST( RString, RString, m_sDefaultModifiers, it ) - pDefaultModifiers->AppendChild( it->first, it->second ); + for (std::pair it : m_sDefaultModifiers) + pDefaultModifiers->AppendChild( it.first, it.second ); } { XNode* pUnlocks = pGeneralDataNode->AppendChild("Unlocks"); - FOREACHS_CONST( RString, m_UnlockedEntryIDs, it ) + for (RString const &unlockEntry : m_UnlockedEntryIDs) { XNode *pEntry = pUnlocks->AppendChild("UnlockEntry"); - RString sUnlockEntry = it->c_str(); - pEntry->AppendAttr( "UnlockEntryID", sUnlockEntry ); + pEntry->AppendAttr( "UnlockEntryID", unlockEntry ); if( !UNLOCK_AUTH_STRING.GetValue().empty() ) { - RString sUnlockAuth = BinaryToHex( CRYPTMAN->GetMD5ForString(sUnlockEntry + UNLOCK_AUTH_STRING.GetValue()) ); + RString sUnlockAuth = BinaryToHex( CRYPTMAN->GetMD5ForString(unlockEntry + UNLOCK_AUTH_STRING.GetValue()) ); pEntry->AppendAttr( "Auth", sUnlockAuth ); } } @@ -1622,10 +1609,10 @@ XNode* Profile::SaveGeneralDataCreateNode() const { XNode* pNumSongsPlayedByStyle = pGeneralDataNode->AppendChild("NumSongsPlayedByStyle"); - FOREACHM_CONST( StyleID, int, m_iNumSongsPlayedByStyle, iter ) + for (std::pair const iter : m_iNumSongsPlayedByStyle) { - const StyleID &s = iter->first; - int iNumPlays = iter->second; + const StyleID &s = iter.first; + int iNumPlays = iter.second; XNode *pStyleNode = s.CreateNode(); pStyleNode->AppendAttr(XNode::TEXT_ATTRIBUTE, iNumPlays ); @@ -1995,14 +1982,14 @@ XNode* Profile::SaveSongScoresCreateNode() const CHECKPOINT_M("Getting the node to save song scores."); const Profile* pProfile = this; - ASSERT( pProfile != NULL ); + ASSERT( pProfile != nullptr ); XNode* pNode = new XNode( "SongScores" ); - FOREACHM_CONST( SongID, HighScoresForASong, m_SongHighScores, i ) + for (std::pair const &i : m_SongHighScores) { - const SongID &songID = i->first; - const HighScoresForASong &hsSong = i->second; + const SongID &songID = i.first; + const HighScoresForASong &hsSong = i.second; // skip songs that have never been played if( pProfile->GetSongNumTimesPlayed(songID) == 0 ) @@ -2012,12 +1999,12 @@ XNode* Profile::SaveSongScoresCreateNode() const int jCheck2 = hsSong.m_StepsHighScores.size(); int jCheck1 = 0; - FOREACHM_CONST( StepsID, HighScoresForASteps, hsSong.m_StepsHighScores, j ) + for (std::pair const &j :hsSong.m_StepsHighScores) { jCheck1++; ASSERT( jCheck1 <= jCheck2 ); - const StepsID &stepsID = j->first; - const HighScoresForASteps &hsSteps = j->second; + const StepsID &stepsID = j.first; + const HighScoresForASteps &hsSteps = j.second; const HighScoreList &hsl = hsSteps.hsl; @@ -2063,7 +2050,7 @@ void Profile::LoadSongScoresFromNode( const XNode* pSongScores ) WARN_AND_CONTINUE; const XNode *pHighScoreListNode = pSteps->GetChild("HighScoreList"); - if( pHighScoreListNode == NULL ) + if( pHighScoreListNode == nullptr ) WARN_AND_CONTINUE; HighScoreList &hsl = m_SongHighScores[songID].m_StepsHighScores[stepsID].hsl; @@ -2078,14 +2065,14 @@ XNode* Profile::SaveCourseScoresCreateNode() const CHECKPOINT_M("Getting the node to save course scores."); const Profile* pProfile = this; - ASSERT( pProfile != NULL ); + ASSERT( pProfile != nullptr ); XNode* pNode = new XNode( "CourseScores" ); - FOREACHM_CONST( CourseID, HighScoresForACourse, m_CourseHighScores, i ) + for (std::pair const &i : m_CourseHighScores) { - const CourseID &courseID = i->first; - const HighScoresForACourse &hsCourse = i->second; + const CourseID &courseID = i.first; + const HighScoresForACourse &hsCourse = i.second; // skip courses that have never been played if( pProfile->GetCourseNumTimesPlayed(courseID) == 0 ) @@ -2093,10 +2080,10 @@ XNode* Profile::SaveCourseScoresCreateNode() const XNode* pCourseNode = pNode->AppendChild( courseID.CreateNode() ); - FOREACHM_CONST( TrailID, HighScoresForATrail, hsCourse.m_TrailHighScores, j ) + for (std::pair const &j : hsCourse.m_TrailHighScores) { - const TrailID &trailID = j->first; - const HighScoresForATrail &hsTrail = j->second; + const TrailID &trailID = j.first; + const HighScoresForATrail &hsTrail = j.second; const HighScoreList &hsl = hsTrail.hsl; @@ -2142,19 +2129,19 @@ void Profile::LoadCourseScoresFromNode( const XNode* pCourseScores ) // and search for matches of just the file name. { Course *pC = courseID.ToCourse(); - if( pC == NULL ) + if( pC == nullptr ) { RString sDir, sFName, sExt; splitpath( courseID.GetPath(), sDir, sFName, sExt ); RString sFullFileName = sFName + sExt; - FOREACH_CONST( Course*, vpAllCourses, c ) + for (Course *c : vpAllCourses) { - RString sOther = (*c)->m_sPath.Right(sFullFileName.size()); + RString sOther = c->m_sPath.Right(sFullFileName.size()); if( sFullFileName.CompareNoCase(sOther) == 0 ) { - pC = *c; + pC = c; courseID.FromCourse( pC ); break; } @@ -2174,7 +2161,7 @@ void Profile::LoadCourseScoresFromNode( const XNode* pCourseScores ) WARN_AND_CONTINUE; const XNode *pHighScoreListNode = pTrail->GetChild("HighScoreList"); - if( pHighScoreListNode == NULL ) + if( pHighScoreListNode == nullptr ) WARN_AND_CONTINUE; HighScoreList &hsl = m_CourseHighScores[courseID].m_TrailHighScores[trailID].hsl; @@ -2188,7 +2175,7 @@ XNode* Profile::SaveCategoryScoresCreateNode() const CHECKPOINT_M("Getting the node that saves category scores."); const Profile* pProfile = this; - ASSERT( pProfile != NULL ); + ASSERT( pProfile != nullptr ); XNode* pNode = new XNode( "CategoryScores" ); @@ -2249,7 +2236,7 @@ void Profile::LoadCategoryScoresFromNode( const XNode* pCategoryScores ) WARN_AND_CONTINUE_M( str ); const XNode *pHighScoreListNode = pRadarCategory->GetChild("HighScoreList"); - if( pHighScoreListNode == NULL ) + if( pHighScoreListNode == nullptr ) WARN_AND_CONTINUE; HighScoreList &hsl = this->GetCategoryHighScoreList( st, rc ); @@ -2260,7 +2247,7 @@ void Profile::LoadCategoryScoresFromNode( const XNode* pCategoryScores ) void Profile::SaveStatsWebPageToDir( RString ) const { - ASSERT( PROFILEMAN != NULL ); + ASSERT( PROFILEMAN != nullptr ); } void Profile::SaveMachinePublicKeyToDir( RString sDir ) const @@ -2296,13 +2283,13 @@ XNode* Profile::SaveScreenshotDataCreateNode() const CHECKPOINT_M("Getting the node containing screenshot data."); const Profile* pProfile = this; - ASSERT( pProfile != NULL ); + ASSERT( pProfile != nullptr ); XNode* pNode = new XNode( "ScreenshotData" ); - FOREACH_CONST( Screenshot, m_vScreenshots, ss ) + for (Screenshot const &ss : m_vScreenshots) { - pNode->AppendChild( ss->CreateNode() ); + pNode->AppendChild( ss.CreateNode() ); } return pNode; @@ -2338,15 +2325,15 @@ XNode* Profile::SaveCalorieDataCreateNode() const CHECKPOINT_M("Getting the node containing calorie data."); const Profile* pProfile = this; - ASSERT( pProfile != NULL ); + ASSERT( pProfile != nullptr ); XNode* pNode = new XNode( "CalorieData" ); - FOREACHM_CONST( DateTime, Calories, m_mapDayToCaloriesBurned, i ) + for (std::pair const &i : m_mapDayToCaloriesBurned) { - XNode* pCaloriesBurned = pNode->AppendChild( "CaloriesBurned", i->second.fCals ); + XNode* pCaloriesBurned = pNode->AppendChild( "CaloriesBurned", i.second.fCals ); - pCaloriesBurned->AppendAttr( "Date", i->first.GetString() ); + pCaloriesBurned->AppendAttr( "Date", i.first.GetString() ); } return pNode; @@ -2397,7 +2384,7 @@ void Profile::SaveStepsRecentScore( const Song* pSong, const Steps* pSteps, High ASSERT( h.stepsID.IsValid() ); h.hs = hs; - auto_ptr xml( new XNode("Stats") ); + unique_ptr xml( new XNode("Stats") ); xml->AppendChild( "MachineGuid", PROFILEMAN->GetMachineProfile()->m_sGuid ); XNode *recent = xml->AppendChild( new XNode("RecentSongScores") ); recent->AppendChild( h.CreateNode() ); @@ -2424,7 +2411,7 @@ void Profile::SaveCourseRecentScore( const Course* pCourse, const Trail* pTrail, h.trailID.FromTrail( pTrail ); h.hs = hs; - auto_ptr xml( new XNode("Stats") ); + unique_ptr xml( new XNode("Stats") ); xml->AppendChild( "MachineGuid", PROFILEMAN->GetMachineProfile()->m_sGuid ); XNode *recent = xml->AppendChild( new XNode("RecentCourseScores") ); recent->AppendChild( h.CreateNode() ); @@ -2436,7 +2423,7 @@ const Profile::HighScoresForASong *Profile::GetHighScoresForASong( const SongID& map::const_iterator it; it = m_SongHighScores.find( songID ); if( it == m_SongHighScores.end() ) - return NULL; + return nullptr; return &it->second; } @@ -2445,7 +2432,7 @@ const Profile::HighScoresForACourse *Profile::GetHighScoresForACourse( const Cou map::const_iterator it; it = m_CourseHighScores.find( courseID ); if( it == m_CourseHighScores.end() ) - return NULL; + return nullptr; return &it->second; } @@ -2461,7 +2448,7 @@ XNode* Profile::SaveCoinDataCreateNode() const CHECKPOINT_M("Getting the node containing coin data."); const Profile* pProfile = this; - ASSERT( pProfile != NULL ); + ASSERT( pProfile != nullptr ); XNode* pNode = new XNode( "CoinData" ); @@ -2536,7 +2523,7 @@ RString Profile::MakeUniqueFileNameNoExtension( RString sDir, RString sFileNameB continue; ASSERT( matches.size() == 1 ); - iIndex = StringToInt( matches[0] )+1; + iIndex = std::stoi( matches[0] )+1; break; } diff --git a/src/ProfileManager.cpp b/src/ProfileManager.cpp index 9a353f8764..a113fb0960 100644 --- a/src/ProfileManager.cpp +++ b/src/ProfileManager.cpp @@ -25,7 +25,7 @@ #include "CharacterManager.h" -ProfileManager* PROFILEMAN = NULL; // global and accessible from anywhere in our program +ProfileManager* PROFILEMAN = nullptr; // global and accessible from anywhere in our program #define ID_DIGITS 8 #define ID_DIGITS_STR "8" @@ -124,12 +124,12 @@ void ProfileManager::Init() { RString sCharacterID = FIXED_PROFILE_CHARACTER_ID( i ); Character *pCharacter = CHARMAN->GetCharacterFromID( sCharacterID ); - ASSERT_M( pCharacter != NULL, sCharacterID ); + ASSERT_M( pCharacter != nullptr, sCharacterID ); RString sProfileID; bool b = CreateLocalProfile( pCharacter->GetDisplayName(), sProfileID ); ASSERT( b ); Profile* pProfile = GetLocalProfile( sProfileID ); - ASSERT_M( pProfile != NULL, sProfileID ); + ASSERT_M( pProfile != nullptr, sProfileID ); pProfile->m_sCharacterID = sCharacterID; SaveLocalProfile( sProfileID ); } @@ -216,7 +216,7 @@ bool ProfileManager::LoadLocalProfileFromMachine( PlayerNumber pn ) m_bWasLoadedFromMemoryCard[pn] = false; m_bLastLoadWasFromLastGood[pn] = false; - if( GetLocalProfile(sProfileID) == NULL ) + if( GetLocalProfile(sProfileID) == nullptr ) { m_sProfileDir[pn] = ""; return false; @@ -364,7 +364,7 @@ bool ProfileManager::SaveProfile( PlayerNumber pn ) const bool ProfileManager::SaveLocalProfile( RString sProfileID ) { const Profile *pProfile = GetLocalProfile( sProfileID ); - ASSERT( pProfile != NULL ); + ASSERT( pProfile != nullptr ); RString sDir = LocalProfileIDToDir( sProfileID ); bool b = pProfile->SaveAllToDir( sDir, PREFSMAN->m_bSignProfileData ); return b; @@ -444,10 +444,10 @@ void ProfileManager::RefreshLocalProfilesFromDisk() // The type data for a profile is in its own file so that loading isn't // slowed down by copying temporary profiles around to make sure the list // is sorted. The profiles are loaded at the end. -Kyz - FOREACH_CONST(RString, profile_ids, id) + for (RString const &id : profile_ids) { DirAndProfile derp; - derp.sDir= *id + "/"; + derp.sDir= id + "/"; derp.profile.LoadTypeFromDir(derp.sDir); map >::iterator category= categorized_profiles.find(derp.profile.m_Type); @@ -458,7 +458,7 @@ void ProfileManager::RefreshLocalProfilesFromDisk() else { bool inserted= false; - FOREACH(DirAndProfile, category->second, curr) + for (auto curr = g_vLocalProfile.begin(); curr != g_vLocalProfile.end(); ++curr) { if(curr->profile.m_ListPriority > derp.profile.m_ListPriority) { @@ -476,23 +476,23 @@ void ProfileManager::RefreshLocalProfilesFromDisk() add_category_to_global_list(categorized_profiles[ProfileType_Guest]); add_category_to_global_list(categorized_profiles[ProfileType_Normal]); add_category_to_global_list(categorized_profiles[ProfileType_Test]); - FOREACH(DirAndProfile, g_vLocalProfile, curr) + for (DirAndProfile &curr : g_vLocalProfile) { - curr->profile.LoadAllFromDir(curr->sDir, PREFSMAN->m_bSignProfileData); + curr.profile.LoadAllFromDir(curr.sDir, PREFSMAN->m_bSignProfileData); } } const Profile *ProfileManager::GetLocalProfile( const RString &sProfileID ) const { RString sDir = LocalProfileIDToDir( sProfileID ); - FOREACH_CONST( DirAndProfile, g_vLocalProfile, dap ) + for (DirAndProfile const &dap : g_vLocalProfile) { - const RString &sOther = dap->sDir; + const RString &sOther = dap.sDir; if( sOther == sDir ) - return &dap->profile; + return &dap.profile; } - return NULL; + return nullptr; } bool ProfileManager::CreateLocalProfile( RString sName, RString &sProfileIDOut ) @@ -510,7 +510,7 @@ bool ProfileManager::CreateLocalProfile( RString sName, RString &sProfileIDOut ) int first_free_number= 0; vector profile_ids; GetLocalProfileIDs(profile_ids); - FOREACH_CONST(RString, profile_ids, id) + for (std::vector::const_iterator id = profile_ids.begin(); id != profile_ids.end(); ++id) { int tmp= 0; if((*id) >> tmp) @@ -536,7 +536,7 @@ bool ProfileManager::CreateLocalProfile( RString sName, RString &sProfileIDOut ) RString profile_id = ssprintf( "%0" ID_DIGITS_STR "d", profile_number ); // make sure this id doesn't already exist - ASSERT_M(GetLocalProfile(profile_id) == NULL, + ASSERT_M(GetLocalProfile(profile_id) == nullptr, ssprintf("creating profile with ID \"%s\" that already exists", profile_id.c_str())); @@ -564,7 +564,7 @@ static void InsertProfileIntoList(DirAndProfile& derp) { bool inserted= false; derp.profile.m_ListPriority= 0; - FOREACH(DirAndProfile, g_vLocalProfile, curr) + for (auto curr = g_vLocalProfile.begin(); curr != g_vLocalProfile.end(); ++curr) { if(curr->profile.m_Type > derp.profile.m_Type) { @@ -588,7 +588,7 @@ static void InsertProfileIntoList(DirAndProfile& derp) void ProfileManager::AddLocalProfileByID( Profile *pProfile, RString sProfileID ) { // make sure this id doesn't already exist - ASSERT_M( GetLocalProfile(sProfileID) == NULL, + ASSERT_M( GetLocalProfile(sProfileID) == nullptr, ssprintf("creating \"%s\" \"%s\" that already exists", pProfile->m_sDisplayName.c_str(), sProfileID.c_str()) ); @@ -603,7 +603,7 @@ bool ProfileManager::RenameLocalProfile( RString sProfileID, RString sNewName ) ASSERT( !sProfileID.empty() ); Profile *pProfile = ProfileManager::GetLocalProfile( sProfileID ); - ASSERT( pProfile != NULL ); + ASSERT( pProfile != nullptr ); pProfile->m_sDisplayName = sNewName; RString sProfileDir = LocalProfileIDToDir( sProfileID ); @@ -613,13 +613,13 @@ bool ProfileManager::RenameLocalProfile( RString sProfileID, RString sNewName ) bool ProfileManager::DeleteLocalProfile( RString sProfileID ) { Profile *pProfile = ProfileManager::GetLocalProfile( sProfileID ); - ASSERT( pProfile != NULL ); + ASSERT( pProfile != nullptr ); RString sProfileDir = LocalProfileIDToDir( sProfileID ); // flush directory cache in an attempt to get this working FILEMAN->FlushDirCache( sProfileDir ); - FOREACH( DirAndProfile, g_vLocalProfile, i ) + for (vector::iterator i = g_vLocalProfile.begin(); i != g_vLocalProfile.end(); ++i) { if( i->sDir == sProfileDir ) { @@ -628,10 +628,10 @@ bool ProfileManager::DeleteLocalProfile( RString sProfileID ) g_vLocalProfile.erase( i ); // Delete all references to this profileID - FOREACH_CONST( Preference*, m_sDefaultLocalProfileID.m_v, j ) + for (Preference *j : m_sDefaultLocalProfileID.m_v) { - if( (*j)->Get() == sProfileID ) - (*j)->Set( "" ); + if( j->Get() == sProfileID ) + j->Set( "" ); } return true; } @@ -746,7 +746,7 @@ void ProfileManager::MergeLocalProfiles(RString const& from_id, RString const& t { Profile* from= GetLocalProfile(from_id); Profile* to= GetLocalProfile(to_id); - if(from == NULL || to == NULL) + if(from == nullptr || to == nullptr) { return; } @@ -757,7 +757,7 @@ void ProfileManager::MergeLocalProfiles(RString const& from_id, RString const& t void ProfileManager::MergeLocalProfileIntoMachine(RString const& from_id, bool skip_totals) { Profile* from= GetLocalProfile(from_id); - if(from == NULL) + if(from == nullptr) { return; } @@ -975,9 +975,9 @@ bool ProfileManager::IsPersistentProfile( ProfileSlot slot ) const void ProfileManager::GetLocalProfileIDs( vector &vsProfileIDsOut ) const { vsProfileIDsOut.clear(); - FOREACH_CONST( DirAndProfile, g_vLocalProfile, i) + for (DirAndProfile const &i : g_vLocalProfile) { - RString sID = LocalProfileDirToID( i->sDir ); + RString sID = LocalProfileDirToID( i.sDir ); vsProfileIDsOut.push_back( sID ); } } @@ -985,17 +985,19 @@ void ProfileManager::GetLocalProfileIDs( vector &vsProfileIDsOut ) cons void ProfileManager::GetLocalProfileDisplayNames( vector &vsProfileDisplayNamesOut ) const { vsProfileDisplayNamesOut.clear(); - FOREACH_CONST( DirAndProfile, g_vLocalProfile, i) - vsProfileDisplayNamesOut.push_back( i->profile.m_sDisplayName ); + for (DirAndProfile const &i : g_vLocalProfile) + vsProfileDisplayNamesOut.push_back( i.profile.m_sDisplayName ); } int ProfileManager::GetLocalProfileIndexFromID( RString sProfileID ) const { RString sDir = LocalProfileIDToDir( sProfileID ); - FOREACH_CONST( DirAndProfile, g_vLocalProfile, i ) + int j = 0; + for (DirAndProfile const &i : g_vLocalProfile) { - if( i->sDir == sDir ) - return i - g_vLocalProfile.begin(); + if( i.sDir == sDir ) + return j; + ++j; } return -1; } @@ -1053,7 +1055,7 @@ public: COMMON_RETURN_SELF; } static int IsPersistentProfile( T* p, lua_State *L ) { lua_pushboolean(L, p->IsPersistentProfile(Enum::Check(L, 1)) ); return 1; } - static int GetProfile( T* p, lua_State *L ) { PlayerNumber pn = Enum::Check(L, 1); Profile* pP = p->GetProfile(pn); ASSERT(pP != NULL); pP->PushSelf(L); return 1; } + static int GetProfile( T* p, lua_State *L ) { PlayerNumber pn = Enum::Check(L, 1); Profile* pP = p->GetProfile(pn); ASSERT(pP != nullptr); pP->PushSelf(L); return 1; } static int GetMachineProfile( T* p, lua_State *L ) { p->GetMachineProfile()->PushSelf(L); return 1; } static int SaveMachineProfile( T* p, lua_State * ) { p->SaveMachineProfile(); return 0; } static int GetLocalProfile( T* p, lua_State *L ) @@ -1073,7 +1075,7 @@ public: luaL_error(L, "Profile index %d out of range.", index); } Profile *pProfile = p->GetLocalProfileFromIndex(index); - if(pProfile == NULL) + if(pProfile == nullptr) { luaL_error(L, "No profile at index %d.", index); } diff --git a/src/RageBitmapTexture.cpp b/src/RageBitmapTexture.cpp index 79b19b64dd..60ae4f4f95 100644 --- a/src/RageBitmapTexture.cpp +++ b/src/RageBitmapTexture.cpp @@ -27,8 +27,8 @@ static void GetResolutionFromFileName( RString sPath, int &iWidth, int &iHeight return; // Check for nonsense values. Some people might not intend the hint. -Kyz - int maybe_width= StringToInt(asMatches[0]); - int maybe_height= StringToInt(asMatches[1]); + int maybe_width= std::stoi(asMatches[0]); + int maybe_height= std::stoi(asMatches[1]); if(maybe_width <= 0 || maybe_height <= 0) { return; @@ -72,7 +72,7 @@ void RageBitmapTexture::Create() /* Load the image into a RageSurface. */ RString error; - RageSurface *pImg= NULL; + RageSurface *pImg = nullptr; if(actualID.filename == TEXTUREMAN->GetScreenTextureID().filename) { pImg= TEXTUREMAN->GetScreenSurface(); @@ -83,14 +83,14 @@ void RageBitmapTexture::Create() } /* Tolerate corrupt/unknown images. */ - if( pImg == NULL ) + if( pImg == nullptr ) { RString warning = ssprintf("RageBitmapTexture: Couldn't load %s: %s", actualID.filename.c_str(), error.c_str()); LOG->Warn("%s", warning.c_str()); Dialog::OK(warning, "missing_texture"); pImg = RageSurfaceUtils::MakeDummySurface( 64, 64 ); - ASSERT( pImg != NULL ); + ASSERT( pImg != nullptr ); } if( actualID.bHotPinkColorKey ) diff --git a/src/RageDisplay.cpp b/src/RageDisplay.cpp index c41ef56d16..4aeebd4ab9 100644 --- a/src/RageDisplay.cpp +++ b/src/RageDisplay.cpp @@ -43,7 +43,7 @@ struct Centering static vector g_CenteringStack( 1, Centering(0, 0, 0, 0) ); -RageDisplay* DISPLAY = NULL; // global and accessible from anywhere in our program +RageDisplay* DISPLAY = nullptr; // global and accessible from anywhere in our program Preference LOG_FPS( "LogFPS", true ); Preference g_fFrameLimitPercent( "FrameLimitPercent", 0.0f ); diff --git a/src/RageDisplay.h b/src/RageDisplay.h index 35eb3c139c..7f6b37db2c 100644 --- a/src/RageDisplay.h +++ b/src/RageDisplay.h @@ -272,9 +272,9 @@ public: int xoffset, int yoffset, int width, int height ) = 0; virtual void DeleteTexture( unsigned iTexHandle ) = 0; - /* Return an object to lock pixels for streaming. If not supported, returns NULL. + /* Return an object to lock pixels for streaming. If not supported, returns nullptr. * Delete the object normally. */ - virtual RageTextureLock *CreateTextureLock() { return NULL; } + virtual RageTextureLock *CreateTextureLock() { return nullptr; } virtual void ClearAllTextures() = 0; virtual int GetNumTextureUnits() = 0; virtual void SetTexture( TextureUnit, unsigned /* iTexture */ ) = 0; @@ -366,7 +366,7 @@ public: virtual RString GetTextureDiagnostics( unsigned /* id */ ) const { return RString(); } virtual RageSurface* CreateScreenshot() = 0; // allocates a surface. Caller must delete it. - virtual RageSurface *GetTexture( unsigned /* iTexture */ ) { return NULL; } // allocates a surface. Caller must delete it. + virtual RageSurface *GetTexture( unsigned /* iTexture */ ) { return nullptr; } // allocates a surface. Caller must delete it. protected: virtual void DrawQuadsInternal( const RageSpriteVertex v[], int iNumVerts ) = 0; diff --git a/src/RageDisplay_D3D.cpp b/src/RageDisplay_D3D.cpp index 960c1755aa..0f112eadf5 100644 --- a/src/RageDisplay_D3D.cpp +++ b/src/RageDisplay_D3D.cpp @@ -36,9 +36,9 @@ RString GetErrorString( HRESULT hr ) } // Globals -HMODULE g_D3D9_Module = NULL; -LPDIRECT3D9 g_pd3d = NULL; -LPDIRECT3DDEVICE9 g_pd3dDevice = NULL; +HMODULE g_D3D9_Module = nullptr; +LPDIRECT3D9 g_pd3d = nullptr; +LPDIRECT3DDEVICE9 g_pd3dDevice = nullptr; D3DCAPS9 g_DeviceCaps; D3DDISPLAYMODE g_DesktopMode; D3DPRESENT_PARAMETERS g_d3dpp; @@ -252,13 +252,13 @@ RageDisplay_D3D::~RageDisplay_D3D() if( g_pd3dDevice ) { g_pd3dDevice->Release(); - g_pd3dDevice = NULL; + g_pd3dDevice = nullptr; } if( g_pd3d ) { g_pd3d->Release(); - g_pd3d = NULL; + g_pd3d = nullptr; } /* Even after we call Release(), D3D may still affect our window. It seems @@ -267,7 +267,7 @@ RageDisplay_D3D::~RageDisplay_D3D() if( g_D3D9_Module ) { FreeLibrary( g_D3D9_Module ); - g_D3D9_Module = NULL; + g_D3D9_Module = nullptr; } } @@ -365,7 +365,7 @@ D3DFORMAT FindBackBufferType(bool bWindowed, int iBPP) RString SetD3DParams( bool &bNewDeviceOut ) { - if( g_pd3dDevice == NULL ) // device is not yet created. We need to create it + if( g_pd3dDevice == nullptr ) // device is not yet created. We need to create it { bNewDeviceOut = true; HRESULT hr = g_pd3d->CreateDevice( @@ -594,7 +594,7 @@ bool RageDisplay_D3D::BeginFrame() } } - g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, + g_pd3dDevice->Clear( 0, nullptr, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0x00000000 ); g_pd3dDevice->BeginScene(); @@ -642,7 +642,7 @@ bool RageDisplay_D3D::SupportsThreadedRendering() RageSurface* RageDisplay_D3D::CreateScreenshot() { - RageSurface * result = NULL; + RageSurface * result = nullptr; // Get the back buffer. IDirect3DSurface9* pSurface; @@ -654,9 +654,9 @@ RageSurface* RageDisplay_D3D::CreateScreenshot() // Copy the back buffer into a surface of a type we support. IDirect3DSurface9* pCopy; - if( SUCCEEDED( g_pd3dDevice->CreateOffscreenPlainSurface( desc.Width, desc.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pCopy, NULL ) ) ) + if( SUCCEEDED( g_pd3dDevice->CreateOffscreenPlainSurface( desc.Width, desc.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pCopy, nullptr ) ) ) { - if( SUCCEEDED( D3DXLoadSurfaceFromSurface( pCopy, NULL, NULL, pSurface, NULL, NULL, D3DX_FILTER_NONE, 0) ) ) + if( SUCCEEDED( D3DXLoadSurfaceFromSurface( pCopy, nullptr, nullptr, pSurface, nullptr, nullptr, D3DX_FILTER_NONE, 0) ) ) { // Update desc from the copy. pCopy->GetDesc( &desc ); @@ -674,7 +674,7 @@ RageSurface* RageDisplay_D3D::CreateScreenshot() } RageSurface *surface = CreateSurfaceFromPixfmt( RagePixelFormat_RGBA8, lr.pBits, desc.Width, desc.Height, lr.Pitch); - ASSERT( surface != NULL ); + ASSERT( surface != nullptr ); // We need to make a copy, since lr.pBits will go away when we call UnlockRect(). result = @@ -722,9 +722,9 @@ void RageDisplay_D3D::SendCurrentMatrices() g_pd3dDevice->SetTextureStageState( tu, D3DTSS_TEXTURETRANSFORMFLAGS, D3DTTFF_COUNT2 ); // If no texture is set for this texture unit, don't bother setting it up. - IDirect3DBaseTexture9* pTexture = NULL; + IDirect3DBaseTexture9* pTexture = nullptr; g_pd3dDevice->GetTexture( tu, &pTexture ); - if( pTexture == NULL ) + if( pTexture == nullptr ) continue; pTexture->Release(); @@ -1049,7 +1049,7 @@ void RageDisplay_D3D::SetTexture( TextureUnit tu, unsigned iTexture ) if( iTexture == 0 ) { - g_pd3dDevice->SetTexture( tu, NULL ); + g_pd3dDevice->SetTexture( tu, nullptr ); /* Intentionally commented out. Don't mess with texture stage state * when just setting the texture. Model sets its texture modes before @@ -1136,9 +1136,9 @@ void RageDisplay_D3D::SetBlendMode( BlendMode mode ) g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE ); break; - // This is not the right way to do BLEND_SUBTRACT. This code is only here - // to prevent crashing when someone tries to use it. -Kyz - case BLEND_SUBTRACT: + // This is not the right way to do BLEND_SUBTRACT. This code is only here + // to prevent crashing when someone tries to use it. -Kyz + case BLEND_SUBTRACT: g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA ); g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO ); break; @@ -1241,7 +1241,7 @@ void RageDisplay_D3D::SetZTestMode( ZTestMode mode ) void RageDisplay_D3D::ClearZBuffer() { - g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0x00000000 ); + g_pd3dDevice->Clear( 0, nullptr, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0,0,0), 1.0f, 0x00000000 ); } void RageDisplay_D3D::SetTextureWrapping( TextureUnit tu, bool b ) @@ -1372,7 +1372,7 @@ unsigned RageDisplay_D3D::CreateTexture( { HRESULT hr; IDirect3DTexture9* pTex; - hr = g_pd3dDevice->CreateTexture( power_of_two(img->w), power_of_two(img->h), 1, 0, D3DFORMATS[pixfmt], D3DPOOL_MANAGED, &pTex, NULL ); + hr = g_pd3dDevice->CreateTexture( power_of_two(img->w), power_of_two(img->h), 1, 0, D3DFORMATS[pixfmt], D3DPOOL_MANAGED, &pTex, nullptr ); if( FAILED(hr) ) RageException::Throw( "CreateTexture(%i,%i,%s) failed: %s", @@ -1409,7 +1409,7 @@ void RageDisplay_D3D::UpdateTexture( int xoffset, int yoffset, int width, int height ) { IDirect3DTexture9* pTex = (IDirect3DTexture9*)uTexHandle; - ASSERT( pTex != NULL ); + ASSERT( pTex != nullptr ); RECT rect; rect.left = xoffset; @@ -1432,7 +1432,7 @@ void RageDisplay_D3D::UpdateTexture( ASSERT( texpixfmt != NUM_RagePixelFormat ); RageSurface *Texture = CreateSurfaceFromPixfmt(RagePixelFormat(texpixfmt), lr.pBits, width, height, lr.Pitch); - ASSERT( Texture != NULL ); + ASSERT( Texture != nullptr ); RageSurfaceUtils::Blit( img, Texture, width, height ); delete Texture; diff --git a/src/RageDisplay_GLES2.cpp b/src/RageDisplay_GLES2.cpp index 45062ff7b6..66ec4e5b5c 100644 --- a/src/RageDisplay_GLES2.cpp +++ b/src/RageDisplay_GLES2.cpp @@ -220,7 +220,7 @@ RageDisplay_GLES2::RageDisplay_GLES2() FixLittleEndian(); // RageDisplay_GLES2_Helpers::Init(); - g_pWind = NULL; + g_pWind = nullptr; } RString @@ -735,7 +735,7 @@ void RageDisplay_Legacy::SetBlendMode( BlendMode mode ) { glEnable(GL_BLEND); - if (glBlendEquation != NULL) + if (glBlendEquation != nullptr) { if (mode == BLEND_INVERT_DEST) glBlendEquation( GL_FUNC_SUBTRACT ); diff --git a/src/RageDisplay_OGL.cpp b/src/RageDisplay_OGL.cpp index e136fddc41..aeb989da90 100644 --- a/src/RageDisplay_OGL.cpp +++ b/src/RageDisplay_OGL.cpp @@ -14,7 +14,6 @@ using namespace RageDisplay_Legacy_Helpers; #include "RageTypes.h" #include "RageUtil.h" #include "EnumHelper.h" -#include "Foreach.h" #include "DisplaySpec.h" #include "LocalizedString.h" @@ -64,7 +63,7 @@ static const GLenum RageSpriteVertexFormat = GL_T2F_C4F_N3F_V3F; static GLhandleARB g_bTextureMatrixShader = 0; static std::map g_mapRenderTargets; -static RenderTarget *g_pCurrentRenderTarget = NULL; +static RenderTarget *g_pCurrentRenderTarget = nullptr; static LowLevelWindow *g_pWind; @@ -262,7 +261,7 @@ RageDisplay_Legacy::RageDisplay_Legacy() FixLittleEndian(); RageDisplay_Legacy_Helpers::Init(); - g_pWind = NULL; + g_pWind = nullptr; g_bTextureMatrixShader = 0; offscreenRenderTarget = nullptr; } @@ -311,11 +310,11 @@ GLhandleARB CompileShader( GLenum ShaderType, RString sFile, vector asD GLhandleARB hShader = glCreateShaderObjectARB( ShaderType ); vector apData; vector aiLength; - FOREACH( RString, asDefines, s ) + for (RString &s : asDefines) { - *s = ssprintf( "#define %s\n", s->c_str() ); - apData.push_back( s->data() ); - aiLength.push_back( s->size() ); + s = ssprintf( "#define %s\n", s.c_str() ); + apData.push_back( s.data() ); + aiLength.push_back( s.size() ); } apData.push_back( "#line 1\n" ); aiLength.push_back( 8 ); @@ -603,7 +602,7 @@ static void CheckPalettedTextures() glTexImage2D( GL_PROXY_TEXTURE_2D, 0, glTexFormat, 16, 16, 0, - glImageFormat, glImageType, NULL ); + glImageFormat, glImageType, nullptr ); GL_CHECK_ERROR( "glTexImage2D" ); GLuint iFormat = 0; @@ -655,8 +654,8 @@ static void CheckPalettedTextures() /* If 8-bit palettes don't work, disable them entirely--don't trust 4-bit * palettes if it can't even get 8-bit ones right. */ - glColorTableEXT = NULL; - glGetColorTableParameterivEXT = NULL; + glColorTableEXT = nullptr; + glGetColorTableParameterivEXT = nullptr; LOG->Info( "Paletted textures disabled: %s.", sError.c_str() ); } @@ -667,7 +666,7 @@ static void CheckReversePackedPixels() glTexImage2D( GL_PROXY_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, - GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, NULL ); + GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, nullptr ); const GLenum glError = glGetError(); if (glError == GL_NO_ERROR) @@ -765,7 +764,7 @@ void RageDisplay_Legacy::ResolutionChanged() if (offscreenRenderTarget && TEXTUREMAN) { TEXTUREMAN->UnloadTexture( offscreenRenderTarget ); - offscreenRenderTarget = NULL; + offscreenRenderTarget = nullptr; } } @@ -796,8 +795,8 @@ RString RageDisplay_Legacy::TryVideoMode( const VideoModeParams &p, bool &bNewDe /* Delete all render targets. They may have associated resources other than * the texture itself. */ - FOREACHM( unsigned, RenderTarget *, g_mapRenderTargets, rt ) - delete rt->second; + for (std::pair &rt : g_mapRenderTargets) + delete rt.second; g_mapRenderTargets.clear(); /* Recreate all vertex buffers. */ @@ -894,7 +893,7 @@ RageSurface* RageDisplay_Legacy::CreateScreenshot() int width = g_pWind->GetActualVideoModeParams().width; int height = g_pWind->GetActualVideoModeParams().height; - RageSurface *image = NULL; + RageSurface *image = nullptr; if (offscreenRenderTarget) { RageSurface *raw = GetTexture(offscreenRenderTarget->GetTexHandle()); image = CreateSurface( offscreenRenderTarget->GetImageWidth(), offscreenRenderTarget->GetImageHeight(), @@ -926,7 +925,7 @@ RageSurface* RageDisplay_Legacy::CreateScreenshot() RageSurface *RageDisplay_Legacy::GetTexture( unsigned iTexture ) { if (iTexture == 0) - return NULL; // XXX + return nullptr; // XXX FlushGLErrors(); @@ -1137,8 +1136,8 @@ public: static void InvalidateObjects() { - FOREACHS( InvalidateObject*, g_InvalidateList, it ) - (*it)->Invalidate(); + for (InvalidateObject *it : g_InvalidateList) + it->Invalidate(); } class RageCompiledGeometryHWOGL : public RageCompiledGeometrySWOGL, public InvalidateObject @@ -1304,7 +1303,7 @@ void RageCompiledGeometryHWOGL::Allocate( const vector &vMeshes ) glBufferDataARB( GL_ARRAY_BUFFER_ARB, GetTotalVertices()*sizeof(RageVector3), - NULL, + nullptr, GL_STATIC_DRAW_ARB ); DebugAssertNoGLError(); @@ -1313,7 +1312,7 @@ void RageCompiledGeometryHWOGL::Allocate( const vector &vMeshes ) glBufferDataARB( GL_ARRAY_BUFFER_ARB, GetTotalVertices()*sizeof(RageVector2), - NULL, + nullptr, GL_STATIC_DRAW_ARB ); DebugAssertNoGLError(); @@ -1322,7 +1321,7 @@ void RageCompiledGeometryHWOGL::Allocate( const vector &vMeshes ) glBufferDataARB( GL_ARRAY_BUFFER_ARB, GetTotalVertices()*sizeof(RageVector3), - NULL, + nullptr, GL_STATIC_DRAW_ARB ); DebugAssertNoGLError(); @@ -1331,7 +1330,7 @@ void RageCompiledGeometryHWOGL::Allocate( const vector &vMeshes ) glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, GetTotalTriangles()*sizeof(msTriangle), - NULL, + nullptr, GL_STATIC_DRAW_ARB ); DebugAssertNoGLError(); @@ -1340,7 +1339,7 @@ void RageCompiledGeometryHWOGL::Allocate( const vector &vMeshes ) glBufferDataARB( GL_ARRAY_BUFFER_ARB, GetTotalVertices()*sizeof(RageVector2), - NULL, + nullptr, GL_STATIC_DRAW_ARB ); } @@ -1363,7 +1362,7 @@ void RageCompiledGeometryHWOGL::Draw( int iMeshIndex ) const DebugAssertNoGLError(); glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_nPositions ); DebugAssertNoGLError(); - glVertexPointer(3, GL_FLOAT, 0, NULL ); + glVertexPointer(3, GL_FLOAT, 0, nullptr ); DebugAssertNoGLError(); glDisableClientState(GL_COLOR_ARRAY); @@ -1373,7 +1372,7 @@ void RageCompiledGeometryHWOGL::Draw( int iMeshIndex ) const DebugAssertNoGLError(); glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_nTextureCoords ); DebugAssertNoGLError(); - glTexCoordPointer(2, GL_FLOAT, 0, NULL); + glTexCoordPointer(2, GL_FLOAT, 0, nullptr); DebugAssertNoGLError(); // TRICKY: Don't bind and send normals if lighting is disabled. This @@ -1392,7 +1391,7 @@ void RageCompiledGeometryHWOGL::Draw( int iMeshIndex ) const DebugAssertNoGLError(); glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_nNormals ); DebugAssertNoGLError(); - glNormalPointer(GL_FLOAT, 0, NULL); + glNormalPointer(GL_FLOAT, 0, nullptr); DebugAssertNoGLError(); } else @@ -1412,7 +1411,7 @@ void RageCompiledGeometryHWOGL::Draw( int iMeshIndex ) const DebugAssertNoGLError(); glBindBufferARB( GL_ARRAY_BUFFER_ARB, m_nTextureMatrixScale ); DebugAssertNoGLError(); - glVertexAttribPointerARB( g_iAttribTextureMatrixScale, 2, GL_FLOAT, false, 0, NULL ); + glVertexAttribPointerARB( g_iAttribTextureMatrixScale, 2, GL_FLOAT, false, 0, nullptr ); DebugAssertNoGLError(); glUseProgramObjectARB( g_bTextureMatrixShader ); @@ -1450,7 +1449,7 @@ void RageCompiledGeometryHWOGL::Draw( int iMeshIndex ) const #define BUFFER_OFFSET(o) ((char*)(o)) - ASSERT( glDrawRangeElements != NULL ); + ASSERT( glDrawRangeElements != nullptr ); glDrawRangeElements( GL_TRIANGLES, meshInfo.iVertexStart, // minimum array index contained in indices @@ -1861,7 +1860,7 @@ void RageDisplay_Legacy::SetBlendMode( BlendMode mode ) { glEnable(GL_BLEND); - if (glBlendEquation != NULL) + if (glBlendEquation != nullptr) { if (mode == BLEND_INVERT_DEST) glBlendEquation( GL_FUNC_SUBTRACT ); @@ -2300,7 +2299,7 @@ unsigned RageDisplay_Legacy::CreateTexture( glTexImage2D( GL_TEXTURE_2D, 0, glTexFormat, power_of_two(pImg->w), power_of_two(pImg->h), 0, - glImageFormat, glImageType, NULL ); + glImageFormat, glImageType, nullptr ); if (pImg->pixels) glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, @@ -2354,7 +2353,7 @@ public: void Lock( unsigned iTexHandle, RageSurface *pSurface ) { ASSERT( m_iTexHandle == 0 ); - ASSERT( pSurface->pixels == NULL ); + ASSERT( pSurface->pixels == nullptr ); CreateObject(); @@ -2362,7 +2361,7 @@ public: glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_iBuffer ); int iSize = pSurface->h * pSurface->pitch; - glBufferDataARB( GL_PIXEL_UNPACK_BUFFER_ARB, iSize, NULL, GL_STREAM_DRAW ); + glBufferDataARB( GL_PIXEL_UNPACK_BUFFER_ARB, iSize, nullptr, GL_STREAM_DRAW ); void *pSurfaceMemory = glMapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, GL_WRITE_ONLY ); pSurface->pixels = (uint8_t *) pSurfaceMemory; @@ -2378,7 +2377,7 @@ public: if (bChanged) DISPLAY->UpdateTexture( m_iTexHandle, pSurface, 0, 0, pSurface->w, pSurface->h ); - pSurface->pixels = NULL; + pSurface->pixels = nullptr; m_iTexHandle = 0; glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, 0 ); @@ -2403,7 +2402,7 @@ private: RageTextureLock *RageDisplay_Legacy::CreateTextureLock() { if (!GLEW_ARB_pixel_buffer_object) - return NULL; + return nullptr; return new RageTextureLock_OGL; } @@ -2505,7 +2504,7 @@ void RenderTarget_FramebufferObject::Create( const RenderTargetParam ¶m, int internalformat = param.bWithAlpha? GL_RGBA8:GL_RGB8; glTexImage2D( GL_TEXTURE_2D, 0, internalformat, - iTextureWidth, iTextureHeight, 0, type, GL_UNSIGNED_BYTE, NULL ); + iTextureWidth, iTextureHeight, 0, type, GL_UNSIGNED_BYTE, nullptr ); DebugAssertNoGLError(); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); @@ -2625,12 +2624,12 @@ void RageDisplay_Legacy::SetRenderTarget( unsigned iTexture, bool bPreserveTextu if (g_pCurrentRenderTarget) g_pCurrentRenderTarget->FinishRenderingTo(); - g_pCurrentRenderTarget = NULL; + g_pCurrentRenderTarget = nullptr; return; } /* If we already had a render target, disable it. */ - if (g_pCurrentRenderTarget != NULL) + if (g_pCurrentRenderTarget != nullptr) SetRenderTarget(0, true); /* Enable the new render target. */ diff --git a/src/RageException.cpp b/src/RageException.cpp index 3bd77a4d0f..ec4458f660 100644 --- a/src/RageException.cpp +++ b/src/RageException.cpp @@ -15,7 +15,7 @@ using CrashHandler::DebugBreak; #endif static uint64_t g_HandlerThreadID = RageThread::GetInvalidThreadID(); -static void (*g_CleanupHandler)( const RString &sError ) = NULL; +static void (*g_CleanupHandler)( const RString &sError ) = nullptr; void RageException::SetCleanupHandler( void (*pHandler)(const RString &sError) ) { g_HandlerThreadID = RageThread::GetCurrentThreadID(); @@ -55,7 +55,7 @@ void RageException::Throw( const char *sFmt, ... ) ASSERT_M( g_HandlerThreadID == RageThread::GetInvalidThreadID() || g_HandlerThreadID == RageThread::GetCurrentThreadID(), ssprintf("RageException::Throw() on another thread: %s", error.c_str()) ); - if( g_CleanupHandler != NULL ) + if( g_CleanupHandler != nullptr ) g_CleanupHandler( error ); exit(1); diff --git a/src/RageFile.cpp b/src/RageFile.cpp index 8f4103feb1..32dd3af825 100644 --- a/src/RageFile.cpp +++ b/src/RageFile.cpp @@ -13,7 +13,7 @@ RageFile::RageFile() { - m_File = NULL; + m_File = nullptr; } RageFile::RageFile( const RageFile &cpy ): @@ -44,7 +44,7 @@ RString RageFile::GetPath() const bool RageFile::Open( const RString& path, int mode ) { - ASSERT( FILEMAN != NULL ); + ASSERT( FILEMAN != nullptr ); Close(); m_Path = path; @@ -67,7 +67,7 @@ bool RageFile::Open( const RString& path, int mode ) int error; m_File = FILEMAN->Open( path, mode, error ); - if( m_File == NULL ) + if( m_File == nullptr ) { SetError( strerror(error) ); return false; @@ -78,12 +78,12 @@ bool RageFile::Open( const RString& path, int mode ) void RageFile::Close() { - if( m_File == NULL ) + if( m_File == nullptr ) return; delete m_File; if( m_Mode & WRITE ) FILEMAN->CacheFile( m_File, m_Path ); - m_File = NULL; + m_File = nullptr; } #define ASSERT_OPEN ASSERT_M( IsOpen(), ssprintf("\"%s\" is not open.", m_Path.c_str()) ); @@ -122,14 +122,14 @@ bool RageFile::AtEOF() const void RageFile::ClearError() { - if( m_File != NULL ) + if( m_File != nullptr ) m_File->ClearError(); m_sError = ""; } RString RageFile::GetError() const { - if( m_File != NULL && m_File->GetError() != "" ) + if( m_File != nullptr && m_File->GetError() != "" ) return m_File->GetError(); return m_sError; } @@ -137,7 +137,7 @@ RString RageFile::GetError() const void RageFile::SetError( const RString &err ) { - if( m_File != NULL ) + if( m_File != nullptr ) m_File->ClearError(); m_sError = err; } @@ -475,7 +475,7 @@ namespace RageFileUtil const luaL_Reg RageFileUtilTable[] = { LIST_METHOD( CreateRageFile ), - { NULL, NULL } + { nullptr, nullptr } }; LUA_REGISTER_NAMESPACE( RageFileUtil ); } diff --git a/src/RageFile.h b/src/RageFile.h index cbae9d5e72..d0b94eeb4c 100644 --- a/src/RageFile.h +++ b/src/RageFile.h @@ -45,7 +45,7 @@ public: bool Open( const RString& path, int mode = READ ); void Close(); - bool IsOpen() const { return m_File != NULL; } + bool IsOpen() const { return m_File != nullptr; } int GetMode() const { return m_Mode; } bool AtEOF() const; diff --git a/src/RageFileBasic.cpp b/src/RageFileBasic.cpp index 88f4ca9e8b..ae654717b3 100644 --- a/src/RageFileBasic.cpp +++ b/src/RageFileBasic.cpp @@ -7,8 +7,8 @@ REGISTER_CLASS_TRAITS( RageFileBasic, pCopy->Copy() ); RageFileObj::RageFileObj() { - m_pReadBuffer = NULL; - m_pWriteBuffer = NULL; + m_pReadBuffer = nullptr; + m_pWriteBuffer = nullptr; ResetReadBuf(); @@ -25,7 +25,7 @@ RageFileObj::RageFileObj( const RageFileObj &cpy ): RageFileBasic(cpy) { /* If the original file has a buffer, copy it. */ - if( cpy.m_pReadBuffer != NULL ) + if( cpy.m_pReadBuffer != nullptr ) { m_pReadBuffer = new char[BSIZE]; memcpy( m_pReadBuffer, cpy.m_pReadBuffer, BSIZE ); @@ -35,17 +35,17 @@ RageFileObj::RageFileObj( const RageFileObj &cpy ): } else { - m_pReadBuffer = NULL; + m_pReadBuffer = nullptr; } - if( cpy.m_pWriteBuffer != NULL ) + if( cpy.m_pWriteBuffer != nullptr ) { m_pWriteBuffer = new char[cpy.m_iWriteBufferSize]; memcpy( m_pWriteBuffer, cpy.m_pWriteBuffer, m_iWriteBufferUsed ); } else { - m_pWriteBuffer = NULL; + m_pWriteBuffer = nullptr; } m_iReadBufAvail = cpy.m_iReadBufAvail; @@ -105,7 +105,7 @@ int RageFileObj::Read( void *pBuffer, size_t iBytes ) while( !m_bEOF && iBytes > 0 ) { - if( m_pReadBuffer != NULL && m_iReadBufAvail ) + if( m_pReadBuffer != nullptr && m_iReadBufAvail ) { /* Copy data out of the buffer first. */ int iFromBuffer = min( (int) iBytes, m_iReadBufAvail ); @@ -129,7 +129,7 @@ int RageFileObj::Read( void *pBuffer, size_t iBytes ) /* If buffering is disabled, or the block is bigger than the buffer, * read the remainder of the data directly into the desteination buffer. */ - if( m_pReadBuffer == NULL || iBytes >= BSIZE ) + if( m_pReadBuffer == nullptr || iBytes >= BSIZE ) { /* We have a lot more to read, so don't waste time copying it into the * buffer. */ @@ -204,7 +204,7 @@ int RageFileObj::Read( void *pBuffer, size_t iBytes, int iNmemb ) /* Empty the write buffer to disk. Return -1 on error, 0 on success. */ int RageFileObj::EmptyWriteBuf() { - if( m_pWriteBuffer == NULL ) + if( m_pWriteBuffer == nullptr ) return 0; if( m_iWriteBufferUsed ) @@ -230,7 +230,7 @@ int RageFileObj::EmptyWriteBuf() int RageFileObj::Write( const void *pBuffer, size_t iBytes ) { - if( m_pWriteBuffer != NULL ) + if( m_pWriteBuffer != nullptr ) { /* If the file position has moved away from the write buffer, or the * incoming data won't fit in the buffer, flush. */ @@ -285,13 +285,13 @@ int RageFileObj::Flush() void RageFileObj::EnableReadBuffering() { - if( m_pReadBuffer == NULL ) + if( m_pReadBuffer == nullptr ) m_pReadBuffer = new char[BSIZE]; } void RageFileObj::EnableWriteBuffering( int iBytes ) { - if( m_pWriteBuffer == NULL ) + if( m_pWriteBuffer == nullptr ) { m_pWriteBuffer = new char[iBytes]; m_iWriteBufferPos = m_iFilePos; @@ -340,7 +340,7 @@ int RageFileObj::GetLine( RString &sOut ) /* Find the end of the block we'll move to out. */ char *p = (char *) memchr( m_pReadBuf, '\n', m_iReadBufAvail ); bool bReAddCR = false; - if( p == NULL ) + if( p == nullptr ) { /* Hack: If the last character of the buffer is \r, then it's likely that an * \r\n has been split across buffers. Move everything else, then move the @@ -433,7 +433,7 @@ int RageFileObj::PutLine( const RString &sStr ) int RageFileObj::FillReadBuf() { /* Don't call this unless buffering is enabled. */ - ASSERT( m_pReadBuffer != NULL ); + ASSERT( m_pReadBuffer != nullptr ); /* The buffer starts at m_Buffer; any data in it starts at m_pReadBuf; space between * the two is old data that we've read. (Don't mangle that data; we can use it diff --git a/src/RageFileDriver.cpp b/src/RageFileDriver.cpp index 84d5e8efb3..7497181d66 100644 --- a/src/RageFileDriver.cpp +++ b/src/RageFileDriver.cpp @@ -68,7 +68,7 @@ void RageFileDriver::FlushDirCache( const RString &sPath ) } -const struct FileDriverEntry *g_pFileDriverList = NULL; +const struct FileDriverEntry *g_pFileDriverList = nullptr; FileDriverEntry::FileDriverEntry( const RString &sType ) { @@ -79,7 +79,7 @@ FileDriverEntry::FileDriverEntry( const RString &sType ) FileDriverEntry::~FileDriverEntry() { - g_pFileDriverList = NULL; /* invalidate */ + g_pFileDriverList = nullptr; /* invalidate */ } RageFileDriver *MakeFileDriver( const RString &sType, const RString &sRoot ) @@ -87,7 +87,7 @@ RageFileDriver *MakeFileDriver( const RString &sType, const RString &sRoot ) for( const FileDriverEntry *p = g_pFileDriverList; p; p = p->m_pLink ) if( !p->m_sType.CompareNoCase(sType) ) return p->Create( sRoot ); - return NULL; + return nullptr; } /* diff --git a/src/RageFileDriverDeflate.cpp b/src/RageFileDriverDeflate.cpp index 3f85f763aa..5d2fe24471 100644 --- a/src/RageFileDriverDeflate.cpp +++ b/src/RageFileDriverDeflate.cpp @@ -313,7 +313,7 @@ int RageFileObjDeflate::FlushInternal() */ RageFileObjInflate *GunzipFile( RageFileBasic *pFile_, RString &sError, uint32_t *iCRC32 ) { - auto_ptr pFile(pFile_); + unique_ptr pFile(pFile_); sError = ""; @@ -324,12 +324,12 @@ RageFileObjInflate *GunzipFile( RageFileBasic *pFile_, RString &sError, uint32_t char magic[2]; FileReading::ReadBytes( *pFile, magic, 2, sError ); if( sError != "" ) - return NULL; + return nullptr; if( magic[0] != '\x1f' || magic[1] != '\x8b' ) { sError = "Not a gzipped file"; - return NULL; + return nullptr; } } @@ -339,7 +339,7 @@ RageFileObjInflate *GunzipFile( RageFileBasic *pFile_, RString &sError, uint32_t FileReading::read_8( *pFile, sError ); /* xfl */ FileReading::read_8( *pFile, sError ); /* os */ if( sError != "" ) - return NULL; + return nullptr; #define FTEXT 1<<0 #define FHCRC 1<<1 @@ -350,7 +350,7 @@ RageFileObjInflate *GunzipFile( RageFileBasic *pFile_, RString &sError, uint32_t if( iCompressionMethod != 8 ) { sError = ssprintf( "Unsupported compression: %i", iCompressionMethod ); - return NULL; + return nullptr; } /* Warning: flags other than FNAME are untested, since gzip doesn't @@ -358,7 +358,7 @@ RageFileObjInflate *GunzipFile( RageFileBasic *pFile_, RString &sError, uint32_t if( iFlags & UNSUPPORTED_MASK ) { sError = ssprintf( "Unsupported flags: %x", iFlags ); - return NULL; + return nullptr; } if( iFlags & FEXTRA ) @@ -385,12 +385,12 @@ RageFileObjInflate *GunzipFile( RageFileBasic *pFile_, RString &sError, uint32_t uint16_t iExpectedCRC16 = FileReading::read_u16_le( *pFile, sError ); uint16_t iActualCRC16 = int16_t( iActualCRC32 & 0xFFFF ); if( sError != "" ) - return NULL; + return nullptr; if( iActualCRC16 != iExpectedCRC16 ) { sError = "Header CRC error"; - return NULL; + return nullptr; } } @@ -399,7 +399,7 @@ RageFileObjInflate *GunzipFile( RageFileBasic *pFile_, RString &sError, uint32_t pFile->EnableCRC32( false ); if( sError != "" ) - return NULL; + return nullptr; int iDataPos = pFile->Tell(); @@ -410,13 +410,13 @@ RageFileObjInflate *GunzipFile( RageFileBasic *pFile_, RString &sError, uint32_t uint32_t iExpectedCRC32 = FileReading::read_u32_le( *pFile, sError ); uint32_t iUncompressedSize = FileReading::read_u32_le( *pFile, sError ); - if( iCRC32 != NULL ) + if( iCRC32 != nullptr ) *iCRC32 = iExpectedCRC32; FileReading::Seek( *pFile, iDataPos, sError ); if( sError != "" ) - return NULL; + return nullptr; RageFileDriverSlice *pSliceFile = new RageFileDriverSlice( pFile.release(), iDataPos, iFooterPos-iDataPos ); pSliceFile->DeleteFileWhenFinished(); @@ -424,7 +424,7 @@ RageFileObjInflate *GunzipFile( RageFileBasic *pFile_, RString &sError, uint32_t pInflateFile->DeleteFileWhenFinished(); /* Enable CRC calculation only if the caller is interested. */ - if( iCRC32 != NULL ) + if( iCRC32 != nullptr ) pInflateFile->EnableCRC32(); return pInflateFile; @@ -532,7 +532,7 @@ bool GunzipString( const RString &sIn, RString &sOut, RString &sError ) uint32_t iCRC32; RageFileBasic *pFile = GunzipFile( mem, sError, &iCRC32 ); - if( pFile == NULL ) + if( pFile == nullptr ) return false; pFile->Read( sOut ); diff --git a/src/RageFileDriverDirect.cpp b/src/RageFileDriverDirect.cpp index 54d9f70ae0..6f535511ab 100644 --- a/src/RageFileDriverDirect.cpp +++ b/src/RageFileDriverDirect.cpp @@ -81,7 +81,7 @@ static RageFileObjDirect *MakeFileObjDirect( RString sPath, int iMode, int &iErr if( iFD == -1 ) { iError = errno; - return NULL; + return nullptr; } #if defined(UNIX) @@ -90,7 +90,7 @@ static RageFileObjDirect *MakeFileObjDirect( RString sPath, int iMode, int &iErr { iError = EISDIR; close( iFD ); - return NULL; + return nullptr; } #endif @@ -141,7 +141,7 @@ bool RageFileDriverDirect::Move( const RString &sOldPath_, const RString &sNewPa } FDB->DelFile( sOldPath ); - FDB->AddFile( sNewPath, size, hash, NULL ); + FDB->AddFile( sNewPath, size, hash, nullptr ); return true; } @@ -185,7 +185,7 @@ RageFileObjDirect *RageFileObjDirect::Copy() const int iErr; RageFileObjDirect *ret = MakeFileObjDirect( m_sPath, m_iMode, iErr ); - if( ret == NULL ) + if( ret == nullptr ) RageException::Throw( "Couldn't reopen \"%s\": %s", m_sPath.c_str(), strerror(iErr) ); ret->Seek( (int)lseek( m_iFD, 0, SEEK_CUR ) ); @@ -212,7 +212,7 @@ RageFileBasic *RageFileDriverDirectReadOnly::Open( const RString &sPath, int iMo if( iMode & RageFile::WRITE ) { iError = EROFS; - return NULL; + return nullptr; } return RageFileDriverDirect::Open( sPath, iMode, iError ); diff --git a/src/RageFileDriverDirectHelpers.cpp b/src/RageFileDriverDirectHelpers.cpp index 219878103c..3cfa48a984 100644 --- a/src/RageFileDriverDirectHelpers.cpp +++ b/src/RageFileDriverDirectHelpers.cpp @@ -2,7 +2,7 @@ #include "RageFileDriverDirectHelpers.h" #include "RageUtil.h" #include "RageLog.h" -#include "Foreach.h" + #include #include @@ -161,7 +161,7 @@ void DirectFilenameDB::CacheFile( const RString &sPath ) CHECKPOINT_M( root+sPath ); RString sDir = Dirname( sPath ); FileSet *pFileSet = GetFileSet( sDir, false ); - if( pFileSet == NULL ) + if( pFileSet == nullptr ) { // This directory isn't cached so do nothing. m_Mutex.Unlock(); // Locked by GetFileSet() @@ -254,7 +254,7 @@ void DirectFilenameDB::PopulateFileSet( FileSet &fs, const RString &path ) * scans are I/O-bound. */ DIR *pDir = opendir(root+sPath); - if( pDir == NULL ) + if( pDir == nullptr ) return; while( struct dirent *pEnt = readdir(pDir) ) @@ -315,11 +315,11 @@ void DirectFilenameDB::PopulateFileSet( FileSet &fs, const RString &path ) vsFilesToRemove.push_back( sFileLNameToIgnore ); } - FOREACH_CONST( RString, vsFilesToRemove, iter ) + for (RString const &iter : vsFilesToRemove) { // Erase the file corresponding to the ignore marker File fileToDelete; - fileToDelete.SetName( *iter ); + fileToDelete.SetName( iter ); set::iterator iter2 = fs.files.find( fileToDelete ); if( iter2 != fs.files.end() ) fs.files.erase( iter2 ); diff --git a/src/RageFileDriverMemory.cpp b/src/RageFileDriverMemory.cpp index c8b5a5e5c7..477be38a3e 100644 --- a/src/RageFileDriverMemory.cpp +++ b/src/RageFileDriverMemory.cpp @@ -1,207 +1,207 @@ -#include "global.h" -#include "RageFileDriverMemory.h" -#include "RageFile.h" -#include "RageUtil.h" -#include "RageUtil_FileDB.h" -#include - -struct RageFileObjMemFile -{ - RageFileObjMemFile(): - m_iRefs(0), - m_Mutex("RageFileObjMemFile") { } - RString m_sBuf; - int m_iRefs; - RageMutex m_Mutex; - - static void AddReference( RageFileObjMemFile *pFile ) - { - pFile->m_Mutex.Lock(); - ++pFile->m_iRefs; - pFile->m_Mutex.Unlock(); - } - - static void ReleaseReference( RageFileObjMemFile *pFile ) - { - pFile->m_Mutex.Lock(); - const int iRefs = --pFile->m_iRefs; - const bool bShouldDelete = (pFile->m_iRefs == 0); - pFile->m_Mutex.Unlock(); - ASSERT( iRefs >= 0 ); - - if( bShouldDelete ) - delete pFile; - } -}; - -RageFileObjMem::RageFileObjMem( RageFileObjMemFile *pFile ) -{ - if( pFile == NULL ) - pFile = new RageFileObjMemFile; - - m_pFile = pFile; - m_iFilePos = 0; - RageFileObjMemFile::AddReference( m_pFile ); -} - -RageFileObjMem::~RageFileObjMem() -{ - RageFileObjMemFile::ReleaseReference( m_pFile ); -} - -int RageFileObjMem::ReadInternal( void *buffer, size_t bytes ) -{ - LockMut(m_pFile->m_Mutex); - - m_iFilePos = min( m_iFilePos, GetFileSize() ); - bytes = min( bytes, (size_t) GetFileSize() - m_iFilePos ); - if( bytes == 0 ) - return 0; - memcpy( buffer, &m_pFile->m_sBuf[m_iFilePos], bytes ); - m_iFilePos += bytes; - - return bytes; -} - -int RageFileObjMem::WriteInternal( const void *buffer, size_t bytes ) -{ - m_pFile->m_Mutex.Lock(); - m_pFile->m_sBuf.replace( m_iFilePos, bytes, (const char *) buffer, bytes ); - m_pFile->m_Mutex.Unlock(); - - m_iFilePos += bytes; - return bytes; -} - -int RageFileObjMem::SeekInternal( int offset ) -{ - m_iFilePos = clamp( offset, 0, GetFileSize() ); - return m_iFilePos; -} - -int RageFileObjMem::GetFileSize() const -{ - LockMut(m_pFile->m_Mutex); - return m_pFile->m_sBuf.size(); -} - -RageFileObjMem::RageFileObjMem( const RageFileObjMem &cpy ): - RageFileObj( cpy ) -{ - m_pFile = cpy.m_pFile; - m_iFilePos = cpy.m_iFilePos; - RageFileObjMemFile::AddReference( m_pFile ); -} - -RageFileObjMem *RageFileObjMem::Copy() const -{ - RageFileObjMem *pRet = new RageFileObjMem( *this ); - return pRet; -} - -const RString &RageFileObjMem::GetString() const -{ - return m_pFile->m_sBuf; -} - -void RageFileObjMem::PutString( const RString &sBuf ) -{ - m_pFile->m_Mutex.Lock(); - m_pFile->m_sBuf = sBuf; - m_pFile->m_Mutex.Unlock(); -} - -RageFileDriverMem::RageFileDriverMem(): - RageFileDriver( new NullFilenameDB ), - m_Mutex("RageFileDriverMem") -{ -} - -RageFileDriverMem::~RageFileDriverMem() -{ - for( unsigned i = 0; i < m_Files.size(); ++i ) - { - RageFileObjMemFile *pFile = m_Files[i]; - RageFileObjMemFile::ReleaseReference( pFile ); - } -} - -RageFileBasic *RageFileDriverMem::Open( const RString &sPath, int mode, int &err ) -{ - LockMut(m_Mutex); - - if( mode == RageFile::WRITE ) - { - /* If the file exists, delete it. */ - Remove( sPath ); - - RageFileObjMemFile *pFile = new RageFileObjMemFile; - - /* Add one reference, representing the file in the filesystem. */ - RageFileObjMemFile::AddReference( pFile ); - - m_Files.push_back( pFile ); - FDB->AddFile( sPath, 0, 0, pFile ); - - return new RageFileObjMem( pFile ); - } - - RageFileObjMemFile *pFile = (RageFileObjMemFile *) FDB->GetFilePriv( sPath ); - if( pFile == NULL ) - { - err = ENOENT; - return NULL; - } - - return new RageFileObjMem( pFile ); -} - -bool RageFileDriverMem::Remove( const RString &sPath ) -{ - LockMut(m_Mutex); - - RageFileObjMemFile *pFile = (RageFileObjMemFile *) FDB->GetFilePriv( sPath ); - if( pFile == NULL ) - return false; - - /* Unregister the file. */ - FDB->DelFile( sPath ); - vector::iterator it = find( m_Files.begin(), m_Files.end(), pFile ); - ASSERT( it != m_Files.end() ); - m_Files.erase( it ); - - RageFileObjMemFile::ReleaseReference( pFile ); - - return true; -} - -static struct FileDriverEntry_MEM: public FileDriverEntry -{ - FileDriverEntry_MEM(): FileDriverEntry( "MEM" ) { } - RageFileDriver *Create( const RString &sRoot ) const { return new RageFileDriverMem(); } -} const g_RegisterDriver; - -/* - * (c) 2004 Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "RageFileDriverMemory.h" +#include "RageFile.h" +#include "RageUtil.h" +#include "RageUtil_FileDB.h" +#include + +struct RageFileObjMemFile +{ + RageFileObjMemFile(): + m_iRefs(0), + m_Mutex("RageFileObjMemFile") { } + RString m_sBuf; + int m_iRefs; + RageMutex m_Mutex; + + static void AddReference( RageFileObjMemFile *pFile ) + { + pFile->m_Mutex.Lock(); + ++pFile->m_iRefs; + pFile->m_Mutex.Unlock(); + } + + static void ReleaseReference( RageFileObjMemFile *pFile ) + { + pFile->m_Mutex.Lock(); + const int iRefs = --pFile->m_iRefs; + const bool bShouldDelete = (pFile->m_iRefs == 0); + pFile->m_Mutex.Unlock(); + ASSERT( iRefs >= 0 ); + + if( bShouldDelete ) + delete pFile; + } +}; + +RageFileObjMem::RageFileObjMem( RageFileObjMemFile *pFile ) +{ + if( pFile == nullptr ) + pFile = new RageFileObjMemFile; + + m_pFile = pFile; + m_iFilePos = 0; + RageFileObjMemFile::AddReference( m_pFile ); +} + +RageFileObjMem::~RageFileObjMem() +{ + RageFileObjMemFile::ReleaseReference( m_pFile ); +} + +int RageFileObjMem::ReadInternal( void *buffer, size_t bytes ) +{ + LockMut(m_pFile->m_Mutex); + + m_iFilePos = min( m_iFilePos, GetFileSize() ); + bytes = min( bytes, (size_t) GetFileSize() - m_iFilePos ); + if( bytes == 0 ) + return 0; + memcpy( buffer, &m_pFile->m_sBuf[m_iFilePos], bytes ); + m_iFilePos += bytes; + + return bytes; +} + +int RageFileObjMem::WriteInternal( const void *buffer, size_t bytes ) +{ + m_pFile->m_Mutex.Lock(); + m_pFile->m_sBuf.replace( m_iFilePos, bytes, (const char *) buffer, bytes ); + m_pFile->m_Mutex.Unlock(); + + m_iFilePos += bytes; + return bytes; +} + +int RageFileObjMem::SeekInternal( int offset ) +{ + m_iFilePos = clamp( offset, 0, GetFileSize() ); + return m_iFilePos; +} + +int RageFileObjMem::GetFileSize() const +{ + LockMut(m_pFile->m_Mutex); + return m_pFile->m_sBuf.size(); +} + +RageFileObjMem::RageFileObjMem( const RageFileObjMem &cpy ): + RageFileObj( cpy ) +{ + m_pFile = cpy.m_pFile; + m_iFilePos = cpy.m_iFilePos; + RageFileObjMemFile::AddReference( m_pFile ); +} + +RageFileObjMem *RageFileObjMem::Copy() const +{ + RageFileObjMem *pRet = new RageFileObjMem( *this ); + return pRet; +} + +const RString &RageFileObjMem::GetString() const +{ + return m_pFile->m_sBuf; +} + +void RageFileObjMem::PutString( const RString &sBuf ) +{ + m_pFile->m_Mutex.Lock(); + m_pFile->m_sBuf = sBuf; + m_pFile->m_Mutex.Unlock(); +} + +RageFileDriverMem::RageFileDriverMem(): + RageFileDriver( new NullFilenameDB ), + m_Mutex("RageFileDriverMem") +{ +} + +RageFileDriverMem::~RageFileDriverMem() +{ + for( unsigned i = 0; i < m_Files.size(); ++i ) + { + RageFileObjMemFile *pFile = m_Files[i]; + RageFileObjMemFile::ReleaseReference( pFile ); + } +} + +RageFileBasic *RageFileDriverMem::Open( const RString &sPath, int mode, int &err ) +{ + LockMut(m_Mutex); + + if( mode == RageFile::WRITE ) + { + /* If the file exists, delete it. */ + Remove( sPath ); + + RageFileObjMemFile *pFile = new RageFileObjMemFile; + + /* Add one reference, representing the file in the filesystem. */ + RageFileObjMemFile::AddReference( pFile ); + + m_Files.push_back( pFile ); + FDB->AddFile( sPath, 0, 0, pFile ); + + return new RageFileObjMem( pFile ); + } + + RageFileObjMemFile *pFile = (RageFileObjMemFile *) FDB->GetFilePriv( sPath ); + if( pFile == nullptr ) + { + err = ENOENT; + return nullptr; + } + + return new RageFileObjMem( pFile ); +} + +bool RageFileDriverMem::Remove( const RString &sPath ) +{ + LockMut(m_Mutex); + + RageFileObjMemFile *pFile = (RageFileObjMemFile *) FDB->GetFilePriv( sPath ); + if( pFile == nullptr ) + return false; + + /* Unregister the file. */ + FDB->DelFile( sPath ); + vector::iterator it = find( m_Files.begin(), m_Files.end(), pFile ); + ASSERT( it != m_Files.end() ); + m_Files.erase( it ); + + RageFileObjMemFile::ReleaseReference( pFile ); + + return true; +} + +static struct FileDriverEntry_MEM: public FileDriverEntry +{ + FileDriverEntry_MEM(): FileDriverEntry( "MEM" ) { } + RageFileDriver *Create( const RString &sRoot ) const { return new RageFileDriverMem(); } +} const g_RegisterDriver; + +/* + * (c) 2004 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/RageFileDriverMemory.h b/src/RageFileDriverMemory.h index f431650698..d3467f94fe 100644 --- a/src/RageFileDriverMemory.h +++ b/src/RageFileDriverMemory.h @@ -1,74 +1,74 @@ -/* RageFileDriverMemory: Simple memory-based "filesystem". */ - -#ifndef RAGE_FILE_DRIVER_MEMORY_H -#define RAGE_FILE_DRIVER_MEMORY_H - -#include "RageFileDriver.h" -#include "RageFileBasic.h" -#include "RageThreads.h" - -struct RageFileObjMemFile; -class RageFileObjMem: public RageFileObj -{ -public: - RageFileObjMem( RageFileObjMemFile *pFile = NULL ); - RageFileObjMem( const RageFileObjMem &cpy ); - ~RageFileObjMem(); - - int ReadInternal( void *buffer, size_t bytes ); - int WriteInternal( const void *buffer, size_t bytes ); - int SeekInternal( int offset ); - int GetFileSize() const; - RageFileObjMem *Copy() const; - - /* Retrieve the contents of this file. */ - const RString &GetString() const; - void PutString( const RString &sBuf ); - -private: - RageFileObjMemFile *m_pFile; - int m_iFilePos; -}; - -class RageFileDriverMem: public RageFileDriver -{ -public: - RageFileDriverMem(); - ~RageFileDriverMem(); - - RageFileBasic *Open( const RString &sPath, int mode, int &err ); - void FlushDirCache( const RString & /* sPath */ ) { } - - bool Remove( const RString &sPath ); - -private: - RageMutex m_Mutex; - vector m_Files; -}; - -#endif - -/* - * (c) 2004 Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +/* RageFileDriverMemory: Simple memory-based "filesystem". */ + +#ifndef RAGE_FILE_DRIVER_MEMORY_H +#define RAGE_FILE_DRIVER_MEMORY_H + +#include "RageFileDriver.h" +#include "RageFileBasic.h" +#include "RageThreads.h" + +struct RageFileObjMemFile; +class RageFileObjMem: public RageFileObj +{ +public: + RageFileObjMem( RageFileObjMemFile *pFile = nullptr ); + RageFileObjMem( const RageFileObjMem &cpy ); + ~RageFileObjMem(); + + int ReadInternal( void *buffer, size_t bytes ); + int WriteInternal( const void *buffer, size_t bytes ); + int SeekInternal( int offset ); + int GetFileSize() const; + RageFileObjMem *Copy() const; + + /* Retrieve the contents of this file. */ + const RString &GetString() const; + void PutString( const RString &sBuf ); + +private: + RageFileObjMemFile *m_pFile; + int m_iFilePos; +}; + +class RageFileDriverMem: public RageFileDriver +{ +public: + RageFileDriverMem(); + ~RageFileDriverMem(); + + RageFileBasic *Open( const RString &sPath, int mode, int &err ); + void FlushDirCache( const RString & /* sPath */ ) { } + + bool Remove( const RString &sPath ); + +private: + RageMutex m_Mutex; + vector m_Files; +}; + +#endif + +/* + * (c) 2004 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/RageFileDriverTimeout.cpp b/src/RageFileDriverTimeout.cpp index b2c8003c31..c234441350 100644 --- a/src/RageFileDriverTimeout.cpp +++ b/src/RageFileDriverTimeout.cpp @@ -1,966 +1,966 @@ -/* - * This is a filesystem wrapper driver. To use it, mount it on top of another filesystem at a - * different mountpoint. For example, mount the local path "d:/" as a normal directory to - * /cdrom-native: - * - * FILEMAN->Mount( "dir", "d:/", "/cdrom-native" ); - * - * and then mount a timeout filesystem on top of that: - * - * FILEMAN->Mount( "timeout", "/cdrom-native", "/cdrom-timeout" ); - * - * and do all access to the device at /cdrom-timeout. - * - * A common problem with accessing devices, such as CDROMs or flaky pen drives, is that they - * can take a very long time to fail under error conditions. A single request may have a - * timeout of 500ms, but a single operation may do many requests. The system will usually - * retry operations, and we want to allow it to do so, but we don't want the high-level - * operation to take too long as a whole. - * - * There's no portable way to abort a running filesystem operation. In Unix, you may be - * able to use SIGALRM, which should cause a running operation to fail with EINTR, but - * I don't trust that, and it's not portable. - * - * This driver abstracts all access to another driver, and enforces high-level timeouts. - * Operations are run in a separate thread. If an operation takes too long to complete, - * the main thread will see it fail. The operation in the thread will actually continue; - * it will time out for real eventually. To prevent accumulation of failed threads, if - * an operation times out, we'll refuse all further access until all operations have - * finished and exited. (Load a separate driver for each device, so if one device fails, - * others continue to function.) - * - * All operations must run in the thread, including retrieving directory lists, Open() - * and deleting file objects. Read/write operations are copied through an intermediate - * buffer, so we don't clobber stuff if the operation times out, the call returns and the - * operation then completes. - * - * Unmounting the filesystem will wait for all timed-out operations to complete. - * - * This class is not threadsafe; do not access files on this filesystem from multiple - * threads simultaneously. - */ - -#include "global.h" -#include "RageFileDriverTimeout.h" -#include "RageFile.h" -#include "RageUtil.h" -#include "RageUtil_FileDB.h" -#include "RageUtil_WorkerThread.h" -#include "RageLog.h" -#include - -enum ThreadRequest -{ - REQ_OPEN, - REQ_CLOSE, - REQ_GET_FILE_SIZE, - REQ_GET_FD, - REQ_READ, - REQ_WRITE, - REQ_SEEK, - REQ_FLUSH, - REQ_COPY, - REQ_POPULATE_FILE_SET, - REQ_FLUSH_DIR_CACHE, - REQ_MOVE, - REQ_REMOVE, -}; - -/* This is the class that does most of the work. */ -class ThreadedFileWorker: public RageWorkerThread -{ -public: - ThreadedFileWorker( RString sPath ); - ~ThreadedFileWorker(); - - /* Threaded operations. If a file operation times out, the caller loses all access - * to the file and should fail all future operations; this is because the thread - * is still trying to finish the operation. The thread will clean up afterwards. */ - RageFileBasic *Open( const RString &sPath, int iMode, int &iErr ); - void Close( RageFileBasic *pFile ); - int GetFileSize( RageFileBasic *&pFile ); - int GetFD( RageFileBasic *&pFile ); - int Seek( RageFileBasic *&pFile, int iPos, RString &sError ); - int Read( RageFileBasic *&pFile, void *pBuf, int iSize, RString &sError ); - int Write( RageFileBasic *&pFile, const void *pBuf, int iSize, RString &sError ); - int Flush( RageFileBasic *&pFile, RString &sError ); - RageFileBasic *Copy( RageFileBasic *&pFile, RString &sError ); - - bool FlushDirCache( const RString &sPath ); - int Move( const RString &sOldPath, const RString &sNewPath ); - int Remove( const RString &sPath ); - bool PopulateFileSet( FileSet &fs, const RString &sPath ); - -protected: - void HandleRequest( int iRequest ); - void RequestTimedOut(); - -private: - - /* All requests: */ - RageFileDriver *m_pChildDriver; - - /* List of files to delete: */ - vector m_apDeletedFiles; - RageMutex m_DeletedFilesLock; - - /* REQ_OPEN, REQ_POPULATE_FILE_SET, REQ_FLUSH_DIR_CACHE, REQ_REMOVE, REQ_MOVE: */ - RString m_sRequestPath; /* in */ - - /* REQ_MOVE: */ - RString m_sRequestPath2; /* in */ - - /* REQ_OPEN, REQ_COPY: */ - RageFileBasic *m_pResultFile; /* out */ - - /* REQ_POPULATE_FILE_SET: */ - FileSet m_ResultFileSet; /* out */ - - /* REQ_OPEN: */ - int m_iRequestMode; /* in */ - - /* REQ_CLOSE, REQ_GET_FILE_SIZE, REQ_COPY: */ - RageFileBasic *m_pRequestFile; /* in */ - - /* REQ_OPEN, REQ_GET_FILE_SIZE, REQ_READ, REQ_SEEK */ - int m_iResultRequest; /* out */ - - /* REQ_READ, REQ_WRITE */ - int m_iRequestSize; /* in */ - RString m_sResultError; /* out */ - - /* REQ_SEEK */ - int m_iRequestPos; /* in */ - - /* REQ_READ */ - char *m_pResultBuffer; /* out */ - - /* REQ_WRITE */ - char *m_pRequestBuffer; /* in */ -}; - -static vector g_apWorkers; -static RageMutex g_apWorkersMutex("WorkersMutex"); - -/* Set the timeout length, and reset the timer. */ -void RageFileDriverTimeout::SetTimeout( float fSeconds ) -{ - g_apWorkersMutex.Lock(); - for( unsigned i = 0; i < g_apWorkers.size(); ++i ) - g_apWorkers[i]->SetTimeout( fSeconds ); - g_apWorkersMutex.Unlock(); -} - - -ThreadedFileWorker::ThreadedFileWorker( RString sPath ): - RageWorkerThread( sPath ), - m_DeletedFilesLock( sPath + "DeletedFilesLock" ) -{ - /* Grab a reference to the child driver. We'll operate on it directly. */ - m_pChildDriver = FILEMAN->GetFileDriver( sPath ); - if( m_pChildDriver == NULL ) - WARN( ssprintf("ThreadedFileWorker: Mountpoint \"%s\" not found", sPath.c_str()) ); - - m_pResultFile = NULL; - m_pRequestFile = NULL; - m_pResultBuffer = NULL; - m_pRequestBuffer = NULL; - - g_apWorkersMutex.Lock(); - g_apWorkers.push_back( this ); - g_apWorkersMutex.Unlock(); - - StartThread(); -} - -ThreadedFileWorker::~ThreadedFileWorker() -{ - StopThread(); - - if( m_pChildDriver != NULL ) - FILEMAN->ReleaseFileDriver( m_pChildDriver ); - - /* Unregister ourself. */ - g_apWorkersMutex.Lock(); - for( unsigned i = 0; i < g_apWorkers.size(); ++i ) - { - if( g_apWorkers[i] == this ) - { - g_apWorkers.erase( g_apWorkers.begin()+i ); - break; - } - } - g_apWorkersMutex.Unlock(); -} - -void ThreadedFileWorker::HandleRequest( int iRequest ) -{ - { - m_DeletedFilesLock.Lock(); - vector apDeletedFiles = m_apDeletedFiles; - m_apDeletedFiles.clear(); - m_DeletedFilesLock.Unlock(); - - for( unsigned i = 0; i < apDeletedFiles.size(); ++i ) - delete apDeletedFiles[i]; - } - - /* We have a request. */ - switch( iRequest ) - { - case REQ_OPEN: - ASSERT( m_pResultFile == NULL ); - ASSERT( !m_sRequestPath.empty() ); - m_iResultRequest = 0; - m_pResultFile = m_pChildDriver->Open( m_sRequestPath, m_iRequestMode, m_iResultRequest ); - break; - - case REQ_CLOSE: - ASSERT( m_pRequestFile != NULL ); - delete m_pRequestFile; - - /* Clear m_pRequestFile, so RequestTimedOut doesn't double-delete. */ - m_pRequestFile = NULL; - break; - - case REQ_GET_FILE_SIZE: - ASSERT( m_pRequestFile != NULL ); - m_iResultRequest = m_pRequestFile->GetFileSize(); - break; - - case REQ_SEEK: - ASSERT( m_pRequestFile != NULL ); - m_iResultRequest = m_pRequestFile->Seek( m_iRequestPos ); - m_sResultError = m_pRequestFile->GetError(); - break; - - case REQ_READ: - ASSERT( m_pRequestFile != NULL ); - ASSERT( m_pResultBuffer != NULL ); - m_iResultRequest = m_pRequestFile->Read( m_pResultBuffer, m_iRequestSize ); - m_sResultError = m_pRequestFile->GetError(); - break; - - case REQ_WRITE: - ASSERT( m_pRequestFile != NULL ); - ASSERT( m_pRequestBuffer != NULL ); - m_iResultRequest = m_pRequestFile->Write( m_pRequestBuffer, m_iRequestSize ); - m_sResultError = m_pRequestFile->GetError(); - break; - - case REQ_FLUSH: - ASSERT( m_pRequestFile != NULL ); - m_iResultRequest = m_pRequestFile->Flush(); - m_sResultError = m_pRequestFile->GetError(); - break; - - case REQ_COPY: - ASSERT( m_pRequestFile != NULL ); - m_pResultFile = m_pRequestFile->Copy(); - break; - - case REQ_POPULATE_FILE_SET: - ASSERT( !m_sRequestPath.empty() ); - m_ResultFileSet = FileSet(); - m_pChildDriver->FDB->GetFileSetCopy( m_sRequestPath, m_ResultFileSet ); - break; - - case REQ_FLUSH_DIR_CACHE: - m_pChildDriver->FlushDirCache( m_sRequestPath ); - break; - - case REQ_REMOVE: - ASSERT( !m_sRequestPath.empty() ); - m_iResultRequest = m_pChildDriver->Remove( m_sRequestPath )? 0:-1; - break; - - case REQ_MOVE: - ASSERT( !m_sRequestPath.empty() ); - ASSERT( !m_sRequestPath2.empty() ); - m_iResultRequest = m_pChildDriver->Move( m_sRequestPath, m_sRequestPath2 )? 0:-1; - break; - - default: - FAIL_M( ssprintf("%i", iRequest) ); - } -} - -void ThreadedFileWorker::RequestTimedOut() -{ - /* The event timed out. Clean up any residue from the last action. */ - SAFE_DELETE( m_pRequestFile ); - SAFE_DELETE( m_pResultFile ); - SAFE_DELETE_ARRAY( m_pRequestBuffer ); - SAFE_DELETE_ARRAY( m_pResultBuffer ); -} - -RageFileBasic *ThreadedFileWorker::Open( const RString &sPath, int iMode, int &iErr ) -{ - if( m_pChildDriver == NULL ) - { - iErr = ENODEV; - return NULL; - } - - /* If we're currently in a timed-out state, fail. */ - if( IsTimedOut() ) - { - iErr = EFAULT; /* Win32 has no ETIMEDOUT */ - return NULL; - } - - m_sRequestPath = sPath; - m_iRequestMode = iMode; - - if( !DoRequest(REQ_OPEN) ) - { - LOG->Trace( "Open(%s) timed out", sPath.c_str() ); - iErr = EFAULT; /* Win32 has no ETIMEDOUT */ - return NULL; - } - - iErr = m_iResultRequest; - RageFileBasic *pRet = m_pResultFile; - m_pResultFile = NULL; - - return pRet; -} - -void ThreadedFileWorker::Close( RageFileBasic *pFile ) -{ - ASSERT( m_pChildDriver != NULL ); /* how did you get a file to begin with? */ - - if( pFile == NULL ) - return; - - if( !IsTimedOut() ) - { - /* If we're not in a timed-out state, try to wait for the deletion to complete - * before continuing. */ - m_pRequestFile = pFile; - if( !DoRequest(REQ_CLOSE) ) - return; - m_pRequestFile = NULL; - } - else - { - /* Delete the file when the timeout completes. */ - m_DeletedFilesLock.Lock(); - m_apDeletedFiles.push_back( pFile ); - m_DeletedFilesLock.Unlock(); - } -} - -int ThreadedFileWorker::GetFileSize( RageFileBasic *&pFile ) -{ - ASSERT( m_pChildDriver != NULL ); /* how did you get a file to begin with? */ - - /* If we're currently in a timed-out state, fail. */ - if( IsTimedOut() ) - { - this->Close( pFile ); - pFile = NULL; - } - - if( pFile == NULL ) - return -1; - - m_pRequestFile = pFile; - - if( !DoRequest(REQ_GET_FILE_SIZE) ) - { - /* If we time out, we can no longer access pFile. */ - pFile = NULL; - return -1; - } - - m_pRequestFile = NULL; - - return m_iResultRequest; -} - -int ThreadedFileWorker::GetFD( RageFileBasic *&pFile ) -{ - ASSERT( m_pChildDriver != NULL ); /* how did you get a file to begin with? */ - - /* If we're currently in a timed-out state, fail. */ - if( IsTimedOut() ) - { - this->Close( pFile ); - pFile = NULL; - } - - if( pFile == NULL ) - return -1; - - m_pRequestFile = pFile; - - if( !DoRequest(REQ_GET_FD) ) - { - /* If we time out, we can no longer access pFile. */ - pFile = NULL; - return -1; - } - - m_pRequestFile = NULL; - - return m_iResultRequest; -} - -int ThreadedFileWorker::Seek( RageFileBasic *&pFile, int iPos, RString &sError ) -{ - ASSERT( m_pChildDriver != NULL ); /* how did you get a file to begin with? */ - - /* If we're currently in a timed-out state, fail. */ - if( IsTimedOut() ) - { - this->Close( pFile ); - pFile = NULL; - } - - if( pFile == NULL ) - { - sError = "Operation timed out"; - return -1; - } - - m_pRequestFile = pFile; - m_iRequestPos = iPos; /* in */ - - if( !DoRequest(REQ_SEEK) ) - { - /* If we time out, we can no longer access pFile. */ - sError = "Operation timed out"; - pFile = NULL; - return -1; - } - - if( m_iResultRequest == -1 ) - sError = m_sResultError; - m_pRequestFile = NULL; - - return m_iResultRequest; -} - -int ThreadedFileWorker::Read( RageFileBasic *&pFile, void *pBuf, int iSize, RString &sError ) -{ - ASSERT( m_pChildDriver != NULL ); /* how did you get a file to begin with? */ - - /* If we're currently in a timed-out state, fail. */ - if( IsTimedOut() ) - { - this->Close( pFile ); - pFile = NULL; - } - - if( pFile == NULL ) - { - sError = "Operation timed out"; - return -1; - } - - m_pRequestFile = pFile; - m_iRequestSize = iSize; - m_pResultBuffer = new char[iSize]; - - if( !DoRequest(REQ_READ) ) - { - /* If we time out, we can no longer access pFile. */ - sError = "Operation timed out"; - pFile = NULL; - return -1; - } - - int iGot = m_iResultRequest; - if( iGot == -1 ) - sError = m_sResultError; - else - memcpy( pBuf, m_pResultBuffer, iGot ); - - m_pRequestFile = NULL; - delete [] m_pResultBuffer; - m_pResultBuffer = NULL; - - return iGot; -} - -int ThreadedFileWorker::Write( RageFileBasic *&pFile, const void *pBuf, int iSize, RString &sError ) -{ - ASSERT( m_pChildDriver != NULL ); /* how did you get a file to begin with? */ - - /* If we're currently in a timed-out state, fail. */ - if( IsTimedOut() ) - { - this->Close( pFile ); - pFile = NULL; - } - - if( pFile == NULL ) - { - sError = "Operation timed out"; - return -1; - } - - m_pRequestFile = pFile; - m_iRequestSize = iSize; - m_pRequestBuffer = new char[iSize]; - memcpy( m_pRequestBuffer, pBuf, iSize ); - - if( !DoRequest(REQ_WRITE) ) - { - /* If we time out, we can no longer access pFile. */ - sError = "Operation timed out"; - pFile = NULL; - return -1; - } - - int iGot = m_iResultRequest; - if( m_iResultRequest == -1 ) - sError = m_sResultError; - - m_pRequestFile = NULL; - delete [] m_pRequestBuffer; - m_pRequestBuffer = NULL; - - return iGot; -} - -int ThreadedFileWorker::Flush( RageFileBasic *&pFile, RString &sError ) -{ - ASSERT( m_pChildDriver != NULL ); /* how did you get a file to begin with? */ - - /* If we're currently in a timed-out state, fail. */ - if( IsTimedOut() ) - { - this->Close( pFile ); - pFile = NULL; - } - - if( pFile == NULL ) - { - sError = "Operation timed out"; - return -1; - } - - m_pRequestFile = pFile; - - if( !DoRequest(REQ_FLUSH) ) - { - /* If we time out, we can no longer access pFile. */ - sError = "Operation timed out"; - pFile = NULL; - return -1; - } - - if( m_iResultRequest == -1 ) - sError = m_sResultError; - - m_pRequestFile = NULL; - - return m_iResultRequest; -} - -RageFileBasic *ThreadedFileWorker::Copy( RageFileBasic *&pFile, RString &sError ) -{ - ASSERT( m_pChildDriver != NULL ); /* how did you get a file to begin with? */ - - /* If we're currently in a timed-out state, fail. */ - if( IsTimedOut() ) - { - this->Close( pFile ); - pFile = NULL; - } - - if( pFile == NULL ) - { - sError = "Operation timed out"; - return NULL; - } - - m_pRequestFile = pFile; - if( !DoRequest(REQ_COPY) ) - { - /* If we time out, we can no longer access pFile. */ - sError = "Operation timed out"; - pFile = NULL; - return NULL; - } - - RageFileBasic *pRet = m_pResultFile; - m_pRequestFile = NULL; - m_pResultFile = NULL; - - return pRet; -} - - -bool ThreadedFileWorker::PopulateFileSet( FileSet &fs, const RString &sPath ) -{ - if( m_pChildDriver == NULL ) - return false; - - /* If we're currently in a timed-out state, fail. */ - if( IsTimedOut() ) - return false; - - /* Fill in a different FileSet; copy the results in on success. */ - m_sRequestPath = sPath; - - /* Kick off the worker thread, and wait for it to finish. */ - if( !DoRequest(REQ_POPULATE_FILE_SET) ) - { - LOG->Trace( "PopulateFileSet(%s) timed out", sPath.c_str() ); - return false; - } - - fs = m_ResultFileSet; - return true; -} - -int ThreadedFileWorker::Move( const RString &sOldPath, const RString &sNewPath ) -{ - ASSERT( m_pChildDriver != NULL ); /* how did you get a file to begin with? */ - - /* If we're currently in a timed-out state, fail. */ - if( IsTimedOut() ) - return -1; - - m_sRequestPath = sOldPath; - m_sRequestPath2 = sNewPath; - - if( !DoRequest(REQ_MOVE) ) - { - /* If we time out, we can no longer access pFile. */ - return -1; - } - - return m_iResultRequest; -} - -int ThreadedFileWorker::Remove( const RString &sPath ) -{ - ASSERT( m_pChildDriver != NULL ); /* how did you get a file to begin with? */ - - /* If we're currently in a timed-out state, fail. */ - if( IsTimedOut() ) - return -1; - - m_sRequestPath = sPath; - - if( !DoRequest(REQ_REMOVE) ) - { - /* If we time out, we can no longer access pFile. */ - return -1; - } - - return m_iResultRequest; -} - -bool ThreadedFileWorker::FlushDirCache( const RString &sPath ) -{ - /* FlushDirCache() is often called globally, on all drivers, which means it's called with - * no timeout. Temporarily enable a timeout if needed. */ - bool bTimeoutEnabled = TimeoutEnabled(); - if( !bTimeoutEnabled ) - SetTimeout(1); - - if( m_pChildDriver == NULL ) - return false; - - /* If we're currently in a timed-out state, fail. */ - if( IsTimedOut() ) - return false; - - m_sRequestPath = sPath; - - /* Kick off the worker thread, and wait for it to finish. */ - if( !DoRequest(REQ_FLUSH_DIR_CACHE) ) - { - if( !bTimeoutEnabled ) - SetTimeout(-1); - - LOG->Trace( "FlushDirCache(%s) timed out", sPath.c_str() ); - return false; - } - - if( !bTimeoutEnabled ) - SetTimeout(-1); - - return true; -} - - -class RageFileObjTimeout: public RageFileObj -{ -public: - /* pFile will be freed by passing it to pWorker. */ - RageFileObjTimeout( ThreadedFileWorker *pWorker, RageFileBasic *pFile, int iSize, int iMode ) - { - m_pWorker = pWorker; - m_pFile = pFile; - m_iFileSize = iSize; - m_iMode = iMode; - /* We have a lot of overhead per read and write operation, since we send - * commands to the worker thread. Buffer these operations. */ - if( iMode & RageFile::WRITE ) - EnableWriteBuffering(); - if( iMode & RageFile::READ ) - EnableReadBuffering(); - } - - ~RageFileObjTimeout() - { - if( m_pFile != NULL ) - { - Flush(); - m_pWorker->Close( m_pFile ); - } - } - - int GetFileSize() const - { - return m_iFileSize; - } - - int GetFD() - { - RString sError; - int iRet = m_pWorker->GetFD( m_pFile ); - - if( m_pFile == NULL ) - { - SetError( "Operation timed out" ); - return -1; - } - - if( iRet == -1 ) - SetError( sError ); - - return iRet; - } - - RageFileBasic *Copy() const - { - RString sError; - RageFileBasic *pCopy = m_pWorker->Copy( m_pFile, sError ); - - if( m_pFile == NULL ) - { -// SetError( "Operation timed out" ); - return NULL; - } - - if( pCopy == NULL ) - { -// SetError( sError ); - return NULL; - } - - return new RageFileObjTimeout( m_pWorker, pCopy, m_iFileSize, m_iMode ); - } - -protected: - int SeekInternal( int iPos ) - { - RString sError; - int iRet = m_pWorker->Seek( m_pFile, iPos, sError ); - - if( m_pFile == NULL ) - { - SetError( "Operation timed out" ); - return -1; - } - - if( iRet == -1 ) - SetError( sError ); - - return iRet; - } - - - int ReadInternal( void *pBuffer, size_t iBytes ) - { - RString sError; - int iRet = m_pWorker->Read( m_pFile, pBuffer, iBytes, sError ); - - if( m_pFile == NULL ) - { - SetError( "Operation timed out" ); - return -1; - } - - if( iRet == -1 ) - SetError( sError ); - - return iRet; - } - - int WriteInternal( const void *pBuffer, size_t iBytes ) - { - RString sError; - int iRet = m_pWorker->Write( m_pFile, pBuffer, iBytes, sError ); - - if( m_pFile == NULL ) - { - SetError( "Operation timed out" ); - return -1; - } - - if( iRet == -1 ) - SetError( sError ); - - return iRet; - } - - int FlushInternal() - { - RString sError; - int iRet = m_pWorker->Flush( m_pFile, sError ); - - if( m_pFile == NULL ) - { - SetError( "Operation timed out" ); - return -1; - } - - if( iRet == -1 ) - SetError( sError ); - - return iRet; - } - - /* Mutable because the const operation Copy() timing out results in the original - * object no longer being available. */ - mutable RageFileBasic *m_pFile; - - ThreadedFileWorker *m_pWorker; - - /* GetFileSize isn't allowed to fail, so cache the file size on load. */ - int m_iFileSize; - //cache filemode - int m_iMode; -}; - -/* This FilenameDB runs PopulateFileSet in the worker thread. */ -class TimedFilenameDB: public FilenameDB -{ -public: - TimedFilenameDB() - { - ExpireSeconds = -1; - m_pWorker = NULL; - } - - void SetWorker( ThreadedFileWorker *pWorker ) - { - ASSERT( pWorker != NULL ); - m_pWorker = pWorker; - } - - void PopulateFileSet( FileSet &fs, const RString &sPath ) - { - ASSERT( m_pWorker != NULL ); - m_pWorker->PopulateFileSet( fs, sPath ); - } - -private: - ThreadedFileWorker *m_pWorker; -}; - -RageFileDriverTimeout::RageFileDriverTimeout( const RString &sPath ): - RageFileDriver( new TimedFilenameDB() ) -{ - m_pWorker = new ThreadedFileWorker( sPath ); - - ((TimedFilenameDB *) FDB)->SetWorker( m_pWorker ); -} - -RageFileBasic *RageFileDriverTimeout::Open( const RString &sPath, int iMode, int &iErr ) -{ - RageFileBasic *pChildFile = m_pWorker->Open( sPath, iMode, iErr ); - if( pChildFile == NULL ) - return NULL; - - /* RageBasicFile::GetFileSize isn't allowed to fail, but we are; grab the file - * size now and store it. */ - int iSize = 0; - if( iMode & RageFile::READ ) - { - iSize = m_pWorker->GetFileSize( pChildFile ); - if( iSize == -1 ) - { - /* When m_pWorker->GetFileSize fails, it takes ownership of pChildFile. */ - ASSERT( pChildFile == NULL ); - iErr = EFAULT; - return NULL; - } - } - - return new RageFileObjTimeout( m_pWorker, pChildFile, iSize, iMode ); -} - -void RageFileDriverTimeout::FlushDirCache( const RString &sPath ) -{ - RageFileDriver::FlushDirCache( sPath ); - m_pWorker->FlushDirCache( sPath ); -} - -bool RageFileDriverTimeout::Move( const RString &sOldPath, const RString &sNewPath ) -{ - int iRet = m_pWorker->Move( sOldPath, sNewPath ); - if( iRet == -1 ) - { - WARN( ssprintf("RageFileDriverTimeout::Move(%s,%s) failed", sOldPath.c_str(), sNewPath.c_str()) ); - return false; - } - - return true; -} - -bool RageFileDriverTimeout::Remove( const RString &sPath ) -{ - int iRet = m_pWorker->Remove( sPath ); - if( iRet == -1 ) - { - WARN( ssprintf("RageFileDriverTimeout::Remove(%s) failed", sPath.c_str()) ); - return false; - } - - return true; -} - -RageFileDriverTimeout::~RageFileDriverTimeout() -{ - delete m_pWorker; -} - -static struct FileDriverEntry_Timeout: public FileDriverEntry -{ - FileDriverEntry_Timeout(): FileDriverEntry( "TIMEOUT" ) { } - RageFileDriver *Create( const RString &sRoot ) const { return new RageFileDriverTimeout( sRoot ); } -} const g_RegisterDriver; - -/* - * Copyright (c) 2005 Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +/* + * This is a filesystem wrapper driver. To use it, mount it on top of another filesystem at a + * different mountpoint. For example, mount the local path "d:/" as a normal directory to + * /cdrom-native: + * + * FILEMAN->Mount( "dir", "d:/", "/cdrom-native" ); + * + * and then mount a timeout filesystem on top of that: + * + * FILEMAN->Mount( "timeout", "/cdrom-native", "/cdrom-timeout" ); + * + * and do all access to the device at /cdrom-timeout. + * + * A common problem with accessing devices, such as CDROMs or flaky pen drives, is that they + * can take a very long time to fail under error conditions. A single request may have a + * timeout of 500ms, but a single operation may do many requests. The system will usually + * retry operations, and we want to allow it to do so, but we don't want the high-level + * operation to take too long as a whole. + * + * There's no portable way to abort a running filesystem operation. In Unix, you may be + * able to use SIGALRM, which should cause a running operation to fail with EINTR, but + * I don't trust that, and it's not portable. + * + * This driver abstracts all access to another driver, and enforces high-level timeouts. + * Operations are run in a separate thread. If an operation takes too long to complete, + * the main thread will see it fail. The operation in the thread will actually continue; + * it will time out for real eventually. To prevent accumulation of failed threads, if + * an operation times out, we'll refuse all further access until all operations have + * finished and exited. (Load a separate driver for each device, so if one device fails, + * others continue to function.) + * + * All operations must run in the thread, including retrieving directory lists, Open() + * and deleting file objects. Read/write operations are copied through an intermediate + * buffer, so we don't clobber stuff if the operation times out, the call returns and the + * operation then completes. + * + * Unmounting the filesystem will wait for all timed-out operations to complete. + * + * This class is not threadsafe; do not access files on this filesystem from multiple + * threads simultaneously. + */ + +#include "global.h" +#include "RageFileDriverTimeout.h" +#include "RageFile.h" +#include "RageUtil.h" +#include "RageUtil_FileDB.h" +#include "RageUtil_WorkerThread.h" +#include "RageLog.h" +#include + +enum ThreadRequest +{ + REQ_OPEN, + REQ_CLOSE, + REQ_GET_FILE_SIZE, + REQ_GET_FD, + REQ_READ, + REQ_WRITE, + REQ_SEEK, + REQ_FLUSH, + REQ_COPY, + REQ_POPULATE_FILE_SET, + REQ_FLUSH_DIR_CACHE, + REQ_MOVE, + REQ_REMOVE, +}; + +/* This is the class that does most of the work. */ +class ThreadedFileWorker: public RageWorkerThread +{ +public: + ThreadedFileWorker( RString sPath ); + ~ThreadedFileWorker(); + + /* Threaded operations. If a file operation times out, the caller loses all access + * to the file and should fail all future operations; this is because the thread + * is still trying to finish the operation. The thread will clean up afterwards. */ + RageFileBasic *Open( const RString &sPath, int iMode, int &iErr ); + void Close( RageFileBasic *pFile ); + int GetFileSize( RageFileBasic *&pFile ); + int GetFD( RageFileBasic *&pFile ); + int Seek( RageFileBasic *&pFile, int iPos, RString &sError ); + int Read( RageFileBasic *&pFile, void *pBuf, int iSize, RString &sError ); + int Write( RageFileBasic *&pFile, const void *pBuf, int iSize, RString &sError ); + int Flush( RageFileBasic *&pFile, RString &sError ); + RageFileBasic *Copy( RageFileBasic *&pFile, RString &sError ); + + bool FlushDirCache( const RString &sPath ); + int Move( const RString &sOldPath, const RString &sNewPath ); + int Remove( const RString &sPath ); + bool PopulateFileSet( FileSet &fs, const RString &sPath ); + +protected: + void HandleRequest( int iRequest ); + void RequestTimedOut(); + +private: + + /* All requests: */ + RageFileDriver *m_pChildDriver; + + /* List of files to delete: */ + vector m_apDeletedFiles; + RageMutex m_DeletedFilesLock; + + /* REQ_OPEN, REQ_POPULATE_FILE_SET, REQ_FLUSH_DIR_CACHE, REQ_REMOVE, REQ_MOVE: */ + RString m_sRequestPath; /* in */ + + /* REQ_MOVE: */ + RString m_sRequestPath2; /* in */ + + /* REQ_OPEN, REQ_COPY: */ + RageFileBasic *m_pResultFile; /* out */ + + /* REQ_POPULATE_FILE_SET: */ + FileSet m_ResultFileSet; /* out */ + + /* REQ_OPEN: */ + int m_iRequestMode; /* in */ + + /* REQ_CLOSE, REQ_GET_FILE_SIZE, REQ_COPY: */ + RageFileBasic *m_pRequestFile; /* in */ + + /* REQ_OPEN, REQ_GET_FILE_SIZE, REQ_READ, REQ_SEEK */ + int m_iResultRequest; /* out */ + + /* REQ_READ, REQ_WRITE */ + int m_iRequestSize; /* in */ + RString m_sResultError; /* out */ + + /* REQ_SEEK */ + int m_iRequestPos; /* in */ + + /* REQ_READ */ + char *m_pResultBuffer; /* out */ + + /* REQ_WRITE */ + char *m_pRequestBuffer; /* in */ +}; + +static vector g_apWorkers; +static RageMutex g_apWorkersMutex("WorkersMutex"); + +/* Set the timeout length, and reset the timer. */ +void RageFileDriverTimeout::SetTimeout( float fSeconds ) +{ + g_apWorkersMutex.Lock(); + for( unsigned i = 0; i < g_apWorkers.size(); ++i ) + g_apWorkers[i]->SetTimeout( fSeconds ); + g_apWorkersMutex.Unlock(); +} + + +ThreadedFileWorker::ThreadedFileWorker( RString sPath ): + RageWorkerThread( sPath ), + m_DeletedFilesLock( sPath + "DeletedFilesLock" ) +{ + /* Grab a reference to the child driver. We'll operate on it directly. */ + m_pChildDriver = FILEMAN->GetFileDriver( sPath ); + if( m_pChildDriver == nullptr ) + WARN( ssprintf("ThreadedFileWorker: Mountpoint \"%s\" not found", sPath.c_str()) ); + + m_pResultFile = nullptr; + m_pRequestFile = nullptr; + m_pResultBuffer = nullptr; + m_pRequestBuffer = nullptr; + + g_apWorkersMutex.Lock(); + g_apWorkers.push_back( this ); + g_apWorkersMutex.Unlock(); + + StartThread(); +} + +ThreadedFileWorker::~ThreadedFileWorker() +{ + StopThread(); + + if( m_pChildDriver != nullptr ) + FILEMAN->ReleaseFileDriver( m_pChildDriver ); + + /* Unregister ourself. */ + g_apWorkersMutex.Lock(); + for( unsigned i = 0; i < g_apWorkers.size(); ++i ) + { + if( g_apWorkers[i] == this ) + { + g_apWorkers.erase( g_apWorkers.begin()+i ); + break; + } + } + g_apWorkersMutex.Unlock(); +} + +void ThreadedFileWorker::HandleRequest( int iRequest ) +{ + { + m_DeletedFilesLock.Lock(); + vector apDeletedFiles = m_apDeletedFiles; + m_apDeletedFiles.clear(); + m_DeletedFilesLock.Unlock(); + + for( unsigned i = 0; i < apDeletedFiles.size(); ++i ) + delete apDeletedFiles[i]; + } + + /* We have a request. */ + switch( iRequest ) + { + case REQ_OPEN: + ASSERT( m_pResultFile == nullptr ); + ASSERT( !m_sRequestPath.empty() ); + m_iResultRequest = 0; + m_pResultFile = m_pChildDriver->Open( m_sRequestPath, m_iRequestMode, m_iResultRequest ); + break; + + case REQ_CLOSE: + ASSERT( m_pRequestFile != nullptr ); + delete m_pRequestFile; + + /* Clear m_pRequestFile, so RequestTimedOut doesn't double-delete. */ + m_pRequestFile = nullptr; + break; + + case REQ_GET_FILE_SIZE: + ASSERT( m_pRequestFile != nullptr ); + m_iResultRequest = m_pRequestFile->GetFileSize(); + break; + + case REQ_SEEK: + ASSERT( m_pRequestFile != nullptr ); + m_iResultRequest = m_pRequestFile->Seek( m_iRequestPos ); + m_sResultError = m_pRequestFile->GetError(); + break; + + case REQ_READ: + ASSERT( m_pRequestFile != nullptr ); + ASSERT( m_pResultBuffer != nullptr ); + m_iResultRequest = m_pRequestFile->Read( m_pResultBuffer, m_iRequestSize ); + m_sResultError = m_pRequestFile->GetError(); + break; + + case REQ_WRITE: + ASSERT( m_pRequestFile != nullptr ); + ASSERT( m_pRequestBuffer != nullptr ); + m_iResultRequest = m_pRequestFile->Write( m_pRequestBuffer, m_iRequestSize ); + m_sResultError = m_pRequestFile->GetError(); + break; + + case REQ_FLUSH: + ASSERT( m_pRequestFile != nullptr ); + m_iResultRequest = m_pRequestFile->Flush(); + m_sResultError = m_pRequestFile->GetError(); + break; + + case REQ_COPY: + ASSERT( m_pRequestFile != nullptr ); + m_pResultFile = m_pRequestFile->Copy(); + break; + + case REQ_POPULATE_FILE_SET: + ASSERT( !m_sRequestPath.empty() ); + m_ResultFileSet = FileSet(); + m_pChildDriver->FDB->GetFileSetCopy( m_sRequestPath, m_ResultFileSet ); + break; + + case REQ_FLUSH_DIR_CACHE: + m_pChildDriver->FlushDirCache( m_sRequestPath ); + break; + + case REQ_REMOVE: + ASSERT( !m_sRequestPath.empty() ); + m_iResultRequest = m_pChildDriver->Remove( m_sRequestPath )? 0:-1; + break; + + case REQ_MOVE: + ASSERT( !m_sRequestPath.empty() ); + ASSERT( !m_sRequestPath2.empty() ); + m_iResultRequest = m_pChildDriver->Move( m_sRequestPath, m_sRequestPath2 )? 0:-1; + break; + + default: + FAIL_M( ssprintf("%i", iRequest) ); + } +} + +void ThreadedFileWorker::RequestTimedOut() +{ + /* The event timed out. Clean up any residue from the last action. */ + SAFE_DELETE( m_pRequestFile ); + SAFE_DELETE( m_pResultFile ); + SAFE_DELETE_ARRAY( m_pRequestBuffer ); + SAFE_DELETE_ARRAY( m_pResultBuffer ); +} + +RageFileBasic *ThreadedFileWorker::Open( const RString &sPath, int iMode, int &iErr ) +{ + if( m_pChildDriver == nullptr ) + { + iErr = ENODEV; + return nullptr; + } + + /* If we're currently in a timed-out state, fail. */ + if( IsTimedOut() ) + { + iErr = EFAULT; /* Win32 has no ETIMEDOUT */ + return nullptr; + } + + m_sRequestPath = sPath; + m_iRequestMode = iMode; + + if( !DoRequest(REQ_OPEN) ) + { + LOG->Trace( "Open(%s) timed out", sPath.c_str() ); + iErr = EFAULT; /* Win32 has no ETIMEDOUT */ + return nullptr; + } + + iErr = m_iResultRequest; + RageFileBasic *pRet = m_pResultFile; + m_pResultFile = nullptr; + + return pRet; +} + +void ThreadedFileWorker::Close( RageFileBasic *pFile ) +{ + ASSERT( m_pChildDriver != nullptr ); /* how did you get a file to begin with? */ + + if( pFile == nullptr ) + return; + + if( !IsTimedOut() ) + { + /* If we're not in a timed-out state, try to wait for the deletion to complete + * before continuing. */ + m_pRequestFile = pFile; + if( !DoRequest(REQ_CLOSE) ) + return; + m_pRequestFile = nullptr; + } + else + { + /* Delete the file when the timeout completes. */ + m_DeletedFilesLock.Lock(); + m_apDeletedFiles.push_back( pFile ); + m_DeletedFilesLock.Unlock(); + } +} + +int ThreadedFileWorker::GetFileSize( RageFileBasic *&pFile ) +{ + ASSERT( m_pChildDriver != nullptr ); /* how did you get a file to begin with? */ + + /* If we're currently in a timed-out state, fail. */ + if( IsTimedOut() ) + { + this->Close( pFile ); + pFile = nullptr; + } + + if( pFile == nullptr ) + return -1; + + m_pRequestFile = pFile; + + if( !DoRequest(REQ_GET_FILE_SIZE) ) + { + /* If we time out, we can no longer access pFile. */ + pFile = nullptr; + return -1; + } + + m_pRequestFile = nullptr; + + return m_iResultRequest; +} + +int ThreadedFileWorker::GetFD( RageFileBasic *&pFile ) +{ + ASSERT( m_pChildDriver != nullptr ); /* how did you get a file to begin with? */ + + /* If we're currently in a timed-out state, fail. */ + if( IsTimedOut() ) + { + this->Close( pFile ); + pFile = nullptr; + } + + if( pFile == nullptr ) + return -1; + + m_pRequestFile = pFile; + + if( !DoRequest(REQ_GET_FD) ) + { + /* If we time out, we can no longer access pFile. */ + pFile = nullptr; + return -1; + } + + m_pRequestFile = nullptr; + + return m_iResultRequest; +} + +int ThreadedFileWorker::Seek( RageFileBasic *&pFile, int iPos, RString &sError ) +{ + ASSERT( m_pChildDriver != nullptr ); /* how did you get a file to begin with? */ + + /* If we're currently in a timed-out state, fail. */ + if( IsTimedOut() ) + { + this->Close( pFile ); + pFile = nullptr; + } + + if( pFile == nullptr ) + { + sError = "Operation timed out"; + return -1; + } + + m_pRequestFile = pFile; + m_iRequestPos = iPos; /* in */ + + if( !DoRequest(REQ_SEEK) ) + { + /* If we time out, we can no longer access pFile. */ + sError = "Operation timed out"; + pFile = nullptr; + return -1; + } + + if( m_iResultRequest == -1 ) + sError = m_sResultError; + m_pRequestFile = nullptr; + + return m_iResultRequest; +} + +int ThreadedFileWorker::Read( RageFileBasic *&pFile, void *pBuf, int iSize, RString &sError ) +{ + ASSERT( m_pChildDriver != nullptr ); /* how did you get a file to begin with? */ + + /* If we're currently in a timed-out state, fail. */ + if( IsTimedOut() ) + { + this->Close( pFile ); + pFile = nullptr; + } + + if( pFile == nullptr ) + { + sError = "Operation timed out"; + return -1; + } + + m_pRequestFile = pFile; + m_iRequestSize = iSize; + m_pResultBuffer = new char[iSize]; + + if( !DoRequest(REQ_READ) ) + { + /* If we time out, we can no longer access pFile. */ + sError = "Operation timed out"; + pFile = nullptr; + return -1; + } + + int iGot = m_iResultRequest; + if( iGot == -1 ) + sError = m_sResultError; + else + memcpy( pBuf, m_pResultBuffer, iGot ); + + m_pRequestFile = nullptr; + delete [] m_pResultBuffer; + m_pResultBuffer = nullptr; + + return iGot; +} + +int ThreadedFileWorker::Write( RageFileBasic *&pFile, const void *pBuf, int iSize, RString &sError ) +{ + ASSERT( m_pChildDriver != nullptr ); /* how did you get a file to begin with? */ + + /* If we're currently in a timed-out state, fail. */ + if( IsTimedOut() ) + { + this->Close( pFile ); + pFile = nullptr; + } + + if( pFile == nullptr ) + { + sError = "Operation timed out"; + return -1; + } + + m_pRequestFile = pFile; + m_iRequestSize = iSize; + m_pRequestBuffer = new char[iSize]; + memcpy( m_pRequestBuffer, pBuf, iSize ); + + if( !DoRequest(REQ_WRITE) ) + { + /* If we time out, we can no longer access pFile. */ + sError = "Operation timed out"; + pFile = nullptr; + return -1; + } + + int iGot = m_iResultRequest; + if( m_iResultRequest == -1 ) + sError = m_sResultError; + + m_pRequestFile = nullptr; + delete [] m_pRequestBuffer; + m_pRequestBuffer = nullptr; + + return iGot; +} + +int ThreadedFileWorker::Flush( RageFileBasic *&pFile, RString &sError ) +{ + ASSERT( m_pChildDriver != nullptr ); /* how did you get a file to begin with? */ + + /* If we're currently in a timed-out state, fail. */ + if( IsTimedOut() ) + { + this->Close( pFile ); + pFile = nullptr; + } + + if( pFile == nullptr ) + { + sError = "Operation timed out"; + return -1; + } + + m_pRequestFile = pFile; + + if( !DoRequest(REQ_FLUSH) ) + { + /* If we time out, we can no longer access pFile. */ + sError = "Operation timed out"; + pFile = nullptr; + return -1; + } + + if( m_iResultRequest == -1 ) + sError = m_sResultError; + + m_pRequestFile = nullptr; + + return m_iResultRequest; +} + +RageFileBasic *ThreadedFileWorker::Copy( RageFileBasic *&pFile, RString &sError ) +{ + ASSERT( m_pChildDriver != nullptr ); /* how did you get a file to begin with? */ + + /* If we're currently in a timed-out state, fail. */ + if( IsTimedOut() ) + { + this->Close( pFile ); + pFile = nullptr; + } + + if( pFile == nullptr ) + { + sError = "Operation timed out"; + return nullptr; + } + + m_pRequestFile = pFile; + if( !DoRequest(REQ_COPY) ) + { + /* If we time out, we can no longer access pFile. */ + sError = "Operation timed out"; + pFile = nullptr; + return nullptr; + } + + RageFileBasic *pRet = m_pResultFile; + m_pRequestFile = nullptr; + m_pResultFile = nullptr; + + return pRet; +} + + +bool ThreadedFileWorker::PopulateFileSet( FileSet &fs, const RString &sPath ) +{ + if( m_pChildDriver == nullptr ) + return false; + + /* If we're currently in a timed-out state, fail. */ + if( IsTimedOut() ) + return false; + + /* Fill in a different FileSet; copy the results in on success. */ + m_sRequestPath = sPath; + + /* Kick off the worker thread, and wait for it to finish. */ + if( !DoRequest(REQ_POPULATE_FILE_SET) ) + { + LOG->Trace( "PopulateFileSet(%s) timed out", sPath.c_str() ); + return false; + } + + fs = m_ResultFileSet; + return true; +} + +int ThreadedFileWorker::Move( const RString &sOldPath, const RString &sNewPath ) +{ + ASSERT( m_pChildDriver != nullptr ); /* how did you get a file to begin with? */ + + /* If we're currently in a timed-out state, fail. */ + if( IsTimedOut() ) + return -1; + + m_sRequestPath = sOldPath; + m_sRequestPath2 = sNewPath; + + if( !DoRequest(REQ_MOVE) ) + { + /* If we time out, we can no longer access pFile. */ + return -1; + } + + return m_iResultRequest; +} + +int ThreadedFileWorker::Remove( const RString &sPath ) +{ + ASSERT( m_pChildDriver != nullptr ); /* how did you get a file to begin with? */ + + /* If we're currently in a timed-out state, fail. */ + if( IsTimedOut() ) + return -1; + + m_sRequestPath = sPath; + + if( !DoRequest(REQ_REMOVE) ) + { + /* If we time out, we can no longer access pFile. */ + return -1; + } + + return m_iResultRequest; +} + +bool ThreadedFileWorker::FlushDirCache( const RString &sPath ) +{ + /* FlushDirCache() is often called globally, on all drivers, which means it's called with + * no timeout. Temporarily enable a timeout if needed. */ + bool bTimeoutEnabled = TimeoutEnabled(); + if( !bTimeoutEnabled ) + SetTimeout(1); + + if( m_pChildDriver == nullptr ) + return false; + + /* If we're currently in a timed-out state, fail. */ + if( IsTimedOut() ) + return false; + + m_sRequestPath = sPath; + + /* Kick off the worker thread, and wait for it to finish. */ + if( !DoRequest(REQ_FLUSH_DIR_CACHE) ) + { + if( !bTimeoutEnabled ) + SetTimeout(-1); + + LOG->Trace( "FlushDirCache(%s) timed out", sPath.c_str() ); + return false; + } + + if( !bTimeoutEnabled ) + SetTimeout(-1); + + return true; +} + + +class RageFileObjTimeout: public RageFileObj +{ +public: + /* pFile will be freed by passing it to pWorker. */ + RageFileObjTimeout( ThreadedFileWorker *pWorker, RageFileBasic *pFile, int iSize, int iMode ) + { + m_pWorker = pWorker; + m_pFile = pFile; + m_iFileSize = iSize; + m_iMode = iMode; + /* We have a lot of overhead per read and write operation, since we send + * commands to the worker thread. Buffer these operations. */ + if( iMode & RageFile::WRITE ) + EnableWriteBuffering(); + if( iMode & RageFile::READ ) + EnableReadBuffering(); + } + + ~RageFileObjTimeout() + { + if( m_pFile != nullptr ) + { + Flush(); + m_pWorker->Close( m_pFile ); + } + } + + int GetFileSize() const + { + return m_iFileSize; + } + + int GetFD() + { + RString sError; + int iRet = m_pWorker->GetFD( m_pFile ); + + if( m_pFile == nullptr ) + { + SetError( "Operation timed out" ); + return -1; + } + + if( iRet == -1 ) + SetError( sError ); + + return iRet; + } + + RageFileBasic *Copy() const + { + RString sError; + RageFileBasic *pCopy = m_pWorker->Copy( m_pFile, sError ); + + if( m_pFile == nullptr ) + { +// SetError( "Operation timed out" ); + return nullptr; + } + + if( pCopy == nullptr ) + { +// SetError( sError ); + return nullptr; + } + + return new RageFileObjTimeout( m_pWorker, pCopy, m_iFileSize, m_iMode ); + } + +protected: + int SeekInternal( int iPos ) + { + RString sError; + int iRet = m_pWorker->Seek( m_pFile, iPos, sError ); + + if( m_pFile == nullptr ) + { + SetError( "Operation timed out" ); + return -1; + } + + if( iRet == -1 ) + SetError( sError ); + + return iRet; + } + + + int ReadInternal( void *pBuffer, size_t iBytes ) + { + RString sError; + int iRet = m_pWorker->Read( m_pFile, pBuffer, iBytes, sError ); + + if( m_pFile == nullptr ) + { + SetError( "Operation timed out" ); + return -1; + } + + if( iRet == -1 ) + SetError( sError ); + + return iRet; + } + + int WriteInternal( const void *pBuffer, size_t iBytes ) + { + RString sError; + int iRet = m_pWorker->Write( m_pFile, pBuffer, iBytes, sError ); + + if( m_pFile == nullptr ) + { + SetError( "Operation timed out" ); + return -1; + } + + if( iRet == -1 ) + SetError( sError ); + + return iRet; + } + + int FlushInternal() + { + RString sError; + int iRet = m_pWorker->Flush( m_pFile, sError ); + + if( m_pFile == nullptr ) + { + SetError( "Operation timed out" ); + return -1; + } + + if( iRet == -1 ) + SetError( sError ); + + return iRet; + } + + /* Mutable because the const operation Copy() timing out results in the original + * object no longer being available. */ + mutable RageFileBasic *m_pFile; + + ThreadedFileWorker *m_pWorker; + + /* GetFileSize isn't allowed to fail, so cache the file size on load. */ + int m_iFileSize; + //cache filemode + int m_iMode; +}; + +/* This FilenameDB runs PopulateFileSet in the worker thread. */ +class TimedFilenameDB: public FilenameDB +{ +public: + TimedFilenameDB() + { + ExpireSeconds = -1; + m_pWorker = nullptr; + } + + void SetWorker( ThreadedFileWorker *pWorker ) + { + ASSERT( pWorker != nullptr ); + m_pWorker = pWorker; + } + + void PopulateFileSet( FileSet &fs, const RString &sPath ) + { + ASSERT( m_pWorker != nullptr ); + m_pWorker->PopulateFileSet( fs, sPath ); + } + +private: + ThreadedFileWorker *m_pWorker; +}; + +RageFileDriverTimeout::RageFileDriverTimeout( const RString &sPath ): + RageFileDriver( new TimedFilenameDB() ) +{ + m_pWorker = new ThreadedFileWorker( sPath ); + + ((TimedFilenameDB *) FDB)->SetWorker( m_pWorker ); +} + +RageFileBasic *RageFileDriverTimeout::Open( const RString &sPath, int iMode, int &iErr ) +{ + RageFileBasic *pChildFile = m_pWorker->Open( sPath, iMode, iErr ); + if( pChildFile == nullptr ) + return nullptr; + + /* RageBasicFile::GetFileSize isn't allowed to fail, but we are; grab the file + * size now and store it. */ + int iSize = 0; + if( iMode & RageFile::READ ) + { + iSize = m_pWorker->GetFileSize( pChildFile ); + if( iSize == -1 ) + { + /* When m_pWorker->GetFileSize fails, it takes ownership of pChildFile. */ + ASSERT( pChildFile == nullptr ); + iErr = EFAULT; + return nullptr; + } + } + + return new RageFileObjTimeout( m_pWorker, pChildFile, iSize, iMode ); +} + +void RageFileDriverTimeout::FlushDirCache( const RString &sPath ) +{ + RageFileDriver::FlushDirCache( sPath ); + m_pWorker->FlushDirCache( sPath ); +} + +bool RageFileDriverTimeout::Move( const RString &sOldPath, const RString &sNewPath ) +{ + int iRet = m_pWorker->Move( sOldPath, sNewPath ); + if( iRet == -1 ) + { + WARN( ssprintf("RageFileDriverTimeout::Move(%s,%s) failed", sOldPath.c_str(), sNewPath.c_str()) ); + return false; + } + + return true; +} + +bool RageFileDriverTimeout::Remove( const RString &sPath ) +{ + int iRet = m_pWorker->Remove( sPath ); + if( iRet == -1 ) + { + WARN( ssprintf("RageFileDriverTimeout::Remove(%s) failed", sPath.c_str()) ); + return false; + } + + return true; +} + +RageFileDriverTimeout::~RageFileDriverTimeout() +{ + delete m_pWorker; +} + +static struct FileDriverEntry_Timeout: public FileDriverEntry +{ + FileDriverEntry_Timeout(): FileDriverEntry( "TIMEOUT" ) { } + RageFileDriver *Create( const RString &sRoot ) const { return new RageFileDriverTimeout( sRoot ); } +} const g_RegisterDriver; + +/* + * Copyright (c) 2005 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/RageFileDriverZip.cpp b/src/RageFileDriverZip.cpp index e223490240..dbd1fe7dc5 100644 --- a/src/RageFileDriverZip.cpp +++ b/src/RageFileDriverZip.cpp @@ -1,374 +1,374 @@ -/* - * Ref: http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip - */ - -#include "global.h" -#include "RageFileDriverZip.h" -#include "RageFileDriverSlice.h" -#include "RageFileDriverDeflate.h" -#include "RageFile.h" -#include "RageLog.h" -#include "RageUtil.h" -#include "RageUtil_FileDB.h" -#include - -static struct FileDriverEntry_ZIP: public FileDriverEntry -{ - FileDriverEntry_ZIP(): FileDriverEntry( "ZIP" ) { } - RageFileDriver *Create( const RString &sRoot ) const { return new RageFileDriverZip( sRoot ); } -} const g_RegisterDriver; - - -RageFileDriverZip::RageFileDriverZip(): - RageFileDriver( new NullFilenameDB ), - m_Mutex( "RageFileDriverZip" ) -{ - m_bFileOwned = false; - m_pZip = NULL; -} - -RageFileDriverZip::RageFileDriverZip( const RString &sPath ): - RageFileDriver( new NullFilenameDB ), - m_Mutex( "RageFileDriverZip" ) -{ - m_bFileOwned = false; - m_pZip = NULL; - Load( sPath ); -} - -bool RageFileDriverZip::Load( const RString &sPath ) -{ - ASSERT( m_pZip == NULL ); /* don't load twice */ - - m_bFileOwned = true; - m_sPath = sPath; - m_Mutex.SetName( ssprintf("RageFileDriverZip(%s)", sPath.c_str()) ); - - RageFile *pFile = new RageFile; - - if( !pFile->Open(sPath) ) - { - WARN( ssprintf("Couldn't open %s: %s", sPath.c_str(), pFile->GetError().c_str()) ); - delete pFile; - return false; - } - - m_pZip = pFile; - - return ParseZipfile(); -} - -bool RageFileDriverZip::Load( RageFileBasic *pFile ) -{ - ASSERT( m_pZip == NULL ); /* don't load twice */ - m_sPath = ssprintf("%p", pFile); - m_Mutex.SetName( ssprintf("RageFileDriverZip(%p)", pFile) ); - - m_pZip = pFile; - - return ParseZipfile(); -} - - -bool RageFileDriverZip::ReadEndCentralRecord( int &iTotalEntries, int &iCentralDirectoryOffset ) -{ - RString sError; - RString sSig = FileReading::ReadString( *m_pZip, 4, sError ); - FileReading::read_16_le( *m_pZip, sError ); /* skip number of this disk */ - FileReading::read_16_le( *m_pZip, sError ); /* skip disk with central directory */ - FileReading::read_16_le( *m_pZip, sError ); /* skip number of entries on this disk */ - iTotalEntries = FileReading::read_16_le( *m_pZip, sError ); - FileReading::read_32_le( *m_pZip, sError ); /* skip size of the central directory */ - iCentralDirectoryOffset = FileReading::read_32_le( *m_pZip, sError ); - int iCommentLength = FileReading::read_16_le( *m_pZip, sError ); - m_sComment = FileReading::ReadString( *m_pZip, iCommentLength, sError ); - - if( sError != "" ) - { - WARN( ssprintf("%s: %s", m_sPath.c_str(), sError.c_str()) ); - return false; - } - - return true; -} - -/* Find the end of central directory record, and seek to it. */ -bool RageFileDriverZip::SeekToEndCentralRecord() -{ - const int iSearchTo = max( m_pZip->GetFileSize() - 1024*32, 0 ); - int iRealPos = m_pZip->GetFileSize(); - - while( iRealPos > 0 && iRealPos >= iSearchTo ) - { - /* Move back in the file; leave some overlap between checks, to handle - * the case where the signature crosses the block boundary. */ - char buf[1024*4]; - iRealPos -= sizeof(buf) - 4; - iRealPos = max( 0, iRealPos ); - m_pZip->Seek( iRealPos ); - - int iGot = m_pZip->Read( buf, sizeof(buf) ); - if( iGot == -1 ) - { - WARN( ssprintf("%s: %s", m_sPath.c_str(), m_pZip->GetError().c_str()) ); - return false; - } - - for( int iPos = iGot - 4; iPos >= 0; --iPos ) - { - if( memcmp(buf + iPos, "\x50\x4B\x05\x06", 4) ) - continue; - - m_pZip->Seek( iRealPos + iPos ); - return true; - } - } - - return false; -} - -bool RageFileDriverZip::ParseZipfile() -{ - if( !SeekToEndCentralRecord() ) - { - WARN( ssprintf("Couldn't open %s: couldn't find end of central directory record", m_sPath.c_str()) ); - return false; - } - - /* Read the end of central directory record. */ - int iTotalEntries, iCentralDirectoryOffset; - if( !ReadEndCentralRecord(iTotalEntries, iCentralDirectoryOffset) ) - return false; /* warned already */ - - /* Seek to the start of the central file directory. */ - m_pZip->Seek( iCentralDirectoryOffset ); - - /* Loop through files in central directory. */ - for( int i = 0; i < iTotalEntries; ++i ) - { - FileInfo info; - info.m_iDataOffset = -1; - int got = ProcessCdirFileHdr( info ); - if( got == -1 ) /* error */ - break; - if( got == 0 ) /* skip */ - continue; - - FileInfo *pInfo = new FileInfo( info ); - m_pFiles.push_back( pInfo ); - FDB->AddFile( "/" + pInfo->m_sName, pInfo->m_iUncompressedSize, pInfo->m_iCRC32, pInfo ); - } - - if( m_pFiles.size() == 0 ) - WARN( ssprintf("%s: no files found in central file header", m_sPath.c_str()) ); - - return true; -} - -int RageFileDriverZip::ProcessCdirFileHdr( FileInfo &info ) -{ - RString sError; - RString sSig = FileReading::ReadString( *m_pZip, 4, sError ); - if( sSig != "\x50\x4B\x01\x02" ) - { - WARN( ssprintf("%s: central directory record signature not found", m_sPath.c_str()) ); - return -1; - } - - FileReading::read_8( *m_pZip, sError ); /* skip version made by */ - int iOSMadeBy = FileReading::read_8( *m_pZip, sError ); - FileReading::read_16_le( *m_pZip, sError ); /* skip version needed to extract */ - int iGeneralPurpose = FileReading::read_16_le( *m_pZip, sError ); - info.m_iCompressionMethod = (ZipCompressionMethod) FileReading::read_16_le( *m_pZip, sError ); - FileReading::read_16_le( *m_pZip, sError ); /* skip last mod file time */ - FileReading::read_16_le( *m_pZip, sError ); /* skip last mod file date */ - info.m_iCRC32 = FileReading::read_32_le( *m_pZip, sError ); - info.m_iCompressedSize = FileReading::read_32_le( *m_pZip, sError ); - info.m_iUncompressedSize = FileReading::read_32_le( *m_pZip, sError ); - int iFilenameLength = FileReading::read_16_le( *m_pZip, sError ); - int iExtraFieldLength = FileReading::read_16_le( *m_pZip, sError ); - int iFileCommentLength = FileReading::read_16_le( *m_pZip, sError ); - FileReading::read_16_le( *m_pZip, sError ); /* relative offset of local header */ - FileReading::read_16_le( *m_pZip, sError ); /* skip internal file attributes */ - unsigned iExternalFileAttributes = FileReading::read_32_le( *m_pZip, sError ); - info.m_iOffset = FileReading::read_32_le( *m_pZip, sError ); - - /* Check for errors before reading variable-length fields. */ - if( sError != "" ) - { - WARN( ssprintf("%s: %s", m_sPath.c_str(), sError.c_str()) ); - return -1; - } - - info.m_sName = FileReading::ReadString( *m_pZip, iFilenameLength, sError ); - FileReading::SkipBytes( *m_pZip, iExtraFieldLength, sError ); /* skip extra field */ - FileReading::SkipBytes( *m_pZip, iFileCommentLength, sError ); /* skip file comment */ - - if( sError != "" ) - { - WARN( ssprintf("%s: %s", m_sPath.c_str(), sError.c_str()) ); - return -1; - } - - /* Check usability last, so we always read past the whole entry and don't leave the - * file pointer in the middle of a record. */ - if( iGeneralPurpose & 1 ) - { - WARN( ssprintf("Skipped encrypted \"%s\" in \"%s\"", info.m_sName.c_str(), m_sPath.c_str()) ); - return 0; - } - - /* Skip directories. */ - if( iExternalFileAttributes & (1<<4) ) - return 0; - - info.m_iFilePermissions = 0; - enum { MADE_BY_UNIX = 3 }; - switch( iOSMadeBy ) - { - case MADE_BY_UNIX: - info.m_iFilePermissions = (iExternalFileAttributes >> 16) & 0x1FF; - break; - } - - if( info.m_iCompressionMethod != STORED && info.m_iCompressionMethod != DEFLATED ) - { - WARN( ssprintf("File \"%s\" in \"%s\" uses unsupported compression method %i", - info.m_sName.c_str(), m_sPath.c_str(), info.m_iCompressionMethod) ); - - return 0; - } - - return 1; -} - -bool RageFileDriverZip::ReadLocalFileHeader( FileInfo &info ) -{ - /* Seek to and read the local file header. */ - m_pZip->Seek( info.m_iOffset ); - - RString sError; - RString sSig = FileReading::ReadString( *m_pZip, 4, sError ); - - if( sError != "" ) - { - WARN( ssprintf("%s: error opening \"%s\": %s", m_sPath.c_str(), info.m_sName.c_str(), sError.c_str()) ); - return false; - } - - if( sSig != "\x50\x4B\x03\x04" ) - { - WARN( ssprintf("%s: local file header not found for \"%s\"", m_sPath.c_str(), info.m_sName.c_str()) ); - return false; - } - - FileReading::SkipBytes( *m_pZip, 22, sError ); /* skip most of the local file header */ - - const int iFilenameLength = FileReading::read_16_le( *m_pZip, sError ); - const int iExtraFieldLength = FileReading::read_16_le( *m_pZip, sError ); - info.m_iDataOffset = m_pZip->Tell() + iFilenameLength + iExtraFieldLength; - - if( sError != "" ) - { - WARN( ssprintf("%s: %s", m_sPath.c_str(), sError.c_str()) ); - return false; - } - - return true; -} - -RageFileDriverZip::~RageFileDriverZip() -{ - for( unsigned i = 0; i < m_pFiles.size(); ++i ) - delete m_pFiles[i]; - - if( m_bFileOwned ) - delete m_pZip; -} - -const RageFileDriverZip::FileInfo *RageFileDriverZip::GetFileInfo( const RString &sPath ) const -{ - return (const FileInfo *) FDB->GetFilePriv( sPath ); -} - -RageFileBasic *RageFileDriverZip::Open( const RString &sPath, int iMode, int &iErr ) -{ - if( iMode & RageFile::WRITE ) - { - iErr = ERROR_WRITING_NOT_SUPPORTED; - return NULL; - } - - FileInfo *info = (FileInfo *) FDB->GetFilePriv( sPath ); - if( info == NULL ) - { - iErr = ENOENT; - return NULL; - } - - m_Mutex.Lock(); - - /* If we haven't figured out the offset to the real data yet, do so now. */ - if( info->m_iDataOffset == -1 ) - { - if( !ReadLocalFileHeader(*info) ) - { - m_Mutex.Unlock(); - return NULL; - } - } - - /* We won't do any further access to zip, except to copy it (which is - * threadsafe), so we can unlock now. */ - m_Mutex.Unlock(); - - RageFileDriverSlice *pSlice = new RageFileDriverSlice( m_pZip->Copy(), info->m_iDataOffset, info->m_iCompressedSize ); - pSlice->DeleteFileWhenFinished(); - - switch( info->m_iCompressionMethod ) - { - case STORED: - return pSlice; - case DEFLATED: - { - RageFileObjInflate *pInflate = new RageFileObjInflate( pSlice, info->m_iUncompressedSize ); - pInflate->DeleteFileWhenFinished(); - return pInflate; - } - default: - /* unknown compression method */ - iErr = ENOSYS; - return NULL; - } -} - -/* NOP for now. This could check to see if the ZIP's mtime has changed, and reload. */ -void RageFileDriverZip::FlushDirCache( const RString &sPath ) -{ - -} - -/* - * Copyright (c) 2003-2005 Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +/* + * Ref: http://www.info-zip.org/pub/infozip/doc/appnote-981119-iz.zip + */ + +#include "global.h" +#include "RageFileDriverZip.h" +#include "RageFileDriverSlice.h" +#include "RageFileDriverDeflate.h" +#include "RageFile.h" +#include "RageLog.h" +#include "RageUtil.h" +#include "RageUtil_FileDB.h" +#include + +static struct FileDriverEntry_ZIP: public FileDriverEntry +{ + FileDriverEntry_ZIP(): FileDriverEntry( "ZIP" ) { } + RageFileDriver *Create( const RString &sRoot ) const { return new RageFileDriverZip( sRoot ); } +} const g_RegisterDriver; + + +RageFileDriverZip::RageFileDriverZip(): + RageFileDriver( new NullFilenameDB ), + m_Mutex( "RageFileDriverZip" ) +{ + m_bFileOwned = false; + m_pZip = nullptr; +} + +RageFileDriverZip::RageFileDriverZip( const RString &sPath ): + RageFileDriver( new NullFilenameDB ), + m_Mutex( "RageFileDriverZip" ) +{ + m_bFileOwned = false; + m_pZip = nullptr; + Load( sPath ); +} + +bool RageFileDriverZip::Load( const RString &sPath ) +{ + ASSERT( m_pZip == nullptr ); /* don't load twice */ + + m_bFileOwned = true; + m_sPath = sPath; + m_Mutex.SetName( ssprintf("RageFileDriverZip(%s)", sPath.c_str()) ); + + RageFile *pFile = new RageFile; + + if( !pFile->Open(sPath) ) + { + WARN( ssprintf("Couldn't open %s: %s", sPath.c_str(), pFile->GetError().c_str()) ); + delete pFile; + return false; + } + + m_pZip = pFile; + + return ParseZipfile(); +} + +bool RageFileDriverZip::Load( RageFileBasic *pFile ) +{ + ASSERT( m_pZip == nullptr ); /* don't load twice */ + m_sPath = ssprintf("%p", pFile); + m_Mutex.SetName( ssprintf("RageFileDriverZip(%p)", pFile) ); + + m_pZip = pFile; + + return ParseZipfile(); +} + + +bool RageFileDriverZip::ReadEndCentralRecord( int &iTotalEntries, int &iCentralDirectoryOffset ) +{ + RString sError; + RString sSig = FileReading::ReadString( *m_pZip, 4, sError ); + FileReading::read_16_le( *m_pZip, sError ); /* skip number of this disk */ + FileReading::read_16_le( *m_pZip, sError ); /* skip disk with central directory */ + FileReading::read_16_le( *m_pZip, sError ); /* skip number of entries on this disk */ + iTotalEntries = FileReading::read_16_le( *m_pZip, sError ); + FileReading::read_32_le( *m_pZip, sError ); /* skip size of the central directory */ + iCentralDirectoryOffset = FileReading::read_32_le( *m_pZip, sError ); + int iCommentLength = FileReading::read_16_le( *m_pZip, sError ); + m_sComment = FileReading::ReadString( *m_pZip, iCommentLength, sError ); + + if( sError != "" ) + { + WARN( ssprintf("%s: %s", m_sPath.c_str(), sError.c_str()) ); + return false; + } + + return true; +} + +/* Find the end of central directory record, and seek to it. */ +bool RageFileDriverZip::SeekToEndCentralRecord() +{ + const int iSearchTo = max( m_pZip->GetFileSize() - 1024*32, 0 ); + int iRealPos = m_pZip->GetFileSize(); + + while( iRealPos > 0 && iRealPos >= iSearchTo ) + { + /* Move back in the file; leave some overlap between checks, to handle + * the case where the signature crosses the block boundary. */ + char buf[1024*4]; + iRealPos -= sizeof(buf) - 4; + iRealPos = max( 0, iRealPos ); + m_pZip->Seek( iRealPos ); + + int iGot = m_pZip->Read( buf, sizeof(buf) ); + if( iGot == -1 ) + { + WARN( ssprintf("%s: %s", m_sPath.c_str(), m_pZip->GetError().c_str()) ); + return false; + } + + for( int iPos = iGot - 4; iPos >= 0; --iPos ) + { + if( memcmp(buf + iPos, "\x50\x4B\x05\x06", 4) ) + continue; + + m_pZip->Seek( iRealPos + iPos ); + return true; + } + } + + return false; +} + +bool RageFileDriverZip::ParseZipfile() +{ + if( !SeekToEndCentralRecord() ) + { + WARN( ssprintf("Couldn't open %s: couldn't find end of central directory record", m_sPath.c_str()) ); + return false; + } + + /* Read the end of central directory record. */ + int iTotalEntries, iCentralDirectoryOffset; + if( !ReadEndCentralRecord(iTotalEntries, iCentralDirectoryOffset) ) + return false; /* warned already */ + + /* Seek to the start of the central file directory. */ + m_pZip->Seek( iCentralDirectoryOffset ); + + /* Loop through files in central directory. */ + for( int i = 0; i < iTotalEntries; ++i ) + { + FileInfo info; + info.m_iDataOffset = -1; + int got = ProcessCdirFileHdr( info ); + if( got == -1 ) /* error */ + break; + if( got == 0 ) /* skip */ + continue; + + FileInfo *pInfo = new FileInfo( info ); + m_pFiles.push_back( pInfo ); + FDB->AddFile( "/" + pInfo->m_sName, pInfo->m_iUncompressedSize, pInfo->m_iCRC32, pInfo ); + } + + if( m_pFiles.size() == 0 ) + WARN( ssprintf("%s: no files found in central file header", m_sPath.c_str()) ); + + return true; +} + +int RageFileDriverZip::ProcessCdirFileHdr( FileInfo &info ) +{ + RString sError; + RString sSig = FileReading::ReadString( *m_pZip, 4, sError ); + if( sSig != "\x50\x4B\x01\x02" ) + { + WARN( ssprintf("%s: central directory record signature not found", m_sPath.c_str()) ); + return -1; + } + + FileReading::read_8( *m_pZip, sError ); /* skip version made by */ + int iOSMadeBy = FileReading::read_8( *m_pZip, sError ); + FileReading::read_16_le( *m_pZip, sError ); /* skip version needed to extract */ + int iGeneralPurpose = FileReading::read_16_le( *m_pZip, sError ); + info.m_iCompressionMethod = (ZipCompressionMethod) FileReading::read_16_le( *m_pZip, sError ); + FileReading::read_16_le( *m_pZip, sError ); /* skip last mod file time */ + FileReading::read_16_le( *m_pZip, sError ); /* skip last mod file date */ + info.m_iCRC32 = FileReading::read_32_le( *m_pZip, sError ); + info.m_iCompressedSize = FileReading::read_32_le( *m_pZip, sError ); + info.m_iUncompressedSize = FileReading::read_32_le( *m_pZip, sError ); + int iFilenameLength = FileReading::read_16_le( *m_pZip, sError ); + int iExtraFieldLength = FileReading::read_16_le( *m_pZip, sError ); + int iFileCommentLength = FileReading::read_16_le( *m_pZip, sError ); + FileReading::read_16_le( *m_pZip, sError ); /* relative offset of local header */ + FileReading::read_16_le( *m_pZip, sError ); /* skip internal file attributes */ + unsigned iExternalFileAttributes = FileReading::read_32_le( *m_pZip, sError ); + info.m_iOffset = FileReading::read_32_le( *m_pZip, sError ); + + /* Check for errors before reading variable-length fields. */ + if( sError != "" ) + { + WARN( ssprintf("%s: %s", m_sPath.c_str(), sError.c_str()) ); + return -1; + } + + info.m_sName = FileReading::ReadString( *m_pZip, iFilenameLength, sError ); + FileReading::SkipBytes( *m_pZip, iExtraFieldLength, sError ); /* skip extra field */ + FileReading::SkipBytes( *m_pZip, iFileCommentLength, sError ); /* skip file comment */ + + if( sError != "" ) + { + WARN( ssprintf("%s: %s", m_sPath.c_str(), sError.c_str()) ); + return -1; + } + + /* Check usability last, so we always read past the whole entry and don't leave the + * file pointer in the middle of a record. */ + if( iGeneralPurpose & 1 ) + { + WARN( ssprintf("Skipped encrypted \"%s\" in \"%s\"", info.m_sName.c_str(), m_sPath.c_str()) ); + return 0; + } + + /* Skip directories. */ + if( iExternalFileAttributes & (1<<4) ) + return 0; + + info.m_iFilePermissions = 0; + enum { MADE_BY_UNIX = 3 }; + switch( iOSMadeBy ) + { + case MADE_BY_UNIX: + info.m_iFilePermissions = (iExternalFileAttributes >> 16) & 0x1FF; + break; + } + + if( info.m_iCompressionMethod != STORED && info.m_iCompressionMethod != DEFLATED ) + { + WARN( ssprintf("File \"%s\" in \"%s\" uses unsupported compression method %i", + info.m_sName.c_str(), m_sPath.c_str(), info.m_iCompressionMethod) ); + + return 0; + } + + return 1; +} + +bool RageFileDriverZip::ReadLocalFileHeader( FileInfo &info ) +{ + /* Seek to and read the local file header. */ + m_pZip->Seek( info.m_iOffset ); + + RString sError; + RString sSig = FileReading::ReadString( *m_pZip, 4, sError ); + + if( sError != "" ) + { + WARN( ssprintf("%s: error opening \"%s\": %s", m_sPath.c_str(), info.m_sName.c_str(), sError.c_str()) ); + return false; + } + + if( sSig != "\x50\x4B\x03\x04" ) + { + WARN( ssprintf("%s: local file header not found for \"%s\"", m_sPath.c_str(), info.m_sName.c_str()) ); + return false; + } + + FileReading::SkipBytes( *m_pZip, 22, sError ); /* skip most of the local file header */ + + const int iFilenameLength = FileReading::read_16_le( *m_pZip, sError ); + const int iExtraFieldLength = FileReading::read_16_le( *m_pZip, sError ); + info.m_iDataOffset = m_pZip->Tell() + iFilenameLength + iExtraFieldLength; + + if( sError != "" ) + { + WARN( ssprintf("%s: %s", m_sPath.c_str(), sError.c_str()) ); + return false; + } + + return true; +} + +RageFileDriverZip::~RageFileDriverZip() +{ + for( unsigned i = 0; i < m_pFiles.size(); ++i ) + delete m_pFiles[i]; + + if( m_bFileOwned ) + delete m_pZip; +} + +const RageFileDriverZip::FileInfo *RageFileDriverZip::GetFileInfo( const RString &sPath ) const +{ + return (const FileInfo *) FDB->GetFilePriv( sPath ); +} + +RageFileBasic *RageFileDriverZip::Open( const RString &sPath, int iMode, int &iErr ) +{ + if( iMode & RageFile::WRITE ) + { + iErr = ERROR_WRITING_NOT_SUPPORTED; + return nullptr; + } + + FileInfo *info = (FileInfo *) FDB->GetFilePriv( sPath ); + if( info == nullptr ) + { + iErr = ENOENT; + return nullptr; + } + + m_Mutex.Lock(); + + /* If we haven't figured out the offset to the real data yet, do so now. */ + if( info->m_iDataOffset == -1 ) + { + if( !ReadLocalFileHeader(*info) ) + { + m_Mutex.Unlock(); + return nullptr; + } + } + + /* We won't do any further access to zip, except to copy it (which is + * threadsafe), so we can unlock now. */ + m_Mutex.Unlock(); + + RageFileDriverSlice *pSlice = new RageFileDriverSlice( m_pZip->Copy(), info->m_iDataOffset, info->m_iCompressedSize ); + pSlice->DeleteFileWhenFinished(); + + switch( info->m_iCompressionMethod ) + { + case STORED: + return pSlice; + case DEFLATED: + { + RageFileObjInflate *pInflate = new RageFileObjInflate( pSlice, info->m_iUncompressedSize ); + pInflate->DeleteFileWhenFinished(); + return pInflate; + } + default: + /* unknown compression method */ + iErr = ENOSYS; + return nullptr; + } +} + +/* NOP for now. This could check to see if the ZIP's mtime has changed, and reload. */ +void RageFileDriverZip::FlushDirCache( const RString &sPath ) +{ + +} + +/* + * Copyright (c) 2003-2005 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/RageFileManager.cpp b/src/RageFileManager.cpp index 84e175e415..950012f3f7 100644 --- a/src/RageFileManager.cpp +++ b/src/RageFileManager.cpp @@ -6,7 +6,6 @@ #include "RageUtil_FileDB.h" #include "RageLog.h" #include "RageThreads.h" -#include "Foreach.h" #include "arch/ArchHooks/ArchHooks.h" #include "LuaManager.h" @@ -18,7 +17,7 @@ #include #endif -RageFileManager *FILEMAN = NULL; +RageFileManager *FILEMAN = nullptr; /* Lock this before touching any of these globals (except FILEMAN itself). */ static RageEvent *g_Mutex; @@ -38,7 +37,7 @@ struct LoadedDriver int m_iRefs; - LoadedDriver() { m_pDriver = NULL; m_iRefs = 0; } + LoadedDriver() { m_pDriver = nullptr; m_iRefs = 0; } RString GetPath( const RString &sPath ) const; }; @@ -73,7 +72,7 @@ RageFileDriver *RageFileManager::GetFileDriver( RString sMountpoint ) sMountpoint += '/'; g_Mutex->Lock(); - RageFileDriver *pRet = NULL; + RageFileDriver *pRet = nullptr; for( unsigned i = 0; i < g_pDrivers.size(); ++i ) { if( g_pDrivers[i]->m_sType == "mountpoints" ) @@ -92,7 +91,7 @@ RageFileDriver *RageFileManager::GetFileDriver( RString sMountpoint ) void RageFileManager::ReleaseFileDriver( RageFileDriver *pDriver ) { - ASSERT( pDriver != NULL ); + ASSERT( pDriver != nullptr ); g_Mutex->Lock(); unsigned i; @@ -157,7 +156,7 @@ public: RageFileBasic *Open( const RString &sPath, int iMode, int &iError ) { iError = (iMode == RageFile::WRITE)? ERROR_WRITING_NOT_SUPPORTED:ENOENT; - return NULL; + return nullptr; } /* Never flush FDB, except in LoadFromDrivers. */ void FlushDirCache( const RString &sPath ) { } @@ -173,7 +172,7 @@ public: FDB->AddFile( apDrivers[i]->m_sMountPoint, 0, 0 ); } }; -static RageFileDriverMountpoints *g_Mountpoints = NULL; +static RageFileDriverMountpoints *g_Mountpoints = nullptr; static RString ExtractDirectory( RString sPath ) { @@ -218,7 +217,7 @@ static RString GetDirOfExecutable( RString argv0 ) RString sPath; #if defined(WIN32) char szBuf[MAX_PATH]; - GetModuleFileName( NULL, szBuf, sizeof(szBuf) ); + GetModuleFileName( nullptr, szBuf, sizeof(szBuf) ); sPath = szBuf; #else sPath = argv0; @@ -250,11 +249,11 @@ static RString GetDirOfExecutable( RString argv0 ) vector vPath; split( path, ":", vPath ); - FOREACH( RString, vPath, i ) + for (RString &i : vPath) { - if( access(*i + "/" + argv0, X_OK|R_OK) ) + if( access(i + "/" + argv0, X_OK|R_OK) ) continue; - sPath = ExtractDirectory(ReadlinkRecursive(*i + "/" + argv0)); + sPath = ExtractDirectory(ReadlinkRecursive(i + "/" + argv0)); break; } if( sPath.empty() ) @@ -351,10 +350,10 @@ RageFileManager::~RageFileManager() g_pDrivers.clear(); // delete g_Mountpoints; // g_Mountpoints was in g_pDrivers - g_Mountpoints = NULL; + g_Mountpoints = nullptr; delete g_Mutex; - g_Mutex = NULL; + g_Mutex = nullptr; } /* path must be normalized (FixSlashesInPlace, CollapsePath). */ @@ -575,7 +574,7 @@ bool RageFileManager::Mount( const RString &sType, const RString &sRoot_, const CHECKPOINT_M( ssprintf("About to make a driver with \"%s\", \"%s\"", sType.c_str(), sRoot.c_str())); RageFileDriver *pDriver = MakeFileDriver( sType, sRoot ); - if( pDriver == NULL ) + if( pDriver == nullptr ) { CHECKPOINT_M( ssprintf("Can't mount unknown VFS type \"%s\", root \"%s\"", sType.c_str(), sRoot.c_str() ) ); @@ -668,7 +667,7 @@ void RageFileManager::Unmount( const RString &sType, const RString &sRoot_, cons void RageFileManager::Remount( RString sMountpoint, RString sPath ) { RageFileDriver *pDriver = GetFileDriver( sMountpoint ); - if( pDriver == NULL ) + if( pDriver == nullptr ) { if( LOG ) LOG->Warn( "Remount(%s,%s): mountpoint not found", sMountpoint.c_str(), sPath.c_str() ); @@ -928,7 +927,7 @@ RageFileBasic *RageFileManager::OpenForReading( const RString &sPath, int mode, } UnreferenceAllDrivers( apDriverList ); - return NULL; + return nullptr; } RageFileBasic *RageFileManager::OpenForWriting( const RString &sPath, int mode, int &iError ) @@ -1009,7 +1008,7 @@ RageFileBasic *RageFileManager::OpenForWriting( const RString &sPath, int mode, UnreferenceAllDrivers( apDriverList ); - return NULL; + return nullptr; } bool RageFileManager::IsAFile( const RString &sPath ) { return GetFileType(sPath) == TYPE_FILE; } @@ -1089,12 +1088,12 @@ bool DeleteRecursive( RageFileDriver *prfd, const RString &sDir ) vector vsFiles; prfd->GetDirListing( sDir+"*", vsFiles, false, true ); - FOREACH_CONST( RString, vsFiles, s ) + for (RString const &s : vsFiles) { - if( IsADirectory(*s) ) - DeleteRecursive( *s+"/" ); + if( IsADirectory(s) ) + DeleteRecursive( s+"/" ); else - FILEMAN->Remove( *s ); + FILEMAN->Remove( s ); } return FILEMAN->Remove( sDir ); @@ -1106,12 +1105,12 @@ bool DeleteRecursive( const RString &sDir ) vector vsFiles; GetDirListing( sDir+"*", vsFiles, false, true ); - FOREACH_CONST( RString, vsFiles, s ) + for (RString const &s : vsFiles) { - if( IsADirectory(*s) ) - DeleteRecursive( *s+"/" ); + if( IsADirectory(s) ) + DeleteRecursive( s+"/" ); else - FILEMAN->Remove( *s ); + FILEMAN->Remove( s ); } return FILEMAN->Remove( sDir ); diff --git a/src/RageInput.cpp b/src/RageInput.cpp index c384de4b12..ceca0e6beb 100644 --- a/src/RageInput.cpp +++ b/src/RageInput.cpp @@ -2,12 +2,11 @@ #include "RageInput.h" #include "RageLog.h" #include "arch/InputHandler/InputHandler.h" -#include "Foreach.h" #include "Preference.h" #include "LuaManager.h" #include "LocalizedString.h" -RageInput* INPUTMAN = NULL; // global and accessible from anywhere in our program +RageInput* INPUTMAN = nullptr; // global and accessible from anywhere in our program Preference g_sInputDrivers( "InputDrivers", "" ); // "" == DEFAULT_INPUT_DRIVER_LIST @@ -101,7 +100,7 @@ void RageInput::WindowReset() void RageInput::AddHandler( InputHandler *pHandler ) { - ASSERT( pHandler != NULL ); + ASSERT( pHandler != nullptr ); LoadedInputHandler hand; hand.m_pDevice = pHandler; @@ -109,8 +108,8 @@ void RageInput::AddHandler( InputHandler *pHandler ) vector aDeviceInfo; hand.m_pDevice->GetDevicesAndDescriptions( aDeviceInfo ); - FOREACH_CONST( InputDeviceInfo, aDeviceInfo, idi ) - g_mapDeviceToHandler[idi->id] = pHandler; + for (InputDeviceInfo const &idi : aDeviceInfo) + g_mapDeviceToHandler[idi.id] = pHandler; } /** @brief Return the first InputDriver for the requested InputDevice. */ @@ -118,14 +117,14 @@ InputHandler *RageInput::GetHandlerForDevice( const InputDevice id ) { map::iterator it = g_mapDeviceToHandler.find(id); if( it == g_mapDeviceToHandler.end() ) - return NULL; + return nullptr; return it->second; } RString RageInput::GetDeviceSpecificInputString( const DeviceInput &di ) { InputHandler *pDriver = GetHandlerForDevice( di.device ); - if( pDriver != NULL ) + if( pDriver != nullptr ) return pDriver->GetDeviceSpecificInputString(di); else return di.ToString(); @@ -134,7 +133,7 @@ RString RageInput::GetDeviceSpecificInputString( const DeviceInput &di ) RString RageInput::GetLocalizedInputString( const DeviceInput &di ) { InputHandler *pDriver = GetHandlerForDevice( di.device ); - if( pDriver != NULL ) + if( pDriver != nullptr ) return pDriver->GetLocalizedInputString(di); else return Capitalize( DeviceButtonToString(di.button) ); @@ -143,7 +142,7 @@ RString RageInput::GetLocalizedInputString( const DeviceInput &di ) wchar_t RageInput::DeviceInputToChar( DeviceInput di, bool bUseCurrentKeyModifiers ) { InputHandler *pDriver = GetHandlerForDevice( di.device ); - if( pDriver != NULL ) + if( pDriver != nullptr ) return pDriver->DeviceButtonToChar(di.button, bUseCurrentKeyModifiers); else return '\0'; @@ -152,7 +151,7 @@ wchar_t RageInput::DeviceInputToChar( DeviceInput di, bool bUseCurrentKeyModifie InputDeviceState RageInput::GetInputDeviceState( InputDevice id ) { InputHandler *pDriver = GetHandlerForDevice( id ); - if( pDriver != NULL ) + if( pDriver != nullptr ) return pDriver->GetInputDeviceState(id); else return InputDeviceState_NoInputHandler; @@ -187,8 +186,8 @@ public: vector vDevices; p->GetDevicesAndDescriptions( vDevices ); vector vsDescriptions; - FOREACH_CONST( InputDeviceInfo, vDevices, idi ) - vsDescriptions.push_back( idi->sDesc ); + for (InputDeviceInfo const &idi : vDevices) + vsDescriptions.push_back( idi.sDesc ); LuaHelpers::CreateTableFromArray( vsDescriptions, L ); return 1; } diff --git a/src/RageInputDevice.cpp b/src/RageInputDevice.cpp index 2cc6bce46c..9271f387a3 100644 --- a/src/RageInputDevice.cpp +++ b/src/RageInputDevice.cpp @@ -4,7 +4,6 @@ #include "global.h" #include "RageInputDevice.h" #include "RageUtil.h" -#include "Foreach.h" #include "LocalizedString.h" static const char *InputDeviceStateNames[] = { @@ -137,8 +136,8 @@ static void InitNames() g_mapNamesToString[MOUSE_WHEELUP] = "mousewheel up"; g_mapNamesToString[MOUSE_WHEELDOWN] = "mousewheel down"; - FOREACHM( DeviceButton, RString, g_mapNamesToString, m ) - g_mapStringToNames[m->second] = m->first; + for (std::pair m : g_mapNamesToString) + g_mapStringToNames[m.second] = m.first; } /* Return a reversible representation of a DeviceButton. This is not affected diff --git a/src/RageInputDevice.h b/src/RageInputDevice.h index 6c29b995e3..bd93899cab 100644 --- a/src/RageInputDevice.h +++ b/src/RageInputDevice.h @@ -49,7 +49,7 @@ enum InputDevice DEVICE_MOUSE, DEVICE_PIUIO, NUM_InputDevice, // leave this at the end - InputDevice_Invalid // means this is NULL + InputDevice_Invalid // means this is nullptr }; /** @brief A special foreach loop for each input device. */ #define FOREACH_InputDevice( i ) FOREACH_ENUM( InputDevice, i ) diff --git a/src/RageLog.cpp b/src/RageLog.cpp index 5fe0f5f768..f6fe00d4dd 100644 --- a/src/RageLog.cpp +++ b/src/RageLog.cpp @@ -4,7 +4,6 @@ #include "RageTimer.h" #include "RageFile.h" #include "RageThreads.h" -#include "Foreach.h" #include #if defined(_WINDOWS) @@ -374,7 +373,7 @@ void RageLog::AddToRecentLogs( const RString &str ) const char *RageLog::GetRecentLog( int n ) { if( n >= BACKLOG_LINES || n >= backlog_cnt ) - return NULL; + return nullptr; if( backlog_cnt == BACKLOG_LINES ) { @@ -394,8 +393,8 @@ static int g_AdditionalLogSize = 0; void RageLog::UpdateMappedLog() { RString str; - FOREACHM_CONST( RString, RString, LogMaps, i ) - str += ssprintf( "%s" NEWLINE, i->second.c_str() ); + for (auto const &i : LogMaps) + str += ssprintf( "%s" NEWLINE, i.second.c_str() ); g_AdditionalLogSize = min( sizeof(g_AdditionalLogStr), str.size()+1 ); memcpy( g_AdditionalLogStr, str.c_str(), g_AdditionalLogSize ); diff --git a/src/RageLog.h b/src/RageLog.h index 4ee91be7b1..0849c2cc59 100644 --- a/src/RageLog.h +++ b/src/RageLog.h @@ -22,7 +22,7 @@ public: static const char *GetAdditionalLog(); static const char *GetInfo(); - /* Returns NULL if past the last recent log. */ + /* Returns nullptr if past the last recent log. */ static const char *GetRecentLog( int n ); void SetShowLogOutput( bool show ); // enable or disable logging to stdout diff --git a/src/RageSound.cpp b/src/RageSound.cpp index 5943b86116..0eaea35777 100644 --- a/src/RageSound.cpp +++ b/src/RageSound.cpp @@ -48,12 +48,12 @@ RageSoundLoadParams::RageSoundLoadParams(): m_bSupportRateChanging(false), m_bSupportPan(false) {} RageSound::RageSound(): - m_Mutex( "RageSound" ), m_pSource(NULL), + m_Mutex( "RageSound" ), m_pSource(nullptr), m_sFilePath(""), m_Param(), m_iStreamFrame(0), m_iStoppedSourceFrame(0), m_bPlaying(false), m_bDeleteWhenFinished(false), m_sError("") { - ASSERT( SOUNDMAN != NULL ); + ASSERT( SOUNDMAN != nullptr ); } RageSound::~RageSound() @@ -65,9 +65,9 @@ RageSound::RageSound( const RageSound &cpy ): RageSoundBase( cpy ), m_Mutex( "RageSound" ) { - ASSERT(SOUNDMAN != NULL); + ASSERT(SOUNDMAN != nullptr); - m_pSource = NULL; + m_pSource = nullptr; *this = cpy; } @@ -86,14 +86,14 @@ RageSound &RageSound::operator=( const RageSound &cpy ) m_bPlaying = false; m_bDeleteWhenFinished = false; - if(m_pSource != NULL) + if(m_pSource != nullptr) { delete m_pSource; } if( cpy.m_pSource ) m_pSource = cpy.m_pSource->Copy(); else - m_pSource = NULL; + m_pSource = nullptr; m_sFilePath = cpy.m_sFilePath; @@ -107,11 +107,11 @@ void RageSound::Unload() LockMut(m_Mutex); - if(m_pSource != NULL) + if(m_pSource != nullptr) { delete m_pSource; } - m_pSource = NULL; + m_pSource = nullptr; m_sFilePath = ""; } @@ -136,7 +136,7 @@ void RageSound::DeleteSelfWhenFinishedPlaying() bool RageSound::IsLoaded() const { - return m_pSource != NULL; + return m_pSource != nullptr; } class RageSoundReader_Silence: public RageSoundReader @@ -166,7 +166,7 @@ bool RageSound::Load( RString sSoundFilePath, bool bPrecache, const RageSoundLoa { LOG->Trace( "RageSound: Load \"%s\" (precache: %i)", sSoundFilePath.c_str(), bPrecache ); - if( pParams == NULL ) + if( pParams == nullptr ) { static const RageSoundLoadParams Defaults; pParams = &Defaults; @@ -176,12 +176,12 @@ bool RageSound::Load( RString sSoundFilePath, bool bPrecache, const RageSoundLoa * of that. Since RageSoundReader_Preload is refcounted, this is cheap. */ RageSoundReader *pSound = SOUNDMAN->GetLoadedSound( sSoundFilePath ); bool bNeedBuffer = true; - if( pSound == NULL ) + if( pSound == nullptr ) { RString error; bool bPrebuffer; pSound = RageSoundReader_FileReader::OpenFile( sSoundFilePath, error, &bPrebuffer ); - if( pSound == NULL ) + if( pSound == nullptr ) { LOG->Warn( "RageSound::Load: error opening sound \"%s\": %s", sSoundFilePath.c_str(), error.c_str() ); @@ -272,7 +272,7 @@ int RageSound::GetDataToPlay( float *pBuffer, int iFrames, int64_t &iStreamFrame // LockMut(m_Mutex); ASSERT_M( m_bPlaying, ssprintf("%p", this) ); - ASSERT( m_pSource != NULL ); + ASSERT( m_pSource != nullptr ); iFramesStored = 0; iStreamFrame = m_iStreamFrame; @@ -370,7 +370,7 @@ void RageSound::SoundIsFinishedPlaying() return; /* Get our current hardware position. */ - int64_t iCurrentHardwareFrame = SOUNDMAN->GetPosition( NULL ); + int64_t iCurrentHardwareFrame = SOUNDMAN->GetPosition(nullptr); m_Mutex.Lock(); @@ -400,7 +400,7 @@ void RageSound::SoundIsFinishedPlaying() void RageSound::Play(bool is_action, const RageSoundParams *pParams) { - if( m_pSource == NULL ) + if( m_pSource == nullptr ) { LOG->Warn( "RageSound::Play: sound not loaded" ); return; @@ -444,7 +444,7 @@ void RageSound::Stop() bool RageSound::Pause( bool bPause ) { - if( m_pSource == NULL ) + if( m_pSource == nullptr ) { LOG->Warn( "RageSound::Pause: sound not loaded" ); return false; @@ -455,7 +455,7 @@ bool RageSound::Pause( bool bPause ) float RageSound::GetLengthSeconds() { - if( m_pSource == NULL ) + if( m_pSource == nullptr ) { LOG->Warn( "RageSound::GetLengthSeconds: sound not loaded" ); return -1; @@ -487,10 +487,10 @@ int RageSound::GetSourceFrameFromHardwareFrame( int64_t iHardwareFrame, bool *bA return (int) iSourceFrame; } -/* If non-NULL, approximate is set to true if the returned time is approximated because of +/* If non-nullptr, approximate is set to true if the returned time is approximated because of * underrun, the sound not having started (after Play()) or finished (after EOF) yet. * - * If non-NULL, Timestamp is set to the real clock time associated with the returned sound + * If non-nullptr, Timestamp is set to the real clock time associated with the returned sound * position. We might take a variable amount of time before grabbing the timestamp (to * lock SOUNDMAN); we might lose the scheduler after grabbing it, when releasing SOUNDMAN. */ @@ -529,7 +529,7 @@ bool RageSound::SetPositionFrames( int iFrames ) { LockMut( m_Mutex ); - if( m_pSource == NULL ) + if( m_pSource == nullptr ) { LOG->Warn( "RageSound::SetPositionFrames(%d): sound not loaded", iFrames ); return false; @@ -573,7 +573,7 @@ void RageSound::SetParams( const RageSoundParams &p ) void RageSound::ApplyParams() { - if( m_pSource == NULL ) + if( m_pSource == nullptr ) return; m_pSource->SetProperty( "Pitch", m_Param.m_fPitch ); @@ -654,7 +654,7 @@ public: static int get_length(T* p, lua_State* L) { RageSoundReader* reader= p->GetSoundReader(); - if(reader == NULL) + if(reader == nullptr) { lua_pushnumber(L, -1.0f); } diff --git a/src/RageSound.h b/src/RageSound.h index 28b32a08d7..89f1937ce3 100644 --- a/src/RageSound.h +++ b/src/RageSound.h @@ -98,7 +98,7 @@ public: * they can be ignored most of the time, so we continue to work if a file * is broken or missing. */ - bool Load( RString sFile, bool bPrecache, const RageSoundLoadParams *pParams = NULL ); + bool Load( RString sFile, bool bPrecache, const RageSoundLoadParams *pParams = nullptr ); /* Using this version means the "don't care" about caching. Currently, * this always will not cache the sound; this may become a preference. */ @@ -120,8 +120,8 @@ public: RString GetError() const { return m_sError; } - void Play(bool is_action, const RageSoundParams *params=NULL); - void PlayCopy(bool is_action, const RageSoundParams *pParams = NULL) const; + void Play(bool is_action, const RageSoundParams *params=nullptr); + void PlayCopy(bool is_action, const RageSoundParams *pParams = nullptr) const; void Stop(); /* Cleanly pause or unpause the sound. If the sound wasn't already playing, @@ -129,7 +129,7 @@ public: bool Pause( bool bPause ); float GetLengthSeconds(); - float GetPositionSeconds( bool *approximate=NULL, RageTimer *Timestamp=NULL ) const; + float GetPositionSeconds( bool *approximate=nullptr, RageTimer *Timestamp=nullptr ) const; RString GetLoadedFilePath() const { return m_sFilePath; } bool IsPlaying() const { return m_bPlaying; } @@ -173,7 +173,7 @@ private: RString m_sError; - int GetSourceFrameFromHardwareFrame( int64_t iHardwareFrame, bool *bApproximate = NULL ) const; + int GetSourceFrameFromHardwareFrame( int64_t iHardwareFrame, bool *bApproximate = nullptr ) const; bool SetPositionFrames( int frames = -1 ); RageSoundParams::StopMode_t GetStopMode() const; // resolves M_AUTO diff --git a/src/RageSoundManager.cpp b/src/RageSoundManager.cpp index edb006771a..39c119a826 100644 --- a/src/RageSoundManager.cpp +++ b/src/RageSoundManager.cpp @@ -15,7 +15,6 @@ #include "RageLog.h" #include "RageTimer.h" #include "RageSoundReader_Preload.h" -#include "Foreach.h" #include "LocalizedString.h" #include "Preference.h" #include "RageSoundReader_PostBuffering.h" @@ -34,16 +33,16 @@ static RageMutex g_SoundManMutex("SoundMan"); static Preference g_sSoundDrivers( "SoundDrivers", "" ); // "" == DEFAULT_SOUND_DRIVER_LIST -RageSoundManager *SOUNDMAN = NULL; +RageSoundManager *SOUNDMAN = nullptr; -RageSoundManager::RageSoundManager(): m_pDriver(NULL), +RageSoundManager::RageSoundManager(): m_pDriver(nullptr), m_fVolumeOfNonCriticalSounds(1.0f) {} static LocalizedString COULDNT_FIND_SOUND_DRIVER( "RageSoundManager", "Couldn't find a sound driver that works" ); void RageSoundManager::Init() { m_pDriver = RageSoundDriver::Create( g_sSoundDrivers ); - if( m_pDriver == NULL ) + if( m_pDriver == nullptr ) RageException::Throw( "%s", COULDNT_FIND_SOUND_DRIVER.GetValue().c_str() ); } @@ -51,8 +50,8 @@ RageSoundManager::~RageSoundManager() { /* Don't lock while deleting the driver (the decoder thread might deadlock). */ delete m_pDriver; - FOREACHM( RString, RageSoundReader_Preload *, m_mapPreloadedSounds, s ) - delete s->second; + for (std::pair s : m_mapPreloadedSounds) + delete s.second; m_mapPreloadedSounds.clear(); } @@ -81,19 +80,19 @@ void RageSoundManager::Shutdown() void RageSoundManager::StartMixing( RageSoundBase *pSound ) { - if( m_pDriver != NULL ) + if( m_pDriver != nullptr ) m_pDriver->StartMixing( pSound ); } void RageSoundManager::StopMixing( RageSoundBase *pSound ) { - if( m_pDriver != NULL ) + if( m_pDriver != nullptr ) m_pDriver->StopMixing( pSound ); } bool RageSoundManager::Pause( RageSoundBase *pSound, bool bPause ) { - if( m_pDriver == NULL ) + if( m_pDriver == nullptr ) return false; else return m_pDriver->PauseMixing( pSound, bPause ); @@ -101,7 +100,7 @@ bool RageSoundManager::Pause( RageSoundBase *pSound, bool bPause ) int64_t RageSoundManager::GetPosition( RageTimer *pTimer ) const { - if( m_pDriver == NULL ) + if( m_pDriver == nullptr ) return 0; return m_pDriver->GetHardwareFrame( pTimer ); } @@ -130,13 +129,13 @@ void RageSoundManager::Update() g_SoundManMutex.Unlock(); /* finished with m_mapPreloadedSounds */ - if( m_pDriver != NULL ) + if( m_pDriver != nullptr ) m_pDriver->Update(); } float RageSoundManager::GetPlayLatency() const { - if( m_pDriver == NULL ) + if( m_pDriver == nullptr ) return 0; return m_pDriver->GetPlayLatency(); @@ -144,13 +143,13 @@ float RageSoundManager::GetPlayLatency() const int RageSoundManager::GetDriverSampleRate() const { - if( m_pDriver == NULL ) + if( m_pDriver == nullptr ) return 44100; return m_pDriver->GetSampleRate(); } -/* If the given path is loaded, return a copy; otherwise return NULL. +/* If the given path is loaded, return a copy; otherwise return nullptr. * It's the caller's responsibility to delete the result. */ RageSoundReader *RageSoundManager::GetLoadedSound( const RString &sPath_ ) { @@ -161,7 +160,7 @@ RageSoundReader *RageSoundManager::GetLoadedSound( const RString &sPath_ ) map::const_iterator it; it = m_mapPreloadedSounds.find( sPath ); if( it == m_mapPreloadedSounds.end() ) - return NULL; + return nullptr; return it->second->Copy(); } diff --git a/src/RageSoundMixBuffer.cpp b/src/RageSoundMixBuffer.cpp index 01352cdc04..11aafc9944 100644 --- a/src/RageSoundMixBuffer.cpp +++ b/src/RageSoundMixBuffer.cpp @@ -12,7 +12,7 @@ static bool g_bVector = Vector::CheckForVector(); RageSoundMixBuffer::RageSoundMixBuffer() { m_iBufSize = m_iBufUsed = 0; - m_pMixbuf = NULL; + m_pMixbuf = nullptr; m_iOffset = 0; } diff --git a/src/RageSoundPosMap.cpp b/src/RageSoundPosMap.cpp index 923d11b6fb..a3a0940ebd 100644 --- a/src/RageSoundPosMap.cpp +++ b/src/RageSoundPosMap.cpp @@ -3,7 +3,6 @@ #include "RageLog.h" #include "RageUtil.h" #include "RageTimer.h" -#include "Foreach.h" #include #include @@ -136,10 +135,8 @@ int64_t pos_map_queue::Search( int64_t iSourceFrame, bool *bApproximate ) const * it maps to. */ int64_t iClosestPosition = 0, iClosestPositionDist = INT_MAX; const pos_map_t *pClosestBlock = &*m_pImpl->m_Queue.begin(); /* print only */ - FOREACHL_CONST( pos_map_t, m_pImpl->m_Queue, it ) + for (pos_map_t const &pm : m_pImpl->m_Queue) { - const pos_map_t &pm = *it; - if( iSourceFrame >= pm.m_iSourceFrame && iSourceFrame < pm.m_iSourceFrame+pm.m_iFrames ) { diff --git a/src/RageSoundReader.h b/src/RageSoundReader.h index 635f4fefc0..baba9c33bd 100644 --- a/src/RageSoundReader.h +++ b/src/RageSoundReader.h @@ -1,71 +1,71 @@ -/* RageSoundReader - Data source for a RageSound. */ - -#ifndef RAGE_SOUND_READER_H -#define RAGE_SOUND_READER_H - -class RageSoundReader -{ -public: - virtual int GetLength() const = 0; /* ms */ - virtual int GetLength_Fast() const { return GetLength(); } /* ms */ - virtual int SetPosition( int iFrame ) = 0; - virtual int Read( float *pBuf, int iFrames ) = 0; - virtual ~RageSoundReader() { } - virtual RageSoundReader *Copy() const = 0; - virtual int GetSampleRate() const = 0; - virtual unsigned GetNumChannels() const = 0; - virtual bool SetProperty( const RString & /* sProperty */, float /* fValue */ ) { return false; } - virtual RageSoundReader *GetSource() { return NULL; } - - /* Return values for Read(). */ - enum { - /* An error occurred; GetError() will return a description of the error. */ - ERROR = -1, - END_OF_FILE = -2, - - /* A nonblocking buffer in the filter chain has underrun, and no data is - * currently available. */ - WOULD_BLOCK = -3, - - /* The source position has changed in an expected way, such as looping. - * Seeking manually will not cause this. */ - STREAM_LOOPED = -4, - }; - - /* GetNextSourceFrame() provides the source frame associated with the next frame - * that will be read via Read(). GetStreamToSourceRatio() returns the ratio - * for extrapolating the source frames of the remainder of the block. These - * values are valid so long as no parameters are changed before the next Read(). */ - virtual int GetNextSourceFrame() const = 0; - virtual float GetStreamToSourceRatio() const = 0; - - virtual RString GetError() const = 0; - int RetriedRead( float *pBuffer, int iFrames, int *iSourceFrame = NULL, float *fRate = NULL ); -}; - -#endif - -/* - * Copyright (c) 2002-2003 Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +/* RageSoundReader - Data source for a RageSound. */ + +#ifndef RAGE_SOUND_READER_H +#define RAGE_SOUND_READER_H + +class RageSoundReader +{ +public: + virtual int GetLength() const = 0; /* ms */ + virtual int GetLength_Fast() const { return GetLength(); } /* ms */ + virtual int SetPosition( int iFrame ) = 0; + virtual int Read( float *pBuf, int iFrames ) = 0; + virtual ~RageSoundReader() { } + virtual RageSoundReader *Copy() const = 0; + virtual int GetSampleRate() const = 0; + virtual unsigned GetNumChannels() const = 0; + virtual bool SetProperty( const RString & /* sProperty */, float /* fValue */ ) { return false; } + virtual RageSoundReader *GetSource() { return nullptr; } + + /* Return values for Read(). */ + enum { + /* An error occurred; GetError() will return a description of the error. */ + ERROR = -1, + END_OF_FILE = -2, + + /* A nonblocking buffer in the filter chain has underrun, and no data is + * currently available. */ + WOULD_BLOCK = -3, + + /* The source position has changed in an expected way, such as looping. + * Seeking manually will not cause this. */ + STREAM_LOOPED = -4, + }; + + /* GetNextSourceFrame() provides the source frame associated with the next frame + * that will be read via Read(). GetStreamToSourceRatio() returns the ratio + * for extrapolating the source frames of the remainder of the block. These + * values are valid so long as no parameters are changed before the next Read(). */ + virtual int GetNextSourceFrame() const = 0; + virtual float GetStreamToSourceRatio() const = 0; + + virtual RString GetError() const = 0; + int RetriedRead( float *pBuffer, int iFrames, int *iSourceFrame = nullptr, float *fRate = nullptr ); +}; + +#endif + +/* + * Copyright (c) 2002-2003 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/RageSoundReader_Chain.cpp b/src/RageSoundReader_Chain.cpp index c95c90d714..1d51c3ef0e 100644 --- a/src/RageSoundReader_Chain.cpp +++ b/src/RageSoundReader_Chain.cpp @@ -1,439 +1,436 @@ -#include "global.h" -#include "RageSoundReader_Chain.h" -#include "RageSoundReader_FileReader.h" -#include "RageSoundReader_Resample_Good.h" -#include "RageSoundReader_Preload.h" -#include "RageSoundReader_Pan.h" -#include "RageLog.h" -#include "RageUtil.h" -#include "RageSoundMixBuffer.h" -#include "RageSoundUtil.h" -#include "Foreach.h" - -/* - * Keyed sounds should pass this object to SoundReader_Preload, to preprocess it. - * Streaming more than two or three sounds is too expensive (keyed games can play - * two dozen), and reading from disk is too latent. - * - * This can also be used for chained background music, which should always stream, - * so we don't do the preloading in here. - */ -RageSoundReader_Chain::RageSoundReader_Chain() -{ - m_iPreferredSampleRate = 44100; - m_iActualSampleRate = -1; - m_iChannels = 0; - m_iCurrentFrame = 0; - m_iNextSound = 0; -} - -RageSoundReader_Chain::~RageSoundReader_Chain() -{ - /* Clear m_apActiveSounds. */ - while( !m_apActiveSounds.empty() ) - ReleaseSound( m_apActiveSounds.front() ); - - FOREACH( RageSoundReader *, m_apLoadedSounds, it ) - delete *it; -} - -RageSoundReader_Chain *RageSoundReader_Chain::Copy() const -{ - // XXX - FAIL_M("unimplemented"); -} - -/* The same sound may be used several times, and by several different chains. Avoid - * loading the same sound multiple times. We need to make a Copy() if we need to - * read it more than once at a time. */ -void RageSoundReader_Chain::AddSound( int iIndex, float fOffsetSecs, float fPan ) -{ - if( iIndex == -1 ) - return; - - Sound s; - s.iIndex = iIndex; - s.iOffsetMS = lrintf( fOffsetSecs * 1000 ); - s.fPan = fPan; - s.pSound = NULL; - m_aSounds.push_back( s ); -} - -int RageSoundReader_Chain::LoadSound( RString sPath ) -{ - sPath.MakeLower(); - - map::const_iterator it = m_apNamedSounds.find( sPath ); - if( it != m_apNamedSounds.end() ) - { - const RageSoundReader *pReader = it->second; - - for( int i = 0; i < (int) m_apLoadedSounds.size(); ++i ) - if( m_apLoadedSounds[i] == pReader ) - return i; - FAIL_M( sPath ); - } - - RString sError; - bool bPrebuffer; - RageSoundReader *pReader = RageSoundReader_FileReader::OpenFile( sPath, sError, &bPrebuffer ); - if( pReader == NULL ) - { - LOG->Warn( "RageSoundReader_Chain: error opening sound \"%s\": %s", - sPath.c_str(), sError.c_str() ); - return -1; - } - - m_apNamedSounds[sPath] = pReader; - - m_apLoadedSounds.push_back( m_apNamedSounds[sPath] ); - return m_apLoadedSounds.size()-1; -} - -int RageSoundReader_Chain::LoadSound( RageSoundReader *pSound ) -{ - m_apLoadedSounds.push_back( pSound ); - return m_apLoadedSounds.size()-1; -} - -/* If every sound has the same sample rate, return it. Otherwise, return -1. */ -int RageSoundReader_Chain::GetSampleRateInternal() const -{ - if( m_apLoadedSounds.empty() ) - return m_iPreferredSampleRate; - - int iRate = -1; - FOREACH_CONST( RageSoundReader *, m_apLoadedSounds, it ) - { - if( iRate == -1 ) - iRate = (*it)->GetSampleRate(); - else if( iRate != (*it)->GetSampleRate() ) - return -1; - } - return iRate; -} - -void RageSoundReader_Chain::Finish() -{ - /* Figure out how many channels we have. All sounds must either have 1 or 2 channels, - * which will be converted as needed, or have the same number of channels. */ - m_iChannels = 1; - FOREACH( RageSoundReader *, m_apLoadedSounds, it ) - m_iChannels = max( m_iChannels, (*it)->GetNumChannels() ); - - if( m_iChannels > 2 ) - { - FOREACH( RageSoundReader *, m_apLoadedSounds, it ) - { - if( (*it)->GetNumChannels() != m_iChannels ) - { - LOG->Warn( "Discarded sound with %i channels, not %i", - (*it)->GetNumChannels(), m_iChannels ); - delete (*it); - (*it) = NULL; - } - } - } - - /* Remove any sounds that don't have corresponding RageSoundReaders. */ - for( unsigned i = 0; i < m_aSounds.size(); ) - { - Sound &sound = m_aSounds[i]; - - if( m_apLoadedSounds[sound.iIndex] == NULL ) - { - m_aSounds.erase( m_aSounds.begin()+i ); - continue; - } - - ++i; - } - - /* - * We might get different sample rates from our sources. If they're all the same - * sample rate, just leave it alone, so the whole sound can be resampled as a group. - * If not, resample eveything to the preferred rate. (Using the preferred rate - * should avoid redundant resampling later.) - */ - m_iActualSampleRate = GetSampleRateInternal(); - if( m_iActualSampleRate == -1 ) - { - FOREACH( RageSoundReader *, m_apLoadedSounds, it ) - { - RageSoundReader *&pSound = (*it); - - RageSoundReader_Resample_Good *pResample = new RageSoundReader_Resample_Good( pSound, m_iPreferredSampleRate ); - pSound = pResample; - } - - m_iActualSampleRate = m_iPreferredSampleRate; - } - - /* Attempt to preload all sounds. */ - FOREACH( RageSoundReader *, m_apLoadedSounds, it ) - { - RageSoundReader *&pSound = (*it); - RageSoundReader_Preload::PreloadSound( pSound ); - } - - /* Sort the sounds by start time. */ - sort( m_aSounds.begin(), m_aSounds.end() ); -} - -int RageSoundReader_Chain::SetPosition( int iFrame ) -{ - /* Clear m_apActiveSounds. */ - while( !m_apActiveSounds.empty() ) - ReleaseSound( m_apActiveSounds.front() ); - - m_iCurrentFrame = iFrame; - - /* Run through all sounds in the chain, and activate all sounds which have data - * at iFrame. */ - for( m_iNextSound = 0; m_iNextSound < m_aSounds.size(); ++m_iNextSound ) - { - Sound *pSound = &m_aSounds[m_iNextSound]; - int iOffsetFrame = pSound->GetOffsetFrame( GetSampleRate() ); - - /* If this sound is in the future, skip it. */ - if( iOffsetFrame > iFrame ) - break; - - /* Find the RageSoundReader. */ - ActivateSound( pSound ); - RageSoundReader *pReader = pSound->pSound; - - int iOffsetFrames = iFrame - iOffsetFrame; - if( pReader->SetPosition(iOffsetFrames) == 0 ) - { - /* We're past the end of this sound. */ - ReleaseSound( pSound ); - continue; - } - } - - /* If no sounds were started, and we have no sounds ahead of us, we've seeked - * past EOF. */ - if( m_apActiveSounds.empty() && m_iNextSound == m_aSounds.size() ) - return 0; - - return 1; -} - -void RageSoundReader_Chain::ActivateSound( Sound *s ) -{ - RageSoundReader *pSound = m_apLoadedSounds[s->iIndex]; - s->pSound = pSound->Copy(); - - /* Add a balance filter. If this source has the same number of channels - * as this sound, and does not need to be panned, we can omit this. */ - if( s->fPan != 0.0f || s->pSound->GetNumChannels() != this->GetNumChannels() ) - { - s->pSound = new RageSoundReader_Pan( s->pSound ); - s->pSound->SetProperty( "Pan", s->fPan ); - } - - m_apActiveSounds.push_back( s ); -} - -void RageSoundReader_Chain::ReleaseSound( Sound *s ) -{ - vector::iterator it = find( m_apActiveSounds.begin(), m_apActiveSounds.end(), s ); - ASSERT( it != m_apActiveSounds.end() ); - RageSoundReader *&pSound = s->pSound; - - delete pSound; - pSound = NULL; - - m_apActiveSounds.erase( it ); -} - -bool RageSoundReader_Chain::SetProperty( const RString &sProperty, float fValue ) -{ - bool bRet = false; - for( unsigned i = 0; i < m_apActiveSounds.size(); ++i ) - { - if( m_apActiveSounds[i]->pSound->SetProperty(sProperty, fValue) ) - bRet = true; - } - return bRet; -} - -int RageSoundReader_Chain::GetNextSourceFrame() const -{ - return m_iCurrentFrame; -/* if( m_apActiveSounds.empty() ) - return m_iCurrentFrame; - - int iPosition = m_apActiveSounds[0]->pSound->GetNextSourceFrame(); - iPosition += m_apActiveSounds[0]->GetOffsetFrame( GetSampleRate() ); - - for( unsigned i = 1; i < m_apActiveSounds.size(); ++i ) - { - int iThisPosition = m_apActiveSounds[i]->pSound->GetNextSourceFrame(); - iThisPosition += m_apActiveSounds[i]->GetOffsetFrame( GetSampleRate() ); - if( iThisPosition != iPosition ) - LOG->Warn( "RageSoundReader_Chain: sound positions moving at different rates" ); - } - - return iPosition; -*/ -} - -float RageSoundReader_Chain::GetStreamToSourceRatio() const -{ - if( m_apActiveSounds.empty() ) - return 1.0f; - - float iRate = m_apActiveSounds[0]->pSound->GetStreamToSourceRatio(); - for( unsigned i = 1; i < m_apActiveSounds.size(); ++i ) - { - if( m_apActiveSounds[i]->pSound->GetStreamToSourceRatio() != iRate ) - LOG->Warn( "RageSoundReader_Chain: sound rates changing differently" ); - } - - return iRate; -} - -/* As we iterate through the sound tree, we'll find that we need data from different - * sounds; a sound may be needed by more than one other sound. */ -int RageSoundReader_Chain::Read( float *pBuffer, int iFrames ) -{ - while( m_iNextSound < m_aSounds.size() && m_iCurrentFrame == m_aSounds[m_iNextSound].GetOffsetFrame(m_iActualSampleRate) ) - { - Sound *pSound = &m_aSounds[m_iNextSound]; - ActivateSound( pSound ); - ++m_iNextSound; - } - - if( m_iNextSound == m_aSounds.size() && m_apActiveSounds.empty() ) - return END_OF_FILE; - - /* Clamp iFrames to the beginning of the next sound we need to start. */ - if( m_iNextSound < m_aSounds.size() ) - { - int iOffsetFrame = m_aSounds[m_iNextSound].GetOffsetFrame( m_iActualSampleRate ); - ASSERT_M( iOffsetFrame >= m_iCurrentFrame, ssprintf("%i %i", iOffsetFrame, m_iCurrentFrame) ); - int iFramesToRead = iOffsetFrame - m_iCurrentFrame; - iFrames = min( iFramesToRead, iFrames ); - } - - if( m_apActiveSounds.size() == 1 && - m_apActiveSounds.front()->pSound->GetNumChannels() == m_iChannels && - m_apActiveSounds.front()->pSound->GetSampleRate() == m_iActualSampleRate ) - { - /* We have only one source, and it matches our target. Don't mix; read - * directly from the source into the destination. This is to optimize - * the common case of having one BGM track and no autoplay sounds. */ - iFrames = m_apActiveSounds.front()->pSound->Read( pBuffer, iFrames ); - if( iFrames < 0 ) - ReleaseSound( m_apActiveSounds.front() ); - if( iFrames > 0 ) - m_iCurrentFrame += iFrames; - return iFrames; - } - - if( m_apActiveSounds.empty() ) - { - /* If we have more sounds ahead of us, pretend we read the entire block, since - * there's silence in between. Otherwise, we're at EOF. */ - memset( pBuffer, 0, iFrames * m_iChannels * sizeof(float) ); - m_iCurrentFrame += iFrames; - return iFrames; - } - - RageSoundMixBuffer mix; - /* Read iFrames from each sound. */ - float Buffer[2048]; - iFrames = min( iFrames, (int) (ARRAYLEN(Buffer) / m_iChannels) ); - for( unsigned i = 0; i < m_apActiveSounds.size(); ) - { - RageSoundReader *pSound = m_apActiveSounds[i]->pSound; - ASSERT( pSound->GetNumChannels() == m_iChannels ); // guaranteed by ActivateSound and Finish - - /* If we receive less than we were asked for, keep asking for more data. Most - * filters would simply return what they have in this situation, but we want - * to deal transparently with separate sounds returning differently-sized partial - * blocks. */ - int iFramesRead = 0; - while( iFramesRead < iFrames ) - { - int iGotFrames = pSound->RetriedRead( Buffer, iFrames - iFramesRead ); - if( iGotFrames < 0 ) - { - iFramesRead = iGotFrames; - break; - } - - mix.SetWriteOffset( iFramesRead * pSound->GetNumChannels() ); - mix.write( Buffer, iGotFrames * pSound->GetNumChannels() ); - iFramesRead += iGotFrames; - } - - if( iFramesRead < 0 ) - ReleaseSound( m_apActiveSounds[i] ); - else - ++i; - } - - /* Read mixed frames into the output buffer. */ - int iMaxFramesRead = mix.size() / m_iChannels; - mix.read( pBuffer ); - m_iCurrentFrame += iMaxFramesRead; - - return iMaxFramesRead; -} - -int RageSoundReader_Chain::GetLength() const -{ - int iLength = 0; - for( unsigned i = 0; i < m_aSounds.size(); ++i ) - { - const Sound &sound = m_aSounds[i]; - const RageSoundReader *pSound = m_apLoadedSounds[sound.iIndex]; - int iThisLength = pSound->GetLength(); - if( iThisLength ) - iLength = max( iLength, iThisLength + sound.iOffsetMS ); - } - return iLength; -} - -int RageSoundReader_Chain::GetLength_Fast() const -{ - int iLength = 0; - for( unsigned i = 0; i < m_aSounds.size(); ++i ) - { - const Sound &sound = m_aSounds[i]; - const RageSoundReader *pSound = m_apLoadedSounds[sound.iIndex]; - int iThisLength = pSound->GetLength_Fast(); - if( iThisLength ) - iLength = max( iLength, iThisLength + sound.iOffsetMS ); - } - return iLength; -} - - -/* - * Copyright (c) 2004-2006 Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "RageSoundReader_Chain.h" +#include "RageSoundReader_FileReader.h" +#include "RageSoundReader_Resample_Good.h" +#include "RageSoundReader_Preload.h" +#include "RageSoundReader_Pan.h" +#include "RageLog.h" +#include "RageUtil.h" +#include "RageSoundMixBuffer.h" +#include "RageSoundUtil.h" + + +/* + * Keyed sounds should pass this object to SoundReader_Preload, to preprocess it. + * Streaming more than two or three sounds is too expensive (keyed games can play + * two dozen), and reading from disk is too latent. + * + * This can also be used for chained background music, which should always stream, + * so we don't do the preloading in here. + */ +RageSoundReader_Chain::RageSoundReader_Chain() +{ + m_iPreferredSampleRate = 44100; + m_iActualSampleRate = -1; + m_iChannels = 0; + m_iCurrentFrame = 0; + m_iNextSound = 0; +} + +RageSoundReader_Chain::~RageSoundReader_Chain() +{ + /* Clear m_apActiveSounds. */ + while( !m_apActiveSounds.empty() ) + ReleaseSound( m_apActiveSounds.front() ); + + for (RageSoundReader *it : m_apLoadedSounds) + delete it; +} + +RageSoundReader_Chain *RageSoundReader_Chain::Copy() const +{ + // XXX + FAIL_M("unimplemented"); +} + +/* The same sound may be used several times, and by several different chains. Avoid + * loading the same sound multiple times. We need to make a Copy() if we need to + * read it more than once at a time. */ +void RageSoundReader_Chain::AddSound( int iIndex, float fOffsetSecs, float fPan ) +{ + if( iIndex == -1 ) + return; + + Sound s; + s.iIndex = iIndex; + s.iOffsetMS = lrintf( fOffsetSecs * 1000 ); + s.fPan = fPan; + s.pSound = nullptr; + m_aSounds.push_back( s ); +} + +int RageSoundReader_Chain::LoadSound( RString sPath ) +{ + sPath.MakeLower(); + + map::const_iterator it = m_apNamedSounds.find( sPath ); + if( it != m_apNamedSounds.end() ) + { + const RageSoundReader *pReader = it->second; + + for( int i = 0; i < (int) m_apLoadedSounds.size(); ++i ) + if( m_apLoadedSounds[i] == pReader ) + return i; + FAIL_M( sPath ); + } + + RString sError; + bool bPrebuffer; + RageSoundReader *pReader = RageSoundReader_FileReader::OpenFile( sPath, sError, &bPrebuffer ); + if( pReader == nullptr ) + { + LOG->Warn( "RageSoundReader_Chain: error opening sound \"%s\": %s", + sPath.c_str(), sError.c_str() ); + return -1; + } + + m_apNamedSounds[sPath] = pReader; + + m_apLoadedSounds.push_back( m_apNamedSounds[sPath] ); + return m_apLoadedSounds.size()-1; +} + +int RageSoundReader_Chain::LoadSound( RageSoundReader *pSound ) +{ + m_apLoadedSounds.push_back( pSound ); + return m_apLoadedSounds.size()-1; +} + +/* If every sound has the same sample rate, return it. Otherwise, return -1. */ +int RageSoundReader_Chain::GetSampleRateInternal() const +{ + if( m_apLoadedSounds.empty() ) + return m_iPreferredSampleRate; + + int iRate = -1; + for (RageSoundReader const *it : m_apLoadedSounds) + { + if( iRate == -1 ) + iRate = it->GetSampleRate(); + else if( iRate != it->GetSampleRate() ) + return -1; + } + return iRate; +} + +void RageSoundReader_Chain::Finish() +{ + /* Figure out how many channels we have. All sounds must either have 1 or 2 channels, + * which will be converted as needed, or have the same number of channels. */ + m_iChannels = 1; + for (RageSoundReader *it : m_apLoadedSounds) + m_iChannels = max( m_iChannels, it->GetNumChannels() ); + + if( m_iChannels > 2 ) + { + for (RageSoundReader *it : m_apLoadedSounds) + { + if( it->GetNumChannels() != m_iChannels ) + { + LOG->Warn( "Discarded sound with %i channels, not %i", + it->GetNumChannels(), m_iChannels ); + delete it; + it = nullptr; + } + } + } + + /* Remove any sounds that don't have corresponding RageSoundReaders. */ + for( unsigned i = 0; i < m_aSounds.size(); ) + { + Sound &sound = m_aSounds[i]; + + if( m_apLoadedSounds[sound.iIndex] == nullptr ) + { + m_aSounds.erase( m_aSounds.begin()+i ); + continue; + } + + ++i; + } + + /* + * We might get different sample rates from our sources. If they're all the same + * sample rate, just leave it alone, so the whole sound can be resampled as a group. + * If not, resample eveything to the preferred rate. (Using the preferred rate + * should avoid redundant resampling later.) + */ + m_iActualSampleRate = GetSampleRateInternal(); + if( m_iActualSampleRate == -1 ) + { + for (RageSoundReader *it : m_apLoadedSounds) + { + RageSoundReader_Resample_Good *pResample = new RageSoundReader_Resample_Good( it, m_iPreferredSampleRate ); + it = pResample; + } + + m_iActualSampleRate = m_iPreferredSampleRate; + } + + /* Attempt to preload all sounds. */ + for (RageSoundReader *it : m_apLoadedSounds) + { + RageSoundReader_Preload::PreloadSound( it ); + } + + /* Sort the sounds by start time. */ + sort( m_aSounds.begin(), m_aSounds.end() ); +} + +int RageSoundReader_Chain::SetPosition( int iFrame ) +{ + /* Clear m_apActiveSounds. */ + while( !m_apActiveSounds.empty() ) + ReleaseSound( m_apActiveSounds.front() ); + + m_iCurrentFrame = iFrame; + + /* Run through all sounds in the chain, and activate all sounds which have data + * at iFrame. */ + for( m_iNextSound = 0; m_iNextSound < m_aSounds.size(); ++m_iNextSound ) + { + Sound *pSound = &m_aSounds[m_iNextSound]; + int iOffsetFrame = pSound->GetOffsetFrame( GetSampleRate() ); + + /* If this sound is in the future, skip it. */ + if( iOffsetFrame > iFrame ) + break; + + /* Find the RageSoundReader. */ + ActivateSound( pSound ); + RageSoundReader *pReader = pSound->pSound; + + int iOffsetFrames = iFrame - iOffsetFrame; + if( pReader->SetPosition(iOffsetFrames) == 0 ) + { + /* We're past the end of this sound. */ + ReleaseSound( pSound ); + continue; + } + } + + /* If no sounds were started, and we have no sounds ahead of us, we've seeked + * past EOF. */ + if( m_apActiveSounds.empty() && m_iNextSound == m_aSounds.size() ) + return 0; + + return 1; +} + +void RageSoundReader_Chain::ActivateSound( Sound *s ) +{ + RageSoundReader *pSound = m_apLoadedSounds[s->iIndex]; + s->pSound = pSound->Copy(); + + /* Add a balance filter. If this source has the same number of channels + * as this sound, and does not need to be panned, we can omit this. */ + if( s->fPan != 0.0f || s->pSound->GetNumChannels() != this->GetNumChannels() ) + { + s->pSound = new RageSoundReader_Pan( s->pSound ); + s->pSound->SetProperty( "Pan", s->fPan ); + } + + m_apActiveSounds.push_back( s ); +} + +void RageSoundReader_Chain::ReleaseSound( Sound *s ) +{ + vector::iterator it = find( m_apActiveSounds.begin(), m_apActiveSounds.end(), s ); + ASSERT( it != m_apActiveSounds.end() ); + RageSoundReader *&pSound = s->pSound; + + delete pSound; + pSound = nullptr; + + m_apActiveSounds.erase( it ); +} + +bool RageSoundReader_Chain::SetProperty( const RString &sProperty, float fValue ) +{ + bool bRet = false; + for( unsigned i = 0; i < m_apActiveSounds.size(); ++i ) + { + if( m_apActiveSounds[i]->pSound->SetProperty(sProperty, fValue) ) + bRet = true; + } + return bRet; +} + +int RageSoundReader_Chain::GetNextSourceFrame() const +{ + return m_iCurrentFrame; +/* if( m_apActiveSounds.empty() ) + return m_iCurrentFrame; + + int iPosition = m_apActiveSounds[0]->pSound->GetNextSourceFrame(); + iPosition += m_apActiveSounds[0]->GetOffsetFrame( GetSampleRate() ); + + for( unsigned i = 1; i < m_apActiveSounds.size(); ++i ) + { + int iThisPosition = m_apActiveSounds[i]->pSound->GetNextSourceFrame(); + iThisPosition += m_apActiveSounds[i]->GetOffsetFrame( GetSampleRate() ); + if( iThisPosition != iPosition ) + LOG->Warn( "RageSoundReader_Chain: sound positions moving at different rates" ); + } + + return iPosition; +*/ +} + +float RageSoundReader_Chain::GetStreamToSourceRatio() const +{ + if( m_apActiveSounds.empty() ) + return 1.0f; + + float iRate = m_apActiveSounds[0]->pSound->GetStreamToSourceRatio(); + for( unsigned i = 1; i < m_apActiveSounds.size(); ++i ) + { + if( m_apActiveSounds[i]->pSound->GetStreamToSourceRatio() != iRate ) + LOG->Warn( "RageSoundReader_Chain: sound rates changing differently" ); + } + + return iRate; +} + +/* As we iterate through the sound tree, we'll find that we need data from different + * sounds; a sound may be needed by more than one other sound. */ +int RageSoundReader_Chain::Read( float *pBuffer, int iFrames ) +{ + while( m_iNextSound < m_aSounds.size() && m_iCurrentFrame == m_aSounds[m_iNextSound].GetOffsetFrame(m_iActualSampleRate) ) + { + Sound *pSound = &m_aSounds[m_iNextSound]; + ActivateSound( pSound ); + ++m_iNextSound; + } + + if( m_iNextSound == m_aSounds.size() && m_apActiveSounds.empty() ) + return END_OF_FILE; + + /* Clamp iFrames to the beginning of the next sound we need to start. */ + if( m_iNextSound < m_aSounds.size() ) + { + int iOffsetFrame = m_aSounds[m_iNextSound].GetOffsetFrame( m_iActualSampleRate ); + ASSERT_M( iOffsetFrame >= m_iCurrentFrame, ssprintf("%i %i", iOffsetFrame, m_iCurrentFrame) ); + int iFramesToRead = iOffsetFrame - m_iCurrentFrame; + iFrames = min( iFramesToRead, iFrames ); + } + + if( m_apActiveSounds.size() == 1 && + m_apActiveSounds.front()->pSound->GetNumChannels() == m_iChannels && + m_apActiveSounds.front()->pSound->GetSampleRate() == m_iActualSampleRate ) + { + /* We have only one source, and it matches our target. Don't mix; read + * directly from the source into the destination. This is to optimize + * the common case of having one BGM track and no autoplay sounds. */ + iFrames = m_apActiveSounds.front()->pSound->Read( pBuffer, iFrames ); + if( iFrames < 0 ) + ReleaseSound( m_apActiveSounds.front() ); + if( iFrames > 0 ) + m_iCurrentFrame += iFrames; + return iFrames; + } + + if( m_apActiveSounds.empty() ) + { + /* If we have more sounds ahead of us, pretend we read the entire block, since + * there's silence in between. Otherwise, we're at EOF. */ + memset( pBuffer, 0, iFrames * m_iChannels * sizeof(float) ); + m_iCurrentFrame += iFrames; + return iFrames; + } + + RageSoundMixBuffer mix; + /* Read iFrames from each sound. */ + float Buffer[2048]; + iFrames = min( iFrames, (int) (ARRAYLEN(Buffer) / m_iChannels) ); + for( unsigned i = 0; i < m_apActiveSounds.size(); ) + { + RageSoundReader *pSound = m_apActiveSounds[i]->pSound; + ASSERT( pSound->GetNumChannels() == m_iChannels ); // guaranteed by ActivateSound and Finish + + /* If we receive less than we were asked for, keep asking for more data. Most + * filters would simply return what they have in this situation, but we want + * to deal transparently with separate sounds returning differently-sized partial + * blocks. */ + int iFramesRead = 0; + while( iFramesRead < iFrames ) + { + int iGotFrames = pSound->RetriedRead( Buffer, iFrames - iFramesRead ); + if( iGotFrames < 0 ) + { + iFramesRead = iGotFrames; + break; + } + + mix.SetWriteOffset( iFramesRead * pSound->GetNumChannels() ); + mix.write( Buffer, iGotFrames * pSound->GetNumChannels() ); + iFramesRead += iGotFrames; + } + + if( iFramesRead < 0 ) + ReleaseSound( m_apActiveSounds[i] ); + else + ++i; + } + + /* Read mixed frames into the output buffer. */ + int iMaxFramesRead = mix.size() / m_iChannels; + mix.read( pBuffer ); + m_iCurrentFrame += iMaxFramesRead; + + return iMaxFramesRead; +} + +int RageSoundReader_Chain::GetLength() const +{ + int iLength = 0; + for( unsigned i = 0; i < m_aSounds.size(); ++i ) + { + const Sound &sound = m_aSounds[i]; + const RageSoundReader *pSound = m_apLoadedSounds[sound.iIndex]; + int iThisLength = pSound->GetLength(); + if( iThisLength ) + iLength = max( iLength, iThisLength + sound.iOffsetMS ); + } + return iLength; +} + +int RageSoundReader_Chain::GetLength_Fast() const +{ + int iLength = 0; + for( unsigned i = 0; i < m_aSounds.size(); ++i ) + { + const Sound &sound = m_aSounds[i]; + const RageSoundReader *pSound = m_apLoadedSounds[sound.iIndex]; + int iThisLength = pSound->GetLength_Fast(); + if( iThisLength ) + iLength = max( iLength, iThisLength + sound.iOffsetMS ); + } + return iLength; +} + + +/* + * Copyright (c) 2004-2006 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/RageSoundReader_Chain.h b/src/RageSoundReader_Chain.h index f70127681d..9cc402ea5c 100644 --- a/src/RageSoundReader_Chain.h +++ b/src/RageSoundReader_Chain.h @@ -57,7 +57,7 @@ private: int iIndex; // into m_apLoadedSounds int iOffsetMS; float fPan; - RageSoundReader *pSound; // NULL if not activated + RageSoundReader *pSound; // nullptr if not activated int GetOffsetFrame( int iSampleRate ) const { return int( int64_t(iOffsetMS) * iSampleRate / 1000 ); } bool operator<( const Sound &rhs ) const { return iOffsetMS < rhs.iOffsetMS; } diff --git a/src/RageSoundReader_ChannelSplit.cpp b/src/RageSoundReader_ChannelSplit.cpp index e00f2ece65..09b8f37d9d 100644 --- a/src/RageSoundReader_ChannelSplit.cpp +++ b/src/RageSoundReader_ChannelSplit.cpp @@ -38,7 +38,6 @@ #include "RageUtil.h" #include "RageSoundMixBuffer.h" #include "RageSoundUtil.h" -#include "Foreach.h" #include #include @@ -185,10 +184,10 @@ int RageSoundSplitterImpl::ReadBuffer() /* Discard any bytes that are no longer requested by any sound. */ int iMinFrameRequested = INT_MAX; int iMaxFrameRequested = INT_MIN; - FOREACHS( RageSoundReader_Split *, m_apSounds, snd ) + for (RageSoundReader_Split *snd : m_apSounds) { - iMinFrameRequested = min( iMinFrameRequested, (*snd)->m_iPositionFrame ); - iMaxFrameRequested = max( iMaxFrameRequested, (*snd)->m_iPositionFrame + (*snd)->m_iRequestFrames ); + iMinFrameRequested = min( iMinFrameRequested, snd->m_iPositionFrame ); + iMaxFrameRequested = max( iMaxFrameRequested, snd->m_iPositionFrame + snd->m_iRequestFrames ); } if( iMinFrameRequested > m_iBufferPositionFrames ) diff --git a/src/RageSoundReader_Extend.cpp b/src/RageSoundReader_Extend.cpp index c5e5e87f1c..fb04eff1fc 100644 --- a/src/RageSoundReader_Extend.cpp +++ b/src/RageSoundReader_Extend.cpp @@ -1,225 +1,225 @@ -#include "global.h" -#include "RageSoundReader_Extend.h" -#include "RageLog.h" -#include "RageSoundUtil.h" -#include "RageUtil.h" - -/* - * Add support for negative seeks (adding a delay), extending a sound - * beyond its end (m_LengthSeconds and M_CONTINUE), looping and fading. - * This filter is normally inserted before extended buffering, implementing - * properties that can seek the sound; this results in buffered seeks, but - * changes to these properties are delayed. - */ - -RageSoundReader_Extend::RageSoundReader_Extend( RageSoundReader *pSource ): - RageSoundReader_Filter( pSource ) -{ - ASSERT_M(pSource != NULL, "The music file was not found! Was it deleted or moved while the game was on?"); - m_iPositionFrames = pSource->GetNextSourceFrame(); - - m_StopMode = M_STOP; - m_iStartFrames = 0; - m_iLengthFrames = -1; - m_iFadeOutFrames = 0; - m_iFadeInFrames = 0; - m_bIgnoreFadeInFrames = false; -} - -int RageSoundReader_Extend::SetPosition( int iFrame ) -{ - m_bIgnoreFadeInFrames = false; - - m_iPositionFrames = iFrame; - int iRet = m_pSource->SetPosition( max(iFrame, 0) ); - if( iRet < 0 ) - return iRet; - - if( m_iLengthFrames != -1 ) - return m_iPositionFrames < GetEndFrame(); - - /* If we're in CONTINUE and we seek past the end of the file, don't return EOF. */ - if( m_StopMode == M_CONTINUE ) - return 1; - - return iRet; -} - -int RageSoundReader_Extend::GetEndFrame() const -{ - if( m_iLengthFrames == -1 ) - return -1; - - return m_iStartFrames + m_iLengthFrames; -} - -int RageSoundReader_Extend::GetData( float *pBuffer, int iFrames ) -{ - int iFramesToRead = iFrames; - if( m_iLengthFrames != -1 ) - { - int iFramesLeft = GetEndFrame() - m_iPositionFrames; - iFramesLeft = max( 0, iFramesLeft ); - iFramesToRead = min( iFramesToRead, iFramesLeft ); - } - - if( iFrames && !iFramesToRead ) - return RageSoundReader::END_OF_FILE; - - if( m_iPositionFrames < 0 ) - { - iFramesToRead = min( iFramesToRead, -m_iPositionFrames ); - memset( pBuffer, 0, iFramesToRead * sizeof(float) * this->GetNumChannels() ); - return iFramesToRead; - } - - int iNewPositionFrames = m_pSource->GetNextSourceFrame(); - int iRet = RageSoundReader_Filter::Read( pBuffer, iFramesToRead ); - - /* Update the position from the source. If the source is at EOF, skip this, - * so we'll extrapolate in M_CONTINUE. */ - if( iRet != RageSoundReader::END_OF_FILE ) - m_iPositionFrames = iNewPositionFrames; - return iRet; -} - -int RageSoundReader_Extend::Read( float *pBuffer, int iFrames ) -{ - int iFramesRead = GetData( pBuffer, iFrames ); - if( iFramesRead == RageSoundReader::END_OF_FILE ) - { - if( (m_iLengthFrames != -1 && m_iPositionFrames < GetEndFrame()) || - m_StopMode == M_CONTINUE ) - { - iFramesRead = iFrames; - if( m_StopMode != M_CONTINUE ) - iFramesRead = min( GetEndFrame() - m_iPositionFrames, iFramesRead ); - memset( pBuffer, 0, iFramesRead * sizeof(float) * this->GetNumChannels() ); - } - } - - if( iFramesRead > 0 ) - { - int iFullVolumePositionFrames = 0; - int iSilencePositionFrames = 0; - if( m_iFadeInFrames != 0 && !m_bIgnoreFadeInFrames ) - { - iSilencePositionFrames = 0; - iFullVolumePositionFrames = m_iFadeInFrames; - } - - /* We want to fade when there's m_iFadeFrames frames left, but if - * m_LengthFrames is -1, we don't know the length we're playing. - * (m_LengthFrames is the length to play, not the length of the - * source.) If we don't know the length, don't fade. */ - if( m_iFadeOutFrames != 0 && m_iLengthFrames != -1 ) - { - iSilencePositionFrames = GetEndFrame(); - iFullVolumePositionFrames = iSilencePositionFrames - m_iFadeOutFrames; - } - - if( iSilencePositionFrames != iFullVolumePositionFrames ) - { - const int iStartSecond = m_iPositionFrames; - const int iEndSecond = m_iPositionFrames + iFramesRead; - const float fStartVolume = SCALE( iStartSecond, iFullVolumePositionFrames, iSilencePositionFrames, 1.0f, 0.0f ); - const float fEndVolume = SCALE( iEndSecond, iFullVolumePositionFrames, iSilencePositionFrames, 1.0f, 0.0f ); - RageSoundUtil::Fade( pBuffer, iFramesRead, this->GetNumChannels(), fStartVolume, fEndVolume ); - } - - m_iPositionFrames += iFramesRead; - } - - if( iFramesRead == RageSoundReader::END_OF_FILE && m_StopMode == M_LOOP ) - { - this->SetPosition( m_iStartFrames ); - - /* If we're not fading out at the end, then only fade in once. Ignore - * m_iFadeInFrames until seeked, so we only fade in once. */ - if( m_iFadeOutFrames == 0 ) - m_bIgnoreFadeInFrames = true; - return STREAM_LOOPED; - } - - return iFramesRead; -} - -int RageSoundReader_Extend::GetNextSourceFrame() const -{ - return m_iPositionFrames; -} - -bool RageSoundReader_Extend::SetProperty( const RString &sProperty, float fValue ) -{ - if( sProperty == "StartSecond" ) - { - m_iStartFrames = lrintf( fValue * this->GetSampleRate() ); - return true; - } - - if( sProperty == "LengthSeconds" ) - { - if( fValue == -1 ) - m_iLengthFrames = -1; - else - m_iLengthFrames = lrintf( fValue * this->GetSampleRate() ); - return true; - } - - if( sProperty == "Loop" ) - { - m_StopMode = M_LOOP; - return true; - } - - if( sProperty == "Stop" ) - { - m_StopMode = M_STOP; - return true; - } - - if( sProperty == "Continue" ) - { - m_StopMode = M_CONTINUE; - return true; - } - - if( sProperty == "FadeInSeconds" ) - { - m_iFadeInFrames = lrintf( fValue * this->GetSampleRate() ); - return true; - } - - if( sProperty == "FadeSeconds" || sProperty == "FadeOutSeconds" ) - { - m_iFadeOutFrames = lrintf( fValue * this->GetSampleRate() ); - return true; - } - - return false; -} - -/* - * Copyright (c) 2003-2006 Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "RageSoundReader_Extend.h" +#include "RageLog.h" +#include "RageSoundUtil.h" +#include "RageUtil.h" + +/* + * Add support for negative seeks (adding a delay), extending a sound + * beyond its end (m_LengthSeconds and M_CONTINUE), looping and fading. + * This filter is normally inserted before extended buffering, implementing + * properties that can seek the sound; this results in buffered seeks, but + * changes to these properties are delayed. + */ + +RageSoundReader_Extend::RageSoundReader_Extend( RageSoundReader *pSource ): + RageSoundReader_Filter( pSource ) +{ + ASSERT_M(pSource != nullptr, "The music file was not found! Was it deleted or moved while the game was on?"); + m_iPositionFrames = pSource->GetNextSourceFrame(); + + m_StopMode = M_STOP; + m_iStartFrames = 0; + m_iLengthFrames = -1; + m_iFadeOutFrames = 0; + m_iFadeInFrames = 0; + m_bIgnoreFadeInFrames = false; +} + +int RageSoundReader_Extend::SetPosition( int iFrame ) +{ + m_bIgnoreFadeInFrames = false; + + m_iPositionFrames = iFrame; + int iRet = m_pSource->SetPosition( max(iFrame, 0) ); + if( iRet < 0 ) + return iRet; + + if( m_iLengthFrames != -1 ) + return m_iPositionFrames < GetEndFrame(); + + /* If we're in CONTINUE and we seek past the end of the file, don't return EOF. */ + if( m_StopMode == M_CONTINUE ) + return 1; + + return iRet; +} + +int RageSoundReader_Extend::GetEndFrame() const +{ + if( m_iLengthFrames == -1 ) + return -1; + + return m_iStartFrames + m_iLengthFrames; +} + +int RageSoundReader_Extend::GetData( float *pBuffer, int iFrames ) +{ + int iFramesToRead = iFrames; + if( m_iLengthFrames != -1 ) + { + int iFramesLeft = GetEndFrame() - m_iPositionFrames; + iFramesLeft = max( 0, iFramesLeft ); + iFramesToRead = min( iFramesToRead, iFramesLeft ); + } + + if( iFrames && !iFramesToRead ) + return RageSoundReader::END_OF_FILE; + + if( m_iPositionFrames < 0 ) + { + iFramesToRead = min( iFramesToRead, -m_iPositionFrames ); + memset( pBuffer, 0, iFramesToRead * sizeof(float) * this->GetNumChannels() ); + return iFramesToRead; + } + + int iNewPositionFrames = m_pSource->GetNextSourceFrame(); + int iRet = RageSoundReader_Filter::Read( pBuffer, iFramesToRead ); + + /* Update the position from the source. If the source is at EOF, skip this, + * so we'll extrapolate in M_CONTINUE. */ + if( iRet != RageSoundReader::END_OF_FILE ) + m_iPositionFrames = iNewPositionFrames; + return iRet; +} + +int RageSoundReader_Extend::Read( float *pBuffer, int iFrames ) +{ + int iFramesRead = GetData( pBuffer, iFrames ); + if( iFramesRead == RageSoundReader::END_OF_FILE ) + { + if( (m_iLengthFrames != -1 && m_iPositionFrames < GetEndFrame()) || + m_StopMode == M_CONTINUE ) + { + iFramesRead = iFrames; + if( m_StopMode != M_CONTINUE ) + iFramesRead = min( GetEndFrame() - m_iPositionFrames, iFramesRead ); + memset( pBuffer, 0, iFramesRead * sizeof(float) * this->GetNumChannels() ); + } + } + + if( iFramesRead > 0 ) + { + int iFullVolumePositionFrames = 0; + int iSilencePositionFrames = 0; + if( m_iFadeInFrames != 0 && !m_bIgnoreFadeInFrames ) + { + iSilencePositionFrames = 0; + iFullVolumePositionFrames = m_iFadeInFrames; + } + + /* We want to fade when there's m_iFadeFrames frames left, but if + * m_LengthFrames is -1, we don't know the length we're playing. + * (m_LengthFrames is the length to play, not the length of the + * source.) If we don't know the length, don't fade. */ + if( m_iFadeOutFrames != 0 && m_iLengthFrames != -1 ) + { + iSilencePositionFrames = GetEndFrame(); + iFullVolumePositionFrames = iSilencePositionFrames - m_iFadeOutFrames; + } + + if( iSilencePositionFrames != iFullVolumePositionFrames ) + { + const int iStartSecond = m_iPositionFrames; + const int iEndSecond = m_iPositionFrames + iFramesRead; + const float fStartVolume = SCALE( iStartSecond, iFullVolumePositionFrames, iSilencePositionFrames, 1.0f, 0.0f ); + const float fEndVolume = SCALE( iEndSecond, iFullVolumePositionFrames, iSilencePositionFrames, 1.0f, 0.0f ); + RageSoundUtil::Fade( pBuffer, iFramesRead, this->GetNumChannels(), fStartVolume, fEndVolume ); + } + + m_iPositionFrames += iFramesRead; + } + + if( iFramesRead == RageSoundReader::END_OF_FILE && m_StopMode == M_LOOP ) + { + this->SetPosition( m_iStartFrames ); + + /* If we're not fading out at the end, then only fade in once. Ignore + * m_iFadeInFrames until seeked, so we only fade in once. */ + if( m_iFadeOutFrames == 0 ) + m_bIgnoreFadeInFrames = true; + return STREAM_LOOPED; + } + + return iFramesRead; +} + +int RageSoundReader_Extend::GetNextSourceFrame() const +{ + return m_iPositionFrames; +} + +bool RageSoundReader_Extend::SetProperty( const RString &sProperty, float fValue ) +{ + if( sProperty == "StartSecond" ) + { + m_iStartFrames = lrintf( fValue * this->GetSampleRate() ); + return true; + } + + if( sProperty == "LengthSeconds" ) + { + if( fValue == -1 ) + m_iLengthFrames = -1; + else + m_iLengthFrames = lrintf( fValue * this->GetSampleRate() ); + return true; + } + + if( sProperty == "Loop" ) + { + m_StopMode = M_LOOP; + return true; + } + + if( sProperty == "Stop" ) + { + m_StopMode = M_STOP; + return true; + } + + if( sProperty == "Continue" ) + { + m_StopMode = M_CONTINUE; + return true; + } + + if( sProperty == "FadeInSeconds" ) + { + m_iFadeInFrames = lrintf( fValue * this->GetSampleRate() ); + return true; + } + + if( sProperty == "FadeSeconds" || sProperty == "FadeOutSeconds" ) + { + m_iFadeOutFrames = lrintf( fValue * this->GetSampleRate() ); + return true; + } + + return false; +} + +/* + * Copyright (c) 2003-2006 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/RageSoundReader_FileReader.cpp b/src/RageSoundReader_FileReader.cpp index 53afb856e5..37cffeb487 100644 --- a/src/RageSoundReader_FileReader.cpp +++ b/src/RageSoundReader_FileReader.cpp @@ -20,7 +20,7 @@ RageSoundReader_FileReader *RageSoundReader_FileReader::TryOpenFile( RageFileBasic *pFile, RString &error, RString format, bool &bKeepTrying ) { - RageSoundReader_FileReader *Sample = NULL; + RageSoundReader_FileReader *Sample = nullptr; #if defined(HAS_WAV) if( !format.CompareNoCase("wav") ) @@ -38,10 +38,10 @@ RageSoundReader_FileReader *RageSoundReader_FileReader::TryOpenFile( RageFileBas #endif if( !Sample ) - return NULL; + return nullptr; OpenResult ret = Sample->Open( pFile ); - pFile = NULL; // Sample owns it now + pFile = nullptr; // Sample owns it now if( ret == OPEN_OK ) return Sample; @@ -84,7 +84,7 @@ RageSoundReader_FileReader *RageSoundReader_FileReader::TryOpenFile( RageFileBas default: break; } - return NULL; + return nullptr; } #include "RageFileDriverMemory.h" @@ -98,7 +98,7 @@ RageSoundReader_FileReader *RageSoundReader_FileReader::OpenFile( RString filena { error = pFileOpen->GetError(); delete pFileOpen; - return NULL; + return nullptr; } pFile = pFileOpen; } @@ -108,11 +108,11 @@ RageSoundReader_FileReader *RageSoundReader_FileReader::OpenFile( RString filena if( pFile->GetFileSize() < 1024*50 ) { RageFileObjMem *pMem = new RageFileObjMem; - bool bRet = FileCopy( *pFile, *pMem, error, NULL ); + bool bRet = FileCopy( *pFile, *pMem, error, nullptr ); if( !bRet ) { delete pMem; - return NULL; + return nullptr; } pFile = pMem; @@ -158,7 +158,7 @@ RageSoundReader_FileReader *RageSoundReader_FileReader::OpenFile( RString filena } } - return NULL; + return nullptr; } /* diff --git a/src/RageSoundReader_FileReader.h b/src/RageSoundReader_FileReader.h index 7184939a33..c229bb46f3 100644 --- a/src/RageSoundReader_FileReader.h +++ b/src/RageSoundReader_FileReader.h @@ -31,10 +31,10 @@ public: virtual float GetStreamToSourceRatio() const { return 1.0f; } virtual RString GetError() const { return m_sError; } - /* Open a file. If pPrebuffer is non-NULL, and the file is sufficiently small, + /* Open a file. If pPrebuffer is non-nullptr, and the file is sufficiently small, * the (possibly compressed) data will be loaded entirely into memory, and pPrebuffer * will be set to true. */ - static RageSoundReader_FileReader *OpenFile( RString filename, RString &error, bool *pPrebuffer = NULL ); + static RageSoundReader_FileReader *OpenFile( RString filename, RString &error, bool *pPrebuffer = nullptr ); protected: void SetError( RString sError ) const { m_sError = sError; } diff --git a/src/RageSoundReader_MP3.cpp b/src/RageSoundReader_MP3.cpp index b5ac5eb04c..8d254ed223 100644 --- a/src/RageSoundReader_MP3.cpp +++ b/src/RageSoundReader_MP3.cpp @@ -263,7 +263,7 @@ static int get_this_frame_byte( const madlib_t *mad ) int ret = mad->inbuf_filepos; /* If we have a frame, adjust. */ - if( mad->Stream.this_frame != NULL ) + if( mad->Stream.this_frame != nullptr ) ret += mad->Stream.this_frame-mad->inbuf; return ret; @@ -324,7 +324,7 @@ int RageSoundReader_MP3::fill_buffer() { /* Need more data. */ int inbytes = 0; - if( mad->Stream.next_frame != NULL ) + if( mad->Stream.next_frame != nullptr ) { /* Pull out remaining data from the last buffer. */ inbytes = mad->Stream.bufend-mad->Stream.next_frame; @@ -738,7 +738,7 @@ bool RageSoundReader_MP3::MADLIB_rewind() mad_stream_finish(&mad->Stream); mad_stream_init(&mad->Stream); - mad_stream_buffer(&mad->Stream, NULL, 0); + mad_stream_buffer(&mad->Stream, nullptr, 0); mad->inbuf_filepos = 0; /* Be careful. We need to leave header_bytes alone, so if we try to SetPosition_estimate @@ -747,7 +747,7 @@ bool RageSoundReader_MP3::MADLIB_rewind() * set it, then we'll be desynced by a frame after an accurate seek. */ // mad->header_bytes = 0; mad->first_frame = true; - mad->Stream.this_frame = NULL; + mad->Stream.this_frame = nullptr; return true; } diff --git a/src/RageSoundReader_Merge.cpp b/src/RageSoundReader_Merge.cpp index f00e1e4600..50c8b9ef9f 100644 --- a/src/RageSoundReader_Merge.cpp +++ b/src/RageSoundReader_Merge.cpp @@ -1,331 +1,330 @@ -#include "global.h" -#include "RageSoundReader_Merge.h" -#include "RageSoundReader_Resample_Good.h" -#include "RageSoundReader_Pan.h" -#include "RageLog.h" -#include "RageUtil.h" -#include "RageSoundMixBuffer.h" -#include "RageSoundUtil.h" -#include "Foreach.h" - -RageSoundReader_Merge::RageSoundReader_Merge() -{ - m_iSampleRate = -1; - m_iChannels = 0; - m_iNextSourceFrame = 0; - m_fCurrentStreamToSourceRatio = 1.0f; -} - -RageSoundReader_Merge::~RageSoundReader_Merge() -{ - FOREACH( RageSoundReader *, m_aSounds, it ) - delete *it; -} - -RageSoundReader_Merge::RageSoundReader_Merge( const RageSoundReader_Merge &cpy ): - RageSoundReader(cpy) -{ - m_iSampleRate = cpy.m_iSampleRate; - m_iChannels = cpy.m_iChannels; - m_iNextSourceFrame = cpy.m_iNextSourceFrame; - m_fCurrentStreamToSourceRatio = cpy.m_fCurrentStreamToSourceRatio; - - FOREACH_CONST( RageSoundReader *, cpy.m_aSounds, it ) - m_aSounds.push_back( (*it)->Copy() ); -} - -void RageSoundReader_Merge::AddSound( RageSoundReader *pSound ) -{ - m_aSounds.push_back( pSound ); -} - -/* If every sound has the same sample rate, return it. Otherwise, return -1. */ -int RageSoundReader_Merge::GetSampleRateInternal() const -{ - int iRate = -1; - FOREACH_CONST( RageSoundReader *, m_aSounds, it ) - { - if( iRate == -1 ) - iRate = (*it)->GetSampleRate(); - else if( iRate != (*it)->GetSampleRate() ) - return -1; - } - return iRate; -} - -void RageSoundReader_Merge::Finish( int iPreferredSampleRate ) -{ - /* Figure out how many channels we have. All sounds must either have 1 or 2 channels, - * which will be converted as needed, or have the same number of channels. */ - m_iChannels = 1; - FOREACH( RageSoundReader *, m_aSounds, it ) - m_iChannels = max( m_iChannels, (*it)->GetNumChannels() ); - - /* - * We might get different sample rates from our sources. If they're all the same - * sample rate, just leave it alone, so the whole sound can be resampled as a group. - * If not, resample eveything to the preferred rate. (Using the preferred rate - * should avoid redundant resampling later.) - */ - m_iSampleRate = GetSampleRateInternal(); - if( m_iSampleRate == -1 ) - { - FOREACH( RageSoundReader *, m_aSounds, it ) - { - RageSoundReader *&pSound = (*it); - - RageSoundReader_Resample_Good *pResample = new RageSoundReader_Resample_Good( pSound, iPreferredSampleRate ); - pSound = pResample; - } - - m_iSampleRate = iPreferredSampleRate; - } - - /* If we have two channels, and any sounds have only one, convert them by adding a Pan filter. */ - FOREACH( RageSoundReader *, m_aSounds, it ) - { - if( (*it)->GetNumChannels() != this->GetNumChannels() ) - (*it) = new RageSoundReader_Pan( (*it) ); - } - - /* If we have more than two channels, then all sounds must have the same number of - * channels. */ - if( m_iChannels > 2 ) - { - vector aSounds; - FOREACH( RageSoundReader *, m_aSounds, it ) - { - if( (*it)->GetNumChannels() != m_iChannels ) - { - LOG->Warn( "Discarded sound with %i channels, not %i", - (*it)->GetNumChannels(), m_iChannels ); - delete (*it); - (*it) = NULL; - } - else - { - aSounds.push_back( *it ); - } - } - m_aSounds = aSounds; - } -} - -int RageSoundReader_Merge::SetPosition( int iFrame ) -{ - m_iNextSourceFrame = iFrame; - - int iRet = 0; - for( int i = 0; i < (int) m_aSounds.size(); ++i ) - { - RageSoundReader *pSound = m_aSounds[i]; - int iThisRet = pSound->SetPosition( iFrame ); - if( iThisRet == -1 ) - return -1; - if( iThisRet > 0 ) - iRet = 1; - } - - return iRet; -} - -bool RageSoundReader_Merge::SetProperty( const RString &sProperty, float fValue ) -{ - bool bRet = false; - for( unsigned i = 0; i < m_aSounds.size(); ++i ) - { - if( m_aSounds[i]->SetProperty(sProperty, fValue) ) - bRet = true; - } - - return bRet; -} - -static float Difference( float a, float b ) { return fabsf( a - b ); } -static int Difference( int a, int b ) { return abs( a - b ); } - -/* - * If the audio position drifts apart further than ERROR_CORRECTION_THRESHOLD frames, - * attempt to resync it. - * - * Frames are expressed as whole numbers, and the ratio between source and stream frames - * is floating point. We can't read a specific number of source frames, only stream - * frames. If a stream is early by 15 source frames, we'll convert that to stream - * frames for reading; this rounds back to an integer, so it isn't exact. (The amount - * of error should be no more than the ratio; if we have a ratio of 10, then reading - * 10 stream frames should advance the stream by 100-110 frames. The ratio is normally - * less than 5.) - * - * ERROR_CORRECTION_THRESHOLD should be greater than the maximum rate in use, so we - * can always resync the stream back to within the tolerance of the threshold. - * - * In the pathological case, if this is too low we may never resync properly, each - * attempt to resync leapfrogging past the previous. - */ - -static const int ERROR_CORRECTION_THRESHOLD = 16; - -/* As we iterate through the sound tree, we'll find that we need data from different - * sounds; a sound may be needed by more than one other sound. */ -int RageSoundReader_Merge::Read( float *pBuffer, int iFrames ) -{ - if( m_aSounds.empty() ) - return END_OF_FILE; - - /* - * All sounds which are active should stay aligned; each GetNextSourceFrame should not - * come out of sync. Accomodate small rounding errors. A larger inconsistency - * happens may be a bug, such as sounds at different speeds. - */ - - vector aNextSourceFrames; - vector aRatios; - aNextSourceFrames.resize( m_aSounds.size() ); - aRatios.resize( m_aSounds.size() ); - for( unsigned i = 0; i < m_aSounds.size(); ++i ) - { - aNextSourceFrames[i] = m_aSounds[i]->GetNextSourceFrame(); - aRatios[i] = m_aSounds[i]->GetStreamToSourceRatio(); - } - - { - /* GetNextSourceFrame for each active sound should be the same. If any differ, - * delay the later sounds until the earlier ones catch back up to put them - * back in sync. */ - int iEarliestSound = distance( aNextSourceFrames.begin(), min_element( aNextSourceFrames.begin(), aNextSourceFrames.end() ) ); - - /* Normally, m_iNextSourceFrame should already be aligned with the GetNextSourceFrame of our - * sounds. If it's not, adjust it and return. */ - if( m_iNextSourceFrame != aNextSourceFrames[iEarliestSound] || - m_fCurrentStreamToSourceRatio != aRatios[iEarliestSound] ) - { - m_iNextSourceFrame = aNextSourceFrames[iEarliestSound]; - m_fCurrentStreamToSourceRatio = aRatios[iEarliestSound]; - return 0; - } - - int iMinPosition = aNextSourceFrames[iEarliestSound]; - for( unsigned i = 0; i < m_aSounds.size(); ++i ) - { - if( Difference(aNextSourceFrames[i], iMinPosition) <= ERROR_CORRECTION_THRESHOLD ) - continue; - - /* A sound is being delayed to resync it; clamp the number of frames we - * read now, so we don't advance past it. */ - int iMaxSourceFramesToRead = aNextSourceFrames[i] - iMinPosition; - int iMaxStreamFramesToRead = lrintf( iMaxSourceFramesToRead / m_fCurrentStreamToSourceRatio ); - iFrames = min( iFrames, iMaxStreamFramesToRead ); -// LOG->Warn( "RageSoundReader_Merge: sound positions moving at different rates" ); - } - } - - if( m_aSounds.size() == 1 ) - { - /* We have only one source; read directly into the buffer. */ - RageSoundReader *pSound = m_aSounds.front(); - iFrames = pSound->Read( pBuffer, iFrames ); - if( iFrames > 0 ) - m_iNextSourceFrame += lrintf( iFrames * m_fCurrentStreamToSourceRatio ); - aNextSourceFrames.front() = pSound->GetNextSourceFrame(); - aRatios.front() = pSound->GetStreamToSourceRatio(); - return iFrames; - } - - RageSoundMixBuffer mix; - float Buffer[2048]; - iFrames = min( iFrames, (int) (ARRAYLEN(Buffer) / m_iChannels) ); - - /* Read iFrames from each sound. */ - for( unsigned i = 0; i < m_aSounds.size(); ++i ) - { - RageSoundReader *pSound = m_aSounds[i]; - ASSERT( pSound->GetNumChannels() == m_iChannels ); - - int iFramesRead = 0; - while( iFramesRead < iFrames ) - { -// if( i == 0 ) -//LOG->Trace( "*** %i", Difference(aNextSourceFrames[i], m_iNextSourceFrame + lrintf(iFramesRead * aRatios[i])) ); - - if( Difference(aNextSourceFrames[i], m_iNextSourceFrame + lrintf(iFramesRead * aRatios[i])) > ERROR_CORRECTION_THRESHOLD ) - { - LOG->Trace( "*** hurk %i", Difference(aNextSourceFrames[i], m_iNextSourceFrame + lrintf(iFramesRead * aRatios[i])) ); - break; - } - - int iGotFrames = pSound->Read( Buffer, iFrames - iFramesRead ); - if( 0 && /*i == 1 && */iGotFrames > 0 ) - { - int iAt = aNextSourceFrames[i] + lrintf(iGotFrames * aRatios[i]); - if( iAt != m_aSounds[i]->GetNextSourceFrame() ) - LOG->Trace( "%i: at %i, expected %i", - i, iAt, m_aSounds[i]->GetNextSourceFrame() ); - } - aNextSourceFrames[i] = m_aSounds[i]->GetNextSourceFrame(); - aRatios[i] = m_aSounds[i]->GetStreamToSourceRatio(); -// LOG->Trace( "read %i from %i; %i -> %i", iGotFrames, i, oldf, aNextSourceFrames[i] ); - if( iGotFrames < 0 ) - { - if( i == 0 ) - return iGotFrames; - break; - } - - mix.SetWriteOffset( iFramesRead * pSound->GetNumChannels() ); - mix.write( Buffer, iGotFrames * pSound->GetNumChannels() ); - iFramesRead += iGotFrames; - - if( Difference(aRatios[i], m_fCurrentStreamToSourceRatio) > 0.001f ) - break; - } - } - - /* Read mixed frames into the output buffer. */ - int iMaxFramesRead = mix.size() / m_iChannels; - mix.read( pBuffer ); - - m_iNextSourceFrame += lrintf( iMaxFramesRead * m_fCurrentStreamToSourceRatio ); - - return iMaxFramesRead; -} - -int RageSoundReader_Merge::GetLength() const -{ - int iLength = 0; - for( unsigned i = 0; i < m_aSounds.size(); ++i ) - iLength = max( iLength, m_aSounds[i]->GetLength() ); - return iLength; -} - -int RageSoundReader_Merge::GetLength_Fast() const -{ - int iLength = 0; - for( unsigned i = 0; i < m_aSounds.size(); ++i ) - iLength = max( iLength, m_aSounds[i]->GetLength_Fast() ); - return iLength; -} - -/* - * Copyright (c) 2004-2006 Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "RageSoundReader_Merge.h" +#include "RageSoundReader_Resample_Good.h" +#include "RageSoundReader_Pan.h" +#include "RageLog.h" +#include "RageUtil.h" +#include "RageSoundMixBuffer.h" +#include "RageSoundUtil.h" + + +RageSoundReader_Merge::RageSoundReader_Merge() +{ + m_iSampleRate = -1; + m_iChannels = 0; + m_iNextSourceFrame = 0; + m_fCurrentStreamToSourceRatio = 1.0f; +} + +RageSoundReader_Merge::~RageSoundReader_Merge() +{ + for (RageSoundReader *it : m_aSounds) + delete it; +} + +RageSoundReader_Merge::RageSoundReader_Merge( const RageSoundReader_Merge &cpy ): + RageSoundReader(cpy) +{ + m_iSampleRate = cpy.m_iSampleRate; + m_iChannels = cpy.m_iChannels; + m_iNextSourceFrame = cpy.m_iNextSourceFrame; + m_fCurrentStreamToSourceRatio = cpy.m_fCurrentStreamToSourceRatio; + + for (RageSoundReader const *it : cpy.m_aSounds) + m_aSounds.push_back( it->Copy() ); +} + +void RageSoundReader_Merge::AddSound( RageSoundReader *pSound ) +{ + m_aSounds.push_back( pSound ); +} + +/* If every sound has the same sample rate, return it. Otherwise, return -1. */ +int RageSoundReader_Merge::GetSampleRateInternal() const +{ + // TODO: Convert to a set and compare values? + int iRate = -1; + for (RageSoundReader const *it : m_aSounds) + { + if( iRate == -1 ) + iRate = it->GetSampleRate(); + else if( iRate != it->GetSampleRate() ) + return -1; + } + return iRate; +} + +void RageSoundReader_Merge::Finish( int iPreferredSampleRate ) +{ + /* Figure out how many channels we have. All sounds must either have 1 or 2 channels, + * which will be converted as needed, or have the same number of channels. */ + m_iChannels = 1; + for (RageSoundReader *it : m_aSounds) + m_iChannels = max( m_iChannels, it->GetNumChannels() ); + + /* + * We might get different sample rates from our sources. If they're all the same + * sample rate, just leave it alone, so the whole sound can be resampled as a group. + * If not, resample eveything to the preferred rate. (Using the preferred rate + * should avoid redundant resampling later.) + */ + m_iSampleRate = GetSampleRateInternal(); + if( m_iSampleRate == -1 ) + { + for (RageSoundReader *it : m_aSounds) + { + RageSoundReader_Resample_Good *pResample = new RageSoundReader_Resample_Good( it, iPreferredSampleRate ); + it = pResample; + } + + m_iSampleRate = iPreferredSampleRate; + } + + /* If we have two channels, and any sounds have only one, convert them by adding a Pan filter. */ + for (RageSoundReader *it : m_aSounds) + { + if( it->GetNumChannels() != this->GetNumChannels() ) + it = new RageSoundReader_Pan( it ); + } + + /* If we have more than two channels, then all sounds must have the same number of + * channels. */ + if( m_iChannels > 2 ) + { + vector aSounds; + for (RageSoundReader *it : m_aSounds) + { + if( it->GetNumChannels() != m_iChannels ) + { + LOG->Warn( "Discarded sound with %i channels, not %i", + it->GetNumChannels(), m_iChannels ); + delete it; + it = nullptr; + } + else + { + aSounds.push_back( it ); + } + } + m_aSounds = aSounds; + } +} + +int RageSoundReader_Merge::SetPosition( int iFrame ) +{ + m_iNextSourceFrame = iFrame; + + int iRet = 0; + for( int i = 0; i < (int) m_aSounds.size(); ++i ) + { + RageSoundReader *pSound = m_aSounds[i]; + int iThisRet = pSound->SetPosition( iFrame ); + if( iThisRet == -1 ) + return -1; + if( iThisRet > 0 ) + iRet = 1; + } + + return iRet; +} + +bool RageSoundReader_Merge::SetProperty( const RString &sProperty, float fValue ) +{ + bool bRet = false; + for( unsigned i = 0; i < m_aSounds.size(); ++i ) + { + if( m_aSounds[i]->SetProperty(sProperty, fValue) ) + bRet = true; + } + + return bRet; +} + +static float Difference( float a, float b ) { return fabsf( a - b ); } +static int Difference( int a, int b ) { return abs( a - b ); } + +/* + * If the audio position drifts apart further than ERROR_CORRECTION_THRESHOLD frames, + * attempt to resync it. + * + * Frames are expressed as whole numbers, and the ratio between source and stream frames + * is floating point. We can't read a specific number of source frames, only stream + * frames. If a stream is early by 15 source frames, we'll convert that to stream + * frames for reading; this rounds back to an integer, so it isn't exact. (The amount + * of error should be no more than the ratio; if we have a ratio of 10, then reading + * 10 stream frames should advance the stream by 100-110 frames. The ratio is normally + * less than 5.) + * + * ERROR_CORRECTION_THRESHOLD should be greater than the maximum rate in use, so we + * can always resync the stream back to within the tolerance of the threshold. + * + * In the pathological case, if this is too low we may never resync properly, each + * attempt to resync leapfrogging past the previous. + */ + +static const int ERROR_CORRECTION_THRESHOLD = 16; + +/* As we iterate through the sound tree, we'll find that we need data from different + * sounds; a sound may be needed by more than one other sound. */ +int RageSoundReader_Merge::Read( float *pBuffer, int iFrames ) +{ + if( m_aSounds.empty() ) + return END_OF_FILE; + + /* + * All sounds which are active should stay aligned; each GetNextSourceFrame should not + * come out of sync. Accomodate small rounding errors. A larger inconsistency + * happens may be a bug, such as sounds at different speeds. + */ + + vector aNextSourceFrames; + vector aRatios; + aNextSourceFrames.resize( m_aSounds.size() ); + aRatios.resize( m_aSounds.size() ); + for( unsigned i = 0; i < m_aSounds.size(); ++i ) + { + aNextSourceFrames[i] = m_aSounds[i]->GetNextSourceFrame(); + aRatios[i] = m_aSounds[i]->GetStreamToSourceRatio(); + } + + { + /* GetNextSourceFrame for each active sound should be the same. If any differ, + * delay the later sounds until the earlier ones catch back up to put them + * back in sync. */ + int iEarliestSound = distance( aNextSourceFrames.begin(), min_element( aNextSourceFrames.begin(), aNextSourceFrames.end() ) ); + + /* Normally, m_iNextSourceFrame should already be aligned with the GetNextSourceFrame of our + * sounds. If it's not, adjust it and return. */ + if( m_iNextSourceFrame != aNextSourceFrames[iEarliestSound] || + m_fCurrentStreamToSourceRatio != aRatios[iEarliestSound] ) + { + m_iNextSourceFrame = aNextSourceFrames[iEarliestSound]; + m_fCurrentStreamToSourceRatio = aRatios[iEarliestSound]; + return 0; + } + + int iMinPosition = aNextSourceFrames[iEarliestSound]; + for( unsigned i = 0; i < m_aSounds.size(); ++i ) + { + if( Difference(aNextSourceFrames[i], iMinPosition) <= ERROR_CORRECTION_THRESHOLD ) + continue; + + /* A sound is being delayed to resync it; clamp the number of frames we + * read now, so we don't advance past it. */ + int iMaxSourceFramesToRead = aNextSourceFrames[i] - iMinPosition; + int iMaxStreamFramesToRead = lrintf( iMaxSourceFramesToRead / m_fCurrentStreamToSourceRatio ); + iFrames = min( iFrames, iMaxStreamFramesToRead ); +// LOG->Warn( "RageSoundReader_Merge: sound positions moving at different rates" ); + } + } + + if( m_aSounds.size() == 1 ) + { + /* We have only one source; read directly into the buffer. */ + RageSoundReader *pSound = m_aSounds.front(); + iFrames = pSound->Read( pBuffer, iFrames ); + if( iFrames > 0 ) + m_iNextSourceFrame += lrintf( iFrames * m_fCurrentStreamToSourceRatio ); + aNextSourceFrames.front() = pSound->GetNextSourceFrame(); + aRatios.front() = pSound->GetStreamToSourceRatio(); + return iFrames; + } + + RageSoundMixBuffer mix; + float Buffer[2048]; + iFrames = min( iFrames, (int) (ARRAYLEN(Buffer) / m_iChannels) ); + + /* Read iFrames from each sound. */ + for( unsigned i = 0; i < m_aSounds.size(); ++i ) + { + RageSoundReader *pSound = m_aSounds[i]; + ASSERT( pSound->GetNumChannels() == m_iChannels ); + + int iFramesRead = 0; + while( iFramesRead < iFrames ) + { +// if( i == 0 ) +//LOG->Trace( "*** %i", Difference(aNextSourceFrames[i], m_iNextSourceFrame + lrintf(iFramesRead * aRatios[i])) ); + + if( Difference(aNextSourceFrames[i], m_iNextSourceFrame + lrintf(iFramesRead * aRatios[i])) > ERROR_CORRECTION_THRESHOLD ) + { + LOG->Trace( "*** hurk %i", Difference(aNextSourceFrames[i], m_iNextSourceFrame + lrintf(iFramesRead * aRatios[i])) ); + break; + } + + int iGotFrames = pSound->Read( Buffer, iFrames - iFramesRead ); + if( 0 && /*i == 1 && */iGotFrames > 0 ) + { + int iAt = aNextSourceFrames[i] + lrintf(iGotFrames * aRatios[i]); + if( iAt != m_aSounds[i]->GetNextSourceFrame() ) + LOG->Trace( "%i: at %i, expected %i", + i, iAt, m_aSounds[i]->GetNextSourceFrame() ); + } + aNextSourceFrames[i] = m_aSounds[i]->GetNextSourceFrame(); + aRatios[i] = m_aSounds[i]->GetStreamToSourceRatio(); +// LOG->Trace( "read %i from %i; %i -> %i", iGotFrames, i, oldf, aNextSourceFrames[i] ); + if( iGotFrames < 0 ) + { + if( i == 0 ) + return iGotFrames; + break; + } + + mix.SetWriteOffset( iFramesRead * pSound->GetNumChannels() ); + mix.write( Buffer, iGotFrames * pSound->GetNumChannels() ); + iFramesRead += iGotFrames; + + if( Difference(aRatios[i], m_fCurrentStreamToSourceRatio) > 0.001f ) + break; + } + } + + /* Read mixed frames into the output buffer. */ + int iMaxFramesRead = mix.size() / m_iChannels; + mix.read( pBuffer ); + + m_iNextSourceFrame += lrintf( iMaxFramesRead * m_fCurrentStreamToSourceRatio ); + + return iMaxFramesRead; +} + +int RageSoundReader_Merge::GetLength() const +{ + int iLength = 0; + for( unsigned i = 0; i < m_aSounds.size(); ++i ) + iLength = max( iLength, m_aSounds[i]->GetLength() ); + return iLength; +} + +int RageSoundReader_Merge::GetLength_Fast() const +{ + int iLength = 0; + for( unsigned i = 0; i < m_aSounds.size(); ++i ) + iLength = max( iLength, m_aSounds[i]->GetLength_Fast() ); + return iLength; +} + +/* + * Copyright (c) 2004-2006 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/RageSoundReader_PitchChange.cpp b/src/RageSoundReader_PitchChange.cpp index 9d54e0e214..11d77fc286 100644 --- a/src/RageSoundReader_PitchChange.cpp +++ b/src/RageSoundReader_PitchChange.cpp @@ -1,124 +1,124 @@ -/* - * Implements properties: - * "Speed" - cause the sound to play faster or slower - * "Pitch" - raise or lower the pitch of the sound - * - * Pitch changing is implemented by combining speed changing and rate changing - * (via resampling). The resampler needs to be changed later than the speed - * changer; this class just controls parameters on the other two real filters. - */ - -#include "global.h" -#include "RageSoundReader_PitchChange.h" -#include "RageSoundReader_SpeedChange.h" -#include "RageSoundReader_Resample_Good.h" -#include "RageLog.h" - -RageSoundReader_PitchChange::RageSoundReader_PitchChange( RageSoundReader *pSource ): - RageSoundReader_Filter( NULL ) -{ - m_pSpeedChange = new RageSoundReader_SpeedChange( pSource ); - m_pResample = new RageSoundReader_Resample_Good( m_pSpeedChange, m_pSpeedChange->GetSampleRate() ); - m_pSource = m_pResample; - m_fSpeedRatio = 1.0f; - m_fPitchRatio = 1.0f; - m_fLastSetSpeedRatio = m_fSpeedRatio; - m_fLastSetPitchRatio = m_fPitchRatio; -} - -RageSoundReader_PitchChange::RageSoundReader_PitchChange( const RageSoundReader_PitchChange &cpy ): - RageSoundReader_Filter( cpy ) -{ - /* The source tree has already been copied. Our source is m_pResample; its source - * is m_pSpeedChange (and its source is a copy of the pSource we were initialized - * with). */ - m_pResample = dynamic_cast( &*m_pSource ); - m_pSpeedChange = dynamic_cast( m_pResample->GetSource() ); - m_fSpeedRatio = cpy.m_fSpeedRatio; - m_fPitchRatio = cpy.m_fPitchRatio; - m_fLastSetSpeedRatio = cpy.m_fLastSetSpeedRatio; - m_fLastSetPitchRatio = cpy.m_fLastSetPitchRatio; -} - -int RageSoundReader_PitchChange::Read( float *pBuf, int iFrames ) -{ - /* m_pSpeedChange->NextReadWillStep is true if speed changes will be applied - * immediately on the next Read(). When this is true, apply the ratio to the - * resampler and the speed changer simultaneously, so they take effect as - * closely together as possible. */ - if( (m_fLastSetSpeedRatio != m_fSpeedRatio || m_fLastSetPitchRatio != m_fPitchRatio) && - m_pSpeedChange->NextReadWillStep() ) - { - float fRate = GetStreamToSourceRatio(); - - /* This is the simple way: */ - // m_pResample->SetRate( m_fPitchRatio ); - // m_pSpeedChange->SetSpeedRatio( m_fSpeedRatio / m_fPitchRatio ); - - /* However, the resampler has a limited granularity due to internal fixed- - * point math, and the actual ratio will be slightly different than what - * we tell it to use. The actual ratio used is fActualPitchRatio. */ - m_pResample->SetRate( m_fPitchRatio ); - float fActualPitchRatio = m_pResample->GetRate(); - float fRequestedSpeedRatio = m_fSpeedRatio / fActualPitchRatio; - m_pSpeedChange->SetSpeedRatio( fRequestedSpeedRatio ); - - m_fLastSetSpeedRatio = m_fSpeedRatio; - m_fLastSetPitchRatio = m_fPitchRatio; - - /* If we just applied a new speed and it caused the ratio to change, return - * no data, so the caller can see the new ratio. */ - if( fRate != GetStreamToSourceRatio() ) - return 0; - } - - return RageSoundReader_Filter::Read( pBuf, iFrames ); -} - -bool RageSoundReader_PitchChange::SetProperty( const RString &sProperty, float fValue ) -{ - if( sProperty == "Rate" ) - { - /* Don't propagate this. m_pResample will take it, but it's under - * our control. */ - return false; - } - if( sProperty == "Speed" ) - { - SetSpeedRatio( fValue ); - return true; - } - - if( sProperty == "Pitch" ) - { - SetPitchRatio( fValue ); - return true; - } - - return RageSoundReader_Filter::SetProperty( sProperty, fValue ); -} - -/* - * Copyright (c) 2006 Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +/* + * Implements properties: + * "Speed" - cause the sound to play faster or slower + * "Pitch" - raise or lower the pitch of the sound + * + * Pitch changing is implemented by combining speed changing and rate changing + * (via resampling). The resampler needs to be changed later than the speed + * changer; this class just controls parameters on the other two real filters. + */ + +#include "global.h" +#include "RageSoundReader_PitchChange.h" +#include "RageSoundReader_SpeedChange.h" +#include "RageSoundReader_Resample_Good.h" +#include "RageLog.h" + +RageSoundReader_PitchChange::RageSoundReader_PitchChange( RageSoundReader *pSource ): + RageSoundReader_Filter(nullptr) +{ + m_pSpeedChange = new RageSoundReader_SpeedChange( pSource ); + m_pResample = new RageSoundReader_Resample_Good( m_pSpeedChange, m_pSpeedChange->GetSampleRate() ); + m_pSource = m_pResample; + m_fSpeedRatio = 1.0f; + m_fPitchRatio = 1.0f; + m_fLastSetSpeedRatio = m_fSpeedRatio; + m_fLastSetPitchRatio = m_fPitchRatio; +} + +RageSoundReader_PitchChange::RageSoundReader_PitchChange( const RageSoundReader_PitchChange &cpy ): + RageSoundReader_Filter( cpy ) +{ + /* The source tree has already been copied. Our source is m_pResample; its source + * is m_pSpeedChange (and its source is a copy of the pSource we were initialized + * with). */ + m_pResample = dynamic_cast( &*m_pSource ); + m_pSpeedChange = dynamic_cast( m_pResample->GetSource() ); + m_fSpeedRatio = cpy.m_fSpeedRatio; + m_fPitchRatio = cpy.m_fPitchRatio; + m_fLastSetSpeedRatio = cpy.m_fLastSetSpeedRatio; + m_fLastSetPitchRatio = cpy.m_fLastSetPitchRatio; +} + +int RageSoundReader_PitchChange::Read( float *pBuf, int iFrames ) +{ + /* m_pSpeedChange->NextReadWillStep is true if speed changes will be applied + * immediately on the next Read(). When this is true, apply the ratio to the + * resampler and the speed changer simultaneously, so they take effect as + * closely together as possible. */ + if( (m_fLastSetSpeedRatio != m_fSpeedRatio || m_fLastSetPitchRatio != m_fPitchRatio) && + m_pSpeedChange->NextReadWillStep() ) + { + float fRate = GetStreamToSourceRatio(); + + /* This is the simple way: */ + // m_pResample->SetRate( m_fPitchRatio ); + // m_pSpeedChange->SetSpeedRatio( m_fSpeedRatio / m_fPitchRatio ); + + /* However, the resampler has a limited granularity due to internal fixed- + * point math, and the actual ratio will be slightly different than what + * we tell it to use. The actual ratio used is fActualPitchRatio. */ + m_pResample->SetRate( m_fPitchRatio ); + float fActualPitchRatio = m_pResample->GetRate(); + float fRequestedSpeedRatio = m_fSpeedRatio / fActualPitchRatio; + m_pSpeedChange->SetSpeedRatio( fRequestedSpeedRatio ); + + m_fLastSetSpeedRatio = m_fSpeedRatio; + m_fLastSetPitchRatio = m_fPitchRatio; + + /* If we just applied a new speed and it caused the ratio to change, return + * no data, so the caller can see the new ratio. */ + if( fRate != GetStreamToSourceRatio() ) + return 0; + } + + return RageSoundReader_Filter::Read( pBuf, iFrames ); +} + +bool RageSoundReader_PitchChange::SetProperty( const RString &sProperty, float fValue ) +{ + if( sProperty == "Rate" ) + { + /* Don't propagate this. m_pResample will take it, but it's under + * our control. */ + return false; + } + if( sProperty == "Speed" ) + { + SetSpeedRatio( fValue ); + return true; + } + + if( sProperty == "Pitch" ) + { + SetPitchRatio( fValue ); + return true; + } + + return RageSoundReader_Filter::SetProperty( sProperty, fValue ); +} + +/* + * Copyright (c) 2006 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/RageSoundReader_Preload.cpp b/src/RageSoundReader_Preload.cpp index 91266c6e92..b5e97ac395 100644 --- a/src/RageSoundReader_Preload.cpp +++ b/src/RageSoundReader_Preload.cpp @@ -47,7 +47,7 @@ int RageSoundReader_Preload::GetTotalFrames() const bool RageSoundReader_Preload::Open( RageSoundReader *pSource ) { - ASSERT( pSource != NULL ); + ASSERT( pSource != nullptr ); m_iSampleRate = pSource->GetSampleRate(); m_iChannels = pSource->GetNumChannels(); m_fRate = pSource->GetStreamToSourceRatio(); diff --git a/src/RageSoundReader_Resample_Good.cpp b/src/RageSoundReader_Resample_Good.cpp index 0c3f3e0476..d36bd5f8bc 100644 --- a/src/RageSoundReader_Resample_Good.cpp +++ b/src/RageSoundReader_Resample_Good.cpp @@ -468,7 +468,7 @@ public: * when filtering. This will only cause the low-pass filter to be rounded; * the conversion ratio will always be exact. */ m_iUpFactor = iUpFactor; - m_pPolyphase = NULL; + m_pPolyphase = nullptr; int iFilterIncrement = max( (iMaxDownFactor - iMinDownFactor)/10, 1 ); for( int iDownFactor = iMinDownFactor; iDownFactor <= iMaxDownFactor; iDownFactor += iFilterIncrement ) diff --git a/src/RageSoundReader_ThreadedBuffer.cpp b/src/RageSoundReader_ThreadedBuffer.cpp index 14dac250a9..db7efb2ce0 100644 --- a/src/RageSoundReader_ThreadedBuffer.cpp +++ b/src/RageSoundReader_ThreadedBuffer.cpp @@ -2,7 +2,6 @@ #include "RageSoundReader_ThreadedBuffer.h" #include "RageUtil.h" #include "RageTimer.h" -#include "Foreach.h" #include "RageLog.h" /* Implement threaded read-ahead buffering. @@ -48,7 +47,7 @@ RageSoundReader_ThreadedBuffer::RageSoundReader_ThreadedBuffer( RageSoundReader } RageSoundReader_ThreadedBuffer::RageSoundReader_ThreadedBuffer( const RageSoundReader_ThreadedBuffer &cpy ): - RageSoundReader_Filter( NULL ), // don't touch m_pSource before DisableBuffering + RageSoundReader_Filter(nullptr), // don't touch m_pSource before DisableBuffering m_Event( "ThreadedBuffer" ) { bool bWasEnabled = cpy.DisableBuffering(); diff --git a/src/RageSoundReader_ThreadedBuffer.h b/src/RageSoundReader_ThreadedBuffer.h index f440c35ac7..4b22cc4e67 100644 --- a/src/RageSoundReader_ThreadedBuffer.h +++ b/src/RageSoundReader_ThreadedBuffer.h @@ -1,102 +1,102 @@ -/* RageSoundReader_ThreadedBuffer - Buffer sounds into memory. */ - -#ifndef RAGE_SOUND_READER_THREADED_BUFFER -#define RAGE_SOUND_READER_THREADED_BUFFER - -#include "RageSoundReader_Filter.h" -#include "RageUtil_CircularBuffer.h" -#include "RageThreads.h" -#include - -class RageThread; -class RageSoundReader_ThreadedBuffer: public RageSoundReader_Filter -{ -public: - RageSoundReader_ThreadedBuffer( RageSoundReader *pSource ); - RageSoundReader_ThreadedBuffer( const RageSoundReader_ThreadedBuffer &cpy ); - ~RageSoundReader_ThreadedBuffer(); - RageSoundReader_ThreadedBuffer *Copy() const { return new RageSoundReader_ThreadedBuffer(*this); } - - virtual int SetPosition( int iFrame ); - virtual int Read( float *pBuffer, int iLength ); - virtual int GetNextSourceFrame() const; - - virtual int GetLength() const; - virtual int GetLength_Fast() const; - virtual int GetSampleRate() const { return m_iSampleRate; } - virtual unsigned GetNumChannels() const { return m_iChannels; } - virtual bool SetProperty( const RString &sProperty, float fValue ); - virtual float GetStreamToSourceRatio() const; - virtual RageSoundReader *GetSource() { return NULL; } - - /* Enable and disable threaded buffering. Disable buffering before accessing - * the underlying sound. DisableBuffering returns true if buffering was enabled. */ - void EnableBuffering(); - void EnableBuffering() const { const_cast(this)->EnableBuffering(); } - bool DisableBuffering(); - bool DisableBuffering() const { return const_cast(this)->DisableBuffering(); } - -private: - int FillFrames( int iBytes ); - int FillBlock(); - int GetFilledFrames() const; - int GetEmptyFrames() const; - void WaitUntilFrames( int iWaitUntilFrames ); - - int m_iSampleRate; - int m_iChannels; - - CircBuf m_DataBuffer; - - struct Mapping - { - int iFramesBuffered; - int iPositionOfFirstFrame; - float fRate; - Mapping(): iFramesBuffered(0), iPositionOfFirstFrame(0), - fRate(1.0f) {} - }; - list m_StreamPosition; - - bool m_bEOF; - - bool m_bEnabled; - - /* If this is true, the buffering thread owns m_pSource, even - * if m_Event is unlocked. */ - bool m_bFilling; - - mutable RageEvent m_Event; - - RageThread m_Thread; - bool m_bShutdownThread; - static int StartBufferingThread( void *p ) { ((RageSoundReader_ThreadedBuffer *) p)->BufferingThread(); return 0; } - void BufferingThread(); -}; - -#endif - -/* - * Copyright (c) 2006 Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +/* RageSoundReader_ThreadedBuffer - Buffer sounds into memory. */ + +#ifndef RAGE_SOUND_READER_THREADED_BUFFER +#define RAGE_SOUND_READER_THREADED_BUFFER + +#include "RageSoundReader_Filter.h" +#include "RageUtil_CircularBuffer.h" +#include "RageThreads.h" +#include + +class RageThread; +class RageSoundReader_ThreadedBuffer: public RageSoundReader_Filter +{ +public: + RageSoundReader_ThreadedBuffer( RageSoundReader *pSource ); + RageSoundReader_ThreadedBuffer( const RageSoundReader_ThreadedBuffer &cpy ); + ~RageSoundReader_ThreadedBuffer(); + RageSoundReader_ThreadedBuffer *Copy() const { return new RageSoundReader_ThreadedBuffer(*this); } + + virtual int SetPosition( int iFrame ); + virtual int Read( float *pBuffer, int iLength ); + virtual int GetNextSourceFrame() const; + + virtual int GetLength() const; + virtual int GetLength_Fast() const; + virtual int GetSampleRate() const { return m_iSampleRate; } + virtual unsigned GetNumChannels() const { return m_iChannels; } + virtual bool SetProperty( const RString &sProperty, float fValue ); + virtual float GetStreamToSourceRatio() const; + virtual RageSoundReader *GetSource() { return nullptr; } + + /* Enable and disable threaded buffering. Disable buffering before accessing + * the underlying sound. DisableBuffering returns true if buffering was enabled. */ + void EnableBuffering(); + void EnableBuffering() const { const_cast(this)->EnableBuffering(); } + bool DisableBuffering(); + bool DisableBuffering() const { return const_cast(this)->DisableBuffering(); } + +private: + int FillFrames( int iBytes ); + int FillBlock(); + int GetFilledFrames() const; + int GetEmptyFrames() const; + void WaitUntilFrames( int iWaitUntilFrames ); + + int m_iSampleRate; + int m_iChannels; + + CircBuf m_DataBuffer; + + struct Mapping + { + int iFramesBuffered; + int iPositionOfFirstFrame; + float fRate; + Mapping(): iFramesBuffered(0), iPositionOfFirstFrame(0), + fRate(1.0f) {} + }; + list m_StreamPosition; + + bool m_bEOF; + + bool m_bEnabled; + + /* If this is true, the buffering thread owns m_pSource, even + * if m_Event is unlocked. */ + bool m_bFilling; + + mutable RageEvent m_Event; + + RageThread m_Thread; + bool m_bShutdownThread; + static int StartBufferingThread( void *p ) { ((RageSoundReader_ThreadedBuffer *) p)->BufferingThread(); return 0; } + void BufferingThread(); +}; + +#endif + +/* + * Copyright (c) 2006 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/RageSoundReader_Vorbisfile.cpp b/src/RageSoundReader_Vorbisfile.cpp index 2c403e84fe..caad3a6ce8 100644 --- a/src/RageSoundReader_Vorbisfile.cpp +++ b/src/RageSoundReader_Vorbisfile.cpp @@ -48,22 +48,22 @@ static RString ov_ssprintf( int err, const char *fmt, ...) { // OV_FALSE, OV_EOF, and OV_HOLE were added to this switch because // OV_EOF cases were being reported as unknown. -Kyz - case OV_FALSE: errstr = "OV_FALSE"; break; - case OV_EOF: errstr = "OV_EOF"; break; - case OV_HOLE: errstr = "OV_HOLE"; break; - /* XXX: In the case of OV_EREAD, can we snoop at errno? */ - case OV_EREAD: errstr = "Read error"; break; - case OV_EFAULT: errstr = "Internal error"; break; - case OV_EIMPL: errstr = "Feature not implemented"; break; - case OV_EINVAL: errstr = "Invalid argument"; break; - case OV_ENOTVORBIS: errstr = "Not Vorbis data"; break; - case OV_EBADHEADER: errstr = "Invalid Vorbis bitstream header"; break; - case OV_EVERSION: errstr = "Vorbis version mismatch"; break; - case OV_ENOTAUDIO: errstr = "OV_ENOTAUDIO"; break; - case OV_EBADPACKET: errstr = "OV_EBADPACKET"; break; - case OV_EBADLINK: errstr = "Link corrupted"; break; - case OV_ENOSEEK: errstr = "Stream is not seekable"; break; - default: errstr = ssprintf( "unknown error %i", err ); break; + case OV_FALSE: errstr = "OV_FALSE"; break; + case OV_EOF: errstr = "OV_EOF"; break; + case OV_HOLE: errstr = "OV_HOLE"; break; + /* XXX: In the case of OV_EREAD, can we snoop at errno? */ + case OV_EREAD: errstr = "Read error"; break; + case OV_EFAULT: errstr = "Internal error"; break; + case OV_EIMPL: errstr = "Feature not implemented"; break; + case OV_EINVAL: errstr = "Invalid argument"; break; + case OV_ENOTVORBIS: errstr = "Not Vorbis data"; break; + case OV_EBADHEADER: errstr = "Invalid Vorbis bitstream header"; break; + case OV_EVERSION: errstr = "Vorbis version mismatch"; break; + case OV_ENOTAUDIO: errstr = "OV_ENOTAUDIO"; break; + case OV_EBADPACKET: errstr = "OV_EBADPACKET"; break; + case OV_EBADLINK: errstr = "Link corrupted"; break; + case OV_ENOSEEK: errstr = "Stream is not seekable"; break; + default: errstr = ssprintf( "unknown error %i", err ); break; } return s + ssprintf( " (%s)", errstr.c_str() ); @@ -81,12 +81,12 @@ RageSoundReader_FileReader::OpenResult RageSoundReader_Vorbisfile::Open( RageFil callbacks.close_func = OggRageFile_close_func; callbacks.tell_func = OggRageFile_tell_func; - int ret = ov_open_callbacks( pFile, vf, NULL, 0, callbacks ); + int ret = ov_open_callbacks( pFile, vf, nullptr, 0, callbacks ); if( ret < 0 ) { SetError( ov_ssprintf(ret, "ov_open failed") ); delete vf; - vf = NULL; + vf = nullptr; switch( ret ) { case OV_ENOTVORBIS: @@ -190,7 +190,7 @@ int RageSoundReader_Vorbisfile::Read( float *buf, int iFrames ) { vorbis_info *vi = ov_info( vf, -1 ); - ASSERT( vi != NULL ); + ASSERT( vi != nullptr ); if( (unsigned) vi->channels != channels ) RageException::Throw( "File \"%s\" changes channel count from %i to %i; not supported.", @@ -260,17 +260,17 @@ int RageSoundReader_Vorbisfile::Read( float *buf, int iFrames ) int RageSoundReader_Vorbisfile::GetSampleRate() const { - ASSERT(vf != NULL); + ASSERT(vf != nullptr); vorbis_info *vi = ov_info(vf, -1); - ASSERT(vi != NULL); + ASSERT(vi != nullptr); return vi->rate; } int RageSoundReader_Vorbisfile::GetNextSourceFrame() const { - ASSERT(vf != NULL); + ASSERT(vf != nullptr); int iFrame = (int)ov_pcm_tell( vf ); return iFrame; @@ -278,7 +278,7 @@ int RageSoundReader_Vorbisfile::GetNextSourceFrame() const RageSoundReader_Vorbisfile::RageSoundReader_Vorbisfile() { - vf = NULL; + vf = nullptr; } RageSoundReader_Vorbisfile::~RageSoundReader_Vorbisfile() diff --git a/src/RageSoundReader_WAV.cpp b/src/RageSoundReader_WAV.cpp index 27a423bb2d..5adad7adc9 100644 --- a/src/RageSoundReader_WAV.cpp +++ b/src/RageSoundReader_WAV.cpp @@ -200,7 +200,7 @@ public: WavReaderADPCM( RageFileBasic &f, const RageSoundReader_WAV::WavData &data ): WavReader(f, data) { - m_pBuffer = NULL; + m_pBuffer = nullptr; } virtual ~WavReaderADPCM() @@ -581,31 +581,31 @@ RageSoundReader_FileReader::OpenResult RageSoundReader_WAV::Open( RageFileBasic int RageSoundReader_WAV::GetLength() const { - ASSERT( m_pImpl != NULL ); + ASSERT( m_pImpl != nullptr ); return m_pImpl->GetLength(); } int RageSoundReader_WAV::SetPosition( int iFrame ) { - ASSERT( m_pImpl != NULL ); + ASSERT( m_pImpl != nullptr ); return m_pImpl->SetPosition( iFrame ); } int RageSoundReader_WAV::GetNextSourceFrame() const { - ASSERT( m_pImpl != NULL ); + ASSERT( m_pImpl != nullptr ); return m_pImpl->GetNextSourceFrame(); } int RageSoundReader_WAV::Read( float *pBuf, int iFrames ) { - ASSERT( m_pImpl != NULL ); + ASSERT( m_pImpl != nullptr ); return m_pImpl->Read( pBuf, iFrames ); } RageSoundReader_WAV::RageSoundReader_WAV() { - m_pImpl = NULL; + m_pImpl = nullptr; } RageSoundReader_WAV::~RageSoundReader_WAV() diff --git a/src/RageSurface.cpp b/src/RageSurface.cpp index 70cecbb133..2967d1ff49 100644 --- a/src/RageSurface.cpp +++ b/src/RageSurface.cpp @@ -41,7 +41,7 @@ RageSurfaceFormat::RageSurfaceFormat(): Rmask(Mask[0]), Gmask(Mask[1]), Bmask(Mask[2]), Amask(Mask[3]), Rshift(Shift[0]), Gshift(Shift[1]), Bshift(Shift[2]), Ashift(Shift[3]) { - palette = NULL; + palette = nullptr; } RageSurfaceFormat::RageSurfaceFormat( const RageSurfaceFormat &cpy ): @@ -62,7 +62,7 @@ void RageSurfaceFormat::GetRGB( uint32_t val, uint8_t *r, uint8_t *g, uint8_t *b { if( BytesPerPixel == 1 ) { - ASSERT( palette != NULL ); + ASSERT( palette != nullptr ); *r = palette->colors[val].r; *g = palette->colors[val].g; *b = palette->colors[val].b; @@ -119,7 +119,7 @@ bool RageSurfaceFormat::Equivalent( const RageSurfaceFormat &rhs ) const RageSurface::RageSurface() { format = &fmt; - pixels = NULL; + pixels = nullptr; pixels_owned = true; } @@ -138,7 +138,7 @@ RageSurface::RageSurface( const RageSurface &cpy ) memcpy( pixels, cpy.pixels, pitch*h ); } else - pixels = NULL; + pixels = nullptr; } RageSurface::~RageSurface() diff --git a/src/RageSurfaceUtils.cpp b/src/RageSurfaceUtils.cpp index 539491bdf1..f6756f32e9 100644 --- a/src/RageSurfaceUtils.cpp +++ b/src/RageSurfaceUtils.cpp @@ -1,1072 +1,1072 @@ -#include "global.h" -#include "RageSurfaceUtils.h" -#include "RageSurface.h" -#include "RageUtil.h" -#include "RageLog.h" -#include "RageFile.h" - -uint32_t RageSurfaceUtils::decodepixel( const uint8_t *p, int bpp ) -{ - switch(bpp) - { - case 1: return *p; - case 2: return *(uint16_t *)p; - case 3: - if( BYTE_ORDER == BIG_ENDIAN ) - return p[0] << 16 | p[1] << 8 | p[2]; - else - return p[0] | p[1] << 8 | p[2] << 16; - - case 4: return *(uint32_t *)p; - default: return 0; // shouldn't happen, but avoids warnings - } -} - -void RageSurfaceUtils::encodepixel( uint8_t *p, int bpp, uint32_t pixel ) -{ - switch(bpp) - { - case 1: *p = uint8_t(pixel); break; - case 2: *(uint16_t *)p = uint16_t(pixel); break; - case 3: - if( BYTE_ORDER == BIG_ENDIAN ) - { - p[0] = uint8_t((pixel >> 16) & 0xff); - p[1] = uint8_t((pixel >> 8) & 0xff); - p[2] = uint8_t(pixel & 0xff); - } else { - p[0] = uint8_t(pixel & 0xff); - p[1] = uint8_t((pixel >> 8) & 0xff); - p[2] = uint8_t((pixel >> 16) & 0xff); - } - break; - case 4: *(uint32_t *)p = pixel; break; - } -} - -// Get and set colors without scaling to 0..255. -void RageSurfaceUtils::GetRawRGBAV( uint32_t pixel, const RageSurfaceFormat &fmt, uint8_t *v ) -{ - if( fmt.BytesPerPixel == 1 ) - { - v[0] = fmt.palette->colors[pixel].r; - v[1] = fmt.palette->colors[pixel].g; - v[2] = fmt.palette->colors[pixel].b; - v[3] = fmt.palette->colors[pixel].a; - } else { - v[0] = uint8_t((pixel & fmt.Rmask) >> fmt.Rshift); - v[1] = uint8_t((pixel & fmt.Gmask) >> fmt.Gshift); - v[2] = uint8_t((pixel & fmt.Bmask) >> fmt.Bshift); - v[3] = uint8_t((pixel & fmt.Amask) >> fmt.Ashift); - } -} - -void RageSurfaceUtils::GetRawRGBAV( const uint8_t *p, const RageSurfaceFormat &fmt, uint8_t *v ) -{ - uint32_t pixel = decodepixel( p, fmt.BytesPerPixel ); - GetRawRGBAV( pixel, fmt, v ); -} - -void RageSurfaceUtils::GetRGBAV( uint32_t pixel, const RageSurface *src, uint8_t *v ) -{ - GetRawRGBAV(pixel, src->fmt, v); - const RageSurfaceFormat *fmt = src->format; - for( int c = 0; c < 4; ++c ) - v[c] = v[c] << fmt->Loss[c]; - - // Correct for surfaces that don't have an alpha channel. - if( fmt->Loss[3] == 8 ) - v[3] = 255; -} - -void RageSurfaceUtils::GetRGBAV( const uint8_t *p, const RageSurface *src, uint8_t *v ) -{ - uint32_t pixel = decodepixel(p, src->format->BytesPerPixel); - if( src->format->BytesPerPixel == 1 ) // paletted - { - memcpy( v, &src->format->palette->colors[pixel], sizeof(RageSurfaceColor)); - } - else // RGBA - GetRGBAV(pixel, src, v); -} - - -// Inverse of GetRawRGBAV. -uint32_t RageSurfaceUtils::SetRawRGBAV( const RageSurfaceFormat *fmt, const uint8_t *v ) -{ - return v[0] << fmt->Rshift | - v[1] << fmt->Gshift | - v[2] << fmt->Bshift | - v[3] << fmt->Ashift; -} - -void RageSurfaceUtils::SetRawRGBAV( uint8_t *p, const RageSurface *src, const uint8_t *v ) -{ - uint32_t pixel = SetRawRGBAV(src->format, v); - encodepixel(p, src->format->BytesPerPixel, pixel); -} - -// Inverse of GetRGBAV. -uint32_t RageSurfaceUtils::SetRGBAV( const RageSurfaceFormat *fmt, const uint8_t *v ) -{ - return (v[0] >> fmt->Loss[0]) << fmt->Shift[0] | - (v[1] >> fmt->Loss[1]) << fmt->Shift[1] | - (v[2] >> fmt->Loss[2]) << fmt->Shift[2] | - (v[3] >> fmt->Loss[3]) << fmt->Shift[3]; -} - -void RageSurfaceUtils::SetRGBAV( uint8_t *p, const RageSurface *src, const uint8_t *v ) -{ - uint32_t pixel = SetRGBAV(src->format, v); - encodepixel(p, src->format->BytesPerPixel, pixel); -} - - -void RageSurfaceUtils::GetBitsPerChannel( const RageSurfaceFormat *fmt, uint32_t bits[4] ) -{ - // The actual bits stored in each color is 8-loss. - for( int c = 0; c < 4; ++c ) - bits[c] = 8 - fmt->Loss[c]; -} - -void RageSurfaceUtils::CopySurface( const RageSurface *src, RageSurface *dest ) -{ - // Copy the palette, if we have one. - if( src->format->BitsPerPixel == 8 && dest->format->BitsPerPixel == 8 ) - { - ASSERT( dest->fmt.palette != NULL ); - *dest->fmt.palette = *src->fmt.palette; - } - - Blit( src, dest, -1, -1 ); -} - -bool RageSurfaceUtils::ConvertSurface( const RageSurface *src, RageSurface *&dst, - int width, int height, int bpp, - uint32_t R, uint32_t G, uint32_t B, uint32_t A ) -{ - dst = CreateSurface( width, height, bpp, R, G, B, A ); - - // If the formats are the same, no conversion is needed. Ignore the palette. - if( width == src->w && height == src->h && src->format->Equivalent( *dst->format ) ) - { - delete dst; - dst = NULL; - return false; - } - - CopySurface( src, dst ); - return true; -} - -void RageSurfaceUtils::ConvertSurface(RageSurface *&image, - int width, int height, int bpp, - uint32_t R, uint32_t G, uint32_t B, uint32_t A) -{ - RageSurface *ret_image; - if( !ConvertSurface( image, ret_image, width, height, bpp, R, G, B, A ) ) - return; - - delete image; - image = ret_image; -} - - -// Local helper for FixHiddenAlpha. -static void FindAlphaRGB(const RageSurface *img, uint8_t &r, uint8_t &g, uint8_t &b, bool reverse) -{ - r = g = b = 0; - - // If we have no alpha, there's no alpha color. - if( img->format->BitsPerPixel > 8 && !img->format->Amask ) - return; - - // Eww. Sorry. Iterate front-to-back or in reverse. - for(int y = reverse? img->h-1:0; - reverse? (y >=0):(y < img->h); reverse? (--y):(++y)) - { - uint8_t *row = (uint8_t *)img->pixels + img->pitch*y; - if(reverse) - row += img->format->BytesPerPixel * (img->w-1); - - for(int x = 0; x < img->w; ++x) - { - uint32_t val = RageSurfaceUtils::decodepixel(row, img->format->BytesPerPixel); - if( img->format->BitsPerPixel == 8 ) - { - if( img->format->palette->colors[val].a ) - { - // This color isn't fully transparent, so grab it. - r = img->format->palette->colors[val].r; - g = img->format->palette->colors[val].g; - b = img->format->palette->colors[val].b; - return; - } - } - else - { - if( val & img->format->Amask ) - { - // This color isn't fully transparent, so grab it. - img->format->GetRGB( val, &r, &g, &b ); - return; - } - } - - if( reverse ) - row -= img->format->BytesPerPixel; - else - row += img->format->BytesPerPixel; - } - } - - // Huh? The image is completely transparent. - r = g = b = 0; -} - -/* Local helper for FixHiddenAlpha. Set the underlying RGB values of all pixels - * in img that are completely transparent. */ -static void SetAlphaRGB(const RageSurface *pImg, uint8_t r, uint8_t g, uint8_t b) -{ - // If it's a paletted surface, all we have to do is change the palette. - if( pImg->format->BitsPerPixel == 8 ) - { - for( int c = 0; c < pImg->format->palette->ncolors; ++c ) - { - if( pImg->format->palette->colors[c].a ) - continue; - pImg->format->palette->colors[c].r = r; - pImg->format->palette->colors[c].g = g; - pImg->format->palette->colors[c].b = b; - } - return; - } - - // If it's RGBA and there's no alpha channel, we have nothing to do. - if( pImg->format->BitsPerPixel > 8 && !pImg->format->Amask ) - return; - - uint32_t trans; - pImg->format->MapRGBA( r, g, b, 0, trans ); - for( int y = 0; y < pImg->h; ++y ) - { - uint8_t *row = pImg->pixels + pImg->pitch*y; - - for( int x = 0; x < pImg->w; ++x ) - { - uint32_t val = RageSurfaceUtils::decodepixel( row, pImg->format->BytesPerPixel ); - if( val != trans && !(val&pImg->format->Amask) ) - { - RageSurfaceUtils::encodepixel( row, pImg->format->BytesPerPixel, trans ); - } - - row += pImg->format->BytesPerPixel; - } - } -} - -/* When we scale up images (which we always do in high res), pixels - * that are completely transparent can be blended with opaque pixels, - * causing their RGB elements to show. This is visible in many textures - * as a pixel-wide border in the wrong color. This is tricky to fix. - * We need to set the RGB components of completely transparent pixels - * to a reasonable color. - * - * Most images have a single border color. For these, the transparent - * color is easy: search through the image top-bottom-left-right, - * find the first non-transparent pixel, and pull out its RGB. - * - * A few images don't. We can only make a guess here. After the above - * search, do the same in reverse (bottom-top-right-left). If the color - * we find is different, just set the border color to black. - */ -void RageSurfaceUtils::FixHiddenAlpha( RageSurface *pImg ) -{ - // If there are no alpha bits, there's nothing to fix. - if( pImg->format->BitsPerPixel != 8 && pImg->format->Amask == 0 ) - return; - - uint8_t r, g, b; - FindAlphaRGB( pImg, r, g, b, false ); - - uint8_t cr, cg, cb; // compare - FindAlphaRGB( pImg, cr, cg, cb, true ); - - if( cr != r || cg != g || cb != b ) - r = g = b = 0; - - SetAlphaRGB( pImg, r, g, b ); -} - -/* Scan the surface to see what level of alpha it uses. This can be used to - * find the best surface format for a texture; eg. a TRAIT_BOOL_TRANSPARENCY or - * TRAIT_NO_TRANSPARENCY surface can use RGB5A1 instead of RGBA4 for greater - * color resolution; a TRAIT_NO_TRANSPARENCY could also use R5G6B5. */ -int RageSurfaceUtils::FindSurfaceTraits( const RageSurface *img ) -{ - const int NEEDS_NO_ALPHA=0, NEEDS_BOOL_ALPHA=1, NEEDS_FULL_ALPHA=2; - int alpha_type = NEEDS_NO_ALPHA; - - uint32_t max_alpha; - if( img->format->BitsPerPixel == 8 ) - { - // Short circuit if we already know we have no transparency. - bool bHaveNonOpaque = false; - for( int c = 0; !bHaveNonOpaque && c < img->format->palette->ncolors; ++c ) - { - if( img->format->palette->colors[c].a != 0xFF ) - bHaveNonOpaque = true; - } - - if( !bHaveNonOpaque ) - return TRAIT_NO_TRANSPARENCY; - - max_alpha = 0xFF; - } - else - { - // Short circuit if we already know we have no transparency. - if( img->format->Amask == 0 ) - return TRAIT_NO_TRANSPARENCY; - - max_alpha = img->format->Amask; - } - - for(int y = 0; y < img->h; ++y) - { - uint8_t *row = (uint8_t *)img->pixels + img->pitch*y; - - for(int x = 0; x < img->w; ++x) - { - uint32_t val = decodepixel(row, img->format->BytesPerPixel); - - uint32_t alpha; - if( img->format->BitsPerPixel == 8 ) - alpha = img->format->palette->colors[val].a; - else - alpha = (val & img->format->Amask); - - if( alpha == 0 ) - alpha_type = max( alpha_type, NEEDS_BOOL_ALPHA ); - else if( alpha != max_alpha ) - alpha_type = max( alpha_type, NEEDS_FULL_ALPHA ); - - row += img->format->BytesPerPixel; - } - } - - int ret = 0; - switch( alpha_type ) - { - case NEEDS_NO_ALPHA: ret |= TRAIT_NO_TRANSPARENCY; break; - case NEEDS_BOOL_ALPHA: ret |= TRAIT_BOOL_TRANSPARENCY; break; - case NEEDS_FULL_ALPHA: break; - default: - FAIL_M(ssprintf("Invalid alpha type: %i", alpha_type)); - } - - return ret; -} - - -// Local helper for BlitTransform. -static inline void GetRawRGBAV_XY( const RageSurface *src, uint8_t *v, int x, int y ) -{ - const uint8_t *srcp = (const uint8_t *) src->pixels + (y * src->pitch); - const uint8_t *srcpx = srcp + (x * src->fmt.BytesPerPixel); - - RageSurfaceUtils::GetRawRGBAV( srcpx, src->fmt, v ); -} - -static inline float scale( float x, float l1, float h1, float l2, float h2 ) -{ - return ((x - l1) / (h1 - l1) * (h2 - l2) + l2); -} - -// Completely unoptimized. -void RageSurfaceUtils::BlitTransform( const RageSurface *src, RageSurface *dst, - const float fCoords[8] /* TL, BR, BL, TR */ ) -{ - ASSERT( src->format->BytesPerPixel == dst->format->BytesPerPixel ); - - const float Coords[8] = { - (fCoords[0] * (src->w)), (fCoords[1] * (src->h)), - (fCoords[2] * (src->w)), (fCoords[3] * (src->h)), - (fCoords[4] * (src->w)), (fCoords[5] * (src->h)), - (fCoords[6] * (src->w)), (fCoords[7] * (src->h)) - }; - - const int TL_X = 0, TL_Y = 1, BL_X = 2, BL_Y = 3, - BR_X = 4, BR_Y = 5, TR_X = 6, TR_Y = 7; - - for( int y = 0; y < dst->h; ++y ) - { - uint8_t *dstp = (uint8_t *) dst->pixels + (y * dst->pitch); /* line */ - uint8_t *dstpx = dstp; // pixel - - const float start_y = scale(float(y), 0, float(dst->h), Coords[TL_Y], Coords[BL_Y]); - const float end_y = scale(float(y), 0, float(dst->h), Coords[TR_Y], Coords[BR_Y]); - - const float start_x = scale(float(y), 0, float(dst->h), Coords[TL_X], Coords[BL_X]); - const float end_x = scale(float(y), 0, float(dst->h), Coords[TR_X], Coords[BR_X]); - - for( int x = 0; x < dst->w; ++x ) - { - const float src_xp = scale(float(x), 0, float(dst->w), start_x, end_x); - const float src_yp = scale(float(x), 0, float(dst->w), start_y, end_y); - - /* If the surface is two pixels wide, src_xp is 0..2. .5 indicates - * pixel[0]; 1 indicates 50% pixel[0], 50% pixel[1]; 1.5 indicates - * pixel[1]; 2 indicates 50% pixel[1], 50% pixel[2] (which is clamped - * to pixel[1]). */ - int src_x[2], src_y[2]; - src_x[0] = (int) truncf(src_xp - 0.5f); - src_x[1] = src_x[0] + 1; - - src_y[0] = (int) truncf(src_yp - 0.5f); - src_y[1] = src_y[0] + 1; - - // Emulate GL_REPEAT. - src_x[0] = clamp(src_x[0], 0, src->w); - src_x[1] = clamp(src_x[1], 0, src->w); - src_y[0] = clamp(src_y[0], 0, src->h); - src_y[1] = clamp(src_y[1], 0, src->h); - - // Decode our four pixels. - uint8_t v[4][4]; - GetRawRGBAV_XY(src, v[0], src_x[0], src_y[0]); - GetRawRGBAV_XY(src, v[1], src_x[0], src_y[1]); - GetRawRGBAV_XY(src, v[2], src_x[1], src_y[0]); - GetRawRGBAV_XY(src, v[3], src_x[1], src_y[1]); - - // Distance from the pixel chosen: - float weight_x = src_xp - (src_x[0] + 0.5f); - float weight_y = src_yp - (src_y[0] + 0.5f); - - // Filter: - uint8_t out[4] = { 0,0,0,0 }; - for(int i = 0; i < 4; ++i) - { - float sum = 0; - sum += v[0][i] * (1-weight_x) * (1-weight_y); - sum += v[1][i] * (1-weight_x) * (weight_y); - sum += v[2][i] * (weight_x) * (1-weight_y); - sum += v[3][i] * (weight_x) * (weight_y); - out[i] = (uint8_t) clamp( lrintf(sum), 0L, 255L ); - } - - // If the source has no alpha, set the destination to opaque. - if( src->format->Amask == 0 ) - out[3] = uint8_t( dst->format->Amask >> dst->format->Ashift ); - - SetRawRGBAV(dstpx, dst, out); - - dstpx += dst->format->BytesPerPixel; - } - } -} - - -/* Simplified: - * - * No source alpha. - * Palette -> palette blits assume the palette is identical (no mapping). - * No color key. - * No general blitting rects. */ - -static bool blit_same_type( const RageSurface *src_surf, const RageSurface *dst_surf, int width, int height ) -{ - if( src_surf->format->BytesPerPixel != dst_surf->format->BytesPerPixel || - src_surf->format->Rmask != dst_surf->format->Rmask || - src_surf->format->Gmask != dst_surf->format->Gmask || - src_surf->format->Bmask != dst_surf->format->Bmask || - src_surf->format->Amask != dst_surf->format->Amask ) - return false; - - const uint8_t *src = src_surf->pixels; - uint8_t *dst = dst_surf->pixels; - - // If possible, memcpy the whole thing. - if( src_surf->w == width && dst_surf->w == width && src_surf->pitch == dst_surf->pitch ) - { - memcpy( dst, src, height*src_surf->pitch ); - return true; - } - - // The rows don't line up, so memcpy row by row. - while( height-- ) - { - memcpy( dst, src, width*src_surf->format->BytesPerPixel ); - src += src_surf->pitch; - dst += dst_surf->pitch; - } - - return true; -} - -/* Rescaling blit with no ckey. This is used to update movies in - * D3D, so optimization is very important. */ -static bool blit_rgba_to_rgba( const RageSurface *src_surf, const RageSurface *dst_surf, int width, int height ) -{ - if( src_surf->format->BytesPerPixel == 1 || dst_surf->format->BytesPerPixel == 1 ) - return false; - - const uint8_t *src = src_surf->pixels; - uint8_t *dst = dst_surf->pixels; - - // Bytes to skip at the end of a line. - const int srcskip = src_surf->pitch - width*src_surf->format->BytesPerPixel; - const int dstskip = dst_surf->pitch - width*dst_surf->format->BytesPerPixel; - - const uint32_t *src_shifts = src_surf->format->Shift; - const uint32_t *dst_shifts = dst_surf->format->Shift; - const uint32_t *src_masks = src_surf->format->Mask; - const uint32_t *dst_masks = dst_surf->format->Mask; - - uint8_t lookup[4][256]; - for( int c = 0; c < 4; ++c ) - { - const uint32_t max_src_val = src_masks[c] >> src_shifts[c]; - const uint32_t max_dst_val = dst_masks[c] >> dst_shifts[c]; - ASSERT( max_src_val <= 0xFF ); - ASSERT( max_dst_val <= 0xFF ); - - if( src_masks[c] == 0 ) - { - /* The source is missing a channel. Alpha defaults to opaque, other - * channels default to 0. */ - if( c == 3 ) - lookup[c][0] = (uint8_t) max_dst_val; - else - lookup[c][0] = 0; - } else { - /* Calculate a color conversion table. There are a few ways we can do - * this (each list is the resulting table for 4->2 bit): - * - * SCALE( i, 0, max_src_val+1, 0, max_dst_val+1 ); - * { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3 } - * SCALE( i, 0, max_src_val, 0, max_dst_val ); - * { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3 } - * lrintf( ((float) i / max_src_val) * max_dst_val ) - * { 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3 } - * - * We use the first for increasing resolution, since it gives the most even - * distribution. - * - * 2->4 bit: - * SCALE( i, 0, max_src_val+1, 0, max_dst_val+1 ); - * { 0, 4, 8, 12 } - * SCALE( i, 0, max_src_val, 0, max_dst_val ); - * { 0, 5, 10, 15 } - * lrintf( ((float) i / max_src_val) * max_dst_val ) - * { 0, 5, 10, 15 } - * - * The latter two are equivalent and give an even distribution; we use the - * second, since the first doesn't scale max_src_val to max_dst_val. - * - * Having separate formulas for increasing and decreasing resolution seems - * strange; what's wrong here? */ - if( max_src_val > max_dst_val ) - for( uint32_t i = 0; i <= max_src_val; ++i ) - lookup[c][i] = (uint8_t) SCALE( i, 0, max_src_val+1, 0, max_dst_val+1 ); - else - for( uint32_t i = 0; i <= max_src_val; ++i ) - lookup[c][i] = (uint8_t) SCALE( i, 0, max_src_val, 0, max_dst_val ); - } - } - - while( height-- ) - { - int x = 0; - while( x++ < width ) - { - unsigned int pixel = RageSurfaceUtils::decodepixel( src, src_surf->format->BytesPerPixel ); - - // Convert pixel to the destination format. - unsigned int opixel = 0; - for( int c = 0; c < 4; ++c ) - { - int lSrc = (pixel & src_masks[c]) >> src_shifts[c]; - opixel |= lookup[c][lSrc] << dst_shifts[c]; - } - - // Store it. - RageSurfaceUtils::encodepixel( dst, dst_surf->format->BytesPerPixel, opixel ); - - src += src_surf->format->BytesPerPixel; - dst += dst_surf->format->BytesPerPixel; - } - - src += srcskip; - dst += dstskip; - } - - return true; -} - -static bool blit_generic( const RageSurface *src_surf, const RageSurface *dst_surf, int width, int height ) -{ - if( src_surf->format->BytesPerPixel != 1 || dst_surf->format->BytesPerPixel == 1 ) - return false; - - const uint8_t *src = src_surf->pixels; - uint8_t *dst = dst_surf->pixels; - - // Bytes to skip at the end of a line. - const int srcskip = src_surf->pitch - width*src_surf->format->BytesPerPixel; - const int dstskip = dst_surf->pitch - width*dst_surf->format->BytesPerPixel; - - while( height-- ) - { - int x = 0; - while( x++ < width ) - { - unsigned int pixel = RageSurfaceUtils::decodepixel( src, src_surf->format->BytesPerPixel ); - - uint8_t colors[4]; - // Convert pixel to the destination RGBA. - colors[0] = src_surf->format->palette->colors[pixel].r; - colors[1] = src_surf->format->palette->colors[pixel].g; - colors[2] = src_surf->format->palette->colors[pixel].b; - colors[3] = src_surf->format->palette->colors[pixel].a; - pixel = RageSurfaceUtils::SetRGBAV(dst_surf->format, colors); - - // Store it. - RageSurfaceUtils::encodepixel( dst, dst_surf->format->BytesPerPixel, pixel ); - - src += src_surf->format->BytesPerPixel; - dst += dst_surf->format->BytesPerPixel; - } - - src += srcskip; - dst += dstskip; - } - - return true; -} - -// Blit src onto dst. -void RageSurfaceUtils::Blit( const RageSurface *src, RageSurface *dst, int width, int height ) -{ - if( width == -1 ) - width = src->w; - if( height == -1 ) - height = src->h; - width = min( src->w, dst->w ); - height = min( src->h, dst->h ); - - /* Try each blit until we find one that works; run them in order of efficiency, - * so we use the fastest blit possible. */ - do - { - // RGBA->RGBA with the same format, or PAL->PAL. Simple copy. - if( blit_same_type(src, dst, width, height) ) - break; - - // RGBA->RGBA with different formats. - if( blit_rgba_to_rgba(src, dst, width, height) ) - break; - - // PAL->RGBA. - if( blit_generic(src, dst, width, height) ) - break; - - FAIL_M("We don't do RGBA->PAL"); - } while(0); - - /* The destination surface may be larger than the source. For example, we may be - * blitting a 200x200 image onto a 256x256 surface for OpenGL. Normally, that extra - * space isn't actually used; we'll only render the image space. However, bilinear - * filtering will cause the lines of pixels at 201x... and ...x201 to be visible. We - * need to make sure those pixels make sense. - * - * Previously, we just cleared the image to transparent or the color key. This - * has two problems. First, we may not have space for a color key (an image with - * 256 non-transparent palette colors). Second, that's not completely correct; - * it'll force the outside border of the image to filter to transparent. If the image - * is being tiled with another image, that may leave seams. - * - * (In some cases, filtering to transparent is preferable, particularly when displaying - * a sprite in perspective. If you want that, add blank space to the image explicitly.) - * - * Copy the last column (200x... -> 201x...), then the last row (...x200 -> ...x201). */ - - CorrectBorderPixels( dst, width, height ); -} - -/* If only width x height of img is actually going to be used, and there's extra - * space on the surface, duplicate the last row and column to ensure that we don't - * pull in unexpected data when rendering with bilinear filtering. - * - * We do this if there's memory available, even if that space extends outside - * of the image (in the per-line padding or after the end). This way, surfaces - * can be padded to power-of-two dimensions by the image loaders, and if no other - * adjustments are needed, they can be passed directly to the renderer without - * doing any extra copies. */ -void RageSurfaceUtils::CorrectBorderPixels( RageSurface *img, int width, int height ) -{ - if( width*img->fmt.BytesPerPixel < img->pitch ) - { - // Duplicate the last column. - int offset = img->format->BytesPerPixel * (width-1); - uint8_t *p = (uint8_t *) img->pixels + offset; - - for( int y = 0; y < height; ++y ) - { - uint32_t pixel = decodepixel( p, img->format->BytesPerPixel ); - encodepixel( p+img->format->BytesPerPixel, img->format->BytesPerPixel, pixel ); - - p += img->pitch; - } - } - - if( height < img->h ) - { - // Duplicate the last row. - uint8_t *srcp = img->pixels; - srcp += img->pitch * (height-1); - memcpy( srcp + img->pitch, srcp, img->pitch ); - } -} - -struct SurfaceHeader -{ - int width, height, pitch; - int Rmask, Gmask, Bmask, Amask; - int bpp; -}; - -// Save and load RageSurfaces to disk, in a very fast, nonportable way. -bool RageSurfaceUtils::SaveSurface( const RageSurface *img, RString file ) -{ - RageFile f; - if( !f.Open( file, RageFile::WRITE ) ) - return false; - - SurfaceHeader h; - memset( &h, 0, sizeof(h) ); - - h.height = img->h; - h.width = img->w; - h.pitch = img->pitch; - h.Rmask = img->format->Rmask; - h.Gmask = img->format->Gmask; - h.Bmask = img->format->Bmask; - h.Amask = img->format->Amask; - h.bpp = img->format->BitsPerPixel; - - f.Write( &h, sizeof(h) ); - - if( h.bpp == 8 ) - { - f.Write( &img->format->palette->ncolors, sizeof(img->format->palette->ncolors) ); - f.Write( img->format->palette->colors, img->format->palette->ncolors * sizeof(RageSurfaceColor) ); - } - - f.Write( img->pixels, img->h * img->pitch ); - - return true; -} - -RageSurface *RageSurfaceUtils::LoadSurface( RString file ) -{ - RageFile f; - if( !f.Open( file ) ) - return NULL; - - SurfaceHeader h; - if( f.Read( &h, sizeof(h) ) != sizeof(h) ) - return NULL; - - RageSurfacePalette palette; - if( h.bpp == 8 ) - { - if( f.Read( &palette.ncolors, sizeof(palette.ncolors) ) != sizeof(palette.ncolors) ) - return NULL; - ASSERT_M( palette.ncolors <= 256, ssprintf("%i", palette.ncolors) ); - if( f.Read( palette.colors, palette.ncolors * sizeof(RageSurfaceColor) ) != int(palette.ncolors * sizeof(RageSurfaceColor)) ) - return NULL; - } - - // Create the surface. - RageSurface *img = CreateSurface( h.width, h.height, h.bpp, - h.Rmask, h.Gmask, h.Bmask, h.Amask ); - ASSERT( img != NULL ); - - /* If the pitch has changed, this surface is either corrupt, or was - * created with a different version whose CreateSurface() behavior - * was different. */ - if( h.pitch != img->pitch ) - { - LOG->Trace( "Error loading \"%s\": expected pitch %i, got %i (%ibpp, %i width)", - file.c_str(), h.pitch, img->pitch, h.bpp, h.width ); - delete img; - return NULL; - } - - if( f.Read( img->pixels, h.height * h.pitch ) != h.height * h.pitch ) - { - delete img; - return NULL; - } - - // Set the palette. - if( h.bpp == 8 ) - *img->fmt.palette = palette; - - return img; -} - -/* This converts an image to a special 8-bit paletted format. The palette is set up - * so that palette indexes look like regular, packed components. - * - * For example, an image with 8 bits of grayscale and 0 bits of alpha has a palette - * that looks like { 0,0,0,255 }, { 1,1,1,255 }, { 2,2,2,255 }, ... { 255,255,255,255 }. - * This results in index components that can be treated as grayscale values. - * - * An image with 2 bits of grayscale and 2 bits of alpha look like - * { 0,0,0,0 }, { 85,85,85,0 }, { 170,170,170,0 }, { 255,255,255,0 }, - * { 0,0,0,85 }, { 85,85,85,85 }, { 170,170,170,85 }, { 255,255,255,85 }, ... - * - * This results in index components that can be pulled apart like regular packed - * values: the first two bits of the index are the grayscale component, and the next - * two bits are the alpha component. - * - * This gives us a generic way to handle arbitrary 8-bit texture formats. */ -RageSurface *RageSurfaceUtils::PalettizeToGrayscale( const RageSurface *src_surf, int GrayBits, int AlphaBits ) -{ - AlphaBits = min( AlphaBits, 8-src_surf->format->Loss[3] ); - - const int TotalBits = GrayBits + AlphaBits; - ASSERT( TotalBits <= 8 ); - - RageSurface *dst_surf = CreateSurface(src_surf->w, src_surf->h, - 8, 0,0,0,0 ); - - // Set up the palette. - const int TotalColors = 1 << TotalBits; - const int Ivalues = 1 << GrayBits; // number of intensity values - const int Ishift = 0; // intensity shift - const int Imask = ((1 << GrayBits) - 1) << Ishift; // intensity mask - const int Iloss = 8-GrayBits; - - const int Avalues = 1 << AlphaBits; // number of alpha values - const int Ashift = GrayBits; // alpha shift - const int Amask = ((1 << AlphaBits) - 1) << Ashift; // alpha mask - const int Aloss = 8-AlphaBits; - - for( int index = 0; index < TotalColors; ++index ) - { - const int I = (index & Imask) >> Ishift; - const int A = (index & Amask) >> Ashift; - - int ScaledI; - if( Ivalues == 1 ) - ScaledI = 255; // if only one intensity value, always fullbright - else - ScaledI = clamp( lrintf(I * (255.0f / (Ivalues-1))), 0L, 255L ); - - int ScaledA; - if( Avalues == 1 ) - ScaledA = 255; // if only one alpha value, always opaque - else - ScaledA = clamp( lrintf(A * (255.0f / (Avalues-1))), 0L, 255L ); - - RageSurfaceColor c; - c.r = uint8_t(ScaledI); - c.g = uint8_t(ScaledI); - c.b = uint8_t(ScaledI); - c.a = uint8_t(ScaledA); - - dst_surf->fmt.palette->colors[index] = c; - } - - const uint8_t *src = src_surf->pixels; - uint8_t *dst = dst_surf->pixels; - - int height = src_surf->h; - int width = src_surf->w; - - // Bytes to skip at the end of a line. - const int srcskip = src_surf->pitch - width*src_surf->format->BytesPerPixel; - const int dstskip = dst_surf->pitch - width*dst_surf->format->BytesPerPixel; - - while( height-- ) - { - int x = 0; - while( x++ < width ) - { - unsigned int pixel = decodepixel( src, src_surf->format->BytesPerPixel ); - - uint8_t colors[4]; - GetRGBAV(pixel, src_surf, colors); - - int Ival = 0; - Ival += colors[0]; - Ival += colors[1]; - Ival += colors[2]; - Ival /= 3; - - pixel = (Ival >> Iloss) << Ishift | - (colors[3] >> Aloss) << Ashift; - - // Store it. - *dst = uint8_t(pixel); - - src += src_surf->format->BytesPerPixel; - dst += dst_surf->format->BytesPerPixel; - } - - src += srcskip; - dst += dstskip; - } - - return dst_surf; -} - - -RageSurface *RageSurfaceUtils::MakeDummySurface( int height, int width ) -{ - RageSurface *ret_image = CreateSurface( width, height, 8, 0,0,0,0 ); - - RageSurfaceColor pink( 0xFF, 0x10, 0xFF, 0xFF ); - ret_image->fmt.palette->colors[0] = pink; - - memset( ret_image->pixels, 0, ret_image->h*ret_image->pitch ); - - return ret_image; -} - -/* HACK: Some banners and textures have #F800F8 as the color key. - * Search the edge for it; if we find it, use that as the color key. */ -static bool ImageUsesOffHotPink( const RageSurface *img ) -{ - uint32_t OffHotPink; - if( !img->format->MapRGBA( 0xF8, 0, 0xF8, 0xFF, OffHotPink ) ) - return false; - - const uint8_t *p = img->pixels; - for( int x = 0; x < img->w; ++x ) - { - uint32_t val = RageSurfaceUtils::decodepixel( p, img->format->BytesPerPixel ); - if( val == OffHotPink ) - return true; - p += img->format->BytesPerPixel; - } - - p = img->pixels; - p += img->pitch * (img->h-1); - for( int i=0; i < img->w; i++ ) - { - uint32_t val = RageSurfaceUtils::decodepixel( p, img->format->BytesPerPixel ); - if( val == OffHotPink ) - return true; - p += img->format->BytesPerPixel; - } - return false; -} - -/* Set #FF00FF and #F800F8 to transparent. img may be reallocated if it has no - * alpha bits. */ -void RageSurfaceUtils::ApplyHotPinkColorKey( RageSurface *&img ) -{ - if( img->format->BitsPerPixel == 8 ) - { - uint32_t color; - if( img->format->MapRGBA( 0xF8, 0, 0xF8, 0xFF, color ) ) - img->format->palette->colors[ color ].a = 0; - if( img->format->MapRGBA( 0xFF, 0, 0xFF, 0xFF, color ) ) - img->format->palette->colors[ color ].a = 0; - return; - } - - // RGBA. Make sure we have alpha. - if( img->format->Amask == 0 ) - { - // We don't have any alpha. Try to enable it without copying. - /* XXX: need to scan the surface and make sure the new alpha bit is always 1 */ - /* - const int used_bits = img->format->Rmask | img->format->Gmask | img->format->Bmask; - - for( int i = 0; img->format->Amask == 0 && i < img->format->BitsPerPixel; ++i ) - { - if( (used_bits & (1<format->Amask = 1<format->Aloss = 7; - img->format->Ashift = (uint8_t) i; - } - } - */ - // If we didn't have any free bits, convert to make room. - if( img->format->Amask == 0 ) - ConvertSurface( img, img->w, img->h, - 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF ); - } - - uint32_t HotPink; - - bool bHaveColorKey; - if( ImageUsesOffHotPink(img) ) - bHaveColorKey = img->format->MapRGBA( 0xF8, 0, 0xF8, 0xFF, HotPink ); - else - bHaveColorKey = img->format->MapRGBA( 0xFF, 0, 0xFF, 0xFF, HotPink ); - if( !bHaveColorKey ) - return; - - for( int y = 0; y < img->h; ++y ) - { - uint8_t *row = img->pixels + img->pitch*y; - - for( int x = 0; x < img->w; ++x ) - { - uint32_t val = decodepixel( row, img->format->BytesPerPixel ); - if( val == HotPink ) - encodepixel( row, img->format->BytesPerPixel, 0 ); - - row += img->format->BytesPerPixel; - } - } -} - -void RageSurfaceUtils::FlipVertically( RageSurface *img ) -{ - const int pitch = img->pitch; - const int bytes_per_row = img->format->BytesPerPixel * img->w; - char *row = new char[bytes_per_row]; - - for( int y=0; y < img->h/2; y++ ) - { - int y2 = img->h-1-y; - memcpy( row, img->pixels + pitch * y, bytes_per_row ); - memcpy( img->pixels + pitch * y, img->pixels + pitch * y2, bytes_per_row ); - memcpy( img->pixels + pitch * y2, row, bytes_per_row ); - } - - delete [] row; -} - -/* - * (c) 2001-2004 Glenn Maynard, Chris Danford - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "RageSurfaceUtils.h" +#include "RageSurface.h" +#include "RageUtil.h" +#include "RageLog.h" +#include "RageFile.h" + +uint32_t RageSurfaceUtils::decodepixel( const uint8_t *p, int bpp ) +{ + switch(bpp) + { + case 1: return *p; + case 2: return *(uint16_t *)p; + case 3: + if( BYTE_ORDER == BIG_ENDIAN ) + return p[0] << 16 | p[1] << 8 | p[2]; + else + return p[0] | p[1] << 8 | p[2] << 16; + + case 4: return *(uint32_t *)p; + default: return 0; // shouldn't happen, but avoids warnings + } +} + +void RageSurfaceUtils::encodepixel( uint8_t *p, int bpp, uint32_t pixel ) +{ + switch(bpp) + { + case 1: *p = uint8_t(pixel); break; + case 2: *(uint16_t *)p = uint16_t(pixel); break; + case 3: + if( BYTE_ORDER == BIG_ENDIAN ) + { + p[0] = uint8_t((pixel >> 16) & 0xff); + p[1] = uint8_t((pixel >> 8) & 0xff); + p[2] = uint8_t(pixel & 0xff); + } else { + p[0] = uint8_t(pixel & 0xff); + p[1] = uint8_t((pixel >> 8) & 0xff); + p[2] = uint8_t((pixel >> 16) & 0xff); + } + break; + case 4: *(uint32_t *)p = pixel; break; + } +} + +// Get and set colors without scaling to 0..255. +void RageSurfaceUtils::GetRawRGBAV( uint32_t pixel, const RageSurfaceFormat &fmt, uint8_t *v ) +{ + if( fmt.BytesPerPixel == 1 ) + { + v[0] = fmt.palette->colors[pixel].r; + v[1] = fmt.palette->colors[pixel].g; + v[2] = fmt.palette->colors[pixel].b; + v[3] = fmt.palette->colors[pixel].a; + } else { + v[0] = uint8_t((pixel & fmt.Rmask) >> fmt.Rshift); + v[1] = uint8_t((pixel & fmt.Gmask) >> fmt.Gshift); + v[2] = uint8_t((pixel & fmt.Bmask) >> fmt.Bshift); + v[3] = uint8_t((pixel & fmt.Amask) >> fmt.Ashift); + } +} + +void RageSurfaceUtils::GetRawRGBAV( const uint8_t *p, const RageSurfaceFormat &fmt, uint8_t *v ) +{ + uint32_t pixel = decodepixel( p, fmt.BytesPerPixel ); + GetRawRGBAV( pixel, fmt, v ); +} + +void RageSurfaceUtils::GetRGBAV( uint32_t pixel, const RageSurface *src, uint8_t *v ) +{ + GetRawRGBAV(pixel, src->fmt, v); + const RageSurfaceFormat *fmt = src->format; + for( int c = 0; c < 4; ++c ) + v[c] = v[c] << fmt->Loss[c]; + + // Correct for surfaces that don't have an alpha channel. + if( fmt->Loss[3] == 8 ) + v[3] = 255; +} + +void RageSurfaceUtils::GetRGBAV( const uint8_t *p, const RageSurface *src, uint8_t *v ) +{ + uint32_t pixel = decodepixel(p, src->format->BytesPerPixel); + if( src->format->BytesPerPixel == 1 ) // paletted + { + memcpy( v, &src->format->palette->colors[pixel], sizeof(RageSurfaceColor)); + } + else // RGBA + GetRGBAV(pixel, src, v); +} + + +// Inverse of GetRawRGBAV. +uint32_t RageSurfaceUtils::SetRawRGBAV( const RageSurfaceFormat *fmt, const uint8_t *v ) +{ + return v[0] << fmt->Rshift | + v[1] << fmt->Gshift | + v[2] << fmt->Bshift | + v[3] << fmt->Ashift; +} + +void RageSurfaceUtils::SetRawRGBAV( uint8_t *p, const RageSurface *src, const uint8_t *v ) +{ + uint32_t pixel = SetRawRGBAV(src->format, v); + encodepixel(p, src->format->BytesPerPixel, pixel); +} + +// Inverse of GetRGBAV. +uint32_t RageSurfaceUtils::SetRGBAV( const RageSurfaceFormat *fmt, const uint8_t *v ) +{ + return (v[0] >> fmt->Loss[0]) << fmt->Shift[0] | + (v[1] >> fmt->Loss[1]) << fmt->Shift[1] | + (v[2] >> fmt->Loss[2]) << fmt->Shift[2] | + (v[3] >> fmt->Loss[3]) << fmt->Shift[3]; +} + +void RageSurfaceUtils::SetRGBAV( uint8_t *p, const RageSurface *src, const uint8_t *v ) +{ + uint32_t pixel = SetRGBAV(src->format, v); + encodepixel(p, src->format->BytesPerPixel, pixel); +} + + +void RageSurfaceUtils::GetBitsPerChannel( const RageSurfaceFormat *fmt, uint32_t bits[4] ) +{ + // The actual bits stored in each color is 8-loss. + for( int c = 0; c < 4; ++c ) + bits[c] = 8 - fmt->Loss[c]; +} + +void RageSurfaceUtils::CopySurface( const RageSurface *src, RageSurface *dest ) +{ + // Copy the palette, if we have one. + if( src->format->BitsPerPixel == 8 && dest->format->BitsPerPixel == 8 ) + { + ASSERT( dest->fmt.palette != nullptr ); + *dest->fmt.palette = *src->fmt.palette; + } + + Blit( src, dest, -1, -1 ); +} + +bool RageSurfaceUtils::ConvertSurface( const RageSurface *src, RageSurface *&dst, + int width, int height, int bpp, + uint32_t R, uint32_t G, uint32_t B, uint32_t A ) +{ + dst = CreateSurface( width, height, bpp, R, G, B, A ); + + // If the formats are the same, no conversion is needed. Ignore the palette. + if( width == src->w && height == src->h && src->format->Equivalent( *dst->format ) ) + { + delete dst; + dst = nullptr; + return false; + } + + CopySurface( src, dst ); + return true; +} + +void RageSurfaceUtils::ConvertSurface(RageSurface *&image, + int width, int height, int bpp, + uint32_t R, uint32_t G, uint32_t B, uint32_t A) +{ + RageSurface *ret_image; + if( !ConvertSurface( image, ret_image, width, height, bpp, R, G, B, A ) ) + return; + + delete image; + image = ret_image; +} + + +// Local helper for FixHiddenAlpha. +static void FindAlphaRGB(const RageSurface *img, uint8_t &r, uint8_t &g, uint8_t &b, bool reverse) +{ + r = g = b = 0; + + // If we have no alpha, there's no alpha color. + if( img->format->BitsPerPixel > 8 && !img->format->Amask ) + return; + + // Eww. Sorry. Iterate front-to-back or in reverse. + for(int y = reverse? img->h-1:0; + reverse? (y >=0):(y < img->h); reverse? (--y):(++y)) + { + uint8_t *row = (uint8_t *)img->pixels + img->pitch*y; + if(reverse) + row += img->format->BytesPerPixel * (img->w-1); + + for(int x = 0; x < img->w; ++x) + { + uint32_t val = RageSurfaceUtils::decodepixel(row, img->format->BytesPerPixel); + if( img->format->BitsPerPixel == 8 ) + { + if( img->format->palette->colors[val].a ) + { + // This color isn't fully transparent, so grab it. + r = img->format->palette->colors[val].r; + g = img->format->palette->colors[val].g; + b = img->format->palette->colors[val].b; + return; + } + } + else + { + if( val & img->format->Amask ) + { + // This color isn't fully transparent, so grab it. + img->format->GetRGB( val, &r, &g, &b ); + return; + } + } + + if( reverse ) + row -= img->format->BytesPerPixel; + else + row += img->format->BytesPerPixel; + } + } + + // Huh? The image is completely transparent. + r = g = b = 0; +} + +/* Local helper for FixHiddenAlpha. Set the underlying RGB values of all pixels + * in img that are completely transparent. */ +static void SetAlphaRGB(const RageSurface *pImg, uint8_t r, uint8_t g, uint8_t b) +{ + // If it's a paletted surface, all we have to do is change the palette. + if( pImg->format->BitsPerPixel == 8 ) + { + for( int c = 0; c < pImg->format->palette->ncolors; ++c ) + { + if( pImg->format->palette->colors[c].a ) + continue; + pImg->format->palette->colors[c].r = r; + pImg->format->palette->colors[c].g = g; + pImg->format->palette->colors[c].b = b; + } + return; + } + + // If it's RGBA and there's no alpha channel, we have nothing to do. + if( pImg->format->BitsPerPixel > 8 && !pImg->format->Amask ) + return; + + uint32_t trans; + pImg->format->MapRGBA( r, g, b, 0, trans ); + for( int y = 0; y < pImg->h; ++y ) + { + uint8_t *row = pImg->pixels + pImg->pitch*y; + + for( int x = 0; x < pImg->w; ++x ) + { + uint32_t val = RageSurfaceUtils::decodepixel( row, pImg->format->BytesPerPixel ); + if( val != trans && !(val&pImg->format->Amask) ) + { + RageSurfaceUtils::encodepixel( row, pImg->format->BytesPerPixel, trans ); + } + + row += pImg->format->BytesPerPixel; + } + } +} + +/* When we scale up images (which we always do in high res), pixels + * that are completely transparent can be blended with opaque pixels, + * causing their RGB elements to show. This is visible in many textures + * as a pixel-wide border in the wrong color. This is tricky to fix. + * We need to set the RGB components of completely transparent pixels + * to a reasonable color. + * + * Most images have a single border color. For these, the transparent + * color is easy: search through the image top-bottom-left-right, + * find the first non-transparent pixel, and pull out its RGB. + * + * A few images don't. We can only make a guess here. After the above + * search, do the same in reverse (bottom-top-right-left). If the color + * we find is different, just set the border color to black. + */ +void RageSurfaceUtils::FixHiddenAlpha( RageSurface *pImg ) +{ + // If there are no alpha bits, there's nothing to fix. + if( pImg->format->BitsPerPixel != 8 && pImg->format->Amask == 0 ) + return; + + uint8_t r, g, b; + FindAlphaRGB( pImg, r, g, b, false ); + + uint8_t cr, cg, cb; // compare + FindAlphaRGB( pImg, cr, cg, cb, true ); + + if( cr != r || cg != g || cb != b ) + r = g = b = 0; + + SetAlphaRGB( pImg, r, g, b ); +} + +/* Scan the surface to see what level of alpha it uses. This can be used to + * find the best surface format for a texture; eg. a TRAIT_BOOL_TRANSPARENCY or + * TRAIT_NO_TRANSPARENCY surface can use RGB5A1 instead of RGBA4 for greater + * color resolution; a TRAIT_NO_TRANSPARENCY could also use R5G6B5. */ +int RageSurfaceUtils::FindSurfaceTraits( const RageSurface *img ) +{ + const int NEEDS_NO_ALPHA=0, NEEDS_BOOL_ALPHA=1, NEEDS_FULL_ALPHA=2; + int alpha_type = NEEDS_NO_ALPHA; + + uint32_t max_alpha; + if( img->format->BitsPerPixel == 8 ) + { + // Short circuit if we already know we have no transparency. + bool bHaveNonOpaque = false; + for( int c = 0; !bHaveNonOpaque && c < img->format->palette->ncolors; ++c ) + { + if( img->format->palette->colors[c].a != 0xFF ) + bHaveNonOpaque = true; + } + + if( !bHaveNonOpaque ) + return TRAIT_NO_TRANSPARENCY; + + max_alpha = 0xFF; + } + else + { + // Short circuit if we already know we have no transparency. + if( img->format->Amask == 0 ) + return TRAIT_NO_TRANSPARENCY; + + max_alpha = img->format->Amask; + } + + for(int y = 0; y < img->h; ++y) + { + uint8_t *row = (uint8_t *)img->pixels + img->pitch*y; + + for(int x = 0; x < img->w; ++x) + { + uint32_t val = decodepixel(row, img->format->BytesPerPixel); + + uint32_t alpha; + if( img->format->BitsPerPixel == 8 ) + alpha = img->format->palette->colors[val].a; + else + alpha = (val & img->format->Amask); + + if( alpha == 0 ) + alpha_type = max( alpha_type, NEEDS_BOOL_ALPHA ); + else if( alpha != max_alpha ) + alpha_type = max( alpha_type, NEEDS_FULL_ALPHA ); + + row += img->format->BytesPerPixel; + } + } + + int ret = 0; + switch( alpha_type ) + { + case NEEDS_NO_ALPHA: ret |= TRAIT_NO_TRANSPARENCY; break; + case NEEDS_BOOL_ALPHA: ret |= TRAIT_BOOL_TRANSPARENCY; break; + case NEEDS_FULL_ALPHA: break; + default: + FAIL_M(ssprintf("Invalid alpha type: %i", alpha_type)); + } + + return ret; +} + + +// Local helper for BlitTransform. +static inline void GetRawRGBAV_XY( const RageSurface *src, uint8_t *v, int x, int y ) +{ + const uint8_t *srcp = (const uint8_t *) src->pixels + (y * src->pitch); + const uint8_t *srcpx = srcp + (x * src->fmt.BytesPerPixel); + + RageSurfaceUtils::GetRawRGBAV( srcpx, src->fmt, v ); +} + +static inline float scale( float x, float l1, float h1, float l2, float h2 ) +{ + return ((x - l1) / (h1 - l1) * (h2 - l2) + l2); +} + +// Completely unoptimized. +void RageSurfaceUtils::BlitTransform( const RageSurface *src, RageSurface *dst, + const float fCoords[8] /* TL, BR, BL, TR */ ) +{ + ASSERT( src->format->BytesPerPixel == dst->format->BytesPerPixel ); + + const float Coords[8] = { + (fCoords[0] * (src->w)), (fCoords[1] * (src->h)), + (fCoords[2] * (src->w)), (fCoords[3] * (src->h)), + (fCoords[4] * (src->w)), (fCoords[5] * (src->h)), + (fCoords[6] * (src->w)), (fCoords[7] * (src->h)) + }; + + const int TL_X = 0, TL_Y = 1, BL_X = 2, BL_Y = 3, + BR_X = 4, BR_Y = 5, TR_X = 6, TR_Y = 7; + + for( int y = 0; y < dst->h; ++y ) + { + uint8_t *dstp = (uint8_t *) dst->pixels + (y * dst->pitch); /* line */ + uint8_t *dstpx = dstp; // pixel + + const float start_y = scale(float(y), 0, float(dst->h), Coords[TL_Y], Coords[BL_Y]); + const float end_y = scale(float(y), 0, float(dst->h), Coords[TR_Y], Coords[BR_Y]); + + const float start_x = scale(float(y), 0, float(dst->h), Coords[TL_X], Coords[BL_X]); + const float end_x = scale(float(y), 0, float(dst->h), Coords[TR_X], Coords[BR_X]); + + for( int x = 0; x < dst->w; ++x ) + { + const float src_xp = scale(float(x), 0, float(dst->w), start_x, end_x); + const float src_yp = scale(float(x), 0, float(dst->w), start_y, end_y); + + /* If the surface is two pixels wide, src_xp is 0..2. .5 indicates + * pixel[0]; 1 indicates 50% pixel[0], 50% pixel[1]; 1.5 indicates + * pixel[1]; 2 indicates 50% pixel[1], 50% pixel[2] (which is clamped + * to pixel[1]). */ + int src_x[2], src_y[2]; + src_x[0] = (int) truncf(src_xp - 0.5f); + src_x[1] = src_x[0] + 1; + + src_y[0] = (int) truncf(src_yp - 0.5f); + src_y[1] = src_y[0] + 1; + + // Emulate GL_REPEAT. + src_x[0] = clamp(src_x[0], 0, src->w); + src_x[1] = clamp(src_x[1], 0, src->w); + src_y[0] = clamp(src_y[0], 0, src->h); + src_y[1] = clamp(src_y[1], 0, src->h); + + // Decode our four pixels. + uint8_t v[4][4]; + GetRawRGBAV_XY(src, v[0], src_x[0], src_y[0]); + GetRawRGBAV_XY(src, v[1], src_x[0], src_y[1]); + GetRawRGBAV_XY(src, v[2], src_x[1], src_y[0]); + GetRawRGBAV_XY(src, v[3], src_x[1], src_y[1]); + + // Distance from the pixel chosen: + float weight_x = src_xp - (src_x[0] + 0.5f); + float weight_y = src_yp - (src_y[0] + 0.5f); + + // Filter: + uint8_t out[4] = { 0,0,0,0 }; + for(int i = 0; i < 4; ++i) + { + float sum = 0; + sum += v[0][i] * (1-weight_x) * (1-weight_y); + sum += v[1][i] * (1-weight_x) * (weight_y); + sum += v[2][i] * (weight_x) * (1-weight_y); + sum += v[3][i] * (weight_x) * (weight_y); + out[i] = (uint8_t) clamp( lrintf(sum), 0L, 255L ); + } + + // If the source has no alpha, set the destination to opaque. + if( src->format->Amask == 0 ) + out[3] = uint8_t( dst->format->Amask >> dst->format->Ashift ); + + SetRawRGBAV(dstpx, dst, out); + + dstpx += dst->format->BytesPerPixel; + } + } +} + + +/* Simplified: + * + * No source alpha. + * Palette -> palette blits assume the palette is identical (no mapping). + * No color key. + * No general blitting rects. */ + +static bool blit_same_type( const RageSurface *src_surf, const RageSurface *dst_surf, int width, int height ) +{ + if( src_surf->format->BytesPerPixel != dst_surf->format->BytesPerPixel || + src_surf->format->Rmask != dst_surf->format->Rmask || + src_surf->format->Gmask != dst_surf->format->Gmask || + src_surf->format->Bmask != dst_surf->format->Bmask || + src_surf->format->Amask != dst_surf->format->Amask ) + return false; + + const uint8_t *src = src_surf->pixels; + uint8_t *dst = dst_surf->pixels; + + // If possible, memcpy the whole thing. + if( src_surf->w == width && dst_surf->w == width && src_surf->pitch == dst_surf->pitch ) + { + memcpy( dst, src, height*src_surf->pitch ); + return true; + } + + // The rows don't line up, so memcpy row by row. + while( height-- ) + { + memcpy( dst, src, width*src_surf->format->BytesPerPixel ); + src += src_surf->pitch; + dst += dst_surf->pitch; + } + + return true; +} + +/* Rescaling blit with no ckey. This is used to update movies in + * D3D, so optimization is very important. */ +static bool blit_rgba_to_rgba( const RageSurface *src_surf, const RageSurface *dst_surf, int width, int height ) +{ + if( src_surf->format->BytesPerPixel == 1 || dst_surf->format->BytesPerPixel == 1 ) + return false; + + const uint8_t *src = src_surf->pixels; + uint8_t *dst = dst_surf->pixels; + + // Bytes to skip at the end of a line. + const int srcskip = src_surf->pitch - width*src_surf->format->BytesPerPixel; + const int dstskip = dst_surf->pitch - width*dst_surf->format->BytesPerPixel; + + const uint32_t *src_shifts = src_surf->format->Shift; + const uint32_t *dst_shifts = dst_surf->format->Shift; + const uint32_t *src_masks = src_surf->format->Mask; + const uint32_t *dst_masks = dst_surf->format->Mask; + + uint8_t lookup[4][256]; + for( int c = 0; c < 4; ++c ) + { + const uint32_t max_src_val = src_masks[c] >> src_shifts[c]; + const uint32_t max_dst_val = dst_masks[c] >> dst_shifts[c]; + ASSERT( max_src_val <= 0xFF ); + ASSERT( max_dst_val <= 0xFF ); + + if( src_masks[c] == 0 ) + { + /* The source is missing a channel. Alpha defaults to opaque, other + * channels default to 0. */ + if( c == 3 ) + lookup[c][0] = (uint8_t) max_dst_val; + else + lookup[c][0] = 0; + } else { + /* Calculate a color conversion table. There are a few ways we can do + * this (each list is the resulting table for 4->2 bit): + * + * SCALE( i, 0, max_src_val+1, 0, max_dst_val+1 ); + * { 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3 } + * SCALE( i, 0, max_src_val, 0, max_dst_val ); + * { 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3 } + * lrintf( ((float) i / max_src_val) * max_dst_val ) + * { 0, 0, 0, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3 } + * + * We use the first for increasing resolution, since it gives the most even + * distribution. + * + * 2->4 bit: + * SCALE( i, 0, max_src_val+1, 0, max_dst_val+1 ); + * { 0, 4, 8, 12 } + * SCALE( i, 0, max_src_val, 0, max_dst_val ); + * { 0, 5, 10, 15 } + * lrintf( ((float) i / max_src_val) * max_dst_val ) + * { 0, 5, 10, 15 } + * + * The latter two are equivalent and give an even distribution; we use the + * second, since the first doesn't scale max_src_val to max_dst_val. + * + * Having separate formulas for increasing and decreasing resolution seems + * strange; what's wrong here? */ + if( max_src_val > max_dst_val ) + for( uint32_t i = 0; i <= max_src_val; ++i ) + lookup[c][i] = (uint8_t) SCALE( i, 0, max_src_val+1, 0, max_dst_val+1 ); + else + for( uint32_t i = 0; i <= max_src_val; ++i ) + lookup[c][i] = (uint8_t) SCALE( i, 0, max_src_val, 0, max_dst_val ); + } + } + + while( height-- ) + { + int x = 0; + while( x++ < width ) + { + unsigned int pixel = RageSurfaceUtils::decodepixel( src, src_surf->format->BytesPerPixel ); + + // Convert pixel to the destination format. + unsigned int opixel = 0; + for( int c = 0; c < 4; ++c ) + { + int lSrc = (pixel & src_masks[c]) >> src_shifts[c]; + opixel |= lookup[c][lSrc] << dst_shifts[c]; + } + + // Store it. + RageSurfaceUtils::encodepixel( dst, dst_surf->format->BytesPerPixel, opixel ); + + src += src_surf->format->BytesPerPixel; + dst += dst_surf->format->BytesPerPixel; + } + + src += srcskip; + dst += dstskip; + } + + return true; +} + +static bool blit_generic( const RageSurface *src_surf, const RageSurface *dst_surf, int width, int height ) +{ + if( src_surf->format->BytesPerPixel != 1 || dst_surf->format->BytesPerPixel == 1 ) + return false; + + const uint8_t *src = src_surf->pixels; + uint8_t *dst = dst_surf->pixels; + + // Bytes to skip at the end of a line. + const int srcskip = src_surf->pitch - width*src_surf->format->BytesPerPixel; + const int dstskip = dst_surf->pitch - width*dst_surf->format->BytesPerPixel; + + while( height-- ) + { + int x = 0; + while( x++ < width ) + { + unsigned int pixel = RageSurfaceUtils::decodepixel( src, src_surf->format->BytesPerPixel ); + + uint8_t colors[4]; + // Convert pixel to the destination RGBA. + colors[0] = src_surf->format->palette->colors[pixel].r; + colors[1] = src_surf->format->palette->colors[pixel].g; + colors[2] = src_surf->format->palette->colors[pixel].b; + colors[3] = src_surf->format->palette->colors[pixel].a; + pixel = RageSurfaceUtils::SetRGBAV(dst_surf->format, colors); + + // Store it. + RageSurfaceUtils::encodepixel( dst, dst_surf->format->BytesPerPixel, pixel ); + + src += src_surf->format->BytesPerPixel; + dst += dst_surf->format->BytesPerPixel; + } + + src += srcskip; + dst += dstskip; + } + + return true; +} + +// Blit src onto dst. +void RageSurfaceUtils::Blit( const RageSurface *src, RageSurface *dst, int width, int height ) +{ + if( width == -1 ) + width = src->w; + if( height == -1 ) + height = src->h; + width = min( src->w, dst->w ); + height = min( src->h, dst->h ); + + /* Try each blit until we find one that works; run them in order of efficiency, + * so we use the fastest blit possible. */ + do + { + // RGBA->RGBA with the same format, or PAL->PAL. Simple copy. + if( blit_same_type(src, dst, width, height) ) + break; + + // RGBA->RGBA with different formats. + if( blit_rgba_to_rgba(src, dst, width, height) ) + break; + + // PAL->RGBA. + if( blit_generic(src, dst, width, height) ) + break; + + FAIL_M("We don't do RGBA->PAL"); + } while(0); + + /* The destination surface may be larger than the source. For example, we may be + * blitting a 200x200 image onto a 256x256 surface for OpenGL. Normally, that extra + * space isn't actually used; we'll only render the image space. However, bilinear + * filtering will cause the lines of pixels at 201x... and ...x201 to be visible. We + * need to make sure those pixels make sense. + * + * Previously, we just cleared the image to transparent or the color key. This + * has two problems. First, we may not have space for a color key (an image with + * 256 non-transparent palette colors). Second, that's not completely correct; + * it'll force the outside border of the image to filter to transparent. If the image + * is being tiled with another image, that may leave seams. + * + * (In some cases, filtering to transparent is preferable, particularly when displaying + * a sprite in perspective. If you want that, add blank space to the image explicitly.) + * + * Copy the last column (200x... -> 201x...), then the last row (...x200 -> ...x201). */ + + CorrectBorderPixels( dst, width, height ); +} + +/* If only width x height of img is actually going to be used, and there's extra + * space on the surface, duplicate the last row and column to ensure that we don't + * pull in unexpected data when rendering with bilinear filtering. + * + * We do this if there's memory available, even if that space extends outside + * of the image (in the per-line padding or after the end). This way, surfaces + * can be padded to power-of-two dimensions by the image loaders, and if no other + * adjustments are needed, they can be passed directly to the renderer without + * doing any extra copies. */ +void RageSurfaceUtils::CorrectBorderPixels( RageSurface *img, int width, int height ) +{ + if( width*img->fmt.BytesPerPixel < img->pitch ) + { + // Duplicate the last column. + int offset = img->format->BytesPerPixel * (width-1); + uint8_t *p = (uint8_t *) img->pixels + offset; + + for( int y = 0; y < height; ++y ) + { + uint32_t pixel = decodepixel( p, img->format->BytesPerPixel ); + encodepixel( p+img->format->BytesPerPixel, img->format->BytesPerPixel, pixel ); + + p += img->pitch; + } + } + + if( height < img->h ) + { + // Duplicate the last row. + uint8_t *srcp = img->pixels; + srcp += img->pitch * (height-1); + memcpy( srcp + img->pitch, srcp, img->pitch ); + } +} + +struct SurfaceHeader +{ + int width, height, pitch; + int Rmask, Gmask, Bmask, Amask; + int bpp; +}; + +// Save and load RageSurfaces to disk, in a very fast, nonportable way. +bool RageSurfaceUtils::SaveSurface( const RageSurface *img, RString file ) +{ + RageFile f; + if( !f.Open( file, RageFile::WRITE ) ) + return false; + + SurfaceHeader h; + memset( &h, 0, sizeof(h) ); + + h.height = img->h; + h.width = img->w; + h.pitch = img->pitch; + h.Rmask = img->format->Rmask; + h.Gmask = img->format->Gmask; + h.Bmask = img->format->Bmask; + h.Amask = img->format->Amask; + h.bpp = img->format->BitsPerPixel; + + f.Write( &h, sizeof(h) ); + + if( h.bpp == 8 ) + { + f.Write( &img->format->palette->ncolors, sizeof(img->format->palette->ncolors) ); + f.Write( img->format->palette->colors, img->format->palette->ncolors * sizeof(RageSurfaceColor) ); + } + + f.Write( img->pixels, img->h * img->pitch ); + + return true; +} + +RageSurface *RageSurfaceUtils::LoadSurface( RString file ) +{ + RageFile f; + if( !f.Open( file ) ) + return nullptr; + + SurfaceHeader h; + if( f.Read( &h, sizeof(h) ) != sizeof(h) ) + return nullptr; + + RageSurfacePalette palette; + if( h.bpp == 8 ) + { + if( f.Read( &palette.ncolors, sizeof(palette.ncolors) ) != sizeof(palette.ncolors) ) + return nullptr; + ASSERT_M( palette.ncolors <= 256, ssprintf("%i", palette.ncolors) ); + if( f.Read( palette.colors, palette.ncolors * sizeof(RageSurfaceColor) ) != int(palette.ncolors * sizeof(RageSurfaceColor)) ) + return nullptr; + } + + // Create the surface. + RageSurface *img = CreateSurface( h.width, h.height, h.bpp, + h.Rmask, h.Gmask, h.Bmask, h.Amask ); + ASSERT( img != nullptr ); + + /* If the pitch has changed, this surface is either corrupt, or was + * created with a different version whose CreateSurface() behavior + * was different. */ + if( h.pitch != img->pitch ) + { + LOG->Trace( "Error loading \"%s\": expected pitch %i, got %i (%ibpp, %i width)", + file.c_str(), h.pitch, img->pitch, h.bpp, h.width ); + delete img; + return nullptr; + } + + if( f.Read( img->pixels, h.height * h.pitch ) != h.height * h.pitch ) + { + delete img; + return nullptr; + } + + // Set the palette. + if( h.bpp == 8 ) + *img->fmt.palette = palette; + + return img; +} + +/* This converts an image to a special 8-bit paletted format. The palette is set up + * so that palette indexes look like regular, packed components. + * + * For example, an image with 8 bits of grayscale and 0 bits of alpha has a palette + * that looks like { 0,0,0,255 }, { 1,1,1,255 }, { 2,2,2,255 }, ... { 255,255,255,255 }. + * This results in index components that can be treated as grayscale values. + * + * An image with 2 bits of grayscale and 2 bits of alpha look like + * { 0,0,0,0 }, { 85,85,85,0 }, { 170,170,170,0 }, { 255,255,255,0 }, + * { 0,0,0,85 }, { 85,85,85,85 }, { 170,170,170,85 }, { 255,255,255,85 }, ... + * + * This results in index components that can be pulled apart like regular packed + * values: the first two bits of the index are the grayscale component, and the next + * two bits are the alpha component. + * + * This gives us a generic way to handle arbitrary 8-bit texture formats. */ +RageSurface *RageSurfaceUtils::PalettizeToGrayscale( const RageSurface *src_surf, int GrayBits, int AlphaBits ) +{ + AlphaBits = min( AlphaBits, 8-src_surf->format->Loss[3] ); + + const int TotalBits = GrayBits + AlphaBits; + ASSERT( TotalBits <= 8 ); + + RageSurface *dst_surf = CreateSurface(src_surf->w, src_surf->h, + 8, 0,0,0,0 ); + + // Set up the palette. + const int TotalColors = 1 << TotalBits; + const int Ivalues = 1 << GrayBits; // number of intensity values + const int Ishift = 0; // intensity shift + const int Imask = ((1 << GrayBits) - 1) << Ishift; // intensity mask + const int Iloss = 8-GrayBits; + + const int Avalues = 1 << AlphaBits; // number of alpha values + const int Ashift = GrayBits; // alpha shift + const int Amask = ((1 << AlphaBits) - 1) << Ashift; // alpha mask + const int Aloss = 8-AlphaBits; + + for( int index = 0; index < TotalColors; ++index ) + { + const int I = (index & Imask) >> Ishift; + const int A = (index & Amask) >> Ashift; + + int ScaledI; + if( Ivalues == 1 ) + ScaledI = 255; // if only one intensity value, always fullbright + else + ScaledI = clamp( lrintf(I * (255.0f / (Ivalues-1))), 0L, 255L ); + + int ScaledA; + if( Avalues == 1 ) + ScaledA = 255; // if only one alpha value, always opaque + else + ScaledA = clamp( lrintf(A * (255.0f / (Avalues-1))), 0L, 255L ); + + RageSurfaceColor c; + c.r = uint8_t(ScaledI); + c.g = uint8_t(ScaledI); + c.b = uint8_t(ScaledI); + c.a = uint8_t(ScaledA); + + dst_surf->fmt.palette->colors[index] = c; + } + + const uint8_t *src = src_surf->pixels; + uint8_t *dst = dst_surf->pixels; + + int height = src_surf->h; + int width = src_surf->w; + + // Bytes to skip at the end of a line. + const int srcskip = src_surf->pitch - width*src_surf->format->BytesPerPixel; + const int dstskip = dst_surf->pitch - width*dst_surf->format->BytesPerPixel; + + while( height-- ) + { + int x = 0; + while( x++ < width ) + { + unsigned int pixel = decodepixel( src, src_surf->format->BytesPerPixel ); + + uint8_t colors[4]; + GetRGBAV(pixel, src_surf, colors); + + int Ival = 0; + Ival += colors[0]; + Ival += colors[1]; + Ival += colors[2]; + Ival /= 3; + + pixel = (Ival >> Iloss) << Ishift | + (colors[3] >> Aloss) << Ashift; + + // Store it. + *dst = uint8_t(pixel); + + src += src_surf->format->BytesPerPixel; + dst += dst_surf->format->BytesPerPixel; + } + + src += srcskip; + dst += dstskip; + } + + return dst_surf; +} + + +RageSurface *RageSurfaceUtils::MakeDummySurface( int height, int width ) +{ + RageSurface *ret_image = CreateSurface( width, height, 8, 0,0,0,0 ); + + RageSurfaceColor pink( 0xFF, 0x10, 0xFF, 0xFF ); + ret_image->fmt.palette->colors[0] = pink; + + memset( ret_image->pixels, 0, ret_image->h*ret_image->pitch ); + + return ret_image; +} + +/* HACK: Some banners and textures have #F800F8 as the color key. + * Search the edge for it; if we find it, use that as the color key. */ +static bool ImageUsesOffHotPink( const RageSurface *img ) +{ + uint32_t OffHotPink; + if( !img->format->MapRGBA( 0xF8, 0, 0xF8, 0xFF, OffHotPink ) ) + return false; + + const uint8_t *p = img->pixels; + for( int x = 0; x < img->w; ++x ) + { + uint32_t val = RageSurfaceUtils::decodepixel( p, img->format->BytesPerPixel ); + if( val == OffHotPink ) + return true; + p += img->format->BytesPerPixel; + } + + p = img->pixels; + p += img->pitch * (img->h-1); + for( int i=0; i < img->w; i++ ) + { + uint32_t val = RageSurfaceUtils::decodepixel( p, img->format->BytesPerPixel ); + if( val == OffHotPink ) + return true; + p += img->format->BytesPerPixel; + } + return false; +} + +/* Set #FF00FF and #F800F8 to transparent. img may be reallocated if it has no + * alpha bits. */ +void RageSurfaceUtils::ApplyHotPinkColorKey( RageSurface *&img ) +{ + if( img->format->BitsPerPixel == 8 ) + { + uint32_t color; + if( img->format->MapRGBA( 0xF8, 0, 0xF8, 0xFF, color ) ) + img->format->palette->colors[ color ].a = 0; + if( img->format->MapRGBA( 0xFF, 0, 0xFF, 0xFF, color ) ) + img->format->palette->colors[ color ].a = 0; + return; + } + + // RGBA. Make sure we have alpha. + if( img->format->Amask == 0 ) + { + // We don't have any alpha. Try to enable it without copying. + /* XXX: need to scan the surface and make sure the new alpha bit is always 1 */ + /* + const int used_bits = img->format->Rmask | img->format->Gmask | img->format->Bmask; + + for( int i = 0; img->format->Amask == 0 && i < img->format->BitsPerPixel; ++i ) + { + if( (used_bits & (1<format->Amask = 1<format->Aloss = 7; + img->format->Ashift = (uint8_t) i; + } + } + */ + // If we didn't have any free bits, convert to make room. + if( img->format->Amask == 0 ) + ConvertSurface( img, img->w, img->h, + 32, 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF ); + } + + uint32_t HotPink; + + bool bHaveColorKey; + if( ImageUsesOffHotPink(img) ) + bHaveColorKey = img->format->MapRGBA( 0xF8, 0, 0xF8, 0xFF, HotPink ); + else + bHaveColorKey = img->format->MapRGBA( 0xFF, 0, 0xFF, 0xFF, HotPink ); + if( !bHaveColorKey ) + return; + + for( int y = 0; y < img->h; ++y ) + { + uint8_t *row = img->pixels + img->pitch*y; + + for( int x = 0; x < img->w; ++x ) + { + uint32_t val = decodepixel( row, img->format->BytesPerPixel ); + if( val == HotPink ) + encodepixel( row, img->format->BytesPerPixel, 0 ); + + row += img->format->BytesPerPixel; + } + } +} + +void RageSurfaceUtils::FlipVertically( RageSurface *img ) +{ + const int pitch = img->pitch; + const int bytes_per_row = img->format->BytesPerPixel * img->w; + char *row = new char[bytes_per_row]; + + for( int y=0; y < img->h/2; y++ ) + { + int y2 = img->h-1-y; + memcpy( row, img->pixels + pitch * y, bytes_per_row ); + memcpy( img->pixels + pitch * y, img->pixels + pitch * y2, bytes_per_row ); + memcpy( img->pixels + pitch * y2, row, bytes_per_row ); + } + + delete [] row; +} + +/* + * (c) 2001-2004 Glenn Maynard, Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/RageSurfaceUtils_Palettize.cpp b/src/RageSurfaceUtils_Palettize.cpp index c22d6d8ed6..ee96958f0a 100644 --- a/src/RageSurfaceUtils_Palettize.cpp +++ b/src/RageSurfaceUtils_Palettize.cpp @@ -48,7 +48,7 @@ struct acolorhash_hash for( unsigned i = 0; i < HASH_SIZE; ++i ) { acolorhist_list achl, achlnext; - for ( achl = hash[i]; achl != NULL; achl = achlnext ) + for ( achl = hash[i]; achl != nullptr; achl = achlnext ) { achlnext = achl->next; free( achl ); @@ -103,7 +103,7 @@ void RageSurfaceUtils::Palettize( RageSurface *&pImg, int iColors, bool bDither { ASSERT( iColors != 0 ); - acolorhist_item *acolormap=NULL; + acolorhist_item *acolormap=nullptr; int newcolors = 0; // "apixel", etc. make assumptions about byte order. @@ -123,7 +123,7 @@ void RageSurfaceUtils::Palettize( RageSurface *&pImg, int iColors, bool bDither for(;;) { achv = pam_computeacolorhist( pImg, MAXCOLORS, &colors ); - if( achv != NULL ) + if( achv != nullptr ) { break; } @@ -175,7 +175,7 @@ void RageSurfaceUtils::Palettize( RageSurface *&pImg, int iColors, bool bDither acolorhash_hash acht; bool fs_direction = 0; - pixerror_t *thiserr = NULL, *nexterr = NULL; + pixerror_t *thiserr = nullptr, *nexterr = nullptr; if( bDither ) { @@ -227,8 +227,8 @@ void RageSurfaceUtils::Palettize( RageSurface *&pImg, int iColors, bool bDither if( ind == -1 ) { // No; search acolormap for closest match. - static int square_table[512], *pSquareTable = NULL; - if( pSquareTable == NULL ) + static int square_table[512], *pSquareTable = nullptr; + if( pSquareTable == nullptr ) { pSquareTable = square_table+256; for( int c = -256; c < 256; ++c ) @@ -336,9 +336,9 @@ static acolorhist_item *mediancut( acolorhist_item *achv, int colors, int sum, i int boxes; bv = (box_vector) malloc( sizeof(struct box) * newcolors ); - ASSERT( bv != NULL ); + ASSERT( bv != nullptr ); acolormap = (acolorhist_item*) malloc( sizeof(struct acolorhist_item) * newcolors); - ASSERT( acolormap != NULL ); + ASSERT( acolormap != nullptr ); for ( int i = 0; i < newcolors; ++i ) PAM_ASSIGN( acolormap[i].acolor, 0, 0, 0, 0 ); @@ -522,17 +522,17 @@ static bool pam_computeacolorhash( const RageSurface *src, int maxacolors, int* { int hashval = pam_hashapixel( *pP ); acolorhist_list achl; - for ( achl = hash.hash[hashval]; achl != NULL; achl = achl->next ) + for ( achl = hash.hash[hashval]; achl != nullptr; achl = achl->next ) if ( PAM_EQUAL( achl->ch.acolor, *pP ) ) break; - if ( achl != NULL ) + if ( achl != nullptr ) ++achl->ch.value; else { if ( ++(*acolorsP) > maxacolors ) return false; achl = (acolorhist_list) malloc( sizeof(struct acolorhist_list_item) ); - ASSERT( achl != NULL ); + ASSERT( achl != nullptr ); memcpy( achl->ch.acolor, *pP, sizeof(apixel) ); achl->ch.value = 1; @@ -549,13 +549,13 @@ static acolorhist_item *pam_acolorhashtoacolorhist( const acolorhash_hash &acht, { // Collate the hash table into a simple acolorhist array. acolorhist_item *achv = (acolorhist_item*) malloc( maxacolors * sizeof(struct acolorhist_item) ); - ASSERT( achv != NULL ); + ASSERT( achv != nullptr ); // Loop through the hash table. int j = 0; for( unsigned i = 0; i < HASH_SIZE; ++i ) { - for ( acolorhist_list achl = acht.hash[i]; achl != NULL; achl = achl->next ) + for ( acolorhist_list achl = acht.hash[i]; achl != nullptr; achl = achl->next ) { // Add the new entry. achv[j] = achl->ch; @@ -571,7 +571,7 @@ static acolorhist_item *pam_computeacolorhist( const RageSurface *src, int maxac { acolorhash_hash acht; if ( !pam_computeacolorhash( src, maxacolors, acolorsP, acht ) ) - return NULL; + return nullptr; acolorhist_item *achv = pam_acolorhashtoacolorhist( acht, *acolorsP ); return achv; @@ -580,7 +580,7 @@ static acolorhist_item *pam_computeacolorhist( const RageSurface *src, int maxac static void pam_addtoacolorhash( acolorhash_hash &acht, const uint8_t acolorP[4], int value ) { acolorhist_list achl = (acolorhist_list) malloc( sizeof(struct acolorhist_list_item) ); - ASSERT( achl != NULL ); + ASSERT( achl != nullptr ); int hash = pam_hashapixel( acolorP ); memcpy( achl->ch.acolor, acolorP, sizeof(apixel) ); @@ -593,7 +593,7 @@ static void pam_addtoacolorhash( acolorhash_hash &acht, const uint8_t acolorP[4] static int pam_lookupacolor( const acolorhash_hash &acht, const uint8_t acolorP[4] ) { const int hash = pam_hashapixel( acolorP ); - for ( acolorhist_list_item *achl = acht.hash[hash]; achl != NULL; achl = achl->next ) + for ( acolorhist_list_item *achl = acht.hash[hash]; achl != nullptr; achl = achl->next ) if ( PAM_EQUAL( achl->ch.acolor, acolorP ) ) return achl->ch.value; diff --git a/src/RageSurfaceUtils_Zoom.cpp b/src/RageSurfaceUtils_Zoom.cpp index de9691b243..b519645512 100644 --- a/src/RageSurfaceUtils_Zoom.cpp +++ b/src/RageSurfaceUtils_Zoom.cpp @@ -133,7 +133,7 @@ void RageSurfaceUtils::Zoom( RageSurface *&src, int dstwidth, int dstheight ) { ASSERT_M( dstwidth > 0, ssprintf("%i",dstwidth) ); ASSERT_M( dstheight > 0, ssprintf("%i",dstheight) ); - if( src == NULL ) + if( src == nullptr ) return; if( src->w == dstwidth && src->h == dstheight ) diff --git a/src/RageSurface_Load.cpp b/src/RageSurface_Load.cpp index 663c07b1fd..da384d9723 100644 --- a/src/RageSurface_Load.cpp +++ b/src/RageSurface_Load.cpp @@ -13,7 +13,7 @@ static RageSurface *TryOpenFile( RString sPath, bool bHeaderOnly, RString &error, RString format, bool &bKeepTrying ) { - RageSurface *ret = NULL; + RageSurface *ret = nullptr; RageSurfaceUtils::OpenResult result; if( !format.CompareNoCase("png") ) result = RageSurface_Load_PNG( sPath, ret, bHeaderOnly, error ); @@ -27,12 +27,12 @@ static RageSurface *TryOpenFile( RString sPath, bool bHeaderOnly, RString &error { error = "Unsupported format"; bKeepTrying = true; - return NULL; + return nullptr; } if( result == RageSurfaceUtils::OPEN_OK ) { - ASSERT( ret != NULL ); + ASSERT( ret != nullptr ); return ret; } @@ -71,7 +71,7 @@ static RageSurface *TryOpenFile( RString sPath, bool bHeaderOnly, RString &error default: break; } - return NULL; + return nullptr; } RageSurface *RageSurfaceUtils::LoadFile( const RString &sPath, RString &error, bool bHeaderOnly ) @@ -81,7 +81,7 @@ RageSurface *RageSurfaceUtils::LoadFile( const RString &sPath, RString &error, b if( !TestOpen.Open( sPath ) ) { error = TestOpen.GetError(); - return NULL; + return nullptr; } } @@ -117,7 +117,7 @@ RageSurface *RageSurfaceUtils::LoadFile( const RString &sPath, RString &error, b } } - return NULL; + return nullptr; } /* diff --git a/src/RageSurface_Load_BMP.cpp b/src/RageSurface_Load_BMP.cpp index 686beb9721..53269d9cf6 100644 --- a/src/RageSurface_Load_BMP.cpp +++ b/src/RageSurface_Load_BMP.cpp @@ -1,236 +1,236 @@ -#include "global.h" -#include "RageSurface_Load_BMP.h" -#include "RageFile.h" -#include "RageUtil.h" -#include "RageLog.h" -#include "RageSurface.h" -using namespace FileReading; - -/* Tested with http://entropymine.com/jason/bmpsuite/. */ - -enum -{ - COMP_BI_RGB = 0, - COMP_BI_RLE4, /* unsupported */ - COMP_BI_RLE8, /* unsupported */ - COMP_BI_BITFIELDS -}; - - -/* When returning error, the first error encountered takes priority. */ -#define FATAL_ERROR(s) \ -{ \ - if( sError.size() == 0 ) sError = (s); \ - return RageSurfaceUtils::OPEN_FATAL_ERROR; \ -} - -static RageSurfaceUtils::OpenResult LoadBMP( RageFile &f, RageSurface *&img, RString &sError ) -{ - char magic[2]; - ReadBytes( f, magic, 2, sError ); - if( magic[0] != 'B' || magic[1] != 'M' ) - { - sError = "not a BMP"; - return RageSurfaceUtils::OPEN_UNKNOWN_FILE_FORMAT; - } - - img = NULL; - - read_u32_le( f, sError ); /* file size */ - read_u32_le( f, sError ); /* unused */ - uint32_t iDataOffset = read_u32_le( f, sError ); - uint32_t iHeaderSize = read_u32_le( f, sError ); - - uint32_t iWidth, iHeight, iPlanes, iBPP, iCompression = COMP_BI_RGB, iColors = 0; - if( iHeaderSize == 12 ) - { - /* OS/2 format */ - iWidth = read_u16_le( f, sError ); - iHeight = read_u16_le( f, sError ); - iPlanes = read_u16_le( f, sError ); - iBPP = read_u16_le( f, sError ); - } - else if( iHeaderSize == 40 ) - { - iWidth = read_u32_le( f, sError ); - iHeight = read_u32_le( f, sError ); - iPlanes = read_u16_le( f, sError ); - iBPP = read_u16_le( f, sError ); - iCompression = read_u32_le( f, sError ); - read_u32_le( f, sError ); /* bitmap size */ - read_u32_le( f, sError ); /* horiz resolution */ - read_u32_le( f, sError ); /* vert resolution */ - iColors = read_u32_le( f, sError ); - read_u32_le( f, sError ); /* "important" colors */ - } - else - FATAL_ERROR( ssprintf( "expected header size of 40, got %u", iHeaderSize ) ); - - if( iBPP <= 8 && iColors == 0 ) - iColors = 1 << iBPP; - if( iPlanes != 1 ) - FATAL_ERROR( ssprintf( "expected one plane, got %u", iPlanes ) ); - if( iBPP != 1 && iBPP != 4 && iBPP != 8 && iBPP != 16 && iBPP != 24 && iBPP != 32 ) - FATAL_ERROR( ssprintf( "unsupported bpp %u", iBPP ) ); - if( iCompression != COMP_BI_RGB && iCompression != COMP_BI_BITFIELDS ) - FATAL_ERROR( ssprintf( "unsupported compression %u", iCompression ) ); - - if( iCompression == COMP_BI_BITFIELDS && iBPP <= 8 ) - FATAL_ERROR( ssprintf( "BI_BITFIELDS unexpected with bpp %u", iBPP ) ); - - int iFileBPP = iBPP; - iBPP = max( iBPP, 8u ); - - int Rmask = 0, Gmask = 0, Bmask = 0, Amask = 0; - switch( iBPP ) - { - case 16: - Rmask = Swap16LE( 0x7C00 ); - Gmask = Swap16LE( 0x03E0 ); - Bmask = Swap16LE( 0x001F ); - break; - case 24: - Rmask = Swap24LE( 0xFF0000 ); - Gmask = Swap24LE( 0x00FF00 ); - Bmask = Swap24LE( 0x0000FF ); - break; - case 32: - Rmask = Swap32LE( 0x00FF0000 ); - Gmask = Swap32LE( 0x0000FF00 ); - Bmask = Swap32LE( 0x000000FF ); - break; - } - - if( iCompression == COMP_BI_BITFIELDS ) - { - Rmask = read_u32_le( f, sError ); - Gmask = read_u32_le( f, sError ); - Bmask = read_u32_le( f, sError ); - } - - /* Stop on error before we use any of the values we just read. */ - if( sError.size() != 0 ) - return RageSurfaceUtils::OPEN_FATAL_ERROR; - - img = CreateSurface( iWidth, iHeight, iBPP, Rmask, Gmask, Bmask, Amask ); - - if( iBPP == 8 ) - { - RageSurfaceColor Palette[256]; - ZERO( Palette ); - - if( iColors > 256 ) - FATAL_ERROR( ssprintf( "unexpected colors %i", iColors ) ); - - for( unsigned i = 0; i < iColors; ++i ) - { - Palette[i].b = read_8( f, sError ); - Palette[i].g = read_8( f, sError ); - Palette[i].r = read_8( f, sError ); - Palette[i].a = 0xFF; - /* Windows BMP palettes are padded to 32bpp. */ - if( iHeaderSize == 40 ) - read_8( f, sError ); - } - - memcpy( img->fmt.palette->colors, Palette, sizeof(Palette) ); - } - - /* Stop on error before we seek, so we don't return the wrong error message. */ - if( sError.size() != 0 ) - return RageSurfaceUtils::OPEN_FATAL_ERROR; - - int iFilePitch = iFileBPP * iWidth; // in bits - iFilePitch = (iFilePitch+7) / 8; // in bytes: round up - iFilePitch = (iFilePitch+3) & ~3; // round up a multiple of 4 - - { - int ret = f.Seek( iDataOffset ); - if( ret == -1 ) - FATAL_ERROR( f.GetError() ); - if( ret != (int) iDataOffset ) - FATAL_ERROR( "Unexpected end of file" ); - } - - for( int y = (int) iHeight-1; y >= 0; --y ) - { - uint8_t *pRow = img->pixels + img->pitch*y; - RString buf; - - f.Read( buf, iFilePitch ); - - /* Expand 1- and 4-bits to 8-bits. */ - if( iFileBPP == 1 ) - { - for( unsigned x = 0; x < iWidth; ++x ) - { - int iByteNo = x >> 3; - int iBitNo = 7-(x&7); - int iBit = 1 << iBitNo; - pRow[x] = !!(buf[iByteNo] & iBit); - } - } - else if( iFileBPP == 4 ) - { - for( unsigned x = 0; x < iWidth; ++x ) - { - if( (x & 1) == 0 ) - pRow[x] = buf[x/2] & 0x0F; - else - pRow[x] = (buf[x/2] >> 4) & 0x0F; - } - } - else - memcpy( pRow, buf.data(), img->pitch ); - } - - return sError.size() != 0? RageSurfaceUtils::OPEN_FATAL_ERROR: RageSurfaceUtils::OPEN_OK; -} - -RageSurfaceUtils::OpenResult RageSurface_Load_BMP( const RString &sPath, RageSurface *&img, bool bHeaderOnly, RString &error ) -{ - RageFile f; - - if( !f.Open( sPath ) ) - { - error = f.GetError(); - return RageSurfaceUtils::OPEN_FATAL_ERROR; - } - - RageSurfaceUtils::OpenResult ret; - img = NULL; - ret = LoadBMP( f, img, error ); - - if( ret != RageSurfaceUtils::OPEN_OK && img != NULL ) - { - delete img; - img = NULL; - } - - return ret; -} - -/* - * Copyright (c) 2004 Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "RageSurface_Load_BMP.h" +#include "RageFile.h" +#include "RageUtil.h" +#include "RageLog.h" +#include "RageSurface.h" +using namespace FileReading; + +/* Tested with http://entropymine.com/jason/bmpsuite/. */ + +enum +{ + COMP_BI_RGB = 0, + COMP_BI_RLE4, /* unsupported */ + COMP_BI_RLE8, /* unsupported */ + COMP_BI_BITFIELDS +}; + + +/* When returning error, the first error encountered takes priority. */ +#define FATAL_ERROR(s) \ +{ \ + if( sError.size() == 0 ) sError = (s); \ + return RageSurfaceUtils::OPEN_FATAL_ERROR; \ +} + +static RageSurfaceUtils::OpenResult LoadBMP( RageFile &f, RageSurface *&img, RString &sError ) +{ + char magic[2]; + ReadBytes( f, magic, 2, sError ); + if( magic[0] != 'B' || magic[1] != 'M' ) + { + sError = "not a BMP"; + return RageSurfaceUtils::OPEN_UNKNOWN_FILE_FORMAT; + } + + img = nullptr; + + read_u32_le( f, sError ); /* file size */ + read_u32_le( f, sError ); /* unused */ + uint32_t iDataOffset = read_u32_le( f, sError ); + uint32_t iHeaderSize = read_u32_le( f, sError ); + + uint32_t iWidth, iHeight, iPlanes, iBPP, iCompression = COMP_BI_RGB, iColors = 0; + if( iHeaderSize == 12 ) + { + /* OS/2 format */ + iWidth = read_u16_le( f, sError ); + iHeight = read_u16_le( f, sError ); + iPlanes = read_u16_le( f, sError ); + iBPP = read_u16_le( f, sError ); + } + else if( iHeaderSize == 40 ) + { + iWidth = read_u32_le( f, sError ); + iHeight = read_u32_le( f, sError ); + iPlanes = read_u16_le( f, sError ); + iBPP = read_u16_le( f, sError ); + iCompression = read_u32_le( f, sError ); + read_u32_le( f, sError ); /* bitmap size */ + read_u32_le( f, sError ); /* horiz resolution */ + read_u32_le( f, sError ); /* vert resolution */ + iColors = read_u32_le( f, sError ); + read_u32_le( f, sError ); /* "important" colors */ + } + else + FATAL_ERROR( ssprintf( "expected header size of 40, got %u", iHeaderSize ) ); + + if( iBPP <= 8 && iColors == 0 ) + iColors = 1 << iBPP; + if( iPlanes != 1 ) + FATAL_ERROR( ssprintf( "expected one plane, got %u", iPlanes ) ); + if( iBPP != 1 && iBPP != 4 && iBPP != 8 && iBPP != 16 && iBPP != 24 && iBPP != 32 ) + FATAL_ERROR( ssprintf( "unsupported bpp %u", iBPP ) ); + if( iCompression != COMP_BI_RGB && iCompression != COMP_BI_BITFIELDS ) + FATAL_ERROR( ssprintf( "unsupported compression %u", iCompression ) ); + + if( iCompression == COMP_BI_BITFIELDS && iBPP <= 8 ) + FATAL_ERROR( ssprintf( "BI_BITFIELDS unexpected with bpp %u", iBPP ) ); + + int iFileBPP = iBPP; + iBPP = max( iBPP, 8u ); + + int Rmask = 0, Gmask = 0, Bmask = 0, Amask = 0; + switch( iBPP ) + { + case 16: + Rmask = Swap16LE( 0x7C00 ); + Gmask = Swap16LE( 0x03E0 ); + Bmask = Swap16LE( 0x001F ); + break; + case 24: + Rmask = Swap24LE( 0xFF0000 ); + Gmask = Swap24LE( 0x00FF00 ); + Bmask = Swap24LE( 0x0000FF ); + break; + case 32: + Rmask = Swap32LE( 0x00FF0000 ); + Gmask = Swap32LE( 0x0000FF00 ); + Bmask = Swap32LE( 0x000000FF ); + break; + } + + if( iCompression == COMP_BI_BITFIELDS ) + { + Rmask = read_u32_le( f, sError ); + Gmask = read_u32_le( f, sError ); + Bmask = read_u32_le( f, sError ); + } + + /* Stop on error before we use any of the values we just read. */ + if( sError.size() != 0 ) + return RageSurfaceUtils::OPEN_FATAL_ERROR; + + img = CreateSurface( iWidth, iHeight, iBPP, Rmask, Gmask, Bmask, Amask ); + + if( iBPP == 8 ) + { + RageSurfaceColor Palette[256]; + ZERO( Palette ); + + if( iColors > 256 ) + FATAL_ERROR( ssprintf( "unexpected colors %i", iColors ) ); + + for( unsigned i = 0; i < iColors; ++i ) + { + Palette[i].b = read_8( f, sError ); + Palette[i].g = read_8( f, sError ); + Palette[i].r = read_8( f, sError ); + Palette[i].a = 0xFF; + /* Windows BMP palettes are padded to 32bpp. */ + if( iHeaderSize == 40 ) + read_8( f, sError ); + } + + memcpy( img->fmt.palette->colors, Palette, sizeof(Palette) ); + } + + /* Stop on error before we seek, so we don't return the wrong error message. */ + if( sError.size() != 0 ) + return RageSurfaceUtils::OPEN_FATAL_ERROR; + + int iFilePitch = iFileBPP * iWidth; // in bits + iFilePitch = (iFilePitch+7) / 8; // in bytes: round up + iFilePitch = (iFilePitch+3) & ~3; // round up a multiple of 4 + + { + int ret = f.Seek( iDataOffset ); + if( ret == -1 ) + FATAL_ERROR( f.GetError() ); + if( ret != (int) iDataOffset ) + FATAL_ERROR( "Unexpected end of file" ); + } + + for( int y = (int) iHeight-1; y >= 0; --y ) + { + uint8_t *pRow = img->pixels + img->pitch*y; + RString buf; + + f.Read( buf, iFilePitch ); + + /* Expand 1- and 4-bits to 8-bits. */ + if( iFileBPP == 1 ) + { + for( unsigned x = 0; x < iWidth; ++x ) + { + int iByteNo = x >> 3; + int iBitNo = 7-(x&7); + int iBit = 1 << iBitNo; + pRow[x] = !!(buf[iByteNo] & iBit); + } + } + else if( iFileBPP == 4 ) + { + for( unsigned x = 0; x < iWidth; ++x ) + { + if( (x & 1) == 0 ) + pRow[x] = buf[x/2] & 0x0F; + else + pRow[x] = (buf[x/2] >> 4) & 0x0F; + } + } + else + memcpy( pRow, buf.data(), img->pitch ); + } + + return sError.size() != 0? RageSurfaceUtils::OPEN_FATAL_ERROR: RageSurfaceUtils::OPEN_OK; +} + +RageSurfaceUtils::OpenResult RageSurface_Load_BMP( const RString &sPath, RageSurface *&img, bool bHeaderOnly, RString &error ) +{ + RageFile f; + + if( !f.Open( sPath ) ) + { + error = f.GetError(); + return RageSurfaceUtils::OPEN_FATAL_ERROR; + } + + RageSurfaceUtils::OpenResult ret; + img = nullptr; + ret = LoadBMP( f, img, error ); + + if( ret != RageSurfaceUtils::OPEN_OK && img != nullptr ) + { + delete img; + img = nullptr; + } + + return ret; +} + +/* + * Copyright (c) 2004 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/RageSurface_Load_GIF.cpp b/src/RageSurface_Load_GIF.cpp index 72c91e8024..7c8a5e3d2f 100644 --- a/src/RageSurface_Load_GIF.cpp +++ b/src/RageSurface_Load_GIF.cpp @@ -399,14 +399,14 @@ static RageSurface *ReadImage( RageFile &f, int len, int height, if( !state.Init(f) ) { // RWSetMsg("error reading image"); - return NULL; + return nullptr; } /* If this is an "uninteresting picture" ignore it. */ if( ignore ) { while( state.ReadByte(f) >= 0 ) ; - return NULL; + return nullptr; } RageSurface *image = CreateSurface( len, height, 8, 0, 0, 0, 0 ); diff --git a/src/RageSurface_Load_JPEG.cpp b/src/RageSurface_Load_JPEG.cpp index 0cd8494a7d..5aa297fa29 100644 --- a/src/RageSurface_Load_JPEG.cpp +++ b/src/RageSurface_Load_JPEG.cpp @@ -60,7 +60,7 @@ void RageFile_JPEG_init_source( j_decompress_ptr cinfo ) { RageFile_source_mgr *src = (RageFile_source_mgr *) cinfo->src; src->start_of_file = true; - src->pub.next_input_byte = NULL; + src->pub.next_input_byte = nullptr; src->pub.bytes_in_buffer = 0; } @@ -115,7 +115,7 @@ static RageSurface *RageSurface_Load_JPEG( RageFile *f, const char *fn, char err jerr.pub.error_exit = my_error_exit; jerr.pub.output_message = my_output_message; - RageSurface *volatile img = NULL; /* volatile to prevent possible problems with setjmp */ + RageSurface *volatile img = nullptr; /* volatile to prevent possible problems with setjmp */ if( setjmp(jerr.setjmp_buffer) ) { @@ -124,7 +124,7 @@ static RageSurface *RageSurface_Load_JPEG( RageFile *f, const char *fn, char err jpeg_destroy_decompress( &cinfo ); delete img; - return NULL; + return nullptr; } /* Now we can initialize the JPEG decompression object. */ @@ -153,7 +153,7 @@ static RageSurface *RageSurface_Load_JPEG( RageFile *f, const char *fn, char err case JCS_CMYK: sprintf( errorbuf, "Color format \"%s\" not supported", cinfo.jpeg_color_space == JCS_YCCK? "YCCK":"CMYK" ); jpeg_destroy_decompress( &cinfo ); - return NULL; + return nullptr; default: cinfo.out_color_space = JCS_RGB; @@ -206,7 +206,7 @@ RageSurfaceUtils::OpenResult RageSurface_Load_JPEG( const RString &sPath, RageSu char errorbuf[1024]; ret = RageSurface_Load_JPEG( &f, sPath, errorbuf ); - if( ret == NULL ) + if( ret == nullptr ) { error = errorbuf; return RageSurfaceUtils::OPEN_UNKNOWN_FILE_FORMAT; // XXX diff --git a/src/RageSurface_Load_PNG.cpp b/src/RageSurface_Load_PNG.cpp index 0425ad23cf..17d0de9390 100644 --- a/src/RageSurface_Load_PNG.cpp +++ b/src/RageSurface_Load_PNG.cpp @@ -75,37 +75,37 @@ static RageSurface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro png_struct *png = png_create_read_struct( PNG_LIBPNG_VER_STRING, &error, PNG_Error, PNG_Warning ); - if( png == NULL ) + if( png == nullptr ) { sprintf( errorbuf, "creating png_create_read_struct failed"); - return NULL; + return nullptr; } png_info *info_ptr = png_create_info_struct(png); - if( info_ptr == NULL ) + if( info_ptr == nullptr ) { - png_destroy_read_struct( &png, NULL, NULL ); + png_destroy_read_struct( &png, nullptr, nullptr ); sprintf( errorbuf, "creating png_create_info_struct failed"); - return NULL; + return nullptr; } - RageSurface *volatile img = NULL; + RageSurface *volatile img = nullptr; CHECKPOINT_M("Potential issue with png jump about to be analyzed."); - png_byte** row_pointers= NULL; + png_byte** row_pointers= nullptr; // Throwing an exception in the error callback would make the exception // pass through C code, which is undefined behavior. Works fine on Linux, // and on OS X with C++11, but does not work on OS X without C++11. -Kyz if(setjmp(png_jmpbuf(png))) { - png_destroy_read_struct(&png, &info_ptr, NULL); + png_destroy_read_struct(&png, &info_ptr, nullptr); delete img; - if(row_pointers != NULL) + if(row_pointers != nullptr) { delete[] row_pointers; } - return NULL; + return nullptr; } png_set_read_fn( png, f, RageFile_png_read ); @@ -114,15 +114,15 @@ static RageSurface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro png_uint_32 width, height; int bit_depth, color_type; - png_get_IHDR( png, info_ptr, &width, &height, &bit_depth, &color_type, NULL, NULL, NULL ); + png_get_IHDR( png, info_ptr, &width, &height, &bit_depth, &color_type, nullptr, nullptr, nullptr ); /* If bHeaderOnly is true, don't allocate the pixel storage space or decompress * the image. Just return an empty surface with only the width and height set. */ if( bHeaderOnly ) { CHECKPOINT_M("Header only png about to be processed."); - img = CreateSurfaceFrom( width, height, 32, 0, 0, 0, 0, NULL, width*4 ); - png_destroy_read_struct( &png, &info_ptr, NULL ); + img = CreateSurfaceFrom( width, height, 32, 0, 0, 0, 0, nullptr, width*4 ); + png_destroy_read_struct( &png, &info_ptr, nullptr ); return img; } @@ -176,7 +176,7 @@ static RageSurface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro if( color_type == PNG_COLOR_TYPE_GRAY ) { png_color_16 *trans; - if( png_get_tRNS( png, info_ptr, NULL, NULL, &trans ) == PNG_INFO_tRNS ) + if( png_get_tRNS( png, info_ptr, nullptr, nullptr, &trans ) == PNG_INFO_tRNS ) iColorKey = trans->gray; } else if( color_type == PNG_COLOR_TYPE_PALETTE ) @@ -186,9 +186,9 @@ static RageSurface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro int ret = png_get_PLTE( png, info_ptr, &palette, &num_palette ); ASSERT( ret == PNG_INFO_PLTE ); - png_byte *trans = NULL; + png_byte *trans = nullptr; int num_trans = 0; - png_get_tRNS( png, info_ptr, &trans, &num_trans, NULL ); + png_get_tRNS( png, info_ptr, &trans, &num_trans, nullptr ); for( int i = 0; i < num_palette; ++i ) { @@ -239,7 +239,7 @@ static RageSurface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro default: FAIL_M(ssprintf( "%i", type) ); } - ASSERT( img != NULL ); + ASSERT( img != nullptr ); row_pointers = new png_byte*[height]; CHECKPOINT_M( ssprintf("%p",row_pointers) ); @@ -253,7 +253,7 @@ static RageSurface *RageSurface_Load_PNG( RageFile *f, const char *fn, char erro png_read_image( png, row_pointers ); png_read_end( png, info_ptr ); - png_destroy_read_struct( &png, &info_ptr, NULL ); + png_destroy_read_struct( &png, &info_ptr, nullptr ); return img; } @@ -271,7 +271,7 @@ RageSurfaceUtils::OpenResult RageSurface_Load_PNG( const RString &sPath, RageSur char errorbuf[1024]; ret = RageSurface_Load_PNG( &f, sPath, errorbuf, bHeaderOnly ); - if( ret == NULL ) + if( ret == nullptr ) { error = errorbuf; return RageSurfaceUtils::OPEN_UNKNOWN_FILE_FORMAT; // XXX diff --git a/src/RageSurface_Load_XPM.cpp b/src/RageSurface_Load_XPM.cpp index d909633ec8..ed6e6731a1 100644 --- a/src/RageSurface_Load_XPM.cpp +++ b/src/RageSurface_Load_XPM.cpp @@ -9,9 +9,9 @@ #include #define CheckLine() \ - if( xpm[line] == NULL ) { \ + if( xpm[line] == nullptr ) { \ error = "short file"; \ - return NULL; \ + return nullptr; \ } RageSurface *RageSurface_Load_XPM( char * const *xpm, RString &error ) @@ -24,13 +24,13 @@ RageSurface *RageSurface_Load_XPM( char * const *xpm, RString &error ) if( sscanf( xpm[line++], "%i %i %i %i", &width, &height, &num_colors, &color_length ) != 4 ) { error = "parse error reading specs"; - return NULL; + return nullptr; } if( width > 2048 || height > 2048 || num_colors > 1024*16 || color_length > 4 ) { error = "spec error"; - return NULL; + return nullptr; } vector colors; @@ -85,7 +85,7 @@ RageSurface *RageSurface_Load_XPM( char * const *xpm, RString &error ) { error = ssprintf( "row %i is not expected length (%i != %i)", y, int(row.size()), width*color_length ); delete img; - return NULL; + return nullptr; } int8_t *p = (int8_t *) img->pixels; @@ -100,7 +100,7 @@ RageSurface *RageSurface_Load_XPM( char * const *xpm, RString &error ) { error = ssprintf( "%ix%i is unknown color \"%s\"", x, y, color_name.c_str() ); delete img; - return NULL; + return nullptr; } if( colors.size() <= 256 ) diff --git a/src/RageSurface_Save_JPEG.cpp b/src/RageSurface_Save_JPEG.cpp index 52365acb44..1e19039b25 100644 --- a/src/RageSurface_Save_JPEG.cpp +++ b/src/RageSurface_Save_JPEG.cpp @@ -77,7 +77,7 @@ static void term_destination (jpeg::j_compress_ptr cinfo) */ static void jpeg_RageFile_dest( jpeg::j_compress_ptr cinfo, RageFile &f ) { - ASSERT( cinfo->dest == NULL ); + ASSERT( cinfo->dest == nullptr ); cinfo->dest = (struct jpeg::jpeg_destination_mgr *) (*cinfo->mem->alloc_small) ( (jpeg::j_common_ptr) cinfo, JPOOL_PERMANENT, diff --git a/src/RageSurface_Save_PNG.cpp b/src/RageSurface_Save_PNG.cpp index 49d832e7b5..d0f2d1d3b9 100644 --- a/src/RageSurface_Save_PNG.cpp +++ b/src/RageSurface_Save_PNG.cpp @@ -85,16 +85,16 @@ static bool RageSurface_Save_PNG( RageFile &f, char szErrorbuf[1024], RageSurfac error.szErr = szErrorbuf; png_struct *pPng = png_create_write_struct( PNG_LIBPNG_VER_STRING, &error, PNG_Error, PNG_Warning ); - if( pPng == NULL ) + if( pPng == nullptr ) { sprintf( szErrorbuf, "creating png_create_write_struct failed"); return false; } png_info *pInfo = png_create_info_struct(pPng); - if( pInfo == NULL ) + if( pInfo == nullptr ) { - png_destroy_write_struct( &pPng, NULL ); + png_destroy_write_struct( &pPng, nullptr ); if( bDeleteImg ) delete pImg; sprintf( szErrorbuf, "creating png_create_info_struct failed"); diff --git a/src/RageTexture.cpp b/src/RageTexture.cpp index 55586ef849..f1502d9846 100644 --- a/src/RageTexture.cpp +++ b/src/RageTexture.cpp @@ -52,8 +52,8 @@ void RageTexture::GetFrameDimensionsFromFileName( RString sPath, int* piFramesWi return; } // Check for nonsense values. Some people might not intend the hint. -Kyz - int maybe_width= StringToInt(asMatch[0]); - int maybe_height= StringToInt(asMatch[1]); + int maybe_width= std::stoi(asMatch[0]); + int maybe_height= std::stoi(asMatch[1]); if(maybe_width <= 0 || maybe_height <= 0) { *piFramesWide = *piFramesHigh = 1; diff --git a/src/RageTextureManager.cpp b/src/RageTextureManager.cpp index a5bad909f4..fe28442a63 100644 --- a/src/RageTextureManager.cpp +++ b/src/RageTextureManager.cpp @@ -25,12 +25,11 @@ #include "RageUtil.h" #include "RageLog.h" #include "RageDisplay.h" -#include "Foreach.h" #include "ActorUtil.h" #include -RageTextureManager* TEXTUREMAN = NULL; // global and accessible from anywhere in our program +RageTextureManager* TEXTUREMAN = nullptr; // global and accessible from anywhere in our program namespace { @@ -45,11 +44,11 @@ RageTextureManager::RageTextureManager(): RageTextureManager::~RageTextureManager() { - FOREACHM( RageTextureID, RageTexture*, m_mapPathToTexture, i ) + for (std::pair i : m_mapPathToTexture) { - RageTexture* pTexture = i->second; + RageTexture* pTexture = i.second; if( pTexture->m_iRefCount ) - LOG->Trace( "TEXTUREMAN LEAK: '%s', RefCount = %d.", i->first.filename.c_str(), pTexture->m_iRefCount ); + LOG->Trace( "TEXTUREMAN LEAK: '%s', RefCount = %d.", i.first.filename.c_str(), pTexture->m_iRefCount ); SAFE_DELETE( pTexture ); } m_textures_to_update.clear(); @@ -58,9 +57,9 @@ RageTextureManager::~RageTextureManager() void RageTextureManager::Update( float fDeltaTime ) { - FOREACHM(RageTextureID, RageTexture*, m_textures_to_update, i) + for(std::pair i : m_textures_to_update) { - RageTexture* pTexture = i->second; + RageTexture* pTexture = i.second; pTexture->Update( fDeltaTime ); } } @@ -203,7 +202,7 @@ void RageTextureManager::VolatileTexture( RageTextureID ID ) void RageTextureManager::UnloadTexture( RageTexture *t ) { - if( t == NULL ) + if( t == nullptr ) return; t->m_iRefCount--; @@ -258,14 +257,14 @@ void RageTextureManager::DeleteTexture( RageTexture *t ) else { FAIL_M("Tried to delete a texture that wasn't in the ids by pointer list."); - FOREACHM( RageTextureID, RageTexture*, m_mapPathToTexture, i ) + for (map::iterator iter = m_mapPathToTexture.begin(); iter != m_mapPathToTexture.end(); ++iter) { - if( i->second == t ) + if( iter->second == t ) { - m_mapPathToTexture.erase( i ); // remove map entry + m_mapPathToTexture.erase( iter ); // remove map entry SAFE_DELETE( t ); // free the texture map::iterator tex_update_entry= - m_textures_to_update.find(i->first); + m_textures_to_update.find(iter->first); if(tex_update_entry != m_textures_to_update.end()) { m_textures_to_update.erase(tex_update_entry); @@ -334,9 +333,9 @@ void RageTextureManager::ReloadAll() * ton of cached data that we're not necessarily going to use. */ DoDelayedDelete(); - FOREACHM( RageTextureID, RageTexture*, m_mapPathToTexture, i ) + for (auto const & i : m_mapPathToTexture) { - i->second->Reload(); + i.second->Reload(); } EnableOddDimensionWarning(); @@ -350,9 +349,9 @@ void RageTextureManager::ReloadAll() * associated with a different texture). Ack. */ void RageTextureManager::InvalidateTextures() { - FOREACHM( RageTextureID, RageTexture*, m_mapPathToTexture, i ) + for (auto const & i : m_mapPathToTexture) { - RageTexture* pTexture = i->second; + RageTexture* pTexture = i.second; pTexture->Invalidate(); } } @@ -376,10 +375,10 @@ void RageTextureManager::DiagnosticOutput() const LOG->Trace( "%u textures loaded:", iCount ); int iTotal = 0; - FOREACHM_CONST( RageTextureID, RageTexture*, m_mapPathToTexture, i ) + for (auto const &i : m_mapPathToTexture) { - const RageTextureID &ID = i->first; - const RageTexture *pTex = i->second; + const RageTextureID &ID = i.first; + const RageTexture *pTex = i.second; RString sDiags = DISPLAY->GetTextureDiagnostics( pTex->GetTexHandle() ); RString sStr = ssprintf( "%3ix%3i (%2i)", pTex->GetTextureHeight(), pTex->GetTextureWidth(), diff --git a/src/RageTexturePreloader.cpp b/src/RageTexturePreloader.cpp index 772d5975cf..ba3587fcbc 100644 --- a/src/RageTexturePreloader.cpp +++ b/src/RageTexturePreloader.cpp @@ -1,74 +1,74 @@ -/* - * Preemptively load textures before use, by loading it and keeping - * a reference to it. By putting a RageTexturePreloader inside the - * object doing the preloading, the preload will exist for the lifetime - * of that object. - */ - -#include "global.h" -#include "RageTexturePreloader.h" -#include "RageTextureManager.h" - -RageTexturePreloader &RageTexturePreloader::operator=( const RageTexturePreloader &rhs ) -{ - if( &rhs == this ) - return *this; - - UnloadAll(); - - for( unsigned i = 0; i < rhs.m_apTextures.size(); ++i ) - { - RageTexture *pTexture = TEXTUREMAN->CopyTexture( rhs.m_apTextures[i] ); - m_apTextures.push_back( pTexture ); - } - - return *this; -} - -void RageTexturePreloader::Load( const RageTextureID &ID ) -{ - ASSERT( TEXTUREMAN != NULL ); - - RageTexture *pTexture = TEXTUREMAN->LoadTexture( ID ); - m_apTextures.push_back( pTexture ); -} - -void RageTexturePreloader::UnloadAll() -{ - if( TEXTUREMAN == NULL ) - return; - - for( unsigned i = 0; i < m_apTextures.size(); ++i ) - TEXTUREMAN->UnloadTexture( m_apTextures[i] ); - m_apTextures.clear(); -} - -RageTexturePreloader::~RageTexturePreloader() -{ - UnloadAll(); -} - -/* - * (c) 2005 Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +/* + * Preemptively load textures before use, by loading it and keeping + * a reference to it. By putting a RageTexturePreloader inside the + * object doing the preloading, the preload will exist for the lifetime + * of that object. + */ + +#include "global.h" +#include "RageTexturePreloader.h" +#include "RageTextureManager.h" + +RageTexturePreloader &RageTexturePreloader::operator=( const RageTexturePreloader &rhs ) +{ + if( &rhs == this ) + return *this; + + UnloadAll(); + + for( unsigned i = 0; i < rhs.m_apTextures.size(); ++i ) + { + RageTexture *pTexture = TEXTUREMAN->CopyTexture( rhs.m_apTextures[i] ); + m_apTextures.push_back( pTexture ); + } + + return *this; +} + +void RageTexturePreloader::Load( const RageTextureID &ID ) +{ + ASSERT( TEXTUREMAN != nullptr ); + + RageTexture *pTexture = TEXTUREMAN->LoadTexture( ID ); + m_apTextures.push_back( pTexture ); +} + +void RageTexturePreloader::UnloadAll() +{ + if( TEXTUREMAN == nullptr ) + return; + + for( unsigned i = 0; i < m_apTextures.size(); ++i ) + TEXTUREMAN->UnloadTexture( m_apTextures[i] ); + m_apTextures.clear(); +} + +RageTexturePreloader::~RageTexturePreloader() +{ + UnloadAll(); +} + +/* + * (c) 2005 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/RageThreads.cpp b/src/RageThreads.cpp index e3aeb6b946..8cec411e70 100644 --- a/src/RageThreads.cpp +++ b/src/RageThreads.cpp @@ -35,7 +35,7 @@ bool RageThread::s_bSystemSupportsTLS = false; bool RageThread::s_bIsShowingDialog = false; #define MAX_THREADS 128 -//static vector *g_MutexList = NULL; /* watch out for static initialization order problems */ +//static vector *g_MutexList = nullptr; /* watch out for static initialization order problems */ struct ThreadSlot { @@ -57,8 +57,8 @@ struct ThreadSlot int m_iLine; char m_szFormattedBuf[1024]; - ThreadCheckpoint() { Set( NULL, 0, NULL ); } - void Set( const char *szFile, int iLine, const char *szMessage = NULL ); + ThreadCheckpoint() { Set( nullptr, 0, nullptr ); } + void Set( const char *szFile, int iLine, const char *szMessage = nullptr ); const char *GetFormattedCheckpoint(); }; ThreadCheckpoint m_Checkpoints[CHECKPOINT_COUNT]; @@ -66,12 +66,12 @@ struct ThreadSlot const char *GetFormattedCheckpoint( int lineno ); ThreadSlot(): m_bUsed(false), m_iID(GetInvalidThreadId()), - m_pImpl(NULL), m_iCurCheckpoint(0), m_iNumCheckpoints(0) {} + m_pImpl(nullptr), m_iCurCheckpoint(0), m_iNumCheckpoints(0) {} void Init() { m_iID = GetInvalidThreadId(); m_iCurCheckpoint = m_iNumCheckpoints = 0; - m_pImpl = NULL; + m_pImpl = nullptr; /* Reset used last; otherwise, a thread creation might pick up the slot. */ m_bUsed = false; @@ -94,12 +94,12 @@ void ThreadSlot::ThreadCheckpoint::Set( const char *szFile, int iLine, const cha m_szMessage = szMessage; /* Skip any path components. */ - if( m_szFile != NULL ) + if( m_szFile != nullptr ) { const char *p = strrchr( m_szFile, '/' ); - if( p == NULL ) + if( p == nullptr ) p = strrchr( m_szFile, '\\' ); - if( p != NULL && p[1] != '\0' ) + if( p != nullptr && p[1] != '\0' ) m_szFile = p+1; } @@ -108,8 +108,8 @@ void ThreadSlot::ThreadCheckpoint::Set( const char *szFile, int iLine, const cha const char *ThreadSlot::ThreadCheckpoint::GetFormattedCheckpoint() { - if( m_szFile == NULL ) - return NULL; + if( m_szFile == nullptr ) + return nullptr; /* Make sure it's terminated: */ m_szFormattedBuf[ sizeof(m_szFormattedBuf)-1 ] = 0; @@ -120,7 +120,7 @@ const char *ThreadSlot::ThreadCheckpoint::GetFormattedCheckpoint() const char *ThreadSlot::GetFormattedCheckpoint( int lineno ) { if( lineno >= CHECKPOINT_COUNT || lineno >= m_iNumCheckpoints ) - return NULL; + return nullptr; if( m_iNumCheckpoints == CHECKPOINT_COUNT ) { @@ -132,7 +132,7 @@ const char *ThreadSlot::GetFormattedCheckpoint( int lineno ) } static ThreadSlot g_ThreadSlots[MAX_THREADS]; -struct ThreadSlot *g_pUnknownThreadSlot = NULL; +struct ThreadSlot *g_pUnknownThreadSlot = nullptr; /* Lock this mutex before using or modifying m_pImpl. Other values are just identifiers, * so possibly racing over them is harmless (simply using a stale thread ID, etc). */ @@ -194,7 +194,7 @@ static ThreadSlot *GetThreadSlotFromID( uint64_t iID ) if( g_ThreadSlots[entry].m_iID == iID ) return &g_ThreadSlots[entry]; } - return NULL; + return nullptr; } static ThreadSlot *GetCurThreadSlot() @@ -207,15 +207,15 @@ static ThreadSlot *GetUnknownThreadSlot() return g_pUnknownThreadSlot; } -RageThread::RageThread(): m_pSlot(NULL), m_sName("unnamed") {} +RageThread::RageThread(): m_pSlot(nullptr), m_sName("unnamed") {} /* Copying a thread does not start the copy. */ RageThread::RageThread( const RageThread &cpy ): - m_pSlot(NULL), m_sName(cpy.m_sName) {} + m_pSlot(nullptr), m_sName(cpy.m_sName) {} RageThread::~RageThread() { - if( m_pSlot != NULL ) + if( m_pSlot != nullptr ) Wait(); } @@ -231,7 +231,7 @@ const char *ThreadSlot::GetThreadName() const void RageThread::Create( int (*fn)(void *), void *data ) { /* Don't create a thread that's already running: */ - ASSERT( m_pSlot == NULL ); + ASSERT( m_pSlot == nullptr ); InitThreads(); @@ -275,7 +275,7 @@ RageThreadRegister::~RageThreadRegister() LockMut( GetThreadSlotsLock() ); m_pSlot->Release(); - m_pSlot = NULL; + m_pSlot = nullptr; } const char *RageThread::GetCurrentThreadName() @@ -286,7 +286,7 @@ const char *RageThread::GetCurrentThreadName() const char *RageThread::GetThreadNameByID( uint64_t iID ) { ThreadSlot *slot = GetThreadSlotFromID( iID ); - if( slot == NULL ) + if( slot == nullptr ) return "???"; return slot->GetThreadName(); @@ -310,27 +310,27 @@ bool RageThread::EnumThreadIDs( int n, uint64_t &iID ) int RageThread::Wait() { - ASSERT( m_pSlot != NULL ); - ASSERT( m_pSlot->m_pImpl != NULL ); + ASSERT( m_pSlot != nullptr ); + ASSERT( m_pSlot->m_pImpl != nullptr ); int ret = m_pSlot->m_pImpl->Wait(); LockMut( GetThreadSlotsLock() ); m_pSlot->Release(); - m_pSlot = NULL; + m_pSlot = nullptr; return ret; } void RageThread::Halt(bool Kill) { - ASSERT( m_pSlot != NULL ); - ASSERT( m_pSlot->m_pImpl != NULL ); + ASSERT( m_pSlot != nullptr ); + ASSERT( m_pSlot->m_pImpl != nullptr ); m_pSlot->m_pImpl->Halt(Kill); } void RageThread::Resume() { - ASSERT( m_pSlot != NULL ); - ASSERT( m_pSlot->m_pImpl != NULL ); + ASSERT( m_pSlot != nullptr ); + ASSERT( m_pSlot->m_pImpl != nullptr ); m_pSlot->m_pImpl->Resume(); } @@ -341,7 +341,7 @@ void RageThread::HaltAllThreads( bool Kill ) { if( !g_ThreadSlots[entry].m_bUsed ) continue; - if( ThisThreadID == g_ThreadSlots[entry].m_iID || g_ThreadSlots[entry].m_pImpl == NULL ) + if( ThisThreadID == g_ThreadSlots[entry].m_iID || g_ThreadSlots[entry].m_pImpl == nullptr ) continue; g_ThreadSlots[entry].m_pImpl->Halt( Kill ); } @@ -354,7 +354,7 @@ void RageThread::ResumeAllThreads() { if( !g_ThreadSlots[entry].m_bUsed ) continue; - if( ThisThreadID == g_ThreadSlots[entry].m_iID || g_ThreadSlots[entry].m_pImpl == NULL ) + if( ThisThreadID == g_ThreadSlots[entry].m_iID || g_ThreadSlots[entry].m_pImpl == nullptr ) continue; g_ThreadSlots[entry].m_pImpl->Resume(); @@ -381,11 +381,11 @@ void Checkpoints::LogCheckpoints( bool on ) void Checkpoints::SetCheckpoint( const char *file, int line, const char *message ) { ThreadSlot *slot = GetCurThreadSlot(); - if( slot == NULL ) + if( slot == nullptr ) slot = GetUnknownThreadSlot(); /* We can't ASSERT here, since that uses checkpoints. */ - if( slot == NULL ) - sm_crash( "GetUnknownThreadSlot() returned NULL" ); + if( slot == nullptr ) + sm_crash( "GetUnknownThreadSlot() returned nullptr" ); /* Ignore everything up to and including the first "src/". */ const char *temp = strstr( file, "src/" ); @@ -406,11 +406,11 @@ static const char *GetCheckpointLog( int slotno, int lineno ) { ThreadSlot &slot = g_ThreadSlots[slotno]; if( !slot.m_bUsed ) - return NULL; + return nullptr; /* Only show the "Unknown thread" entry if it has at least one checkpoint. */ - if( &slot == g_pUnknownThreadSlot && slot.GetFormattedCheckpoint(0) == NULL ) - return NULL; + if( &slot == g_pUnknownThreadSlot && slot.GetFormattedCheckpoint(0) == nullptr ) + return nullptr; if( lineno != 0 ) return slot.GetFormattedCheckpoint( lineno-1 ); @@ -427,12 +427,12 @@ void Checkpoints::GetLogs( char *pBuf, int iSize, const char *delim ) for( int slotno = 0; slotno < MAX_THREADS; ++slotno ) { const char *buf = GetCheckpointLog( slotno, 0 ); - if( buf == NULL ) + if( buf == nullptr ) continue; strcat( pBuf, buf ); strcat( pBuf, delim ); - for( int line = 1; (buf = GetCheckpointLog(slotno, line)) != NULL; ++line ) + for( int line = 1; (buf = GetCheckpointLog(slotno, line)) != nullptr; ++line ) { strcat( pBuf, buf ); strcat( pBuf, delim ); @@ -521,7 +521,7 @@ void RageMutex::MarkLockedMutex() } /* XXX: How can g_FreeMutexIDs and g_MutexList be threadsafed? */ -static set *g_FreeMutexIDs = NULL; +static set *g_FreeMutexIDs = nullptr; #endif RageMutex::RageMutex( const RString &name ): @@ -529,7 +529,7 @@ RageMutex::RageMutex( const RString &name ): m_LockedBy(GetInvalidThreadId()), m_LockCnt(0) { -/* if( g_FreeMutexIDs == NULL ) +/* if( g_FreeMutexIDs == nullptr ) { g_FreeMutexIDs = new set; for( int i = 0; i < MAX_MUTEXES; ++i ) @@ -554,7 +554,7 @@ RageMutex::RageMutex( const RString &name ): g_FreeMutexIDs->erase( g_FreeMutexIDs->begin() ); - if( g_MutexList == NULL ) + if( g_MutexList == nullptr ) g_MutexList = new vector; g_MutexList->push_back( this ); @@ -571,7 +571,7 @@ RageMutex::~RageMutex() if( g_MutexList->empty() ) { delete g_MutexList; - g_MutexList = NULL; + g_MutexList = nullptr; } delete m_pMutex; @@ -704,8 +704,8 @@ bool RageEvent::Wait( RageTimer *pTimeout ) ASSERT( m_LockCnt == 0 ); /* A zero RageTimer also means no timeout. */ - if( pTimeout != NULL && pTimeout->IsZero() ) - pTimeout = NULL; + if( pTimeout != nullptr && pTimeout->IsZero() ) + pTimeout = nullptr; bool bRet = m_pEvent->Wait( pTimeout ); m_LockedBy = GetThisThreadId(); diff --git a/src/RageThreads.h b/src/RageThreads.h index ef56261246..27cea773c5 100644 --- a/src/RageThreads.h +++ b/src/RageThreads.h @@ -31,7 +31,7 @@ public: static const char *GetThreadNameByID( uint64_t iID ); static bool EnumThreadIDs( int n, uint64_t &iID ); int Wait(); - bool IsCreated() const { return m_pSlot != NULL; } + bool IsCreated() const { return m_pSlot != nullptr; } /* A system can define HAVE_TLS, indicating that it can compile thread_local * code, but an individual environment may not actually have functional TLS. @@ -131,9 +131,9 @@ class LockMutex public: LockMutex(RageMutex &mut, const char *file, int line); - LockMutex(RageMutex &mut): mutex(mut), file(NULL), line(-1), locked_at(-1), locked(true) { mutex.Lock(); } + LockMutex(RageMutex &mut): mutex(mut), file(nullptr), line(-1), locked_at(-1), locked(true) { mutex.Lock(); } ~LockMutex(); - LockMutex(LockMutex &cpy): mutex(cpy.mutex), file(NULL), line(-1), locked_at(cpy.locked_at), locked(true) { mutex.Lock(); } + LockMutex(LockMutex &cpy): mutex(cpy.mutex), file(nullptr), line(-1), locked_at(cpy.locked_at), locked(true) { mutex.Lock(); } /** * @brief Unlock the mutex (before this would normally go out of scope). @@ -155,12 +155,12 @@ public: ~RageEvent(); /* - * If pTimeout is non-NULL, the event will be automatically signalled at the given + * If pTimeout is non-nullptr, the event will be automatically signalled at the given * time. Note that implementing this timeout is optional; not all archs support it. * If false is returned, the wait timed out (and the mutex is locked, as if the * event had been signalled). */ - bool Wait( RageTimer *pTimeout = NULL ); + bool Wait( RageTimer *pTimeout = nullptr ); void Signal(); void Broadcast(); bool WaitTimeoutSupported() const; diff --git a/src/RageUtil.cpp b/src/RageUtil.cpp index 8a58bcb2bd..a882ba962c 100644 --- a/src/RageUtil.cpp +++ b/src/RageUtil.cpp @@ -4,7 +4,6 @@ #include "RageLog.h" #include "RageFile.h" #include "RageSoundReader_FileReader.h" -#include "Foreach.h" #include "LocalizedString.h" #include "LuaBinding.h" #include "LuaManager.h" @@ -34,7 +33,7 @@ MersenneTwister::MersenneTwister( int iSeed ) : m_iNext(0) void MersenneTwister::Reset( int iSeed ) { if( iSeed == 0 ) - iSeed = time(NULL); + iSeed = time(nullptr); m_Values[0] = iSeed; m_iNext = 0; @@ -152,7 +151,7 @@ namespace { LIST_METHOD( Seed ), LIST_METHOD( Random ), - { NULL, NULL } + { nullptr, nullptr } }; } @@ -277,8 +276,8 @@ float HHMMSSToSeconds( const RString &sHHMMSS ) arrayBits.insert(arrayBits.begin(), "0" ); // pad missing bits float fSeconds = 0; - fSeconds += StringToInt( arrayBits[0] ) * 60 * 60; - fSeconds += StringToInt( arrayBits[1] ) * 60; + fSeconds += std::stoi( arrayBits[0] ) * 60 * 60; + fSeconds += std::stoi( arrayBits[1] ) * 60; fSeconds += StringToFloat( arrayBits[2] ); return fSeconds; @@ -413,7 +412,7 @@ RString FormatNumberAndSuffix( int i ) struct tm GetLocalTime() { - const time_t t = time(NULL); + const time_t t = time(nullptr); struct tm tm; localtime_r( &t, &tm ); return tm; @@ -433,7 +432,7 @@ RString vssprintf( const char *szFormat, va_list argList ) RString sStr; #if defined(WIN32) - char *pBuf = NULL; + char *pBuf = nullptr; int iChars = 1; int iUsed = 0; int iTry = 0; @@ -707,7 +706,7 @@ const LanguageInfo *GetLanguageInfo( const RString &sIsoCode ) return &g_langs[i]; } - return NULL; + return nullptr; } RString join( const RString &sDeliminator, const vector &sSource) @@ -1092,7 +1091,7 @@ bool FindFirstFilenameContaining(const vector& filenames, } int g_argc = 0; -char **g_argv = NULL; +char **g_argv = nullptr; void SetCommandlineArguments( int argc, char **argv ) { @@ -1110,7 +1109,7 @@ void GetCommandLineArguments( int &argc, char **&argv ) * option "--test". All commandline arguments are getopt_long style: --foo; * short arguments (-x) are not supported. (These are not intended for * common, general use, so having short options isn't currently needed.) - * If argument is non-NULL, accept an argument. */ + * If argument is non-nullptr, accept an argument. */ bool GetCommandlineArgument( const RString &option, RString *argument, int iIndex ) { const RString optstr = "--" + option; @@ -1148,7 +1147,7 @@ bool GetCommandlineArgument( const RString &option, RString *argument, int iInde RString GetCwd() { char buf[PATH_MAX]; - bool ret = getcwd(buf, PATH_MAX) != NULL; + bool ret = getcwd(buf, PATH_MAX) != nullptr; ASSERT(ret); return buf; } @@ -1472,12 +1471,12 @@ void Regex::Compile() { const char *error; int offset; - m_pReg = pcre_compile( m_sPattern.c_str(), PCRE_CASELESS, &error, &offset, NULL ); + m_pReg = pcre_compile( m_sPattern.c_str(), PCRE_CASELESS, &error, &offset, nullptr ); - if( m_pReg == NULL ) + if( m_pReg == nullptr ) RageException::Throw( "Invalid regex: \"%s\" (%s).", m_sPattern.c_str(), error ); - int iRet = pcre_fullinfo( (pcre *) m_pReg, NULL, PCRE_INFO_CAPTURECOUNT, &m_iBackrefs ); + int iRet = pcre_fullinfo( (pcre *) m_pReg, nullptr, PCRE_INFO_CAPTURECOUNT, &m_iBackrefs ); ASSERT( iRet >= 0 ); ++m_iBackrefs; @@ -1494,16 +1493,16 @@ void Regex::Set( const RString &sStr ) void Regex::Release() { pcre_free( m_pReg ); - m_pReg = NULL; + m_pReg = nullptr; m_sPattern = RString(); } -Regex::Regex( const RString &sStr ): m_pReg(NULL), m_iBackrefs(0), m_sPattern(RString()) +Regex::Regex( const RString &sStr ): m_pReg(nullptr), m_iBackrefs(0), m_sPattern(RString()) { Set( sStr ); } -Regex::Regex( const Regex &rhs ): m_pReg(NULL), m_iBackrefs(0), m_sPattern(RString()) +Regex::Regex( const Regex &rhs ): m_pReg(nullptr), m_iBackrefs(0), m_sPattern(RString()) { Set( rhs.m_sPattern ); } @@ -1523,7 +1522,7 @@ Regex::~Regex() bool Regex::Compare( const RString &sStr ) { int iMat[128*3]; - int iRet = pcre_exec( (pcre *) m_pReg, NULL, sStr.data(), sStr.size(), 0, 0, iMat, 128*3 ); + int iRet = pcre_exec( (pcre *) m_pReg, nullptr, sStr.data(), sStr.size(), 0, 0, iMat, 128*3 ); if( iRet < -1 ) RageException::Throw( "Unexpected return from pcre_exec('%s'): %i.", m_sPattern.c_str(), iRet ); @@ -1536,7 +1535,7 @@ bool Regex::Compare( const RString &sStr, vector &asMatches ) asMatches.clear(); int iMat[128*3]; - int iRet = pcre_exec( (pcre *) m_pReg, NULL, sStr.data(), sStr.size(), 0, 0, iMat, 128*3 ); + int iRet = pcre_exec( (pcre *) m_pReg, nullptr, sStr.data(), sStr.size(), 0, 0, iMat, 128*3 ); if( iRet < -1 ) RageException::Throw( "Unexpected return from pcre_exec('%s'): %i.", m_sPattern.c_str(), iRet ); @@ -1876,35 +1875,29 @@ void MakeLower( wchar_t *p, size_t iLen ) UnicodeUpperLower( p, iLen, g_LowerCase ); } -int StringToInt( const RString &sString ) -{ - int ret; - istringstream ( sString ) >> ret; - return ret; -} - -RString IntToString( const int &iNum ) -{ - stringstream ss; - ss << iNum; - return ss.str(); -} - float StringToFloat( const RString &sString ) { - float ret = strtof( sString, NULL ); - - if( !isfinite(ret) ) - ret = 0.0f; - return ret; + RString toTrim = sString; + Trim(toTrim); + if (toTrim.size() == 0) + { + return 0; + } + return std::stof(toTrim); } bool StringToFloat( const RString &sString, float &fOut ) { + RString toTrim = sString; + Trim(toTrim); + if (toTrim.size() == 0) + { + return false; + } char *endPtr; - fOut = strtof( sString, &endPtr ); - return sString.size() && *endPtr == '\0' && isfinite( fOut ); + fOut = strtof( toTrim, &endPtr ); + return *endPtr == '\0' && isfinite( fOut ); } RString FloatToString( const float &num ) @@ -2015,8 +2008,8 @@ void ReplaceEntityText( RString &sText, const map &m ) { RString sFind; - FOREACHM_CONST( char, RString, m, c ) - sFind.append( 1, c->first ); + for (std::pair const &c : m) + sFind.append( 1, c.first ); RString sRet; @@ -2338,7 +2331,7 @@ namespace StringConversion if( sValue.size() == 0 ) return false; - out = (StringToInt(sValue) != 0); + out = (std::stoi(sValue) != 0); return true; } @@ -2398,7 +2391,7 @@ bool FileCopy( RageFileBasic &in, RageFileBasic &out, RString &sError, bool *bRe if( in.Read(data, 1024*32) == -1 ) { sError = ssprintf( "read error: %s", in.GetError().c_str() ); - if( bReadError != NULL ) + if( bReadError != nullptr ) { *bReadError = true; } @@ -2412,7 +2405,7 @@ bool FileCopy( RageFileBasic &in, RageFileBasic &out, RString &sError, bool *bRe if( i == -1 ) { sError = ssprintf( "write error: %s", out.GetError().c_str() ); - if( bReadError != NULL ) + if( bReadError != nullptr ) { *bReadError = false; } @@ -2423,7 +2416,7 @@ bool FileCopy( RageFileBasic &in, RageFileBasic &out, RString &sError, bool *bRe if( out.Flush() == -1 ) { sError = ssprintf( "write error: %s", out.GetError().c_str() ); - if( bReadError != NULL ) + if( bReadError != nullptr ) { *bReadError = false; } @@ -2556,7 +2549,7 @@ int LuaFunc_get_music_file_length(lua_State* L) RString path= SArg(1); RString error; RageSoundReader* sample= RageSoundReader_FileReader::OpenFile(path, error); - if(sample == NULL) + if(sample == nullptr) { luaL_error(L, "The music file '%s' does not exist.", path.c_str()); } diff --git a/src/RageUtil.h b/src/RageUtil.h index a4708038fd..85836d0234 100644 --- a/src/RageUtil.h +++ b/src/RageUtil.h @@ -10,9 +10,9 @@ class RageFileDriver; /** @brief Safely delete pointers. */ -#define SAFE_DELETE(p) do { delete (p); (p)=NULL; } while( false ) +#define SAFE_DELETE(p) do { delete (p); (p)=nullptr; } while( false ) /** @brief Safely delete array pointers. */ -#define SAFE_DELETE_ARRAY(p) do { delete[] (p); (p)=NULL; } while( false ) +#define SAFE_DELETE_ARRAY(p) do { delete[] (p); (p)=nullptr; } while( false ) /** @brief Zero out the memory. */ #define ZERO(x) memset(&(x), 0, sizeof(x)) @@ -405,18 +405,9 @@ void MakeUpper( char *p, size_t iLen ); void MakeLower( char *p, size_t iLen ); void MakeUpper( wchar_t *p, size_t iLen ); void MakeLower( wchar_t *p, size_t iLen ); -/** - * @brief Have a standard way of converting Strings to integers. - * @param sString the string to convert. - * @return the integer we are after. */ -int StringToInt( const RString &sString ); -/** - * @brief Have a standard way of converting integers to Strings. - * @param iNum the integer to convert. - * @return the string we are after. */ -RString IntToString( const int &iNum ); + +// TODO: Have the three functions below be moved to better locations. float StringToFloat( const RString &sString ); -RString FloatToString( const float &num ); bool StringToFloat( const RString &sString, float &fOut ); // Better than IntToString because you can check for success. template @@ -466,7 +457,7 @@ RString GetCwd(); void SetCommandlineArguments( int argc, char **argv ); void GetCommandLineArguments( int &argc, char **&argv ); -bool GetCommandlineArgument( const RString &option, RString *argument=NULL, int iIndex=0 ); +bool GetCommandlineArgument( const RString &option, RString *argument=nullptr, int iIndex=0 ); extern int g_argc; extern char **g_argv; @@ -611,7 +602,7 @@ struct char_traits_char_nocase: public char_traits if(fasttoupper(*s) == a) return s; - return NULL; + return nullptr; } }; typedef basic_string istring; @@ -647,7 +638,7 @@ namespace StringConversion class RageFileBasic; bool FileCopy( const RString &sSrcFile, const RString &sDstFile ); -bool FileCopy( RageFileBasic &in, RageFileBasic &out, RString &sError, bool *bReadError = NULL ); +bool FileCopy( RageFileBasic &in, RageFileBasic &out, RString &sError, bool *bReadError = nullptr ); template void GetAsNotInBs( const vector &as, const vector &bs, vector &difference ) diff --git a/src/RageUtil_AutoPtr.h b/src/RageUtil_AutoPtr.h index 1c009dcbb3..bae6abf939 100644 --- a/src/RageUtil_AutoPtr.h +++ b/src/RageUtil_AutoPtr.h @@ -1,219 +1,219 @@ -/* AutoPtrCopyOnWrite - Simple smart pointer template. */ - -#ifndef RAGE_UTIL_AUTO_PTR_H -#define RAGE_UTIL_AUTO_PTR_H - -/* - * This is a simple copy-on-write refcounted smart pointer. Once constructed, all read-only - * access to the object is made without extra copying. If you need read-write access, you - * can get a pointer with Get(), which will cause the object to deep-copy. (Don't free - * the resulting pointer.) - * - * Note that there are no non-const operator* or operator-> overloads, because that would - * cause all const access by code with non-const permissions to deep-copy. For example, - * - * AutoPtrCopyOnWrite a( new int(1) ); - * AutoPtrCopyOnWrite b( a ); - * printf( "%i\n", *a ); - * - * If we have a non-const operator*, this *a will use it (even though it only needs const - * access), and will copy the underlying object wastefully. g++ std::string has this behavior, - * which is why it's important to qualify strings as "const" when const access is desired, - * but that's brittle, so let's make all potential deep-copying explicit. - */ - -template -class AutoPtrCopyOnWrite -{ -public: - /* This constructor only exists to make us work with STL containers. */ - inline AutoPtrCopyOnWrite(): m_pPtr(NULL), m_iRefCount(new int(1)) - { - } - - explicit inline AutoPtrCopyOnWrite( T *p ): m_pPtr(p), m_iRefCount(new int(1)) - { - } - - inline AutoPtrCopyOnWrite( const AutoPtrCopyOnWrite &rhs ): - m_pPtr(rhs.m_pPtr), m_iRefCount(rhs.m_iRefCount) - { - ++(*m_iRefCount); - } - - void Swap( AutoPtrCopyOnWrite &rhs ) - { - swap( m_pPtr, rhs.m_pPtr ); - swap( m_iRefCount, rhs.m_iRefCount ); - } - - inline AutoPtrCopyOnWrite &operator=( const AutoPtrCopyOnWrite &rhs ) - { - AutoPtrCopyOnWrite obj( rhs ); - this->Swap( obj ); - return *this; - } - - ~AutoPtrCopyOnWrite() - { - --(*m_iRefCount); - if( *m_iRefCount == 0 ) - { - delete m_pPtr; - delete m_iRefCount; - } - } - - /* Get a non-const pointer. This will deep-copy the object if necessary. */ - T *Get() - { - if( *m_iRefCount > 1 ) - { - --*m_iRefCount; - m_pPtr = new T(*m_pPtr); - m_iRefCount = new int(1); - } - - return m_pPtr; - } - - int GetReferenceCount() const { return *m_iRefCount; } - - const T &operator *() const { return *m_pPtr; } - const T *operator ->() const { return m_pPtr; } - -private: - T *m_pPtr; - int *m_iRefCount; -}; - -template -inline void swap( AutoPtrCopyOnWrite &a, AutoPtrCopyOnWrite &b ) -{ - a.Swap(b); -} - -/* - * This smart pointer template is used to safely hide implementations from - * headers, to reduce dependencies. This is the same as declaring a pointer - * to a class, and allocating/deallocating it in the implementation: only - * the implementation needs to include that class. This makes copying - * and deletion automatic, so you don't need to include a copy ctor or - * remember to delete it. - * - * There's one subtlety: in order to copy or delete an object, we need its - * definition. This is intended to avoid pulling in the definition. So, - * we use a traits class to hide it. Use REGISTER_CLASS_TRAITS for each - * class used with this template. - * - * Concepts from http://www.gotw.ca/gotw/062.htm. - */ -template -struct HiddenPtrTraits -{ - static T *Copy( const T *pCopy ); - static void Delete( T *p ); -}; -#define REGISTER_CLASS_TRAITS(T, CopyExpr) \ - template<> T *HiddenPtrTraits::Copy( const T *pCopy ) { return CopyExpr; } \ - template<> void HiddenPtrTraits::Delete( T *p ) { delete p; } - -template -class HiddenPtr -{ -public: - const T& operator*() const { return *m_pPtr; } - const T* operator->() const { return m_pPtr; } - T& operator*() { return *m_pPtr; } - T* operator->() { return m_pPtr; } - - explicit HiddenPtr( T *p = NULL ): m_pPtr(p) {} - - HiddenPtr( const HiddenPtr &cpy ): m_pPtr(NULL) - { - if( cpy.m_pPtr != NULL ) - m_pPtr = HiddenPtrTraits::Copy( cpy.m_pPtr ); - } - -#if 0 // broken VC6 - template - HiddenPtr( const HiddenPtr &cpy ) - { - if( cpy.m_pPtr == NULL ) - m_pPtr = NULL; - else - m_pPtr = HiddenPtrTraits::Copy( cpy.m_pPtr ); - } -#endif - - ~HiddenPtr() - { - HiddenPtrTraits::Delete( m_pPtr ); - } - void Swap( HiddenPtr &rhs ) { swap( m_pPtr, rhs.m_pPtr ); } - - HiddenPtr &operator=( T *p ) - { - HiddenPtr t( p ); - Swap( t ); - return *this; - } - - HiddenPtr &operator=( const HiddenPtr &cpy ) - { - HiddenPtr t( cpy ); - Swap( t ); - return *this; - } - -#if 0 // broken VC6 - template - HiddenPtr &operator=( const HiddenPtr &cpy ) - { - HiddenPtr t( cpy ); - Swap( t ); - return *this; - } -#endif - -private: - T *m_pPtr; - -#if 0 // broken VC6 - template - friend class HiddenPtr; -#endif -}; - -template -inline void swap( HiddenPtr &a, HiddenPtr &b ) -{ - a.Swap(b); -} - -#endif - -/* - * (c) 2005 Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +/* AutoPtrCopyOnWrite - Simple smart pointer template. */ + +#ifndef RAGE_UTIL_AUTO_PTR_H +#define RAGE_UTIL_AUTO_PTR_H + +/* + * This is a simple copy-on-write refcounted smart pointer. Once constructed, all read-only + * access to the object is made without extra copying. If you need read-write access, you + * can get a pointer with Get(), which will cause the object to deep-copy. (Don't free + * the resulting pointer.) + * + * Note that there are no non-const operator* or operator-> overloads, because that would + * cause all const access by code with non-const permissions to deep-copy. For example, + * + * AutoPtrCopyOnWrite a( new int(1) ); + * AutoPtrCopyOnWrite b( a ); + * printf( "%i\n", *a ); + * + * If we have a non-const operator*, this *a will use it (even though it only needs const + * access), and will copy the underlying object wastefully. g++ std::string has this behavior, + * which is why it's important to qualify strings as "const" when const access is desired, + * but that's brittle, so let's make all potential deep-copying explicit. + */ + +template +class AutoPtrCopyOnWrite +{ +public: + /* This constructor only exists to make us work with STL containers. */ + inline AutoPtrCopyOnWrite(): m_pPtr(nullptr), m_iRefCount(new int(1)) + { + } + + explicit inline AutoPtrCopyOnWrite( T *p ): m_pPtr(p), m_iRefCount(new int(1)) + { + } + + inline AutoPtrCopyOnWrite( const AutoPtrCopyOnWrite &rhs ): + m_pPtr(rhs.m_pPtr), m_iRefCount(rhs.m_iRefCount) + { + ++(*m_iRefCount); + } + + void Swap( AutoPtrCopyOnWrite &rhs ) + { + swap( m_pPtr, rhs.m_pPtr ); + swap( m_iRefCount, rhs.m_iRefCount ); + } + + inline AutoPtrCopyOnWrite &operator=( const AutoPtrCopyOnWrite &rhs ) + { + AutoPtrCopyOnWrite obj( rhs ); + this->Swap( obj ); + return *this; + } + + ~AutoPtrCopyOnWrite() + { + --(*m_iRefCount); + if( *m_iRefCount == 0 ) + { + delete m_pPtr; + delete m_iRefCount; + } + } + + /* Get a non-const pointer. This will deep-copy the object if necessary. */ + T *Get() + { + if( *m_iRefCount > 1 ) + { + --*m_iRefCount; + m_pPtr = new T(*m_pPtr); + m_iRefCount = new int(1); + } + + return m_pPtr; + } + + int GetReferenceCount() const { return *m_iRefCount; } + + const T &operator *() const { return *m_pPtr; } + const T *operator ->() const { return m_pPtr; } + +private: + T *m_pPtr; + int *m_iRefCount; +}; + +template +inline void swap( AutoPtrCopyOnWrite &a, AutoPtrCopyOnWrite &b ) +{ + a.Swap(b); +} + +/* + * This smart pointer template is used to safely hide implementations from + * headers, to reduce dependencies. This is the same as declaring a pointer + * to a class, and allocating/deallocating it in the implementation: only + * the implementation needs to include that class. This makes copying + * and deletion automatic, so you don't need to include a copy ctor or + * remember to delete it. + * + * There's one subtlety: in order to copy or delete an object, we need its + * definition. This is intended to avoid pulling in the definition. So, + * we use a traits class to hide it. Use REGISTER_CLASS_TRAITS for each + * class used with this template. + * + * Concepts from http://www.gotw.ca/gotw/062.htm. + */ +template +struct HiddenPtrTraits +{ + static T *Copy( const T *pCopy ); + static void Delete( T *p ); +}; +#define REGISTER_CLASS_TRAITS(T, CopyExpr) \ + template<> T *HiddenPtrTraits::Copy( const T *pCopy ) { return CopyExpr; } \ + template<> void HiddenPtrTraits::Delete( T *p ) { delete p; } + +template +class HiddenPtr +{ +public: + const T& operator*() const { return *m_pPtr; } + const T* operator->() const { return m_pPtr; } + T& operator*() { return *m_pPtr; } + T* operator->() { return m_pPtr; } + + explicit HiddenPtr( T *p = nullptr ): m_pPtr(p) {} + + HiddenPtr( const HiddenPtr &cpy ): m_pPtr(nullptr) + { + if( cpy.m_pPtr != nullptr ) + m_pPtr = HiddenPtrTraits::Copy( cpy.m_pPtr ); + } + +#if 0 // broken VC6 + template + HiddenPtr( const HiddenPtr &cpy ) + { + if( cpy.m_pPtr == nullptr ) + m_pPtr = nullptr; + else + m_pPtr = HiddenPtrTraits::Copy( cpy.m_pPtr ); + } +#endif + + ~HiddenPtr() + { + HiddenPtrTraits::Delete( m_pPtr ); + } + void Swap( HiddenPtr &rhs ) { swap( m_pPtr, rhs.m_pPtr ); } + + HiddenPtr &operator=( T *p ) + { + HiddenPtr t( p ); + Swap( t ); + return *this; + } + + HiddenPtr &operator=( const HiddenPtr &cpy ) + { + HiddenPtr t( cpy ); + Swap( t ); + return *this; + } + +#if 0 // broken VC6 + template + HiddenPtr &operator=( const HiddenPtr &cpy ) + { + HiddenPtr t( cpy ); + Swap( t ); + return *this; + } +#endif + +private: + T *m_pPtr; + +#if 0 // broken VC6 + template + friend class HiddenPtr; +#endif +}; + +template +inline void swap( HiddenPtr &a, HiddenPtr &b ) +{ + a.Swap(b); +} + +#endif + +/* + * (c) 2005 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/RageUtil_CachedObject.cpp b/src/RageUtil_CachedObject.cpp index e67ae85cd1..bc2bbc6373 100644 --- a/src/RageUtil_CachedObject.cpp +++ b/src/RageUtil_CachedObject.cpp @@ -20,7 +20,7 @@ struct User Object *p; if( !cache.Get(&p) ) { - p = NULL; + p = nullptr; cache.Set(p); } return p; diff --git a/src/RageUtil_CachedObject.h b/src/RageUtil_CachedObject.h index 1fee1a6397..5b8f4008de 100644 --- a/src/RageUtil_CachedObject.h +++ b/src/RageUtil_CachedObject.h @@ -18,20 +18,20 @@ template class CachedObject { public: - CachedObject(): m_pObject(NULL) + CachedObject(): m_pObject(nullptr) { /* A new object is being constructed, so invalidate negative caching. */ ClearCacheNegative(); } - CachedObject( const CachedObject &cpy ): m_pObject(NULL) + CachedObject( const CachedObject &cpy ): m_pObject(nullptr) { ClearCacheNegative(); } ~CachedObject() { - if( m_pObject != NULL ) + if( m_pObject != nullptr ) ClearCacheSpecific( m_pObject ); } @@ -43,7 +43,7 @@ public: CachedObjectHelpers::Lock(); for( typename set::iterator p = m_spObjectPointers.begin(); p != m_spObjectPointers.end(); ++p ) { - (*p)->m_pCache = NULL; + (*p)->m_pCache = nullptr; (*p)->m_bCacheIsSet = false; } CachedObjectHelpers::Unlock(); @@ -57,7 +57,7 @@ public: { if( (*p)->m_pCache == pObject ) { - (*p)->m_pCache = NULL; + (*p)->m_pCache = nullptr; (*p)->m_bCacheIsSet = false; } } @@ -70,7 +70,7 @@ public: CachedObjectHelpers::Lock(); for( typename set::iterator p = m_spObjectPointers.begin(); p != m_spObjectPointers.end(); ++p ) { - if( (*p)->m_pCache == NULL ) + if( (*p)->m_pCache == nullptr ) (*p)->m_bCacheIsSet = false; } CachedObjectHelpers::Unlock(); @@ -109,7 +109,7 @@ class CachedObjectPointer public: typedef CachedObject Object; - CachedObjectPointer() : m_pCache(NULL), m_bCacheIsSet(false) + CachedObjectPointer() : m_pCache(nullptr), m_bCacheIsSet(false) { Object::Register( this ); } @@ -145,7 +145,7 @@ public: CachedObjectHelpers::Lock(); m_pCache = p; m_bCacheIsSet = true; - if( p != NULL ) + if( p != nullptr ) p->m_CachedObject.m_pObject = p; CachedObjectHelpers::Unlock(); } @@ -153,7 +153,7 @@ public: void Unset() { CachedObjectHelpers::Lock(); - m_pCache = NULL; + m_pCache = nullptr; m_bCacheIsSet = false; CachedObjectHelpers::Unlock(); } diff --git a/src/RageUtil_CharConversions.cpp b/src/RageUtil_CharConversions.cpp index f41957b430..8f7a679cc3 100644 --- a/src/RageUtil_CharConversions.cpp +++ b/src/RageUtil_CharConversions.cpp @@ -1,171 +1,171 @@ -#include "global.h" -#include "RageUtil_CharConversions.h" -#include "RageUtil.h" -#include "RageLog.h" - -#if defined(_WINDOWS) - -#include "archutils/Win32/ErrorStrings.h" -#include - -/* Convert from the given codepage to UTF-8. Return true if successful. */ -static bool CodePageConvert( RString &sText, int iCodePage ) -{ - int iSize = MultiByteToWideChar( iCodePage, MB_ERR_INVALID_CHARS, sText.data(), sText.size(), NULL, 0 ); - if( iSize == 0 ) - { - LOG->Trace( "%s\n", werr_ssprintf(GetLastError(), "err: ").c_str() ); - return false; /* error */ - } - - wstring sOut; - sOut.append( iSize, ' ' ); - /* Nonportable: */ - iSize = MultiByteToWideChar( iCodePage, MB_ERR_INVALID_CHARS, sText.data(), sText.size(), (wchar_t *) sOut.data(), iSize ); - ASSERT( iSize != 0 ); - - sText = WStringToRString( sOut ); - return true; -} - -static bool AttemptEnglishConversion( RString &sText ) { return CodePageConvert( sText, 1252 ); } -static bool AttemptKoreanConversion( RString &sText ) { return CodePageConvert( sText, 949 ); } -static bool AttemptJapaneseConversion( RString &sText ) { return CodePageConvert( sText, 932 ); } - -#elif defined(HAVE_ICONV) -#include -#include - -static bool ConvertFromCharset( RString &sText, const char *szCharset ) -{ - iconv_t converter = iconv_open( "UTF-8", szCharset ); - if( converter == (iconv_t) -1 ) - { - LOG->MapLog( ssprintf("conv %s", szCharset), "iconv_open(%s): %s", szCharset, strerror(errno) ); - return false; - } - - /* Copy the string into a char* for iconv */ - ICONV_CONST char *szTextIn = const_cast( sText.data() ); - size_t iInLeft = sText.size(); - - /* Create a new string with enough room for the new conversion */ - RString sBuf; - sBuf.resize( sText.size() * 5 ); - - char *sTextOut = const_cast( sBuf.data() ); - size_t iOutLeft = sBuf.size(); - size_t size = iconv( converter, &szTextIn, &iInLeft, &sTextOut, &iOutLeft ); - - iconv_close( converter ); - - if( size == (size_t)(-1) ) - { - LOG->Trace( "%s\n", strerror( errno ) ); - return false; /* Returned an error */ - } - - if( iInLeft != 0 ) - { - LOG->Warn( "iconv(UTF-8,%s) for \"%s\": whole buffer not converted (%i left)", szCharset, sText.c_str(), int(iInLeft) ); - return false; - } - - if( sBuf.size() == iOutLeft ) - return false; /* Conversion failed */ - - sBuf.resize( sBuf.size()-iOutLeft ); - - sText = sBuf; - return true; -} - -static bool AttemptEnglishConversion( RString &sText ) { return ConvertFromCharset( sText, "CP1252" ); } -static bool AttemptKoreanConversion( RString &sText ) { return ConvertFromCharset( sText, "CP949" ); } -static bool AttemptJapaneseConversion( RString &sText ) { return ConvertFromCharset( sText, "CP932" ); } - -#elif defined(MACOSX) -#include - -static bool ConvertFromCP( RString &sText, int iCodePage ) -{ - CFStringEncoding encoding = CFStringConvertWindowsCodepageToEncoding( iCodePage ); - - if( encoding == kCFStringEncodingInvalidId ) - return false; - - CFStringRef old = CFStringCreateWithCString( kCFAllocatorDefault, sText, encoding ); - - if( old == NULL ) - return false; - const size_t size = CFStringGetMaximumSizeForEncoding( CFStringGetLength(old), kCFStringEncodingUTF8 ); - - char *buf = new char[size+1]; - buf[0] = '\0'; - bool result = CFStringGetCString( old, buf, size, kCFStringEncodingUTF8 ); - sText = buf; - delete[] buf; - CFRelease( old ); - return result; -} - -static bool AttemptEnglishConversion( RString &sText ) { return ConvertFromCP( sText, 1252 ); } -static bool AttemptKoreanConversion( RString &sText ) { return ConvertFromCP( sText, 949 ); } -static bool AttemptJapaneseConversion( RString &sText ) { return ConvertFromCP( sText, 932 ); } - -#else - -/* No converters are available, so all fail--we only accept UTF-8. */ -static bool AttemptEnglishConversion( RString &sText ) { return false; } -static bool AttemptKoreanConversion( RString &sText ) { return false; } -static bool AttemptJapaneseConversion( RString &sText ) { return false; } - -#endif - -bool ConvertString( RString &str, const RString &encodings ) -{ - if( str.empty() ) - return true; - - vector lst; - split( encodings, ",", lst ); - - for(unsigned i = 0; i < lst.size(); ++i) - { - if( lst[i] == "utf-8" ) - { - /* Is the string already valid utf-8? */ - if( utf8_is_valid(str) ) - return true; - continue; - } - if( lst[i] == "english" ) - { - if( AttemptEnglishConversion(str) ) - return true; - continue; - } - - if( lst[i] == "japanese" ) - { - if( AttemptJapaneseConversion(str) ) - return true; - continue; - } - - if( lst[i] == "korean" ) - { - if( AttemptKoreanConversion(str) ) - return true; - continue; - } - - RageException::Throw( "Unexpected conversion string \"%s\" (string \"%s\").", - lst[i].c_str(), str.c_str() ); - } - - return false; -} - -/* Written by Glenn Maynard. In the public domain; there are so many - * simple conversion interfaces that restricting them is silly. */ +#include "global.h" +#include "RageUtil_CharConversions.h" +#include "RageUtil.h" +#include "RageLog.h" + +#if defined(_WINDOWS) + +#include "archutils/Win32/ErrorStrings.h" +#include + +/* Convert from the given codepage to UTF-8. Return true if successful. */ +static bool CodePageConvert( RString &sText, int iCodePage ) +{ + int iSize = MultiByteToWideChar( iCodePage, MB_ERR_INVALID_CHARS, sText.data(), sText.size(), nullptr, 0 ); + if( iSize == 0 ) + { + LOG->Trace( "%s\n", werr_ssprintf(GetLastError(), "err: ").c_str() ); + return false; /* error */ + } + + wstring sOut; + sOut.append( iSize, ' ' ); + /* Nonportable: */ + iSize = MultiByteToWideChar( iCodePage, MB_ERR_INVALID_CHARS, sText.data(), sText.size(), (wchar_t *) sOut.data(), iSize ); + ASSERT( iSize != 0 ); + + sText = WStringToRString( sOut ); + return true; +} + +static bool AttemptEnglishConversion( RString &sText ) { return CodePageConvert( sText, 1252 ); } +static bool AttemptKoreanConversion( RString &sText ) { return CodePageConvert( sText, 949 ); } +static bool AttemptJapaneseConversion( RString &sText ) { return CodePageConvert( sText, 932 ); } + +#elif defined(HAVE_ICONV) +#include +#include + +static bool ConvertFromCharset( RString &sText, const char *szCharset ) +{ + iconv_t converter = iconv_open( "UTF-8", szCharset ); + if( converter == (iconv_t) -1 ) + { + LOG->MapLog( ssprintf("conv %s", szCharset), "iconv_open(%s): %s", szCharset, strerror(errno) ); + return false; + } + + /* Copy the string into a char* for iconv */ + ICONV_CONST char *szTextIn = const_cast( sText.data() ); + size_t iInLeft = sText.size(); + + /* Create a new string with enough room for the new conversion */ + RString sBuf; + sBuf.resize( sText.size() * 5 ); + + char *sTextOut = const_cast( sBuf.data() ); + size_t iOutLeft = sBuf.size(); + size_t size = iconv( converter, &szTextIn, &iInLeft, &sTextOut, &iOutLeft ); + + iconv_close( converter ); + + if( size == (size_t)(-1) ) + { + LOG->Trace( "%s\n", strerror( errno ) ); + return false; /* Returned an error */ + } + + if( iInLeft != 0 ) + { + LOG->Warn( "iconv(UTF-8,%s) for \"%s\": whole buffer not converted (%i left)", szCharset, sText.c_str(), int(iInLeft) ); + return false; + } + + if( sBuf.size() == iOutLeft ) + return false; /* Conversion failed */ + + sBuf.resize( sBuf.size()-iOutLeft ); + + sText = sBuf; + return true; +} + +static bool AttemptEnglishConversion( RString &sText ) { return ConvertFromCharset( sText, "CP1252" ); } +static bool AttemptKoreanConversion( RString &sText ) { return ConvertFromCharset( sText, "CP949" ); } +static bool AttemptJapaneseConversion( RString &sText ) { return ConvertFromCharset( sText, "CP932" ); } + +#elif defined(MACOSX) +#include + +static bool ConvertFromCP( RString &sText, int iCodePage ) +{ + CFStringEncoding encoding = CFStringConvertWindowsCodepageToEncoding( iCodePage ); + + if( encoding == kCFStringEncodingInvalidId ) + return false; + + CFStringRef old = CFStringCreateWithCString( kCFAllocatorDefault, sText, encoding ); + + if( old == nullptr ) + return false; + const size_t size = CFStringGetMaximumSizeForEncoding( CFStringGetLength(old), kCFStringEncodingUTF8 ); + + char *buf = new char[size+1]; + buf[0] = '\0'; + bool result = CFStringGetCString( old, buf, size, kCFStringEncodingUTF8 ); + sText = buf; + delete[] buf; + CFRelease( old ); + return result; +} + +static bool AttemptEnglishConversion( RString &sText ) { return ConvertFromCP( sText, 1252 ); } +static bool AttemptKoreanConversion( RString &sText ) { return ConvertFromCP( sText, 949 ); } +static bool AttemptJapaneseConversion( RString &sText ) { return ConvertFromCP( sText, 932 ); } + +#else + +/* No converters are available, so all fail--we only accept UTF-8. */ +static bool AttemptEnglishConversion( RString &sText ) { return false; } +static bool AttemptKoreanConversion( RString &sText ) { return false; } +static bool AttemptJapaneseConversion( RString &sText ) { return false; } + +#endif + +bool ConvertString( RString &str, const RString &encodings ) +{ + if( str.empty() ) + return true; + + vector lst; + split( encodings, ",", lst ); + + for(unsigned i = 0; i < lst.size(); ++i) + { + if( lst[i] == "utf-8" ) + { + /* Is the string already valid utf-8? */ + if( utf8_is_valid(str) ) + return true; + continue; + } + if( lst[i] == "english" ) + { + if( AttemptEnglishConversion(str) ) + return true; + continue; + } + + if( lst[i] == "japanese" ) + { + if( AttemptJapaneseConversion(str) ) + return true; + continue; + } + + if( lst[i] == "korean" ) + { + if( AttemptKoreanConversion(str) ) + return true; + continue; + } + + RageException::Throw( "Unexpected conversion string \"%s\" (string \"%s\").", + lst[i].c_str(), str.c_str() ); + } + + return false; +} + +/* Written by Glenn Maynard. In the public domain; there are so many + * simple conversion interfaces that restricting them is silly. */ diff --git a/src/RageUtil_CircularBuffer.h b/src/RageUtil_CircularBuffer.h index 5f29305643..5f3713dba8 100644 --- a/src/RageUtil_CircularBuffer.h +++ b/src/RageUtil_CircularBuffer.h @@ -1,300 +1,300 @@ -/* CircBuf - A fast, thread-safe, lockless circular buffer. */ - -#ifndef RAGE_UTIL_CIRCULAR_BUFFER -#define RAGE_UTIL_CIRCULAR_BUFFER - -/* Lock-free circular buffer. This should be threadsafe if one thread is reading - * and another is writing. */ -template -class CircBuf -{ - T *buf; - /* read_pos is the position data is read from; write_pos is the position - * data is written to. If read_pos == write_pos, the buffer is empty. - * - * There will always be at least one position empty, as a completely full - * buffer (read_pos == write_pos) is indistinguishable from an empty buffer. - * - * Invariants: read_pos < size, write_pos < size. */ - unsigned size; - unsigned m_iBlockSize; - - /* These are volatile to prevent reads and writes to them from being optimized. */ - volatile unsigned read_pos, write_pos; - -public: - CircBuf() - { - buf = NULL; - clear(); - } - - ~CircBuf() - { - delete[] buf; - } - - void swap( CircBuf &rhs ) - { - std::swap( size, rhs.size ); - std::swap( m_iBlockSize, rhs.m_iBlockSize ); - std::swap( read_pos, rhs.read_pos ); - std::swap( write_pos, rhs.write_pos ); - std::swap( buf, rhs.buf ); - } - - CircBuf &operator=( const CircBuf &rhs ) - { - CircBuf c( rhs ); - this->swap( c ); - return *this; - } - - CircBuf( const CircBuf &cpy ) - { - size = cpy.size; - read_pos = cpy.read_pos; - write_pos = cpy.write_pos; - m_iBlockSize = cpy.m_iBlockSize; - if( size ) - { - buf = new T[size]; - memcpy( buf, cpy.buf, size*sizeof(T) ); - } - else - { - buf = NULL; - } - } - - /* Return the number of elements available to read. */ - unsigned num_readable() const - { - const int rpos = read_pos; - const int wpos = write_pos; - if( rpos < wpos ) - /* The buffer looks like "eeeeDDDDeeee" (e = empty, D = data). */ - return wpos - rpos; - else if( rpos > wpos ) - /* The buffer looks like "DDeeeeeeeeDD" (e = empty, D = data). */ - return size - (rpos - wpos); - else // if( rpos == wpos ) - /* The buffer looks like "eeeeeeeeeeee" (e = empty, D = data). */ - return 0; - } - - /* Return the number of writable elements. */ - unsigned num_writable() const - { - const int rpos = read_pos; - const int wpos = write_pos; - - int ret; - if( rpos < wpos ) - /* The buffer looks like "eeeeDDDDeeee" (e = empty, D = data). */ - ret = size - (wpos - rpos); - else if( rpos > wpos ) - /* The buffer looks like "DDeeeeeeeeDD" (e = empty, D = data). */ - ret = rpos - wpos; - else // if( rpos == wpos ) - /* The buffer looks like "eeeeeeeeeeee" (e = empty, D = data). */ - ret = size; - - /* Subtract the blocksize, to account for the element that we never fill - * while keeping the entries aligned to m_iBlockSize. */ - return ret - m_iBlockSize; - } - - unsigned capacity() const { return size; } - - void reserve( unsigned n, int iBlockSize = 1 ) - { - m_iBlockSize = iBlockSize; - - clear(); - delete[] buf; - buf = NULL; - - /* Reserve an extra byte. We'll never fill more than n bytes; the extra - * byte is to guarantee that read_pos != write_pos when the buffer is full, - * since that would be ambiguous with an empty buffer. */ - if( n != 0 ) - { - size = n+1; - size = ((size + iBlockSize - 1) / iBlockSize) * iBlockSize; // round up - - buf = new T[size]; - } - else - size = 0; - } - - void clear() - { - read_pos = write_pos = 0; - } - - /* Indicate that n elements have been written. */ - void advance_write_pointer( int n ) - { - write_pos = (write_pos + n) % size; - } - - /* Indicate that n elements have been read. */ - void advance_read_pointer( int n ) - { - read_pos = (read_pos + n) % size; - } - - void get_write_pointers( T *pPointers[2], unsigned pSizes[2] ) - { - const int rpos = read_pos; - const int wpos = write_pos; - - if( rpos <= wpos ) - { - /* The buffer looks like "eeeeDDDDeeee" or "eeeeeeeeeeee" (e = empty, D = data). */ - pPointers[0] = buf+wpos; - pPointers[1] = buf; - - pSizes[0] = size - wpos; - pSizes[1] = rpos; - } - else if( rpos > wpos ) - { - /* The buffer looks like "DDeeeeeeeeDD" (e = empty, D = data). */ - pPointers[0] = buf+wpos; - pPointers[1] = NULL; - - pSizes[0] = rpos - wpos; - pSizes[1] = 0; - } - - /* Subtract the blocksize, to account for the element that we never fill - * while keeping the entries aligned to m_iBlockSize. */ - if( pSizes[1] ) - pSizes[1] -= m_iBlockSize; - else - pSizes[0] -= m_iBlockSize; - } - - /* Like get_write_pointers, but only return the first range available. */ - T *get_write_pointer( unsigned *pSizes ) - { - T *pBothPointers[2]; - unsigned iBothSizes[2]; - get_write_pointers( pBothPointers, iBothSizes ); - *pSizes = iBothSizes[0]; - return pBothPointers[0]; - } - - void get_read_pointers( T *pPointers[2], unsigned pSizes[2] ) - { - const int rpos = read_pos; - const int wpos = write_pos; - - if( rpos < wpos ) - { - /* The buffer looks like "eeeeDDDDeeee" (e = empty, D = data). */ - pPointers[0] = buf+rpos; - pPointers[1] = NULL; - - pSizes[0] = wpos - rpos; - pSizes[1] = 0; - } - else if( rpos > wpos ) - { - /* The buffer looks like "DDeeeeeeeeDD" (e = empty, D = data). */ - pPointers[0] = buf+rpos; - pPointers[1] = buf; - - pSizes[0] = size - rpos; - pSizes[1] = wpos; - } - else - { - /* The buffer looks like "eeeeeeeeeeee" (e = empty, D = data). */ - pPointers[0] = NULL; - pPointers[1] = NULL; - - pSizes[0] = 0; - pSizes[1] = 0; - } - } - - /* Write buffer_size elements from buffer, and advance the write pointer. If - * the data will not fit entirely, the write pointer will be unchanged - * and false will be returned. */ - bool write( const T *buffer, unsigned buffer_size ) - { - T *p[2]; - unsigned sizes[2]; - get_write_pointers( p, sizes ); - - if( buffer_size > sizes[0] + sizes[1] ) - return false; - - const int from_first = min( buffer_size, sizes[0] ); - memcpy( p[0], buffer, from_first*sizeof(T) ); - if( buffer_size > sizes[0] ) - memcpy( p[1], buffer+from_first, max(buffer_size-sizes[0], 0u)*sizeof(T) ); - - advance_write_pointer( buffer_size ); - - return true; - } - - /* Read buffer_size elements from buffer, and advance the read pointer. If - * the buffer can not be filled completely, the read pointer will be unchanged - * and false will be returned. */ - bool read( T *buffer, unsigned buffer_size ) - { - T *p[2]; - unsigned sizes[2]; - get_read_pointers( p, sizes ); - - if( buffer_size > sizes[0] + sizes[1] ) - return false; - - const int from_first = min( buffer_size, sizes[0] ); - memcpy( buffer, p[0], from_first*sizeof(T) ); - if( buffer_size > sizes[0] ) - memcpy( buffer+from_first, p[1], max(buffer_size-sizes[0], 0u)*sizeof(T) ); - - /* Set the data that we just read to 0xFF. This way, if we're passing pointesr - * through, we can tell if we accidentally get a stale pointer. */ - memset( p[0], 0xFF, from_first*sizeof(T) ); - if( buffer_size > sizes[0] ) - memset( p[1], 0xFF, max(buffer_size-sizes[0], 0u)*sizeof(T) ); - - advance_read_pointer( buffer_size ); - return true; - } -}; - -#endif - -/* - * Copyright (c) 2004 Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +/* CircBuf - A fast, thread-safe, lockless circular buffer. */ + +#ifndef RAGE_UTIL_CIRCULAR_BUFFER +#define RAGE_UTIL_CIRCULAR_BUFFER + +/* Lock-free circular buffer. This should be threadsafe if one thread is reading + * and another is writing. */ +template +class CircBuf +{ + T *buf; + /* read_pos is the position data is read from; write_pos is the position + * data is written to. If read_pos == write_pos, the buffer is empty. + * + * There will always be at least one position empty, as a completely full + * buffer (read_pos == write_pos) is indistinguishable from an empty buffer. + * + * Invariants: read_pos < size, write_pos < size. */ + unsigned size; + unsigned m_iBlockSize; + + /* These are volatile to prevent reads and writes to them from being optimized. */ + volatile unsigned read_pos, write_pos; + +public: + CircBuf() + { + buf = nullptr; + clear(); + } + + ~CircBuf() + { + delete[] buf; + } + + void swap( CircBuf &rhs ) + { + std::swap( size, rhs.size ); + std::swap( m_iBlockSize, rhs.m_iBlockSize ); + std::swap( read_pos, rhs.read_pos ); + std::swap( write_pos, rhs.write_pos ); + std::swap( buf, rhs.buf ); + } + + CircBuf &operator=( const CircBuf &rhs ) + { + CircBuf c( rhs ); + this->swap( c ); + return *this; + } + + CircBuf( const CircBuf &cpy ) + { + size = cpy.size; + read_pos = cpy.read_pos; + write_pos = cpy.write_pos; + m_iBlockSize = cpy.m_iBlockSize; + if( size ) + { + buf = new T[size]; + memcpy( buf, cpy.buf, size*sizeof(T) ); + } + else + { + buf = nullptr; + } + } + + /* Return the number of elements available to read. */ + unsigned num_readable() const + { + const int rpos = read_pos; + const int wpos = write_pos; + if( rpos < wpos ) + /* The buffer looks like "eeeeDDDDeeee" (e = empty, D = data). */ + return wpos - rpos; + else if( rpos > wpos ) + /* The buffer looks like "DDeeeeeeeeDD" (e = empty, D = data). */ + return size - (rpos - wpos); + else // if( rpos == wpos ) + /* The buffer looks like "eeeeeeeeeeee" (e = empty, D = data). */ + return 0; + } + + /* Return the number of writable elements. */ + unsigned num_writable() const + { + const int rpos = read_pos; + const int wpos = write_pos; + + int ret; + if( rpos < wpos ) + /* The buffer looks like "eeeeDDDDeeee" (e = empty, D = data). */ + ret = size - (wpos - rpos); + else if( rpos > wpos ) + /* The buffer looks like "DDeeeeeeeeDD" (e = empty, D = data). */ + ret = rpos - wpos; + else // if( rpos == wpos ) + /* The buffer looks like "eeeeeeeeeeee" (e = empty, D = data). */ + ret = size; + + /* Subtract the blocksize, to account for the element that we never fill + * while keeping the entries aligned to m_iBlockSize. */ + return ret - m_iBlockSize; + } + + unsigned capacity() const { return size; } + + void reserve( unsigned n, int iBlockSize = 1 ) + { + m_iBlockSize = iBlockSize; + + clear(); + delete[] buf; + buf = nullptr; + + /* Reserve an extra byte. We'll never fill more than n bytes; the extra + * byte is to guarantee that read_pos != write_pos when the buffer is full, + * since that would be ambiguous with an empty buffer. */ + if( n != 0 ) + { + size = n+1; + size = ((size + iBlockSize - 1) / iBlockSize) * iBlockSize; // round up + + buf = new T[size]; + } + else + size = 0; + } + + void clear() + { + read_pos = write_pos = 0; + } + + /* Indicate that n elements have been written. */ + void advance_write_pointer( int n ) + { + write_pos = (write_pos + n) % size; + } + + /* Indicate that n elements have been read. */ + void advance_read_pointer( int n ) + { + read_pos = (read_pos + n) % size; + } + + void get_write_pointers( T *pPointers[2], unsigned pSizes[2] ) + { + const int rpos = read_pos; + const int wpos = write_pos; + + if( rpos <= wpos ) + { + /* The buffer looks like "eeeeDDDDeeee" or "eeeeeeeeeeee" (e = empty, D = data). */ + pPointers[0] = buf+wpos; + pPointers[1] = buf; + + pSizes[0] = size - wpos; + pSizes[1] = rpos; + } + else if( rpos > wpos ) + { + /* The buffer looks like "DDeeeeeeeeDD" (e = empty, D = data). */ + pPointers[0] = buf+wpos; + pPointers[1] = nullptr; + + pSizes[0] = rpos - wpos; + pSizes[1] = 0; + } + + /* Subtract the blocksize, to account for the element that we never fill + * while keeping the entries aligned to m_iBlockSize. */ + if( pSizes[1] ) + pSizes[1] -= m_iBlockSize; + else + pSizes[0] -= m_iBlockSize; + } + + /* Like get_write_pointers, but only return the first range available. */ + T *get_write_pointer( unsigned *pSizes ) + { + T *pBothPointers[2]; + unsigned iBothSizes[2]; + get_write_pointers( pBothPointers, iBothSizes ); + *pSizes = iBothSizes[0]; + return pBothPointers[0]; + } + + void get_read_pointers( T *pPointers[2], unsigned pSizes[2] ) + { + const int rpos = read_pos; + const int wpos = write_pos; + + if( rpos < wpos ) + { + /* The buffer looks like "eeeeDDDDeeee" (e = empty, D = data). */ + pPointers[0] = buf+rpos; + pPointers[1] = nullptr; + + pSizes[0] = wpos - rpos; + pSizes[1] = 0; + } + else if( rpos > wpos ) + { + /* The buffer looks like "DDeeeeeeeeDD" (e = empty, D = data). */ + pPointers[0] = buf+rpos; + pPointers[1] = buf; + + pSizes[0] = size - rpos; + pSizes[1] = wpos; + } + else + { + /* The buffer looks like "eeeeeeeeeeee" (e = empty, D = data). */ + pPointers[0] = nullptr; + pPointers[1] = nullptr; + + pSizes[0] = 0; + pSizes[1] = 0; + } + } + + /* Write buffer_size elements from buffer, and advance the write pointer. If + * the data will not fit entirely, the write pointer will be unchanged + * and false will be returned. */ + bool write( const T *buffer, unsigned buffer_size ) + { + T *p[2]; + unsigned sizes[2]; + get_write_pointers( p, sizes ); + + if( buffer_size > sizes[0] + sizes[1] ) + return false; + + const int from_first = min( buffer_size, sizes[0] ); + memcpy( p[0], buffer, from_first*sizeof(T) ); + if( buffer_size > sizes[0] ) + memcpy( p[1], buffer+from_first, max(buffer_size-sizes[0], 0u)*sizeof(T) ); + + advance_write_pointer( buffer_size ); + + return true; + } + + /* Read buffer_size elements from buffer, and advance the read pointer. If + * the buffer can not be filled completely, the read pointer will be unchanged + * and false will be returned. */ + bool read( T *buffer, unsigned buffer_size ) + { + T *p[2]; + unsigned sizes[2]; + get_read_pointers( p, sizes ); + + if( buffer_size > sizes[0] + sizes[1] ) + return false; + + const int from_first = min( buffer_size, sizes[0] ); + memcpy( buffer, p[0], from_first*sizeof(T) ); + if( buffer_size > sizes[0] ) + memcpy( buffer+from_first, p[1], max(buffer_size-sizes[0], 0u)*sizeof(T) ); + + /* Set the data that we just read to 0xFF. This way, if we're passing pointesr + * through, we can tell if we accidentally get a stale pointer. */ + memset( p[0], 0xFF, from_first*sizeof(T) ); + if( buffer_size > sizes[0] ) + memset( p[1], 0xFF, max(buffer_size-sizes[0], 0u)*sizeof(T) ); + + advance_read_pointer( buffer_size ); + return true; + } +}; + +#endif + +/* + * Copyright (c) 2004 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/RageUtil_FileDB.cpp b/src/RageUtil_FileDB.cpp index 4997fe560a..ac11a91a6a 100644 --- a/src/RageUtil_FileDB.cpp +++ b/src/RageUtil_FileDB.cpp @@ -1,648 +1,648 @@ -#include "global.h" - -#include "RageUtil_FileDB.h" -#include "RageUtil.h" -#include "RageLog.h" - -/* Search for "beginning*containing*ending". */ -void FileSet::GetFilesMatching( const RString &sBeginning_, const RString &sContaining_, const RString &sEnding_, vector &asOut, bool bOnlyDirs ) const -{ - /* "files" is a case-insensitive mapping, by filename. Use lower_bound to figure - * out where to start. */ - RString sBeginning = sBeginning_; - sBeginning.MakeLower(); - RString sContaining = sContaining_; - sContaining.MakeLower(); - RString sEnding = sEnding_; - sEnding.MakeLower(); - - set::const_iterator i = files.lower_bound( File(sBeginning) ); - for( ; i != files.end(); ++i ) - { - const File &f = *i; - - if( bOnlyDirs && !f.dir ) - continue; - - const RString &sPath = f.lname; - - /* Check sBeginning. Once we hit a filename that no longer matches sBeginning, - * we're past all possible matches in the sort, so stop. */ - if( sBeginning.size() > sPath.size() ) - break; /* can't start with it */ - if( sPath.compare(0, sBeginning.size(), sBeginning) ) - break; /* doesn't start with it */ - - /* Position the end starts on: */ - int end_pos = int(sPath.size())-int(sEnding.size()); - - /* Check end. */ - if( end_pos < 0 ) - continue; /* can't end with it */ - if( sPath.compare(end_pos, string::npos, sEnding) ) - continue; /* doesn't end with it */ - - /* Check sContaining. Do this last, since it's the slowest (substring - * search instead of string match). */ - if( !sContaining.empty() ) - { - size_t pos = sPath.find( sContaining, sBeginning.size() ); - if( pos == sPath.npos ) - continue; /* doesn't contain it */ - if( pos + sContaining.size() > unsigned(end_pos) ) - continue; /* found it but it overlaps with the end */ - } - - asOut.push_back( f.name ); - } -} - -void FileSet::GetFilesEqualTo( const RString &sStr, vector &asOut, bool bOnlyDirs ) const -{ - set::const_iterator i = files.find( File(sStr) ); - if( i == files.end() ) - return; - - if( bOnlyDirs && !i->dir ) - return; - - asOut.push_back( i->name ); -} - -RageFileManager::FileType FileSet::GetFileType( const RString &sPath ) const -{ - set::const_iterator i = files.find( File(sPath) ); - if( i == files.end() ) - return RageFileManager::TYPE_NONE; - - return i->dir? RageFileManager::TYPE_DIR:RageFileManager::TYPE_FILE; -} - -int FileSet::GetFileSize( const RString &sPath ) const -{ - set::const_iterator i = files.find( File(sPath) ); - if( i == files.end() ) - return -1; - return i->size; -} - -int FileSet::GetFileHash( const RString &sPath ) const -{ - set::const_iterator i = files.find( File(sPath) ); - if( i == files.end() ) - return -1; - return i->hash + i->size; -} - -/* - * Given "foo/bar/baz/" or "foo/bar/baz", return "foo/bar/" and "baz". - * "foo" -> "", "foo" - */ -static void SplitPath( RString sPath, RString &sDir, RString &sName ) -{ - CollapsePath( sPath ); - if( sPath.Right(1) == "/" ) - sPath.erase( sPath.size()-1 ); - - size_t iSep = sPath.find_last_of( '/' ); - if( iSep == RString::npos ) - { - sDir = ""; - sName = sPath; - } - else - { - sDir = sPath.substr( 0, iSep+1 ); - sName = sPath.substr( iSep+1 ); - } -} - - -RageFileManager::FileType FilenameDB::GetFileType( const RString &sPath ) -{ - ASSERT( !m_Mutex.IsLockedByThisThread() ); - - RString sDir, sName; - SplitPath( sPath, sDir, sName ); - - if( sName == "/" ) - return RageFileManager::TYPE_DIR; - - const FileSet *fs = GetFileSet( sDir ); - RageFileManager::FileType ret = fs->GetFileType( sName ); - m_Mutex.Unlock(); /* locked by GetFileSet */ - return ret; -} - - -int FilenameDB::GetFileSize( const RString &sPath ) -{ - ASSERT( !m_Mutex.IsLockedByThisThread() ); - - RString sDir, sName; - SplitPath( sPath, sDir, sName ); - - const FileSet *fs = GetFileSet( sDir ); - int ret = fs->GetFileSize( sName ); - m_Mutex.Unlock(); /* locked by GetFileSet */ - return ret; -} - -int FilenameDB::GetFileHash( const RString &sPath ) -{ - ASSERT( !m_Mutex.IsLockedByThisThread() ); - - RString sDir, sName; - SplitPath( sPath, sDir, sName ); - - const FileSet *fs = GetFileSet( sDir ); - int ret = fs->GetFileHash( sName ); - m_Mutex.Unlock(); /* locked by GetFileSet */ - return ret; -} - -/* path should be fully collapsed, so we can operate in-place: no . or .. */ -bool FilenameDB::ResolvePath( RString &sPath ) -{ - if( sPath == "/" || sPath == "" ) - return true; - - /* Split path into components. */ - int iBegin = 0, iSize = -1; - - /* Resolve each component. */ - RString ret = ""; - const FileSet *fs = NULL; - - static const RString slash("/"); - for(;;) - { - split( sPath, slash, iBegin, iSize, true ); - if( iBegin == (int) sPath.size() ) - break; - - if( fs == NULL ) - fs = GetFileSet( ret ); - else - m_Mutex.Lock(); /* for access to fs */ - - RString p = sPath.substr( iBegin, iSize ); - ASSERT_M( p.size() != 1 || p[0] != '.', sPath ); // no . - ASSERT_M( p.size() != 2 || p[0] != '.' || p[1] != '.', sPath ); // no .. - set::const_iterator it = fs->files.find( File(p) ); - - /* If there were no matches, the path isn't found. */ - if( it == fs->files.end() ) - { - m_Mutex.Unlock(); /* locked by GetFileSet */ - return false; - } - - ret += "/" + it->name; - - fs = it->dirp; - - m_Mutex.Unlock(); /* locked by GetFileSet */ - } - - if( sPath.size() && sPath[sPath.size()-1] == '/' ) - sPath = ret + "/"; - else - sPath = ret; - return true; -} - -void FilenameDB::GetFilesMatching( const RString &sDir, const RString &sBeginning, const RString &sContaining, const RString &sEnding, vector &asOut, bool bOnlyDirs ) -{ - ASSERT( !m_Mutex.IsLockedByThisThread() ); - - const FileSet *fs = GetFileSet( sDir ); - fs->GetFilesMatching( sBeginning, sContaining, sEnding, asOut, bOnlyDirs ); - m_Mutex.Unlock(); /* locked by GetFileSet */ -} - -void FilenameDB::GetFilesEqualTo( const RString &sDir, const RString &sFile, vector &asOut, bool bOnlyDirs ) -{ - ASSERT( !m_Mutex.IsLockedByThisThread() ); - - const FileSet *fs = GetFileSet( sDir ); - fs->GetFilesEqualTo( sFile, asOut, bOnlyDirs ); - m_Mutex.Unlock(); /* locked by GetFileSet */ -} - - -void FilenameDB::GetFilesSimpleMatch( const RString &sDir, const RString &sMask, vector &asOut, bool bOnlyDirs ) -{ - /* Does this contain a wildcard? */ - size_t first_pos = sMask.find_first_of( '*' ); - if( first_pos == sMask.npos ) - { - /* No; just do a regular search. */ - GetFilesEqualTo( sDir, sMask, asOut, bOnlyDirs ); - return; - } - size_t second_pos = sMask.find_first_of( '*', first_pos+1 ); - if( second_pos == sMask.npos ) - { - /* Only one *: "A*B". */ - /* XXX: "_blank.png*.png" shouldn't match the file "_blank.png". */ - GetFilesMatching( sDir, sMask.substr(0, first_pos), RString(), sMask.substr(first_pos+1), asOut, bOnlyDirs ); - return; - } - - /* Two *s: "A*B*C". */ - GetFilesMatching( sDir, - sMask.substr(0, first_pos), - sMask.substr(first_pos+1, second_pos-first_pos-1), - sMask.substr(second_pos+1), asOut, bOnlyDirs ); -} - -/* - * Get the FileSet for dir; if create is true, create the FileSet if necessary. - * - * We want to unlock the object while we populate FileSets, so m_Mutex should not - * be locked when this is called. It will be locked on return; the caller must - * unlock it. - */ -FileSet *FilenameDB::GetFileSet( const RString &sDir_, bool bCreate ) -{ - RString sDir = sDir_; - - /* Creating can take a long time; don't hold the lock if we might do that. */ - if( bCreate && m_Mutex.IsLockedByThisThread() && LOG ) - LOG->Warn( "FilenameDB::GetFileSet: m_Mutex was locked" ); - - /* Normalize the path. */ - sDir.Replace("\\", "/"); /* foo\bar -> foo/bar */ - sDir.Replace("//", "/"); /* foo//bar -> foo/bar */ - - if( sDir == "" ) - sDir = "/"; - - RString sLower = sDir; - sLower.MakeLower(); - - m_Mutex.Lock(); - - for(;;) - { - /* Look for the directory. */ - map::iterator i = dirs.find( sLower ); - if( !bCreate ) - { - if( i == dirs.end() ) - return NULL; - return i->second; - } - - /* We're allowed to create. If the directory wasn't found, break out and - * create it. */ - if( i == dirs.end() ) - break; - - /* This directory already exists. If it's still being filled in by another - * thread, wait for it. */ - FileSet *pFileSet = i->second; - if( !pFileSet->m_bFilled ) - { - m_Mutex.Wait(); - - /* Beware: when we unlock m_Mutex to wait for it to finish filling, - * we give up our claim to dirs, so i may be invalid. Start over - * and re-search. */ - continue; - } - - if( ExpireSeconds == -1 || pFileSet->age.PeekDeltaTime() < ExpireSeconds ) - { - /* Found it, and it hasn't expired. */ - return pFileSet; - } - - /* It's expired. Delete the old entry. */ - this->DelFileSet( i ); - break; - } - - /* Create the FileSet and insert it. Set it to !m_bFilled, so if other threads - * happen to try to use this directory before we finish filling it, they'll wait. */ - FileSet *pRet = new FileSet; - pRet->m_bFilled = false; - dirs[sLower] = pRet; - - /* Unlock while we populate the directory. This way, reads to other directories - * won't block if this takes a while. */ - m_Mutex.Unlock(); - ASSERT( !m_Mutex.IsLockedByThisThread() ); - PopulateFileSet( *pRet, sDir ); - - /* If this isn't the root directory, we want to set the dirp pointer of our parent - * to the newly-created directory. Find the pointer we need to set. Be careful of - * order of operations, here: since we just unlocked, any this->dirs searches we did - * previously are no longer valid. */ - FileSet **pParentDirp = NULL; - if( sDir != "/" ) - { - RString sParent = Dirname( sDir ); - if( sParent == "./" ) - sParent = ""; - - /* This also re-locks m_Mutex for us. */ - FileSet *pParent = GetFileSet( sParent ); - if( pParent != NULL ) - { - set::iterator it = pParent->files.find( File(Basename(sDir)) ); - if( it != pParent->files.end() ) - pParentDirp = const_cast(&it->dirp); - } - } - else - { - m_Mutex.Lock(); - } - - if( pParentDirp != NULL ) - *pParentDirp = pRet; - - pRet->age.Touch(); - pRet->m_bFilled = true; - - /* Signal the event, to wake up any other threads that might be waiting for this - * directory. Leave the mutex locked; those threads will wake up when the current - * operation completes. */ - m_Mutex.Broadcast(); - - return pRet; -} - -/* Add the file or directory "sPath". sPath is a directory if it ends with - * a slash. */ -void FilenameDB::AddFile( const RString &sPath_, int iSize, int iHash, void *pPriv ) -{ - RString sPath(sPath_); - - if( sPath == "" || sPath == "/" ) - return; - - if( sPath[0] != '/' ) - sPath = "/" + sPath; - - vector asParts; - split( sPath, "/", asParts, false ); - - vector::const_iterator begin = asParts.begin(); - vector::const_iterator end = asParts.end(); - - bool IsDir = true; - if( sPath[sPath.size()-1] != '/' ) - IsDir = false; - else - --end; - - /* Skip the leading slash. */ - ++begin; - - do - { - /* Combine all but the last part. */ - RString dir = "/" + join( "/", begin, end-1 ); - if( dir != "/" ) - dir += "/"; - const RString &fn = *(end-1); - FileSet *fs = GetFileSet( dir ); - ASSERT( m_Mutex.IsLockedByThisThread() ); - - // const_cast to cast away the constness that is only needed for the name - File &f = const_cast(*fs->files.insert( fn ).first); - f.dir = IsDir; - if( !IsDir ) - { - f.size = iSize; - f.hash = iHash; - f.priv = pPriv; - } - m_Mutex.Unlock(); /* locked by GetFileSet */ - IsDir = true; - - --end; - } while( begin != end ); -} - -/* Remove the given FileSet, and all dirp pointers to it. This means the cache has - * expired, not that the directory is necessarily gone; don't actually delete the file - * from the parent. */ -void FilenameDB::DelFileSet( map::iterator dir ) -{ - /* If this isn't locked, dir may not be valid. */ - ASSERT( m_Mutex.IsLockedByThisThread() ); - - if( dir == dirs.end() ) - return; - - FileSet *fs = dir->second; - - /* Remove any stale dirp pointers. */ - for( map::iterator it = dirs.begin(); it != dirs.end(); ++it ) - { - FileSet *Clean = it->second; - for( set::iterator f = Clean->files.begin(); f != Clean->files.end(); ++f ) - { - File &ff = (File &) *f; - if( ff.dirp == fs ) - ff.dirp = NULL; - } - } - - delete fs; - dirs.erase( dir ); -} - -void FilenameDB::DelFile( const RString &sPath ) -{ - LockMut(m_Mutex); - RString lower = sPath; - lower.MakeLower(); - - map::iterator fsi = dirs.find( lower ); - DelFileSet( fsi ); - - /* Delete sPath from its parent. */ - RString Dir, Name; - SplitPath(sPath, Dir, Name); - FileSet *Parent = GetFileSet( Dir, false ); - if( Parent ) - Parent->files.erase( Name ); - - m_Mutex.Unlock(); /* locked by GetFileSet */ -} - -void FilenameDB::FlushDirCache( const RString & /* sDir */ ) -{ - FileSet *pFileSet = NULL; - m_Mutex.Lock(); - - for(;;) - { - if( dirs.empty() ) - break; - - /* Grab the first entry. Take it out of the list while we hold the - * lock, to guarantee that we own it. */ - pFileSet = dirs.begin()->second; - - dirs.erase( dirs.begin() ); - - /* If it's being filled, we don't really own it until it's finished being - * filled, so wait. */ - while( !pFileSet->m_bFilled ) - m_Mutex.Wait(); - delete pFileSet; - } - -#if 0 - /* XXX: This is tricky, we want to flush all of the subdirectories of - * sDir, but once we unlock the mutex, we basically have to start over. - * It's just an optimization though, so it can wait. */ - { - if( it != dirs.end() ) - { - pFileSet = it->second; - dirs.erase( it ); - while( !pFileSet->m_bFilled ) - m_Mutex.Wait(); - delete pFileSet; - - if( sDir != "/" ) - { - RString sParent = Dirname( sDir ); - if( sParent == "./" ) - sParent = ""; - sParent.MakeLower(); - it = dirs.find( sParent ); - if( it != dirs.end() ) - { - FileSet *pParent = it->second; - set::iterator fileit = pParent->files.find( File(Basename(sDir)) ); - if( fileit != pParent->files.end() ) - fileit->dirp = NULL; - } - } - } - else - { - LOG->Warn( "Trying to flush an unknown directory %s.", sDir.c_str() ); - } -#endif - m_Mutex.Unlock(); -} - -const File *FilenameDB::GetFile( const RString &sPath ) -{ - if( m_Mutex.IsLockedByThisThread() && LOG ) - LOG->Warn( "FilenameDB::GetFile: m_Mutex was locked" ); - - RString Dir, Name; - SplitPath(sPath, Dir, Name); - FileSet *fs = GetFileSet( Dir ); - - set::iterator it; - it = fs->files.find( File(Name) ); - if( it == fs->files.end() ) - return NULL; - - return &*it; -} - -void *FilenameDB::GetFilePriv( const RString &path ) -{ - ASSERT( !m_Mutex.IsLockedByThisThread() ); - - const File *pFile = GetFile( path ); - void *pRet = NULL; - if( pFile != NULL ) - pRet = pFile->priv; - - m_Mutex.Unlock(); /* locked by GetFileSet */ - return pRet; -} - - - -void FilenameDB::GetDirListing( const RString &sPath_, vector &asAddTo, bool bOnlyDirs, bool bReturnPathToo ) -{ - RString sPath = sPath_; -// LOG->Trace( "GetDirListing( %s )", sPath.c_str() ); - - ASSERT( !sPath.empty() ); - - /* Strip off the last path element and use it as a mask. */ - size_t pos = sPath.find_last_of( '/' ); - RString fn; - if( pos == sPath.npos ) - { - fn = sPath; - sPath = ""; - } - else - { - fn = sPath.substr(pos+1); - sPath = sPath.substr(0, pos+1); - } - - /* If the last element was empty, use "*". */ - if( fn.size() == 0 ) - fn = "*"; - - unsigned iStart = asAddTo.size(); - GetFilesSimpleMatch( sPath, fn, asAddTo, bOnlyDirs ); - - if( bReturnPathToo && iStart < asAddTo.size() ) - { - while( iStart < asAddTo.size() ) - { - asAddTo[iStart].insert( 0, sPath ); - iStart++; - } - } -} - -/* Get a complete copy of a FileSet. This isn't very efficient, since it's a deep - * copy, but allows retrieving a copy from elsewhere without having to worry about - * our locking semantics. */ -void FilenameDB::GetFileSetCopy( const RString &sDir, FileSet &out ) -{ - FileSet *pFileSet = GetFileSet( sDir ); - out = *pFileSet; - m_Mutex.Unlock(); /* locked by GetFileSet */ -} - -void FilenameDB::CacheFile( const RString &sPath ) -{ - LOG->Warn( "Slow cache due to: %s", sPath.c_str() ); - FlushDirCache( Dirname(sPath) ); -} - -/* - * Copyright (c) 2003-2004 Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" + +#include "RageUtil_FileDB.h" +#include "RageUtil.h" +#include "RageLog.h" + +/* Search for "beginning*containing*ending". */ +void FileSet::GetFilesMatching( const RString &sBeginning_, const RString &sContaining_, const RString &sEnding_, vector &asOut, bool bOnlyDirs ) const +{ + /* "files" is a case-insensitive mapping, by filename. Use lower_bound to figure + * out where to start. */ + RString sBeginning = sBeginning_; + sBeginning.MakeLower(); + RString sContaining = sContaining_; + sContaining.MakeLower(); + RString sEnding = sEnding_; + sEnding.MakeLower(); + + set::const_iterator i = files.lower_bound( File(sBeginning) ); + for( ; i != files.end(); ++i ) + { + const File &f = *i; + + if( bOnlyDirs && !f.dir ) + continue; + + const RString &sPath = f.lname; + + /* Check sBeginning. Once we hit a filename that no longer matches sBeginning, + * we're past all possible matches in the sort, so stop. */ + if( sBeginning.size() > sPath.size() ) + break; /* can't start with it */ + if( sPath.compare(0, sBeginning.size(), sBeginning) ) + break; /* doesn't start with it */ + + /* Position the end starts on: */ + int end_pos = int(sPath.size())-int(sEnding.size()); + + /* Check end. */ + if( end_pos < 0 ) + continue; /* can't end with it */ + if( sPath.compare(end_pos, string::npos, sEnding) ) + continue; /* doesn't end with it */ + + /* Check sContaining. Do this last, since it's the slowest (substring + * search instead of string match). */ + if( !sContaining.empty() ) + { + size_t pos = sPath.find( sContaining, sBeginning.size() ); + if( pos == sPath.npos ) + continue; /* doesn't contain it */ + if( pos + sContaining.size() > unsigned(end_pos) ) + continue; /* found it but it overlaps with the end */ + } + + asOut.push_back( f.name ); + } +} + +void FileSet::GetFilesEqualTo( const RString &sStr, vector &asOut, bool bOnlyDirs ) const +{ + set::const_iterator i = files.find( File(sStr) ); + if( i == files.end() ) + return; + + if( bOnlyDirs && !i->dir ) + return; + + asOut.push_back( i->name ); +} + +RageFileManager::FileType FileSet::GetFileType( const RString &sPath ) const +{ + set::const_iterator i = files.find( File(sPath) ); + if( i == files.end() ) + return RageFileManager::TYPE_NONE; + + return i->dir? RageFileManager::TYPE_DIR:RageFileManager::TYPE_FILE; +} + +int FileSet::GetFileSize( const RString &sPath ) const +{ + set::const_iterator i = files.find( File(sPath) ); + if( i == files.end() ) + return -1; + return i->size; +} + +int FileSet::GetFileHash( const RString &sPath ) const +{ + set::const_iterator i = files.find( File(sPath) ); + if( i == files.end() ) + return -1; + return i->hash + i->size; +} + +/* + * Given "foo/bar/baz/" or "foo/bar/baz", return "foo/bar/" and "baz". + * "foo" -> "", "foo" + */ +static void SplitPath( RString sPath, RString &sDir, RString &sName ) +{ + CollapsePath( sPath ); + if( sPath.Right(1) == "/" ) + sPath.erase( sPath.size()-1 ); + + size_t iSep = sPath.find_last_of( '/' ); + if( iSep == RString::npos ) + { + sDir = ""; + sName = sPath; + } + else + { + sDir = sPath.substr( 0, iSep+1 ); + sName = sPath.substr( iSep+1 ); + } +} + + +RageFileManager::FileType FilenameDB::GetFileType( const RString &sPath ) +{ + ASSERT( !m_Mutex.IsLockedByThisThread() ); + + RString sDir, sName; + SplitPath( sPath, sDir, sName ); + + if( sName == "/" ) + return RageFileManager::TYPE_DIR; + + const FileSet *fs = GetFileSet( sDir ); + RageFileManager::FileType ret = fs->GetFileType( sName ); + m_Mutex.Unlock(); /* locked by GetFileSet */ + return ret; +} + + +int FilenameDB::GetFileSize( const RString &sPath ) +{ + ASSERT( !m_Mutex.IsLockedByThisThread() ); + + RString sDir, sName; + SplitPath( sPath, sDir, sName ); + + const FileSet *fs = GetFileSet( sDir ); + int ret = fs->GetFileSize( sName ); + m_Mutex.Unlock(); /* locked by GetFileSet */ + return ret; +} + +int FilenameDB::GetFileHash( const RString &sPath ) +{ + ASSERT( !m_Mutex.IsLockedByThisThread() ); + + RString sDir, sName; + SplitPath( sPath, sDir, sName ); + + const FileSet *fs = GetFileSet( sDir ); + int ret = fs->GetFileHash( sName ); + m_Mutex.Unlock(); /* locked by GetFileSet */ + return ret; +} + +/* path should be fully collapsed, so we can operate in-place: no . or .. */ +bool FilenameDB::ResolvePath( RString &sPath ) +{ + if( sPath == "/" || sPath == "" ) + return true; + + /* Split path into components. */ + int iBegin = 0, iSize = -1; + + /* Resolve each component. */ + RString ret = ""; + const FileSet *fs = nullptr; + + static const RString slash("/"); + for(;;) + { + split( sPath, slash, iBegin, iSize, true ); + if( iBegin == (int) sPath.size() ) + break; + + if( fs == nullptr ) + fs = GetFileSet( ret ); + else + m_Mutex.Lock(); /* for access to fs */ + + RString p = sPath.substr( iBegin, iSize ); + ASSERT_M( p.size() != 1 || p[0] != '.', sPath ); // no . + ASSERT_M( p.size() != 2 || p[0] != '.' || p[1] != '.', sPath ); // no .. + set::const_iterator it = fs->files.find( File(p) ); + + /* If there were no matches, the path isn't found. */ + if( it == fs->files.end() ) + { + m_Mutex.Unlock(); /* locked by GetFileSet */ + return false; + } + + ret += "/" + it->name; + + fs = it->dirp; + + m_Mutex.Unlock(); /* locked by GetFileSet */ + } + + if( sPath.size() && sPath[sPath.size()-1] == '/' ) + sPath = ret + "/"; + else + sPath = ret; + return true; +} + +void FilenameDB::GetFilesMatching( const RString &sDir, const RString &sBeginning, const RString &sContaining, const RString &sEnding, vector &asOut, bool bOnlyDirs ) +{ + ASSERT( !m_Mutex.IsLockedByThisThread() ); + + const FileSet *fs = GetFileSet( sDir ); + fs->GetFilesMatching( sBeginning, sContaining, sEnding, asOut, bOnlyDirs ); + m_Mutex.Unlock(); /* locked by GetFileSet */ +} + +void FilenameDB::GetFilesEqualTo( const RString &sDir, const RString &sFile, vector &asOut, bool bOnlyDirs ) +{ + ASSERT( !m_Mutex.IsLockedByThisThread() ); + + const FileSet *fs = GetFileSet( sDir ); + fs->GetFilesEqualTo( sFile, asOut, bOnlyDirs ); + m_Mutex.Unlock(); /* locked by GetFileSet */ +} + + +void FilenameDB::GetFilesSimpleMatch( const RString &sDir, const RString &sMask, vector &asOut, bool bOnlyDirs ) +{ + /* Does this contain a wildcard? */ + size_t first_pos = sMask.find_first_of( '*' ); + if( first_pos == sMask.npos ) + { + /* No; just do a regular search. */ + GetFilesEqualTo( sDir, sMask, asOut, bOnlyDirs ); + return; + } + size_t second_pos = sMask.find_first_of( '*', first_pos+1 ); + if( second_pos == sMask.npos ) + { + /* Only one *: "A*B". */ + /* XXX: "_blank.png*.png" shouldn't match the file "_blank.png". */ + GetFilesMatching( sDir, sMask.substr(0, first_pos), RString(), sMask.substr(first_pos+1), asOut, bOnlyDirs ); + return; + } + + /* Two *s: "A*B*C". */ + GetFilesMatching( sDir, + sMask.substr(0, first_pos), + sMask.substr(first_pos+1, second_pos-first_pos-1), + sMask.substr(second_pos+1), asOut, bOnlyDirs ); +} + +/* + * Get the FileSet for dir; if create is true, create the FileSet if necessary. + * + * We want to unlock the object while we populate FileSets, so m_Mutex should not + * be locked when this is called. It will be locked on return; the caller must + * unlock it. + */ +FileSet *FilenameDB::GetFileSet( const RString &sDir_, bool bCreate ) +{ + RString sDir = sDir_; + + /* Creating can take a long time; don't hold the lock if we might do that. */ + if( bCreate && m_Mutex.IsLockedByThisThread() && LOG ) + LOG->Warn( "FilenameDB::GetFileSet: m_Mutex was locked" ); + + /* Normalize the path. */ + sDir.Replace("\\", "/"); /* foo\bar -> foo/bar */ + sDir.Replace("//", "/"); /* foo//bar -> foo/bar */ + + if( sDir == "" ) + sDir = "/"; + + RString sLower = sDir; + sLower.MakeLower(); + + m_Mutex.Lock(); + + for(;;) + { + /* Look for the directory. */ + map::iterator i = dirs.find( sLower ); + if( !bCreate ) + { + if( i == dirs.end() ) + return nullptr; + return i->second; + } + + /* We're allowed to create. If the directory wasn't found, break out and + * create it. */ + if( i == dirs.end() ) + break; + + /* This directory already exists. If it's still being filled in by another + * thread, wait for it. */ + FileSet *pFileSet = i->second; + if( !pFileSet->m_bFilled ) + { + m_Mutex.Wait(); + + /* Beware: when we unlock m_Mutex to wait for it to finish filling, + * we give up our claim to dirs, so i may be invalid. Start over + * and re-search. */ + continue; + } + + if( ExpireSeconds == -1 || pFileSet->age.PeekDeltaTime() < ExpireSeconds ) + { + /* Found it, and it hasn't expired. */ + return pFileSet; + } + + /* It's expired. Delete the old entry. */ + this->DelFileSet( i ); + break; + } + + /* Create the FileSet and insert it. Set it to !m_bFilled, so if other threads + * happen to try to use this directory before we finish filling it, they'll wait. */ + FileSet *pRet = new FileSet; + pRet->m_bFilled = false; + dirs[sLower] = pRet; + + /* Unlock while we populate the directory. This way, reads to other directories + * won't block if this takes a while. */ + m_Mutex.Unlock(); + ASSERT( !m_Mutex.IsLockedByThisThread() ); + PopulateFileSet( *pRet, sDir ); + + /* If this isn't the root directory, we want to set the dirp pointer of our parent + * to the newly-created directory. Find the pointer we need to set. Be careful of + * order of operations, here: since we just unlocked, any this->dirs searches we did + * previously are no longer valid. */ + FileSet **pParentDirp = nullptr; + if( sDir != "/" ) + { + RString sParent = Dirname( sDir ); + if( sParent == "./" ) + sParent = ""; + + /* This also re-locks m_Mutex for us. */ + FileSet *pParent = GetFileSet( sParent ); + if( pParent != nullptr ) + { + set::iterator it = pParent->files.find( File(Basename(sDir)) ); + if( it != pParent->files.end() ) + pParentDirp = const_cast(&it->dirp); + } + } + else + { + m_Mutex.Lock(); + } + + if( pParentDirp != nullptr ) + *pParentDirp = pRet; + + pRet->age.Touch(); + pRet->m_bFilled = true; + + /* Signal the event, to wake up any other threads that might be waiting for this + * directory. Leave the mutex locked; those threads will wake up when the current + * operation completes. */ + m_Mutex.Broadcast(); + + return pRet; +} + +/* Add the file or directory "sPath". sPath is a directory if it ends with + * a slash. */ +void FilenameDB::AddFile( const RString &sPath_, int iSize, int iHash, void *pPriv ) +{ + RString sPath(sPath_); + + if( sPath == "" || sPath == "/" ) + return; + + if( sPath[0] != '/' ) + sPath = "/" + sPath; + + vector asParts; + split( sPath, "/", asParts, false ); + + vector::const_iterator begin = asParts.begin(); + vector::const_iterator end = asParts.end(); + + bool IsDir = true; + if( sPath[sPath.size()-1] != '/' ) + IsDir = false; + else + --end; + + /* Skip the leading slash. */ + ++begin; + + do + { + /* Combine all but the last part. */ + RString dir = "/" + join( "/", begin, end-1 ); + if( dir != "/" ) + dir += "/"; + const RString &fn = *(end-1); + FileSet *fs = GetFileSet( dir ); + ASSERT( m_Mutex.IsLockedByThisThread() ); + + // const_cast to cast away the constness that is only needed for the name + File &f = const_cast(*fs->files.insert( fn ).first); + f.dir = IsDir; + if( !IsDir ) + { + f.size = iSize; + f.hash = iHash; + f.priv = pPriv; + } + m_Mutex.Unlock(); /* locked by GetFileSet */ + IsDir = true; + + --end; + } while( begin != end ); +} + +/* Remove the given FileSet, and all dirp pointers to it. This means the cache has + * expired, not that the directory is necessarily gone; don't actually delete the file + * from the parent. */ +void FilenameDB::DelFileSet( map::iterator dir ) +{ + /* If this isn't locked, dir may not be valid. */ + ASSERT( m_Mutex.IsLockedByThisThread() ); + + if( dir == dirs.end() ) + return; + + FileSet *fs = dir->second; + + /* Remove any stale dirp pointers. */ + for( map::iterator it = dirs.begin(); it != dirs.end(); ++it ) + { + FileSet *Clean = it->second; + for( set::iterator f = Clean->files.begin(); f != Clean->files.end(); ++f ) + { + File &ff = (File &) *f; + if( ff.dirp == fs ) + ff.dirp = nullptr; + } + } + + delete fs; + dirs.erase( dir ); +} + +void FilenameDB::DelFile( const RString &sPath ) +{ + LockMut(m_Mutex); + RString lower = sPath; + lower.MakeLower(); + + map::iterator fsi = dirs.find( lower ); + DelFileSet( fsi ); + + /* Delete sPath from its parent. */ + RString Dir, Name; + SplitPath(sPath, Dir, Name); + FileSet *Parent = GetFileSet( Dir, false ); + if( Parent ) + Parent->files.erase( Name ); + + m_Mutex.Unlock(); /* locked by GetFileSet */ +} + +void FilenameDB::FlushDirCache( const RString & /* sDir */ ) +{ + FileSet *pFileSet = nullptr; + m_Mutex.Lock(); + + for(;;) + { + if( dirs.empty() ) + break; + + /* Grab the first entry. Take it out of the list while we hold the + * lock, to guarantee that we own it. */ + pFileSet = dirs.begin()->second; + + dirs.erase( dirs.begin() ); + + /* If it's being filled, we don't really own it until it's finished being + * filled, so wait. */ + while( !pFileSet->m_bFilled ) + m_Mutex.Wait(); + delete pFileSet; + } + +#if 0 + /* XXX: This is tricky, we want to flush all of the subdirectories of + * sDir, but once we unlock the mutex, we basically have to start over. + * It's just an optimization though, so it can wait. */ + { + if( it != dirs.end() ) + { + pFileSet = it->second; + dirs.erase( it ); + while( !pFileSet->m_bFilled ) + m_Mutex.Wait(); + delete pFileSet; + + if( sDir != "/" ) + { + RString sParent = Dirname( sDir ); + if( sParent == "./" ) + sParent = ""; + sParent.MakeLower(); + it = dirs.find( sParent ); + if( it != dirs.end() ) + { + FileSet *pParent = it->second; + set::iterator fileit = pParent->files.find( File(Basename(sDir)) ); + if( fileit != pParent->files.end() ) + fileit->dirp = nullptr; + } + } + } + else + { + LOG->Warn( "Trying to flush an unknown directory %s.", sDir.c_str() ); + } +#endif + m_Mutex.Unlock(); +} + +const File *FilenameDB::GetFile( const RString &sPath ) +{ + if( m_Mutex.IsLockedByThisThread() && LOG ) + LOG->Warn( "FilenameDB::GetFile: m_Mutex was locked" ); + + RString Dir, Name; + SplitPath(sPath, Dir, Name); + FileSet *fs = GetFileSet( Dir ); + + set::iterator it; + it = fs->files.find( File(Name) ); + if( it == fs->files.end() ) + return nullptr; + + return &*it; +} + +void *FilenameDB::GetFilePriv( const RString &path ) +{ + ASSERT( !m_Mutex.IsLockedByThisThread() ); + + const File *pFile = GetFile( path ); + void *pRet = nullptr; + if( pFile != nullptr ) + pRet = pFile->priv; + + m_Mutex.Unlock(); /* locked by GetFileSet */ + return pRet; +} + + + +void FilenameDB::GetDirListing( const RString &sPath_, vector &asAddTo, bool bOnlyDirs, bool bReturnPathToo ) +{ + RString sPath = sPath_; +// LOG->Trace( "GetDirListing( %s )", sPath.c_str() ); + + ASSERT( !sPath.empty() ); + + /* Strip off the last path element and use it as a mask. */ + size_t pos = sPath.find_last_of( '/' ); + RString fn; + if( pos == sPath.npos ) + { + fn = sPath; + sPath = ""; + } + else + { + fn = sPath.substr(pos+1); + sPath = sPath.substr(0, pos+1); + } + + /* If the last element was empty, use "*". */ + if( fn.size() == 0 ) + fn = "*"; + + unsigned iStart = asAddTo.size(); + GetFilesSimpleMatch( sPath, fn, asAddTo, bOnlyDirs ); + + if( bReturnPathToo && iStart < asAddTo.size() ) + { + while( iStart < asAddTo.size() ) + { + asAddTo[iStart].insert( 0, sPath ); + iStart++; + } + } +} + +/* Get a complete copy of a FileSet. This isn't very efficient, since it's a deep + * copy, but allows retrieving a copy from elsewhere without having to worry about + * our locking semantics. */ +void FilenameDB::GetFileSetCopy( const RString &sDir, FileSet &out ) +{ + FileSet *pFileSet = GetFileSet( sDir ); + out = *pFileSet; + m_Mutex.Unlock(); /* locked by GetFileSet */ +} + +void FilenameDB::CacheFile( const RString &sPath ) +{ + LOG->Warn( "Slow cache due to: %s", sPath.c_str() ); + FlushDirCache( Dirname(sPath) ); +} + +/* + * Copyright (c) 2003-2004 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/RageUtil_FileDB.h b/src/RageUtil_FileDB.h index 196a4d1fc9..52a7f95816 100644 --- a/src/RageUtil_FileDB.h +++ b/src/RageUtil_FileDB.h @@ -29,15 +29,15 @@ struct File /* Private data, for RageFileDrivers. */ void *priv; - /* If this is non-NULL, and dir is true, this is a pointer to the FileSet containing + /* If this is non-nullptr, and dir is true, this is a pointer to the FileSet containing * the directory contents. (This is a cache; it isn't always set.) */ const FileSet *dirp; - File() { dir=false; dirp=NULL; size=-1; hash=-1; priv=NULL;} + File() { dir=false; dirp=nullptr; size=-1; hash=-1; priv=nullptr;} File( const RString &fn ) { SetName( fn ); - dir=false; size=-1; hash=-1; priv=NULL; dirp=NULL; + dir=false; size=-1; hash=-1; priv=nullptr; dirp=nullptr; } bool operator< (const File &rhs) const { return lnameSetBaseAlpha( fBaseAlpha ); - if(m_renderers != NULL) + if(m_renderers != nullptr) { // set arrow XYZ (*m_renderers)[c].UpdateReceptorGhostStuff(m_ReceptorArrow[c]); diff --git a/src/RoomInfoDisplay.cpp b/src/RoomInfoDisplay.cpp index 847db6846f..86c9c9103c 100644 --- a/src/RoomInfoDisplay.cpp +++ b/src/RoomInfoDisplay.cpp @@ -1,223 +1,223 @@ -#include "global.h" -#if !defined(WITHOUT_NETWORKING) -#include "RoomInfoDisplay.h" -#include "ActorUtil.h" -#include "NetworkSyncManager.h" -#include "LocalizedString.h" - -AutoScreenMessage( SM_RoomInfoRetract ); -AutoScreenMessage( SM_RoomInfoDeploy ); - -static LocalizedString LAST_ROUND_INFO ( "RoomInfoDisplay", "Last Round Info:" ); -static LocalizedString ROOM_NAME ( "RoomInfoDisplay", "Room Name:" ); -static LocalizedString ROOM_DESC ( "RoomInfoDisplay", "Room Description:" ); -static LocalizedString SONG_TITLE( "RoomInfoDisplay", "Song Title:" ); -static LocalizedString SONG_SUB_TITLE( "RoomInfoDisplay", "Song Subtitle:" ); -static LocalizedString SONG_ARTIST( "RoomInfoDisplay", "Song Artist:" ); -static LocalizedString PLAYERS( "RoomInfoDisplay", "Players" ); - -RoomInfoDisplay::RoomInfoDisplay() : - m_state( OPEN ) -{ - //No code -} - -RoomInfoDisplay::~RoomInfoDisplay() -{ - for (size_t i = 0; i < m_playerList.size(); i++) - { - this->RemoveChild(m_playerList[i]); - SAFE_DELETE(m_playerList[i]); - } -} - -void RoomInfoDisplay::DeployInfoBox() -{ - if (m_state == CLOSED) - { - ON_COMMAND( this ); - m_state = OPEN; - } -} - -void RoomInfoDisplay::RetractInfoBox() -{ - if (m_state == OPEN) - OFF_COMMAND( this ); - - m_state = LOCKED; -} - -void RoomInfoDisplay::Load( RString sType ) -{ - DEPLOY_DELAY.Load( sType, "DeployDelay" ); - RETRACT_DELAY.Load( sType, "RetractDelay" ); - PLAYERLISTX.Load( sType, "PlayerListElementX" ); - PLAYERLISTY.Load( sType, "PlayerListElementY" ); - PLAYERLISTOFFSETX.Load( sType, "PlayerListElementOffsetX" ); - PLAYERLISTOFFSETY.Load( sType, "PlayerListElementOffsetY" ); - - m_bg.Load( THEME->GetPathG(m_sName,"Background") ); - m_bg->SetName( "Background" ); - this->AddChild( m_bg ); - - m_Title.LoadFromFont( THEME->GetPathF(sType,"text") ); - m_Title.SetName( "RoomTitle" ); - m_Title.SetShadowLength( 0 ); - m_Title.SetHorizAlign( align_left ); - LOAD_ALL_COMMANDS( m_Title ); - ON_COMMAND( m_Title ); - this->AddChild( &m_Title ); - - m_Desc.LoadFromFont( THEME->GetPathF(sType,"text") ); - m_Desc.SetName( "RoomDesc" ); - m_Desc.SetShadowLength( 0 ); - m_Desc.SetHorizAlign( align_left ); - LOAD_ALL_COMMANDS( m_Desc ); - ON_COMMAND( m_Desc ); - this->AddChild( &m_Desc ); - - m_lastRound.LoadFromFont( THEME->GetPathF(sType,"text") ); - m_lastRound.SetName( "LastRound" ); - m_lastRound.SetText( LAST_ROUND_INFO.GetValue() ); - m_lastRound.SetShadowLength( 0 ); - m_lastRound.SetHorizAlign( align_left ); - LOAD_ALL_COMMANDS( m_lastRound ); - ON_COMMAND( m_lastRound ); - this->AddChild( &m_lastRound ); - - m_songTitle.LoadFromFont( THEME->GetPathF(sType,"text") ); - m_songTitle.SetName( "SongTitle" ); - m_songTitle.SetShadowLength( 0 ); - m_songTitle.SetHorizAlign( align_left ); - LOAD_ALL_COMMANDS( m_songTitle ); - ON_COMMAND( m_songTitle ); - this->AddChild( &m_songTitle ); - - m_songSub.LoadFromFont( THEME->GetPathF(sType,"text") ); - m_songSub.SetName( "SongSubTitle" ); - m_songSub.SetShadowLength( 0 ); - m_songSub.SetHorizAlign( align_left ); - LOAD_ALL_COMMANDS( m_songSub ); - ON_COMMAND( m_songSub ); - this->AddChild( &m_songSub ); - - m_songArtist.LoadFromFont( THEME->GetPathF(sType,"text") ); - m_songArtist.SetName( "SongArtist" ); - m_songArtist.SetShadowLength( 0 ); - m_songArtist.SetHorizAlign( align_left ); - LOAD_ALL_COMMANDS( m_songArtist ); - ON_COMMAND( m_songArtist ); - this->AddChild( &m_songArtist ); - - m_players.LoadFromFont( THEME->GetPathF(sType,"text") ); - m_players.SetName( "Players" ); - m_players.SetShadowLength( 0 ); - m_players.SetHorizAlign( align_left ); - LOAD_ALL_COMMANDS( m_players ); - ON_COMMAND( m_players ); - this->AddChild( &m_players ); - - LOAD_ALL_COMMANDS( this ); - - this->PlayCommand("Off"); - FinishTweening(); - - m_state = LOCKED; -} - -void RoomInfoDisplay::SetRoom( const RoomWheelItemData* roomData ) -{ - RequestRoomInfo(roomData->m_sText); - - m_Title.SetText( ROOM_NAME.GetValue() + roomData->m_sText ); - m_Desc.SetText( ROOM_DESC.GetValue() + roomData->m_sDesc ); -} - -void RoomInfoDisplay::Update( float fDeltaTime ) -{ - if ((m_deployDelay.PeekDeltaTime() >= DEPLOY_DELAY) && (m_deployDelay.PeekDeltaTime() < (DEPLOY_DELAY + RETRACT_DELAY))) - DeployInfoBox(); - else if (m_deployDelay.PeekDeltaTime() >= DEPLOY_DELAY + RETRACT_DELAY) - RetractInfoBox(); - - ActorFrame::Update(fDeltaTime); -} - -void RoomInfoDisplay::RequestRoomInfo(const RString& name) -{ - NSMAN->m_SMOnlinePacket.ClearPacket(); - NSMAN->m_SMOnlinePacket.Write1((uint8_t)3); //Request Room Info - NSMAN->m_SMOnlinePacket.WriteNT(name); - NSMAN->SendSMOnline( ); -} - -void RoomInfoDisplay::SetRoomInfo( const RoomInfo& info) -{ - m_songTitle.SetText( SONG_TITLE.GetValue() + info.songTitle ); - m_songSub.SetText( SONG_SUB_TITLE.GetValue() + info.songSubTitle ); - m_songArtist.SetText( SONG_ARTIST.GetValue() + info.songArtist ); - m_players.SetText(ssprintf("%s (%d/%d):", PLAYERS.GetValue().c_str(), info.numPlayers, info.maxPlayers)); - - if (m_playerList.size() > info.players.size()) - { - for (size_t i = info.players.size(); i < m_playerList.size(); i++) - { - //if our old list is larger remove some elements - this->RemoveChild(m_playerList[i]); - SAFE_DELETE(m_playerList[i]); - } - m_playerList.resize(info.players.size()); - } - else if (m_playerList.size() < info.players.size()) - { - //add elements if our old list is smaller - int oldsize = m_playerList.size(); - m_playerList.resize(info.players.size()); - for (size_t i = oldsize; i < m_playerList.size(); i++) - { - m_playerList[i] = new BitmapText; - m_playerList[i]->LoadFromFont( THEME->GetPathF(GetName(),"text") ); - m_playerList[i]->SetName("PlayerListElement"); - m_playerList[i]->SetHorizAlign( align_left ); - m_playerList[i]->SetX(PLAYERLISTX + (i * PLAYERLISTOFFSETX)); - m_playerList[i]->SetY(PLAYERLISTY + (i * PLAYERLISTOFFSETY)); - LOAD_ALL_COMMANDS(m_playerList[i]); - ON_COMMAND(m_playerList[i]); - this->AddChild(m_playerList[i]); - } - - } - - for (size_t i = 0; i < m_playerList.size(); i++) - m_playerList[i]->SetText(info.players[i]); - - m_state = CLOSED; - m_deployDelay.Touch(); -} -#endif - -/* - * (c) 2006 Josh Allen - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#if !defined(WITHOUT_NETWORKING) +#include "RoomInfoDisplay.h" +#include "ActorUtil.h" +#include "NetworkSyncManager.h" +#include "LocalizedString.h" + +AutoScreenMessage( SM_RoomInfoRetract ); +AutoScreenMessage( SM_RoomInfoDeploy ); + +static LocalizedString LAST_ROUND_INFO ( "RoomInfoDisplay", "Last Round Info:" ); +static LocalizedString ROOM_NAME ( "RoomInfoDisplay", "Room Name:" ); +static LocalizedString ROOM_DESC ( "RoomInfoDisplay", "Room Description:" ); +static LocalizedString SONG_TITLE( "RoomInfoDisplay", "Song Title:" ); +static LocalizedString SONG_SUB_TITLE( "RoomInfoDisplay", "Song Subtitle:" ); +static LocalizedString SONG_ARTIST( "RoomInfoDisplay", "Song Artist:" ); +static LocalizedString PLAYERS( "RoomInfoDisplay", "Players" ); + +RoomInfoDisplay::RoomInfoDisplay() : + m_state( OPEN ) +{ + //No code +} + +RoomInfoDisplay::~RoomInfoDisplay() +{ + for (size_t i = 0; i < m_playerList.size(); i++) + { + this->RemoveChild(m_playerList[i]); + SAFE_DELETE(m_playerList[i]); + } +} + +void RoomInfoDisplay::DeployInfoBox() +{ + if (m_state == CLOSED) + { + ON_COMMAND( this ); + m_state = OPEN; + } +} + +void RoomInfoDisplay::RetractInfoBox() +{ + if (m_state == OPEN) + OFF_COMMAND( this ); + + m_state = LOCKED; +} + +void RoomInfoDisplay::Load( RString sType ) +{ + DEPLOY_DELAY.Load( sType, "DeployDelay" ); + RETRACT_DELAY.Load( sType, "RetractDelay" ); + PLAYERLISTX.Load( sType, "PlayerListElementX" ); + PLAYERLISTY.Load( sType, "PlayerListElementY" ); + PLAYERLISTOFFSETX.Load( sType, "PlayerListElementOffsetX" ); + PLAYERLISTOFFSETY.Load( sType, "PlayerListElementOffsetY" ); + + m_bg.Load( THEME->GetPathG(m_sName,"Background") ); + m_bg->SetName( "Background" ); + this->AddChild( m_bg ); + + m_Title.LoadFromFont( THEME->GetPathF(sType,"text") ); + m_Title.SetName( "RoomTitle" ); + m_Title.SetShadowLength( 0 ); + m_Title.SetHorizAlign( align_left ); + LOAD_ALL_COMMANDS( m_Title ); + ON_COMMAND( m_Title ); + this->AddChild( &m_Title ); + + m_Desc.LoadFromFont( THEME->GetPathF(sType,"text") ); + m_Desc.SetName( "RoomDesc" ); + m_Desc.SetShadowLength( 0 ); + m_Desc.SetHorizAlign( align_left ); + LOAD_ALL_COMMANDS( m_Desc ); + ON_COMMAND( m_Desc ); + this->AddChild( &m_Desc ); + + m_lastRound.LoadFromFont( THEME->GetPathF(sType,"text") ); + m_lastRound.SetName( "LastRound" ); + m_lastRound.SetText( LAST_ROUND_INFO.GetValue() ); + m_lastRound.SetShadowLength( 0 ); + m_lastRound.SetHorizAlign( align_left ); + LOAD_ALL_COMMANDS( m_lastRound ); + ON_COMMAND( m_lastRound ); + this->AddChild( &m_lastRound ); + + m_songTitle.LoadFromFont( THEME->GetPathF(sType,"text") ); + m_songTitle.SetName( "SongTitle" ); + m_songTitle.SetShadowLength( 0 ); + m_songTitle.SetHorizAlign( align_left ); + LOAD_ALL_COMMANDS( m_songTitle ); + ON_COMMAND( m_songTitle ); + this->AddChild( &m_songTitle ); + + m_songSub.LoadFromFont( THEME->GetPathF(sType,"text") ); + m_songSub.SetName( "SongSubTitle" ); + m_songSub.SetShadowLength( 0 ); + m_songSub.SetHorizAlign( align_left ); + LOAD_ALL_COMMANDS( m_songSub ); + ON_COMMAND( m_songSub ); + this->AddChild( &m_songSub ); + + m_songArtist.LoadFromFont( THEME->GetPathF(sType,"text") ); + m_songArtist.SetName( "SongArtist" ); + m_songArtist.SetShadowLength( 0 ); + m_songArtist.SetHorizAlign( align_left ); + LOAD_ALL_COMMANDS( m_songArtist ); + ON_COMMAND( m_songArtist ); + this->AddChild( &m_songArtist ); + + m_players.LoadFromFont( THEME->GetPathF(sType,"text") ); + m_players.SetName( "Players" ); + m_players.SetShadowLength( 0 ); + m_players.SetHorizAlign( align_left ); + LOAD_ALL_COMMANDS( m_players ); + ON_COMMAND( m_players ); + this->AddChild( &m_players ); + + LOAD_ALL_COMMANDS( this ); + + this->PlayCommand("Off"); + FinishTweening(); + + m_state = LOCKED; +} + +void RoomInfoDisplay::SetRoom( const RoomWheelItemData* roomData ) +{ + RequestRoomInfo(roomData->m_sText); + + m_Title.SetText( ROOM_NAME.GetValue() + roomData->m_sText ); + m_Desc.SetText( ROOM_DESC.GetValue() + roomData->m_sDesc ); +} + +void RoomInfoDisplay::Update( float fDeltaTime ) +{ + if ((m_deployDelay.PeekDeltaTime() >= DEPLOY_DELAY) && (m_deployDelay.PeekDeltaTime() < (DEPLOY_DELAY + RETRACT_DELAY))) + DeployInfoBox(); + else if (m_deployDelay.PeekDeltaTime() >= DEPLOY_DELAY + RETRACT_DELAY) + RetractInfoBox(); + + ActorFrame::Update(fDeltaTime); +} + +void RoomInfoDisplay::RequestRoomInfo(const RString& name) +{ + NSMAN->m_SMOnlinePacket.ClearPacket(); + NSMAN->m_SMOnlinePacket.Write1((uint8_t)3); //Request Room Info + NSMAN->m_SMOnlinePacket.WriteNT(name); + NSMAN->SendSMOnline( ); +} + +void RoomInfoDisplay::SetRoomInfo( const RoomInfo& info) +{ + m_songTitle.SetText( SONG_TITLE.GetValue() + info.songTitle ); + m_songSub.SetText( SONG_SUB_TITLE.GetValue() + info.songSubTitle ); + m_songArtist.SetText( SONG_ARTIST.GetValue() + info.songArtist ); + m_players.SetText(ssprintf("%s (%d/%d):", PLAYERS.GetValue().c_str(), info.numPlayers, info.maxPlayers)); + + if (m_playerList.size() > info.players.size()) + { + for (size_t i = info.players.size(); i < m_playerList.size(); i++) + { + //if our old list is larger remove some elements + this->RemoveChild(m_playerList[i]); + SAFE_DELETE(m_playerList[i]); + } + m_playerList.resize(info.players.size()); + } + else if (m_playerList.size() < info.players.size()) + { + //add elements if our old list is smaller + int oldsize = m_playerList.size(); + m_playerList.resize(info.players.size()); + for (size_t i = oldsize; i < m_playerList.size(); i++) + { + m_playerList[i] = new BitmapText; + m_playerList[i]->LoadFromFont( THEME->GetPathF(GetName(),"text") ); + m_playerList[i]->SetName("PlayerListElement"); + m_playerList[i]->SetHorizAlign( align_left ); + m_playerList[i]->SetX(PLAYERLISTX + (i * PLAYERLISTOFFSETX)); + m_playerList[i]->SetY(PLAYERLISTY + (i * PLAYERLISTOFFSETY)); + LOAD_ALL_COMMANDS(m_playerList[i]); + ON_COMMAND(m_playerList[i]); + this->AddChild(m_playerList[i]); + } + + } + + for (size_t i = 0; i < m_playerList.size(); i++) + m_playerList[i]->SetText(info.players[i]); + + m_state = CLOSED; + m_deployDelay.Touch(); +} +#endif + +/* + * (c) 2006 Josh Allen + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/RoomWheel.cpp b/src/RoomWheel.cpp index 867d00c059..5cffd64c22 100644 --- a/src/RoomWheel.cpp +++ b/src/RoomWheel.cpp @@ -17,8 +17,10 @@ AutoScreenMessage( SM_RoomInfoDeploy ); RoomWheel::~RoomWheel() { - FOREACH( WheelItemBaseData*, m_CurWheelItemData, i ) - SAFE_DELETE( *i ); + for (WheelItemBaseData *i : m_CurWheelItemData) + { + SAFE_DELETE( i ); + } m_CurWheelItemData.clear(); } @@ -127,9 +129,9 @@ void RoomWheel::RemoveItem( int index ) vector::iterator i = m_CurWheelItemData.begin(); i += index; - // If this item's data happened to be last selected, make it NULL. + // If this item's data happened to be last selected, make it nullptr. if( m_LastSelection == *i ) - m_LastSelection = NULL; + m_LastSelection = nullptr; SAFE_DELETE( *i ); m_CurWheelItemData.erase( i ); @@ -152,8 +154,8 @@ bool RoomWheel::Select() return WheelBase::Select(); if( m_iSelection == 0 ) { - // Since this is not actually an option outside of this wheel, NULL is a good idea. - m_LastSelection = NULL; + // Since this is not actually an option outside of this wheel, nullptr is a good idea. + m_LastSelection = nullptr; ScreenTextEntry::TextEntry( SM_BackFromRoomName, ENTER_ROOM_NAME, "", 255 ); } return false; @@ -178,7 +180,7 @@ void RoomWheel::Move( int n ) if( n == 0 && m_iSelection >= m_offset ) { const RoomWheelItemData* data = GetItem( m_iSelection-m_offset ); - if( data != NULL ) + if( data != nullptr ) SCREENMAN->PostMessageToTopScreen( SM_RoomInfoDeploy, 0 ); } else diff --git a/src/SampleHistory.cpp b/src/SampleHistory.cpp index 08324f6a12..52d3aeba68 100644 --- a/src/SampleHistory.cpp +++ b/src/SampleHistory.cpp @@ -2,7 +2,7 @@ #include "SampleHistory.h" #include "RageLog.h" #include "RageUtil.h" -#include "Foreach.h" + inline float sample_step_size(int samples_per_second) { diff --git a/src/ScoreKeeperNormal.cpp b/src/ScoreKeeperNormal.cpp index 835c826100..f898b77fdd 100644 --- a/src/ScoreKeeperNormal.cpp +++ b/src/ScoreKeeperNormal.cpp @@ -62,9 +62,9 @@ void ScoreKeeperNormal::Load( for( unsigned i=0; iGetNoteData( ndTemp ); @@ -94,7 +94,7 @@ void ScoreKeeperNormal::Load( GAMESTATE->SetProcessedTimingData(pSteps->GetTimingData()); // XXX: Not sure why but NoteDataUtil::CalculateRadarValues segfaults without this iTotalPossibleDancePoints += this->GetPossibleDancePoints( &ndPre, &ndPost, pSteps->GetTimingData(), pSong->m_fMusicLengthSeconds ); iTotalPossibleGradePoints += this->GetPossibleGradePoints( &ndPre, &ndPost, pSteps->GetTimingData(), pSong->m_fMusicLengthSeconds ); - GAMESTATE->SetProcessedTimingData(NULL); + GAMESTATE->SetProcessedTimingData(nullptr); } m_pPlayerStageStats->m_iPossibleDancePoints = iTotalPossibleDancePoints; @@ -196,7 +196,7 @@ void ScoreKeeperNormal::OnNextSong( int iSongInCourseIndex, const Steps* pSteps, m_iTapNotesHit = 0; - GAMESTATE->SetProcessedTimingData(NULL); + GAMESTATE->SetProcessedTimingData(nullptr); } static int GetScore(int p, int Z, int64_t S, int n) diff --git a/src/ScoreKeeperRave.cpp b/src/ScoreKeeperRave.cpp index b48d53bf23..1c4af32f50 100644 --- a/src/ScoreKeeperRave.cpp +++ b/src/ScoreKeeperRave.cpp @@ -181,7 +181,7 @@ void ScoreKeeperRave::LaunchAttack( AttackLevel al ) RString* asAttacks = GAMESTATE->m_pCurCharacters[pn]->m_sAttacks[al]; // [NUM_ATTACKS_PER_LEVEL] RString sAttackToGive; - if (GAMESTATE->m_pCurCharacters[pn] != NULL) + if (GAMESTATE->m_pCurCharacters[pn] != nullptr) sAttackToGive = asAttacks[ RandomInt(NUM_ATTACKS_PER_LEVEL) ]; else { diff --git a/src/ScreenBookkeeping.cpp b/src/ScreenBookkeeping.cpp index d03857a19e..4f29ee32c6 100644 --- a/src/ScreenBookkeeping.cpp +++ b/src/ScreenBookkeeping.cpp @@ -147,9 +147,8 @@ void ScreenBookkeeping::UpdateView() vector vpSongs; int iCount = 0; - FOREACH_CONST( Song *, SONGMAN->GetAllSongs(), s ) + for (Song *pSong : SONGMAN->GetAllSongs()) { - Song *pSong = *s; if( UNLOCKMAN->SongIsLocked(pSong) & ~LOCKED_DISABLED ) continue; iCount += pProfile->GetSongNumTimesPlayed( pSong ); diff --git a/src/ScreenContinue.cpp b/src/ScreenContinue.cpp index 987c1c2c06..b3c4404e24 100644 --- a/src/ScreenContinue.cpp +++ b/src/ScreenContinue.cpp @@ -22,7 +22,7 @@ void ScreenContinue::Init() void ScreenContinue::BeginScreen() { - GAMESTATE->SetCurrentStyle( NULL, PLAYER_INVALID ); + GAMESTATE->SetCurrentStyle( nullptr, PLAYER_INVALID ); // Unjoin human players with 0 stages left and reset non-human players. // We need to reset non-human players because data in non-human (CPU) diff --git a/src/ScreenDebugOverlay.cpp b/src/ScreenDebugOverlay.cpp index 1d8a50a94f..2fe17069f8 100644 --- a/src/ScreenDebugOverlay.cpp +++ b/src/ScreenDebugOverlay.cpp @@ -57,13 +57,13 @@ static LocalizedString MUTE_ACTIONS_ON ("ScreenDebugOverlay", "Mute actions on") static LocalizedString MUTE_ACTIONS_OFF ("ScreenDebugOverlay", "Mute actions off"); class IDebugLine; -static vector *g_pvpSubscribers = NULL; +static vector *g_pvpSubscribers = nullptr; class IDebugLine { public: IDebugLine() { - if( g_pvpSubscribers == NULL ) + if( g_pvpSubscribers == nullptr ) g_pvpSubscribers = new vector; g_pvpSubscribers->push_back( this ); } @@ -99,13 +99,19 @@ ScreenDebugOverlay::~ScreenDebugOverlay() { this->RemoveAllChildren(); - FOREACH( BitmapText*, m_vptextPages, p ) - SAFE_DELETE( *p ); - FOREACH( BitmapText*, m_vptextButton, p ) - SAFE_DELETE( *p ); + for (BitmapText *p : m_vptextPages) + { + SAFE_DELETE(p); + } + for (BitmapText *p : m_vptextButton) + { + SAFE_DELETE(p); + } m_vptextButton.clear(); - FOREACH( BitmapText*, m_vptextFunction, p ) - SAFE_DELETE( *p ); + for (BitmapText *p : m_vptextFunction) + { + SAFE_DELETE(p); + } m_vptextFunction.clear(); } @@ -223,12 +229,12 @@ void ScreenDebugOverlay::Init() map iNextDebugButton; int iNextGameplayButton = 0; - FOREACH( IDebugLine*, *g_pvpSubscribers, p ) + for (IDebugLine *p : *g_pvpSubscribers) { - RString sPageName = (*p)->GetPageName(); + RString sPageName = p->GetPageName(); DeviceInput di; - switch( (*p)->GetType() ) + switch( p->GetType() ) { case IDebugLine::all_screens: di = g_Mappings.debugButton[iNextDebugButton[sPageName]++]; @@ -237,7 +243,7 @@ void ScreenDebugOverlay::Init() di = g_Mappings.gameplayButton[iNextGameplayButton++]; break; } - (*p)->m_Button = di; + p->m_Button = di; if( find(m_asPages.begin(), m_asPages.end(), sPageName) == m_asPages.end() ) m_asPages.push_back( sPageName ); @@ -258,9 +264,10 @@ void ScreenDebugOverlay::Init() m_textHeader.SetText( DEBUG_MENU ); this->AddChild( &m_textHeader ); - FOREACH_CONST( RString, m_asPages, s ) + auto start = m_asPages.begin(); + for (vector::const_iterator s = m_asPages.begin(); s != m_asPages.end(); ++s) { - int iPage = s - m_asPages.begin(); + int iPage = s - start; DeviceInput di; bool b = GetKeyFromMap( g_Mappings.pageButton, iPage, di ); @@ -279,7 +286,7 @@ void ScreenDebugOverlay::Init() this->AddChild( p ); } - FOREACH_CONST( IDebugLine*, *g_pvpSubscribers, p ) + for (auto p = g_pvpSubscribers->begin(); p != g_pvpSubscribers->end(); ++p) { { BitmapText *bt = new BitmapText; @@ -352,19 +359,21 @@ void ScreenDebugOverlay::Update( float fDeltaTime ) void ScreenDebugOverlay::UpdateText() { - FOREACH_CONST( RString, m_asPages, s ) + auto start = m_asPages.begin(); + for (vector::const_iterator s = m_asPages.begin(); s != m_asPages.end(); ++s) { - int iPage = s - m_asPages.begin(); + int iPage = s - start; m_vptextPages[iPage]->PlayCommand( (iPage == m_iCurrentPage) ? "GainFocus" : "LoseFocus" ); } // todo: allow changing of various spacing/location things -aj int iOffset = 0; - FOREACH_CONST( IDebugLine*, *g_pvpSubscribers, p ) + auto subStart = g_pvpSubscribers->begin(); + for (vector::const_iterator p = subStart; p != g_pvpSubscribers->end(); ++p) { RString sPageName = (*p)->GetPageName(); - int i = p-g_pvpSubscribers->begin(); + int i = p - subStart; float fY = LINE_START_Y + iOffset * LINE_SPACING; @@ -460,11 +469,12 @@ bool ScreenDebugOverlay::Input( const InputEventPlus &input ) return true; } - FOREACH_CONST( IDebugLine*, *g_pvpSubscribers, p ) + auto start = g_pvpSubscribers->begin(); + for (vector::const_iterator p = start; p != g_pvpSubscribers->end(); ++p) { RString sPageName = (*p)->GetPageName(); - int i = p-g_pvpSubscribers->begin(); + int i = p - start; // Gameplay buttons are available only in gameplay. Non-gameplay buttons // are only available when the screen is displayed. @@ -907,35 +917,35 @@ static void FillProfileStats( Profile *pProfile ) PREFSMAN->m_iMaxHighScoresPerListForPlayer.Get(); vector vpAllSongs = SONGMAN->GetAllSongs(); - FOREACH( Song*, vpAllSongs, pSong ) + for (Song const *pSong : vpAllSongs) { - vector vpAllSteps = (*pSong)->GetAllSteps(); - FOREACH( Steps*, vpAllSteps, pSteps ) + vector vpAllSteps = pSong->GetAllSteps(); + for (Steps const *pSteps : vpAllSteps) { if( rand() % 5 ) - pProfile->IncrementStepsPlayCount( *pSong, *pSteps ); + pProfile->IncrementStepsPlayCount( pSong, pSteps ); for( int i=0; iAddStepsHighScore( *pSong, *pSteps, MakeRandomHighScore(fPercentDP), iIndex ); + pProfile->AddStepsHighScore( pSong, pSteps, MakeRandomHighScore(fPercentDP), iIndex ); } } } vector vpAllCourses; SONGMAN->GetAllCourses( vpAllCourses, true ); - FOREACH( Course*, vpAllCourses, pCourse ) + for (Course const *pCourse : vpAllCourses) { vector vpAllTrails; - (*pCourse)->GetAllTrails( vpAllTrails ); - FOREACH( Trail*, vpAllTrails, pTrail ) + pCourse->GetAllTrails( vpAllTrails ); + for (Trail const *pTrail : vpAllTrails) { if( rand() % 5 ) - pProfile->IncrementCoursePlayCount( *pCourse, *pTrail ); + pProfile->IncrementCoursePlayCount( pCourse, pTrail ); for( int i=0; iAddCourseHighScore( *pCourse, *pTrail, MakeRandomHighScore(fPercentDP), iIndex ); + pProfile->AddCourseHighScore( pCourse, pTrail, MakeRandomHighScore(fPercentDP), iIndex ); } } } diff --git a/src/ScreenDemonstration.cpp b/src/ScreenDemonstration.cpp index a12904b37f..021635eb35 100644 --- a/src/ScreenDemonstration.cpp +++ b/src/ScreenDemonstration.cpp @@ -32,9 +32,9 @@ void ScreenDemonstration::Init() vector v; split( ALLOW_STYLE_TYPES, ",", v ); vector vStyleTypeAllow; - FOREACH_CONST( RString, v, s ) + for (RString const &s : v) { - StyleType st = StringToStyleType( *s ); + StyleType st = StringToStyleType( s ); ASSERT( st != StyleType_Invalid ); vStyleTypeAllow.push_back( st ); } @@ -57,7 +57,7 @@ void ScreenDemonstration::Init() ScreenJukebox::Init(); - if( GAMESTATE->m_pCurSong == NULL ) // we didn't find a song. + if( GAMESTATE->m_pCurSong == nullptr ) // we didn't find a song. { PostScreenMessage( SM_GoToNextScreen, 0 ); // Abort demonstration. return; diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index 70eb80bd06..e3a73bc687 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -7,7 +7,6 @@ #include "ArrowEffects.h" #include "BackgroundUtil.h" #include "CommonMetrics.h" -#include "Foreach.h" #include "GameManager.h" #include "GamePreferences.h" #include "GameSoundManager.h" @@ -535,7 +534,7 @@ void ScreenEdit::InitEditMappings() void ScreenEdit::LoadKeymapSectionIntoMappingsMember(XNode const* section, MapEditToDI& mappings) { - if(section == NULL) {return;} // Not an error, sections are optional. -Kyz + if(section == nullptr) {return;} // Not an error, sections are optional. -Kyz FOREACH_CONST_Attr(section, attr) { map::iterator name_entry= @@ -783,49 +782,49 @@ static MenuDef g_MainMenu( "ScreenMiniMenuMainMenu", MenuRowDef(ScreenEdit::play_whole_song, "Play whole song", - true, EditMode_Practice, true, true, 0, NULL ), + true, EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::play_current_beat_to_end, "Play current beat to end", - true, EditMode_Practice, true, true, 0, NULL ), + true, EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::save, "Save", - true, EditMode_Home, true, true, 0, NULL ), + true, EditMode_Home, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::play_selection, "Play selection", - true, EditMode_Practice, true, true, 0, NULL ), + true, EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::set_selection_start, "Set selection start", - true, EditMode_Practice, true, true, 0, NULL ), + true, EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::set_selection_end, "Set selection end", - true, EditMode_Practice, true, true, 0, NULL ), + true, EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::revert_to_last_save, "Revert to last save", - true, EditMode_Home, true, true, 0, NULL ), + true, EditMode_Home, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::revert_from_disk, "Revert from disk", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::options, "Editor options", - true, EditMode_Practice, true, true, 0, NULL ), + true, EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::edit_song_info, "Edit song info", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::edit_steps_information, "Edit steps information", - true, EditMode_Practice, true, true, 0, NULL ), + true, EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::edit_timing_data, "Edit Timing Data", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::view_steps_data, "View steps data", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::play_preview_music, "Play preview music", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::exit, "Exit Edit Mode", - true, EditMode_Practice, true, true, 0, NULL ) + true, EditMode_Practice, true, true, 0, nullptr ) ); static MenuDef g_AlterMenu( @@ -833,12 +832,12 @@ static MenuDef g_AlterMenu( MenuRowDef(ScreenEdit::cut, "Cut", true, - EditMode_Practice, true, true, 0, NULL ), + EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::copy, "Copy", - true, EditMode_Practice, true, true, 0, NULL ), + true, EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::clear, "Clear area", true, - EditMode_Practice, true, true, 0, NULL ), + EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::quantize, "Quantize", true, EditMode_Practice, true, true, 0, "4th","8th","12th","16th","24th","32nd","48th","64th","192nd"), @@ -858,57 +857,57 @@ static MenuDef g_AlterMenu( MenuRowDef(ScreenEdit::play, "Play selection", true, - EditMode_Practice, true, true, 0, NULL ), + EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::record, "Record in selection", true, - EditMode_Practice, true, true, 0, NULL ), + EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::preview_designation, "Designate as Music Preview", true, - EditMode_Full, true, true, 0, NULL ), + EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::convert_to_pause, "Convert selection to pause", true, - EditMode_Full, true, true, 0, NULL ), + EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::convert_to_delay, "Convert selection to delay", true, - EditMode_Full, true, true, 0, NULL ), + EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::convert_to_warp, "Convert selection to warp", true, - EditMode_Full, true, true, 0, NULL ), + EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::convert_to_fake, "Convert selection to fake", true, - EditMode_Full, true, true, 0, NULL ), + EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::convert_to_attack, "Convert selection to attack", true, - EditMode_Full, true, true, 0, NULL), + EditMode_Full, true, true, 0, nullptr), MenuRowDef(ScreenEdit::routine_invert_notes, "Invert notes' player", true, - EditMode_Full, true, true, 0, NULL ), + EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::routine_mirror_1_to_2, "Mirror Player 1 to 2", true, - EditMode_Full, true, true, 0, NULL ), + EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::routine_mirror_2_to_1, "Mirror Player 2 to 1", true, - EditMode_Full, true, true, 0, NULL ) + EditMode_Full, true, true, 0, nullptr ) ); static MenuDef g_AreaMenu( "ScreenMiniMenuAreaMenu", MenuRowDef(ScreenEdit::paste_at_current_beat, "Paste at current beat", - true, EditMode_Practice, true, true, 0, NULL ), + true, EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::paste_at_begin_marker, "Paste at begin marker", - true, EditMode_Practice, true, true, 0, NULL ), + true, EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::insert_and_shift, "Insert beat and shift down", true, EditMode_Practice, true, true, RCC_CHOICES ), @@ -924,27 +923,27 @@ static MenuDef g_AreaMenu( MenuRowDef(ScreenEdit::convert_pause_to_beat, "Convert pause to beats", true, - EditMode_Full, true, true, 0, NULL ), + EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::convert_delay_to_beat, "Convert delay to beats", true, - EditMode_Full, true, true, 0, NULL ), + EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::last_second_at_beat, "Designate last second at current beat", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::undo, "Undo", - true, EditMode_Practice, true, true, 0, NULL ), + true, EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::clear_clipboard, "Clear clipboard", true, - EditMode_Practice, true, true, 0, NULL ), + EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::modify_attacks_at_row, "Modify Attacks at current beat", - true, EditMode_CourseMods, true, true, 0, NULL), + true, EditMode_CourseMods, true, true, 0, nullptr), MenuRowDef(ScreenEdit::modify_keysounds_at_row, "Modify Keysounds at current beat", - true, EditMode_Full, true, true, 0, NULL) + true, EditMode_Full, true, true, 0, nullptr) ); @@ -952,155 +951,155 @@ static MenuDef g_StepsInformation( "ScreenMiniMenuStepsInformation", MenuRowDef(ScreenEdit::difficulty, "Difficulty", - true, EditMode_Practice, true, true, 0, NULL ), + true, EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::meter, "Meter", - true, EditMode_Practice, true, false, 0, NULL ), + true, EditMode_Practice, true, false, 0, nullptr ), MenuRowDef(ScreenEdit::predict_meter, "Predicted Meter", - false, EditMode_Full, true, true, 0, NULL ), + false, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::chartname, "Chart Name", - true, EditMode_Practice, true, true, 0, NULL ), + true, EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::description, "Description", - true, EditMode_Practice, true, true, 0, NULL ), + true, EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::chartstyle, "Chart Style", - true, EditMode_Practice, true, true, 0, NULL ), + true, EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::step_credit, "Step Author", - true, EditMode_Practice, true, true, 0, NULL ), + true, EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::step_display_bpm, "Display BPM", true, EditMode_Full, true, true, 0, "Actual", "Specified", "Random" ), MenuRowDef(ScreenEdit::step_min_bpm, "Min BPM", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::step_max_bpm, "Max BPM", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::step_music, - "Music File", true, EditMode_Full,true, true, 0, NULL) + "Music File", true, EditMode_Full,true, true, 0, nullptr) ); static MenuDef g_StepsData( "ScreenMiniMenuStepsData", - MenuRowDef( ScreenEdit::tap_notes, "Tap Steps", false, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::jumps, "Jumps", false, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::hands, "Hands", false, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::quads, "Quads", false, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::holds, "Holds", false, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::mines, "Mines", false, EditMode_Full, true, true, 0, NULL ), - MenuRowDef(ScreenEdit::rolls, "Rolls", false, EditMode_Full, true, true, 0, NULL ), - MenuRowDef(ScreenEdit::lifts, "Lifts", false, EditMode_Full, true, true, 0, NULL ), - MenuRowDef(ScreenEdit::fakes, "Fakes", false, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::stream, "Stream", false, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::voltage, "Voltage", false, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::air, "Air", false, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::freeze, "Freeze", false, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::chaos, "Chaos", false, EditMode_Full, true, true, 0, NULL ) + MenuRowDef( ScreenEdit::tap_notes, "Tap Steps", false, EditMode_Full, true, true, 0, nullptr ), + MenuRowDef( ScreenEdit::jumps, "Jumps", false, EditMode_Full, true, true, 0, nullptr ), + MenuRowDef( ScreenEdit::hands, "Hands", false, EditMode_Full, true, true, 0, nullptr ), + MenuRowDef( ScreenEdit::quads, "Quads", false, EditMode_Full, true, true, 0, nullptr ), + MenuRowDef( ScreenEdit::holds, "Holds", false, EditMode_Full, true, true, 0, nullptr ), + MenuRowDef( ScreenEdit::mines, "Mines", false, EditMode_Full, true, true, 0, nullptr ), + MenuRowDef(ScreenEdit::rolls, "Rolls", false, EditMode_Full, true, true, 0, nullptr ), + MenuRowDef(ScreenEdit::lifts, "Lifts", false, EditMode_Full, true, true, 0, nullptr ), + MenuRowDef(ScreenEdit::fakes, "Fakes", false, EditMode_Full, true, true, 0, nullptr ), + MenuRowDef( ScreenEdit::stream, "Stream", false, EditMode_Full, true, true, 0, nullptr ), + MenuRowDef( ScreenEdit::voltage, "Voltage", false, EditMode_Full, true, true, 0, nullptr ), + MenuRowDef( ScreenEdit::air, "Air", false, EditMode_Full, true, true, 0, nullptr ), + MenuRowDef( ScreenEdit::freeze, "Freeze", false, EditMode_Full, true, true, 0, nullptr ), + MenuRowDef( ScreenEdit::chaos, "Chaos", false, EditMode_Full, true, true, 0, nullptr ) ); static MenuDef g_SongInformation( "ScreenMiniMenuSongInformation", MenuRowDef(ScreenEdit::main_title, "Main title", - true, EditMode_Practice, true, true, 0, NULL ), + true, EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::sub_title, "Sub title", - true, EditMode_Practice, true, true, 0, NULL ), + true, EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::artist, "Artist", - true, EditMode_Practice, true, true, 0, NULL ), + true, EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::genre, "Genre", - true, EditMode_Practice, true, true, 0, NULL ), + true, EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::credit, "Credit", - true, EditMode_Practice, true, true, 0, NULL ), + true, EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::preview, "Preview", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::main_title_transliteration, "Main title transliteration", - true, EditMode_Practice, true, true, 0, NULL ), + true, EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::sub_title_transliteration, "Sub title transliteration", - true, EditMode_Practice, true, true, 0, NULL ), + true, EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::artist_transliteration, "Artist transliteration", - true, EditMode_Practice, true, true, 0, NULL ), + true, EditMode_Practice, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::last_second_hint, "Last second hint", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::preview_start, "Preview Start", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::preview_length, "Preview Length", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::display_bpm, "Display BPM", true, EditMode_Full, true, true, 0, "Actual", "Specified", "Random" ), MenuRowDef(ScreenEdit::min_bpm, "Min BPM", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::max_bpm, "Max BPM", - true, EditMode_Full, true, true, 0, NULL ) + true, EditMode_Full, true, true, 0, nullptr ) ); // Ugh, I don't like making this global pointer to clipboardFullTiming, but // it's the only way to make it visible to EnabledIfClipboardTimingIsSafe for // making sure it's safe to paste as the timing data for the Steps/Song. -Kyz -static TimingData* clipboard_full_timing= NULL; +static TimingData* clipboard_full_timing= nullptr; static bool EnabledIfClipboardTimingIsSafe(); static bool EnabledIfClipboardTimingIsSafe() { - return clipboard_full_timing != NULL && clipboard_full_timing->IsSafeFullTiming(); + return clipboard_full_timing != nullptr && clipboard_full_timing->IsSafeFullTiming(); } static MenuDef g_TimingDataInformation( "ScreenMiniMenuTimingDataInformation", MenuRowDef(ScreenEdit::beat_0_offset, "Beat 0 Offset", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::bpm, "Edit BPM change", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::stop, "Edit stop", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::delay, "Edit delay", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::label, "Edit label", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::tickcount, "Edit tickcount", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::combo, "Edit combo", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::warp, "Edit warp", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::speed_percent, "Edit speed (percent)", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::speed_wait, "Edit speed (wait)", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::speed_mode, "Edit speed (mode)", true, EditMode_Full, true, true, 0, "Beats", "Seconds" ), MenuRowDef(ScreenEdit::scroll, "Edit scrolling factor", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::fake, "Edit fake", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::shift_timing_in_region_down, "Shift timing in region down", true, EditMode_Full, true, true, RCC_CHOICES), @@ -1109,63 +1108,63 @@ static MenuDef g_TimingDataInformation( true, EditMode_Full, true, true, RCC_CHOICES), MenuRowDef(ScreenEdit::copy_timing_in_region, "Copy timing in region", - true, EditMode_Full, true, true, 0, NULL), + true, EditMode_Full, true, true, 0, nullptr), MenuRowDef(ScreenEdit::clear_timing_in_region, "Clear timing in region", - true, EditMode_Full, true, true, 0, NULL), + true, EditMode_Full, true, true, 0, nullptr), MenuRowDef(ScreenEdit::paste_timing_from_clip, "Paste timing from clipboard", - true, EditMode_Full, true, true, 0, NULL), + true, EditMode_Full, true, true, 0, nullptr), MenuRowDef(ScreenEdit::copy_full_timing, "Copy timing data", - true, EditMode_Full, true, true, 0, NULL ), + true, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::paste_full_timing, "Paste timing data", - EnabledIfClipboardTimingIsSafe, EditMode_Full, true, true, 0, NULL ), + EnabledIfClipboardTimingIsSafe, EditMode_Full, true, true, 0, nullptr ), MenuRowDef(ScreenEdit::erase_step_timing, "Erase step timing", - true, EditMode_Full, true, true, 0, NULL ) + true, EditMode_Full, true, true, 0, nullptr ) ); static MenuDef g_TimingDataChangeInformation( "ScreenMiniMenuTimingDataChangeInformation", MenuRowDef(ScreenEdit::timing_all, "All timing", - true, EditMode_Full, true, true, 0, NULL), + true, EditMode_Full, true, true, 0, nullptr), MenuRowDef(ScreenEdit::timing_bpm, "BPM changes", - true, EditMode_Full, true, true, 0, NULL), + true, EditMode_Full, true, true, 0, nullptr), MenuRowDef(ScreenEdit::timing_stop, "Stops", - true, EditMode_Full, true, true, 0, NULL), + true, EditMode_Full, true, true, 0, nullptr), MenuRowDef(ScreenEdit::timing_delay, "Delays", - true, EditMode_Full, true, true, 0, NULL), + true, EditMode_Full, true, true, 0, nullptr), // Time signatures disabled because they don't fully work. -Kyz // MenuRowDef(ScreenEdit::timing_time_sig, // "Time Signatures", - // true, EditMode_Full, true, true, 0, NULL), + // true, EditMode_Full, true, true, 0, nullptr), MenuRowDef(ScreenEdit::timing_warp, "Warps", - true, EditMode_Full, true, true, 0, NULL), + true, EditMode_Full, true, true, 0, nullptr), MenuRowDef(ScreenEdit::timing_label, "Labels", - true, EditMode_Full, true, true, 0, NULL), + true, EditMode_Full, true, true, 0, nullptr), MenuRowDef(ScreenEdit::timing_tickcount, "Tickcount", - true, EditMode_Full, true, true, 0, NULL), + true, EditMode_Full, true, true, 0, nullptr), MenuRowDef(ScreenEdit::timing_combo, "Combo segments", - true, EditMode_Full, true, true, 0, NULL), + true, EditMode_Full, true, true, 0, nullptr), MenuRowDef(ScreenEdit::timing_speed, "Speed segments", - true, EditMode_Full, true, true, 0, NULL), + true, EditMode_Full, true, true, 0, nullptr), MenuRowDef(ScreenEdit::timing_scroll, "Scroll segments", - true, EditMode_Full, true, true, 0, NULL), + true, EditMode_Full, true, true, 0, nullptr), MenuRowDef(ScreenEdit::timing_fake, "Fakes", - true, EditMode_Full, true, true, 0, NULL) + true, EditMode_Full, true, true, 0, nullptr) ); // XXX: What are these enums used for? @@ -1211,11 +1210,11 @@ static MenuDef g_BackgroundChange( MenuRowDef(ScreenEdit::transition, "Force Transition", true, - EditMode_Full, true, false, 0, NULL ), + EditMode_Full, true, false, 0, nullptr ), MenuRowDef(ScreenEdit::effect, "Force Effect", true, - EditMode_Full, true, false, 0, NULL ), + EditMode_Full, true, false, 0, nullptr ), MenuRowDef(ScreenEdit::color1, "Force Color 1", true, @@ -1236,31 +1235,31 @@ static MenuDef g_BackgroundChange( MenuRowDef(ScreenEdit::file1_song_bganimation, "File1 Song BGAnimation", EnabledIfSet1SongBGAnimation, - EditMode_Full, true, false, 0, NULL ), + EditMode_Full, true, false, 0, nullptr ), MenuRowDef(ScreenEdit::file1_song_movie, "File1 Song Movie", EnabledIfSet1SongMovie, - EditMode_Full, true, false, 0, NULL ), + EditMode_Full, true, false, 0, nullptr ), MenuRowDef(ScreenEdit::file1_song_still, "File1 Song Still", EnabledIfSet1SongBitmap, - EditMode_Full, true, false, 0, NULL ), + EditMode_Full, true, false, 0, nullptr ), MenuRowDef(ScreenEdit::file1_global_bganimation, "File1 Global BGAnimation", EnabledIfSet1GlobalBGAnimation, - EditMode_Full, true, false, 0, NULL ), + EditMode_Full, true, false, 0, nullptr ), MenuRowDef(ScreenEdit::file1_global_movie, "File1 Global Movie", EnabledIfSet1GlobalMovie, - EditMode_Full, true, false, 0, NULL ), + EditMode_Full, true, false, 0, nullptr ), MenuRowDef(ScreenEdit::file1_global_movie_song_group, "File1 Global Movie (Group)", EnabledIfSet1GlobalMovieSongGroup, - EditMode_Full, true, false, 0, NULL ), + EditMode_Full, true, false, 0, nullptr ), MenuRowDef(ScreenEdit::file1_global_movie_song_group_and_genre, "File1 Global Movie (Group + Genre)", EnabledIfSet1GlobalMovieSongGroupAndGenre, - EditMode_Full, true, false, 0, NULL ), + EditMode_Full, true, false, 0, nullptr ), MenuRowDef(ScreenEdit::file2_type, "File2 Type", true, @@ -1271,35 +1270,35 @@ static MenuDef g_BackgroundChange( MenuRowDef(ScreenEdit::file2_song_bganimation, "File2 Song BGAnimation", EnabledIfSet2SongBGAnimation, - EditMode_Full, true, false, 0, NULL ), + EditMode_Full, true, false, 0, nullptr ), MenuRowDef(ScreenEdit::file2_song_movie, "File2 Song Movie", EnabledIfSet2SongMovie, - EditMode_Full, true, false, 0, NULL ), + EditMode_Full, true, false, 0, nullptr ), MenuRowDef(ScreenEdit::file2_song_still, "File2 Song Still", EnabledIfSet2SongBitmap, - EditMode_Full, true, false, 0, NULL ), + EditMode_Full, true, false, 0, nullptr ), MenuRowDef(ScreenEdit::file2_global_bganimation, "File2 Global BGAnimation", EnabledIfSet2GlobalBGAnimation, - EditMode_Full, true, false, 0, NULL ), + EditMode_Full, true, false, 0, nullptr ), MenuRowDef(ScreenEdit::file2_global_movie, "File2 Global Movie", EnabledIfSet2GlobalMovie, - EditMode_Full, true, false, 0, NULL ), + EditMode_Full, true, false, 0, nullptr ), MenuRowDef(ScreenEdit::file2_global_movie_song_group, "File2 Global Movie (Group)", EnabledIfSet2GlobalMovieSongGroup, - EditMode_Full, true, false, 0, NULL ), + EditMode_Full, true, false, 0, nullptr ), MenuRowDef(ScreenEdit::file2_global_movie_song_group_and_genre, "File2 Global Movie (Group + Genre)", EnabledIfSet2GlobalMovieSongGroupAndGenre, - EditMode_Full, true, false, 0, NULL ), + EditMode_Full, true, false, 0, nullptr ), MenuRowDef(ScreenEdit::delete_change, "Remove Change", true, - EditMode_Full, true, true, 0, NULL ) + EditMode_Full, true, true, 0, nullptr ) ); static bool EnabledIfSet1SongBGAnimation() { return ScreenMiniMenu::s_viLastAnswers[ScreenEdit::file1_type] == song_bganimation && !g_BackgroundChange.rows[ScreenEdit::file1_song_bganimation].choices.empty(); } static bool EnabledIfSet1SongMovie() { return ScreenMiniMenu::s_viLastAnswers[ScreenEdit::file1_type] == song_movie && !g_BackgroundChange.rows[ScreenEdit::file1_song_movie].choices.empty(); } @@ -1367,7 +1366,7 @@ static MenuDef g_InsertStepAttack( static MenuDef g_CourseMode( "ScreenMiniMenuCourseDisplay", - MenuRowDef( -1, "Play mods from course", true, EditMode_Practice, true, false, 0, NULL ) + MenuRowDef( -1, "Play mods from course", true, EditMode_Practice, true, false, 0, nullptr ) ); // HACK: need to remember the track we're inserting on so that we can lay the @@ -1395,15 +1394,15 @@ REGISTER_SCREEN_CLASS( ScreenEdit ); void ScreenEdit::Init() { - m_pSoundMusic = NULL; + m_pSoundMusic = nullptr; GAMESTATE->m_bIsUsingStepTiming = false; GAMESTATE->m_bInStepEditor = true; SubscribeToMessage( "Judgment" ); - ASSERT( GAMESTATE->m_pCurSong != NULL ); - ASSERT( GAMESTATE->m_pCurSteps[PLAYER_1] != NULL ); + ASSERT( GAMESTATE->m_pCurSong != nullptr ); + ASSERT( GAMESTATE->m_pCurSteps[PLAYER_1] != nullptr ); EDIT_MODE.Load( m_sName, "EditMode" ); ScreenWithMenuElements::Init(); @@ -1524,7 +1523,7 @@ void ScreenEdit::Init() SetDirty(true); } - m_Player->Init( "Player", GAMESTATE->m_pPlayerState[PLAYER_1], NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ); + m_Player->Init( "Player", GAMESTATE->m_pPlayerState[PLAYER_1], nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr ); m_Player->CacheAllUsedNoteSkins(); GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerController = PC_HUMAN; m_Player->SetXY( PLAYER_X, PLAYER_Y ); @@ -1618,7 +1617,7 @@ void ScreenEdit::PlayPreviewMusic() SOUND->StopMusic(); SOUND->PlayMusic( m_pSong->GetPreviewMusicPath(), - NULL, + nullptr, false, m_pSong->GetPreviewStartSeconds(), m_pSong->m_fMusicSampleLengthSeconds, @@ -1632,11 +1631,11 @@ void ScreenEdit::MakeFilteredMenuDef( const MenuDef* pDef, MenuDef &menu ) menu.rows.clear(); vector aRows; - FOREACH_CONST( MenuRowDef, pDef->rows, r ) + for (MenuRowDef const &r : pDef->rows) { // Don't add rows that aren't applicable to this edit mode. - if( EDIT_MODE >= r->emShowIn ) - menu.rows.push_back( *r ); + if( EDIT_MODE >= r.emShowIn ) + menu.rows.push_back( r ); } } @@ -1655,7 +1654,7 @@ void ScreenEdit::Update( float fDeltaTime ) if( m_pSoundMusic->IsPlaying() ) { RageTimer tm; - const float fSeconds = m_pSoundMusic->GetPositionSeconds( NULL, &tm ); + const float fSeconds = m_pSoundMusic->GetPositionSeconds( nullptr, &tm ); GAMESTATE->UpdateSongPosition( fSeconds, GAMESTATE->m_pCurSong->m_SongTiming, tm ); } @@ -1865,7 +1864,7 @@ static ThemeMetric PREVIEW_LENGTH_FORMAT("ScreenEdit", "PreviewLengthFo static ThemeMetric RECORD_HOLD_TIME_FORMAT("ScreenEdit", "RecordHoldTimeFormat"); void ScreenEdit::UpdateTextInfo() { - if( m_pSteps == NULL ) + if( m_pSteps == nullptr ) return; // Don't update the text during playback or record. It causes skips. @@ -2003,7 +2002,7 @@ void ScreenEdit::UpdateTextInfo() m_textInfo.SetText( sText ); - GAMESTATE->SetProcessedTimingData(NULL); + GAMESTATE->SetProcessedTimingData(nullptr); } void ScreenEdit::DrawPrimitives() @@ -2440,7 +2439,7 @@ bool ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) // save current steps Steps* pSteps = GAMESTATE->m_pCurSteps[PLAYER_1]; - ASSERT( pSteps != NULL ); + ASSERT( pSteps != nullptr ); pSteps->SetNoteData( m_NoteDataEdit ); // Get all Steps of this StepsType @@ -2721,7 +2720,7 @@ bool ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) BackgroundUtil::GetSongBGAnimations( m_pSong, "", vThrowAway, menu.rows[file1_song_bganimation].choices ); BackgroundUtil::GetSongMovies( m_pSong, "", vThrowAway, menu.rows[file1_song_movie].choices ); BackgroundUtil::GetSongBitmaps( m_pSong, "", vThrowAway, menu.rows[file1_song_still].choices ); - BackgroundUtil::GetGlobalBGAnimations( m_pSong, "", vThrowAway, menu.rows[file1_global_bganimation].choices ); // NULL to get all background files + BackgroundUtil::GetGlobalBGAnimations( m_pSong, "", vThrowAway, menu.rows[file1_global_bganimation].choices ); // nullptr to get all background files BackgroundUtil::GetGlobalRandomMovies( m_pSong, "", vThrowAway, menu.rows[file1_global_movie].choices, false, false ); // all backgrounds BackgroundUtil::GetGlobalRandomMovies( m_pSong, "", vThrowAway, menu.rows[file1_global_movie_song_group].choices, false, true ); // song group's backgrounds BackgroundUtil::GetGlobalRandomMovies( m_pSong, "", vThrowAway, menu.rows[file1_global_movie_song_group_and_genre].choices, true, true ); // song group and genre's backgrounds @@ -2739,12 +2738,12 @@ bool ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) // Fill in lines enabled/disabled bool bAlreadyBGChangeHere = false; BackgroundChange bgChange; - FOREACH( BackgroundChange, m_pSong->GetBackgroundChanges(g_CurrentBGChangeLayer), bgc ) + for (BackgroundChange &bgc : m_pSong->GetBackgroundChanges(g_CurrentBGChangeLayer)) { - if( bgc->m_fStartBeat == GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ) + if( bgc.m_fStartBeat == GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ) { bAlreadyBGChangeHere = true; - bgChange = *bgc; + bgChange = bgc; } } @@ -2843,7 +2842,7 @@ bool ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) { // TODO: Give Song/Step Timing switches/functions here? Course *pCourse = GAMESTATE->m_pCurCourse; - if( pCourse == NULL ) + if( pCourse == nullptr ) return false; CourseEntry &ce = pCourse->m_vEntries[GAMESTATE->m_iEditCourseEntryIndex]; float fStartTime = m_pSteps->GetTimingData()->GetElapsedTimeFromBeat( GAMESTATE->m_pPlayerState[PLAYER_1]->m_Position.m_fSongBeat ); @@ -2851,7 +2850,7 @@ bool ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) if( iAttack >= 0 ) { - const RString sDuration = FloatToString(ce.attacks[iAttack].fSecsRemaining ); + const RString sDuration = std::to_string(ce.attacks[iAttack].fSecsRemaining ); g_InsertCourseAttack.rows[remove].bEnabled = true; if( g_InsertCourseAttack.rows[duration].choices.size() == 9 ) @@ -2915,7 +2914,7 @@ bool ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) float fStart, fEnd; PlayerOptions po; const Course *pCourse = GAMESTATE->m_pCurCourse; - if( pCourse == NULL ) + if( pCourse == nullptr ) return false; const CourseEntry &ce = pCourse->m_vEntries[GAMESTATE->m_iEditCourseEntryIndex]; @@ -2962,12 +2961,13 @@ bool ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) BackgroundLayer iLayer = BACKGROUND_LAYER_1; BackgroundChange bgChange; bgChange.m_fStartBeat = GAMESTATE->m_Position.m_fSongBeat; - FOREACH( BackgroundChange, m_pSong->GetBackgroundChanges(iLayer), bgc ) + auto & changes = m_pSong->GetBackgroundChanges(iLayer); + for (auto bgc = changes.begin(); bgc != changes.end(); ++bgc) { if( bgc->m_fStartBeat == GAMESTATE->m_Position.m_fSongBeat ) { bgChange = *bgc; - m_pSong->GetBackgroundChanges(iLayer).erase( bgc ); + changes.erase( bgc ); break; } } @@ -3434,7 +3434,7 @@ void ScreenEdit::TransitionEditState( EditState em ) /* FirstBeat affects backgrounds, so commit changes to memory (not to disk) * and recalc it. */ Steps* pSteps = GAMESTATE->m_pCurSteps[PLAYER_1]; - ASSERT( pSteps != NULL ); + ASSERT( pSteps != nullptr ); pSteps->SetNoteData( m_NoteDataEdit ); m_pSong->ReCalculateRadarValuesAndLastSecond(); @@ -3579,7 +3579,7 @@ void ScreenEdit::HandleMessage( const Message &msg ) if( GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerOptions.GetCurrent().m_bMuteOnError ) { RageSoundReader *pSoundReader = m_AutoKeysounds.GetPlayerSound( pn ); - if( pSoundReader == NULL ) + if( pSoundReader == nullptr ) pSoundReader = m_AutoKeysounds.GetSharedSound(); HoldNoteScore hns; @@ -3670,7 +3670,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) } else if( SM == SM_BackFromDifficultyMeterChange ) { - int i = StringToInt( ScreenTextEntry::s_sLastAnswer ); + int i = std::stoi( ScreenTextEntry::s_sLastAnswer ); GAMESTATE->m_pCurSteps[PLAYER_1]->SetMeter(i); SetDirty( true ); } @@ -3724,7 +3724,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) } else if ( SM == SM_BackFromTickcountChange && !ScreenTextEntry::s_bCancelledLast ) { - int iTick = StringToInt( ScreenTextEntry::s_sLastAnswer ); + int iTick = std::stoi( ScreenTextEntry::s_sLastAnswer ); if ( iTick >= 0 && iTick <= ROWS_PER_BEAT ) GetAppropriateTimingForUpdate().AddSegment( TickcountSegment( GetRow(), iTick) ); @@ -3789,7 +3789,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) } else { - int tmp = StringToInt(ScreenTextEntry::s_sLastAnswer ); + int tmp = std::stoi(ScreenTextEntry::s_sLastAnswer ); SpeedSegment::BaseUnit unit = (tmp == 0 ) ? SpeedSegment::UNIT_BEATS : SpeedSegment::UNIT_SECONDS; @@ -3827,24 +3827,26 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) else if( SM == SM_BackFromCourseModeMenu ) { const int num = ScreenMiniMenu::s_viLastAnswers[0]; - GAMESTATE->m_pCurCourse.Set( NULL ); + GAMESTATE->m_pCurCourse.Set(nullptr); if( num != 0 ) { const RString name = g_CourseMode.rows[0].choices[num]; Course *pCourse = SONGMAN->FindCourse( name ); int iCourseEntryIndex = -1; - FOREACH_CONST( CourseEntry, pCourse->m_vEntries, i ) + int index = 0; + for (CourseEntry const &i : pCourse->m_vEntries) { - if( i->songID.ToSong() == GAMESTATE->m_pCurSong.Get() ) - iCourseEntryIndex = i - pCourse->m_vEntries.begin(); + if( i.songID.ToSong() == GAMESTATE->m_pCurSong.Get() ) + iCourseEntryIndex = index; + ++index; } ASSERT( iCourseEntryIndex != -1 ); GAMESTATE->m_pCurCourse.Set( pCourse ); GAMESTATE->m_iEditCourseEntryIndex.Set( iCourseEntryIndex ); - ASSERT( GAMESTATE->m_pCurCourse != NULL ); + ASSERT( GAMESTATE->m_pCurCourse != nullptr ); } } else if (SM == SM_BackFromKeysoundTrack) @@ -4042,14 +4044,14 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) { ScreenTextEntry::TextEntry(SM_BackFromEditingAttackStart, EDIT_ATTACK_START, - FloatToString(attack.fStartSecond), + std::to_string(attack.fStartSecond), 10); } else if (option == 1) // adjusting the length of the attack { ScreenTextEntry::TextEntry(SM_BackFromEditingAttackLength, EDIT_ATTACK_LENGTH, - FloatToString(attack.fSecsRemaining), + std::to_string(attack.fSecsRemaining), 10); } else if (option >= 2 + mods.size()) // adding a new mod @@ -4120,8 +4122,8 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) true, true, 0, - NULL)); - g_IndividualAttack.rows[0].SetOneUnthemedChoice(FloatToString(attack.fStartSecond)); + nullptr)); + g_IndividualAttack.rows[0].SetOneUnthemedChoice(std::to_string(attack.fStartSecond)); g_IndividualAttack.rows.push_back(MenuRowDef(1, "Secs Remaining", true, @@ -4129,8 +4131,8 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) true, true, 0, - NULL)); - g_IndividualAttack.rows[1].SetOneUnthemedChoice(FloatToString(attack.fSecsRemaining)); + nullptr)); + g_IndividualAttack.rows[1].SetOneUnthemedChoice(std::to_string(attack.fSecsRemaining)); vector mods; split(attack.sModifiers, ",", mods); for (unsigned i = 0; i < mods.size(); ++i) @@ -4143,7 +4145,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) false, true, 0, - NULL)); + nullptr)); g_IndividualAttack.rows[col].SetOneUnthemedChoice(mods[i].c_str()); } @@ -4154,7 +4156,7 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) true, true, 0, - NULL)); + nullptr)); EditMiniMenu(&g_IndividualAttack, SM_BackFromInsertStepAttack); } @@ -4373,32 +4375,31 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) Song *pSong = GAMESTATE->m_pCurSong; const vector &apSteps = pSong->GetAllSteps(); vector apToDelete; - FOREACH_CONST( Steps *, apSteps, s ) + for (Steps *s : apSteps) { // If we're not on the same style, let it go. - if( GAMESTATE->m_pCurSteps[PLAYER_1]->m_StepsType != (*s)->m_StepsType ) + if( GAMESTATE->m_pCurSteps[PLAYER_1]->m_StepsType != s->m_StepsType ) continue; // If autogenned, it isn't being saved. - if( (*s)->IsAutogen() ) + if( s->IsAutogen() ) continue; // If the notedata has content, let it go. - if( !(*s)->GetNoteData().IsEmpty() ) + if( !s->GetNoteData().IsEmpty() ) continue; // It's hard to say if these steps were saved to disk or not. /* - if( !(*s)->GetSavedToDisk() ) + if( !(s->GetSavedToDisk() ) continue; */ - apToDelete.push_back( *s ); + apToDelete.push_back( s ); } - FOREACH_CONST( Steps *, apToDelete, s ) + for (Steps *pSteps : apToDelete) { - Steps *pSteps = *s; pSong->DeleteSteps( pSteps ); if( m_pSteps == pSteps ) - m_pSteps = NULL; + m_pSteps = nullptr; if( GAMESTATE->m_pCurSteps[PLAYER_1].Get() == pSteps ) - GAMESTATE->m_pCurSteps[PLAYER_1].Set( NULL ); + GAMESTATE->m_pCurSteps[PLAYER_1].Set(nullptr); } @@ -4561,7 +4562,7 @@ static void ChangeStepCredit( const RString &sNew ) static void ChangeStepMeter( const RString &sNew ) { - int diff = StringToInt(sNew); + int diff = std::stoi(sNew); GAMESTATE->m_pCurSteps[PLAYER_1]->SetMeter(max(diff, 1)); } @@ -4608,7 +4609,7 @@ static void ChangePreview(const RString& sNew) { RString error; RageSoundReader* sample= RageSoundReader_FileReader::OpenFile(pSong->GetPreviewMusicPath(), error); - if(sample == NULL) + if(sample == nullptr) { LOG->UserLog( "Preview file", pSong->GetPreviewMusicPath(), "couldn't be opened: %s", error.c_str() ); } @@ -4747,25 +4748,25 @@ void ScreenEdit::DisplayTimingMenu() // bool bIsSelecting = ( (m_NoteFieldEdit.m_iEndMarker != -1) && (m_NoteFieldEdit.m_iBeginMarker != -1) ); - g_TimingDataInformation.rows[beat_0_offset].SetOneUnthemedChoice( FloatToString(pTime.m_fBeat0OffsetInSeconds) ); - g_TimingDataInformation.rows[bpm].SetOneUnthemedChoice( FloatToString(pTime.GetBPMAtRow( row ) ) ); - g_TimingDataInformation.rows[stop].SetOneUnthemedChoice( FloatToString(pTime.GetStopAtRow( row ) ) ) ; - g_TimingDataInformation.rows[delay].SetOneUnthemedChoice( FloatToString(pTime.GetDelayAtRow( row ) ) ); + g_TimingDataInformation.rows[beat_0_offset].SetOneUnthemedChoice( std::to_string(pTime.m_fBeat0OffsetInSeconds) ); + g_TimingDataInformation.rows[bpm].SetOneUnthemedChoice( std::to_string(pTime.GetBPMAtRow( row ) ) ); + g_TimingDataInformation.rows[stop].SetOneUnthemedChoice( std::to_string(pTime.GetStopAtRow( row ) ) ) ; + g_TimingDataInformation.rows[delay].SetOneUnthemedChoice( std::to_string(pTime.GetDelayAtRow( row ) ) ); g_TimingDataInformation.rows[label].SetOneUnthemedChoice( pTime.GetLabelAtRow( row ).c_str() ); g_TimingDataInformation.rows[tickcount].SetOneUnthemedChoice( ssprintf("%d", pTime.GetTickcountAtRow( row ) ) ); g_TimingDataInformation.rows[combo].SetOneUnthemedChoice( ssprintf("%d / %d", pTime.GetComboAtRow( row ), pTime.GetMissComboAtRow( row ) ) ); - g_TimingDataInformation.rows[warp].SetOneUnthemedChoice( FloatToString(pTime.GetWarpAtRow( row ) ) ); - g_TimingDataInformation.rows[speed_percent].SetOneUnthemedChoice( bHasSpeedOnThisRow ? FloatToString(pTime.GetSpeedPercentAtRow( row ) ) : "---" ); - g_TimingDataInformation.rows[speed_wait].SetOneUnthemedChoice( bHasSpeedOnThisRow ? FloatToString(pTime.GetSpeedWaitAtRow( row ) ) : "---" ); + g_TimingDataInformation.rows[warp].SetOneUnthemedChoice( std::to_string(pTime.GetWarpAtRow( row ) ) ); + g_TimingDataInformation.rows[speed_percent].SetOneUnthemedChoice( bHasSpeedOnThisRow ? std::to_string(pTime.GetSpeedPercentAtRow( row ) ) : "---" ); + g_TimingDataInformation.rows[speed_wait].SetOneUnthemedChoice( bHasSpeedOnThisRow ? std::to_string(pTime.GetSpeedWaitAtRow( row ) ) : "---" ); RString starting = ( pTime.GetSpeedModeAtRow( row ) == 1 ? "Seconds" : "Beats" ); g_TimingDataInformation.rows[speed_mode].SetOneUnthemedChoice( starting.c_str() ); - g_TimingDataInformation.rows[scroll].SetOneUnthemedChoice( FloatToString(pTime.GetScrollAtRow( row ) ) ); - g_TimingDataInformation.rows[fake].SetOneUnthemedChoice( FloatToString(pTime.GetFakeAtRow( row ) ) ); + g_TimingDataInformation.rows[scroll].SetOneUnthemedChoice( std::to_string(pTime.GetScrollAtRow( row ) ) ); + g_TimingDataInformation.rows[fake].SetOneUnthemedChoice( std::to_string(pTime.GetFakeAtRow( row ) ) ); // g_TimingDataInformation.rows[speed_percent].bEnabled = !bIsSelecting; g_TimingDataInformation.rows[speed_wait].bEnabled = bHasSpeedOnThisRow; @@ -4882,8 +4883,8 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector &iAns g_StepsInformation.rows[step_credit].bEnabled = (EDIT_MODE.GetValue() >= EditMode_Full); g_StepsInformation.rows[step_credit].SetOneUnthemedChoice( pSteps->GetCredit() ); g_StepsInformation.rows[step_display_bpm].iDefaultChoice = pSteps->GetDisplayBPM(); - g_StepsInformation.rows[step_min_bpm].SetOneUnthemedChoice( FloatToString(pSteps->GetMinBPM())); - g_StepsInformation.rows[step_max_bpm].SetOneUnthemedChoice( FloatToString(pSteps->GetMaxBPM())); + g_StepsInformation.rows[step_min_bpm].SetOneUnthemedChoice( std::to_string(pSteps->GetMinBPM())); + g_StepsInformation.rows[step_max_bpm].SetOneUnthemedChoice( std::to_string(pSteps->GetMaxBPM())); g_StepsInformation.rows[step_music].bEnabled = (EDIT_MODE.GetValue() >= EditMode_Full); g_StepsInformation.rows[step_music].SetOneUnthemedChoice( pSteps->GetMusicFile() ); EditMiniMenu( &g_StepsInformation, SM_BackFromStepsInformation, SM_None ); @@ -4964,12 +4965,12 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector &iAns g_SongInformation.rows[main_title_transliteration].SetOneUnthemedChoice( pSong->m_sMainTitleTranslit ); g_SongInformation.rows[sub_title_transliteration].SetOneUnthemedChoice( pSong->m_sSubTitleTranslit ); g_SongInformation.rows[artist_transliteration].SetOneUnthemedChoice( pSong->m_sArtistTranslit ); - g_SongInformation.rows[last_second_hint].SetOneUnthemedChoice( FloatToString(pSong->GetSpecifiedLastSecond()) ); - g_SongInformation.rows[preview_start].SetOneUnthemedChoice( FloatToString(pSong->m_fMusicSampleStartSeconds) ); - g_SongInformation.rows[preview_length].SetOneUnthemedChoice( FloatToString(pSong->m_fMusicSampleLengthSeconds) ); + g_SongInformation.rows[last_second_hint].SetOneUnthemedChoice( std::to_string(pSong->GetSpecifiedLastSecond()) ); + g_SongInformation.rows[preview_start].SetOneUnthemedChoice( std::to_string(pSong->m_fMusicSampleStartSeconds) ); + g_SongInformation.rows[preview_length].SetOneUnthemedChoice( std::to_string(pSong->m_fMusicSampleLengthSeconds) ); g_SongInformation.rows[display_bpm].iDefaultChoice = pSong->m_DisplayBPMType; - g_SongInformation.rows[min_bpm].SetOneUnthemedChoice( FloatToString(pSong->m_fSpecifiedBPMMin) ); - g_SongInformation.rows[max_bpm].SetOneUnthemedChoice( FloatToString(pSong->m_fSpecifiedBPMMax) ); + g_SongInformation.rows[min_bpm].SetOneUnthemedChoice( std::to_string(pSong->m_fSpecifiedBPMMin) ); + g_SongInformation.rows[max_bpm].SetOneUnthemedChoice( std::to_string(pSong->m_fSpecifiedBPMMax) ); EditMiniMenu( &g_SongInformation, SM_BackFromSongInformation ); } @@ -5001,7 +5002,7 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector &iAns } break; }; - GAMESTATE->SetProcessedTimingData(NULL); + GAMESTATE->SetProcessedTimingData(nullptr); } static LocalizedString ENTER_ARBITRARY_MAPPING( "ScreenEdit", "Enter the new track mapping." ); @@ -5607,7 +5608,7 @@ void ScreenEdit::HandleStepsInformationChoice( StepsInformationChoice c, const v MAX_STEPS_DESCRIPTION_LENGTH, SongUtil::ValidateCurrentStepsChartName, ChangeChartName, - NULL); + nullptr); break; } case description: @@ -5618,7 +5619,7 @@ void ScreenEdit::HandleStepsInformationChoice( StepsInformationChoice c, const v MAX_STEPS_DESCRIPTION_LENGTH, SongUtil::ValidateCurrentStepsDescription, ChangeDescription, - NULL); + nullptr); break; } case chartstyle: @@ -5627,9 +5628,9 @@ void ScreenEdit::HandleStepsInformationChoice( StepsInformationChoice c, const v ENTER_NEW_CHART_STYLE, m_pSteps->GetChartStyle(), 255, - NULL, + nullptr, ChangeChartStyle, - NULL); + nullptr); break; } case step_credit: @@ -5640,7 +5641,7 @@ void ScreenEdit::HandleStepsInformationChoice( StepsInformationChoice c, const v 255, SongUtil::ValidateCurrentStepsCredit, ChangeStepCredit, - NULL); + nullptr); break; } case meter: @@ -5651,23 +5652,23 @@ void ScreenEdit::HandleStepsInformationChoice( StepsInformationChoice c, const v 4, ScreenTextEntry::IntValidate, ChangeStepMeter, - NULL); + nullptr); break; } case step_min_bpm: { ScreenTextEntry::TextEntry(SM_None, ENTER_MIN_BPM, - FloatToString(pSteps->GetMinBPM()), 20, + std::to_string(pSteps->GetMinBPM()), 20, ScreenTextEntry::FloatValidate, - ChangeStepsMinBPM, NULL); + ChangeStepsMinBPM, nullptr); break; } case step_max_bpm: { ScreenTextEntry::TextEntry(SM_None, ENTER_MAX_BPM, - FloatToString(pSteps->GetMaxBPM()), 20, + std::to_string(pSteps->GetMaxBPM()), 20, ScreenTextEntry::FloatValidate, - ChangeStepsMaxBPM, NULL); + ChangeStepsMaxBPM, nullptr); break; } case step_music: @@ -5678,7 +5679,7 @@ void ScreenEdit::HandleStepsInformationChoice( StepsInformationChoice c, const v 255, SongUtil::ValidateCurrentStepsMusic, ChangeStepMusic, - NULL); + nullptr); break; } default: @@ -5692,7 +5693,7 @@ static LocalizedString ENTER_SUB_TITLE ("ScreenEdit","Enter a new sub title.") static LocalizedString ENTER_ARTIST ("ScreenEdit","Enter a new artist."); static LocalizedString ENTER_GENRE ("ScreenEdit","Enter a new genre."); static LocalizedString ENTER_CREDIT ("ScreenEdit","Enter a new credit."); -static LocalizedString ENTER_PREVIEW ("ScreenEdit", "Enter a preview file."); +static LocalizedString ENTER_PREVIEW ("ScreenEdit","Enter a preview file."); static LocalizedString ENTER_MAIN_TITLE_TRANSLIT ("ScreenEdit","Enter a new main title transliteration."); static LocalizedString ENTER_SUB_TITLE_TRANSLIT ("ScreenEdit","Enter a new sub title transliteration."); static LocalizedString ENTER_ARTIST_TRANSLIT ("ScreenEdit","Enter a new artist transliteration."); @@ -5707,56 +5708,56 @@ void ScreenEdit::HandleSongInformationChoice( SongInformationChoice c, const vec switch( c ) { case main_title: - ScreenTextEntry::TextEntry( SM_None, ENTER_MAIN_TITLE, pSong->m_sMainTitle, 100, NULL, ChangeMainTitle, NULL ); + ScreenTextEntry::TextEntry( SM_None, ENTER_MAIN_TITLE, pSong->m_sMainTitle, 100, nullptr, ChangeMainTitle, nullptr ); break; case sub_title: - ScreenTextEntry::TextEntry( SM_None, ENTER_SUB_TITLE, pSong->m_sSubTitle, 100, NULL, ChangeSubTitle, NULL ); + ScreenTextEntry::TextEntry( SM_None, ENTER_SUB_TITLE, pSong->m_sSubTitle, 100, nullptr, ChangeSubTitle, nullptr ); break; case artist: - ScreenTextEntry::TextEntry( SM_None, ENTER_ARTIST, pSong->m_sArtist, 100, NULL, ChangeArtist, NULL ); + ScreenTextEntry::TextEntry( SM_None, ENTER_ARTIST, pSong->m_sArtist, 100, nullptr, ChangeArtist, nullptr ); break; case genre: - ScreenTextEntry::TextEntry( SM_None, ENTER_GENRE, pSong->m_sGenre, 100, NULL, ChangeGenre, NULL ); + ScreenTextEntry::TextEntry( SM_None, ENTER_GENRE, pSong->m_sGenre, 100, nullptr, ChangeGenre, nullptr ); break; case credit: - ScreenTextEntry::TextEntry( SM_None, ENTER_CREDIT, pSong->m_sCredit, 100, NULL, ChangeCredit, NULL ); + ScreenTextEntry::TextEntry( SM_None, ENTER_CREDIT, pSong->m_sCredit, 100, nullptr, ChangeCredit, nullptr ); break; case preview: - ScreenTextEntry::TextEntry(SM_None, ENTER_PREVIEW, pSong->m_PreviewFile, 100, SongUtil::ValidateCurrentSongPreview, ChangePreview, NULL); + ScreenTextEntry::TextEntry(SM_None, ENTER_PREVIEW, pSong->m_PreviewFile, 100, SongUtil::ValidateCurrentSongPreview, ChangePreview, nullptr); break; case main_title_transliteration: - ScreenTextEntry::TextEntry( SM_None, ENTER_MAIN_TITLE_TRANSLIT, pSong->m_sMainTitleTranslit, 100, NULL, ChangeMainTitleTranslit, NULL ); + ScreenTextEntry::TextEntry( SM_None, ENTER_MAIN_TITLE_TRANSLIT, pSong->m_sMainTitleTranslit, 100, nullptr, ChangeMainTitleTranslit, nullptr ); break; case sub_title_transliteration: - ScreenTextEntry::TextEntry( SM_None, ENTER_SUB_TITLE_TRANSLIT, pSong->m_sSubTitleTranslit, 100, NULL, ChangeSubTitleTranslit, NULL ); + ScreenTextEntry::TextEntry( SM_None, ENTER_SUB_TITLE_TRANSLIT, pSong->m_sSubTitleTranslit, 100, nullptr, ChangeSubTitleTranslit, nullptr ); break; case artist_transliteration: - ScreenTextEntry::TextEntry( SM_None, ENTER_ARTIST_TRANSLIT, pSong->m_sArtistTranslit, 100, NULL, ChangeArtistTranslit, NULL ); + ScreenTextEntry::TextEntry( SM_None, ENTER_ARTIST_TRANSLIT, pSong->m_sArtistTranslit, 100, nullptr, ChangeArtistTranslit, nullptr ); break; case last_second_hint: ScreenTextEntry::TextEntry( SM_None, ENTER_LAST_SECOND_HINT, - FloatToString(pSong->GetSpecifiedLastSecond()), 20, - ScreenTextEntry::FloatValidate, ChangeLastSecondHint, NULL ); + std::to_string(pSong->GetSpecifiedLastSecond()), 20, + ScreenTextEntry::FloatValidate, ChangeLastSecondHint, nullptr ); break; case preview_start: ScreenTextEntry::TextEntry( SM_None, ENTER_PREVIEW_START, - FloatToString(pSong->m_fMusicSampleStartSeconds), 20, - ScreenTextEntry::FloatValidate, ChangePreviewStart, NULL ); + std::to_string(pSong->m_fMusicSampleStartSeconds), 20, + ScreenTextEntry::FloatValidate, ChangePreviewStart, nullptr ); break; case preview_length: ScreenTextEntry::TextEntry( SM_None, ENTER_PREVIEW_LENGTH, - FloatToString(pSong->m_fMusicSampleLengthSeconds), 20, - ScreenTextEntry::FloatValidate, ChangePreviewLength, NULL ); + std::to_string(pSong->m_fMusicSampleLengthSeconds), 20, + ScreenTextEntry::FloatValidate, ChangePreviewLength, nullptr ); break; case min_bpm: ScreenTextEntry::TextEntry( SM_None, ENTER_MIN_BPM, - FloatToString(pSong->m_fSpecifiedBPMMin), 20, - ScreenTextEntry::FloatValidate, ChangeMinBPM, NULL ); + std::to_string(pSong->m_fSpecifiedBPMMin), 20, + ScreenTextEntry::FloatValidate, ChangeMinBPM, nullptr ); break; case max_bpm: ScreenTextEntry::TextEntry( SM_None, ENTER_MAX_BPM, - FloatToString(pSong->m_fSpecifiedBPMMax), 20, - ScreenTextEntry::FloatValidate, ChangeMaxBPM, NULL ); + std::to_string(pSong->m_fSpecifiedBPMMax), 20, + ScreenTextEntry::FloatValidate, ChangeMaxBPM, nullptr ); break; default: break; }; @@ -5775,7 +5776,7 @@ static LocalizedString ENTER_WARP_VALUE ( "ScreenEdit", "Enter a new Warp val static LocalizedString ENTER_SPEED_PERCENT_VALUE ( "ScreenEdit", "Enter a new Speed percent value." ); static LocalizedString ENTER_SPEED_WAIT_VALUE ( "ScreenEdit", "Enter a new Speed wait value." ); static LocalizedString ENTER_SPEED_MODE_VALUE ( "ScreenEdit", "Enter a new Speed mode value." ); -static LocalizedString ENTER_SCROLL_VALUE ( "ScreenEdit", "Enter a new Scroll value." ); +static LocalizedString ENTER_SCROLL_VALUE ( "ScreenEdit", "Enter a new Scroll value." ); static LocalizedString ENTER_FAKE_VALUE ( "ScreenEdit", "Enter a new Fake value." ); static LocalizedString CONFIRM_TIMING_ERASE ( "ScreenEdit", "Are you sure you want to erase this chart's timing data?" ); void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice c, const vector &iAnswers ) @@ -5787,7 +5788,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromBeat0Change, ENTER_BEAT_0_OFFSET, - FloatToString(GetAppropriateTiming().m_fBeat0OffsetInSeconds), + std::to_string(GetAppropriateTiming().m_fBeat0OffsetInSeconds), 20 ); break; @@ -5795,7 +5796,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromBPMChange, ENTER_BPM_VALUE, - FloatToString( GetAppropriateTiming().GetBPMAtBeat( GetBeat() ) ), + std::to_string( GetAppropriateTiming().GetBPMAtBeat( GetBeat() ) ), 10 ); break; @@ -5803,7 +5804,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromStopChange, ENTER_STOP_VALUE, - FloatToString( GetAppropriateTiming().GetStopAtBeat( GetBeat() ) ), + std::to_string( GetAppropriateTiming().GetStopAtBeat( GetBeat() ) ), 10 ); break; @@ -5811,7 +5812,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromDelayChange, ENTER_DELAY_VALUE, - FloatToString( GetAppropriateTiming().GetDelayAtBeat( GetBeat() ) ), + std::to_string( GetAppropriateTiming().GetDelayAtBeat( GetBeat() ) ), 10 ); break; @@ -5846,7 +5847,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromWarpChange, ENTER_WARP_VALUE, - FloatToString( GetAppropriateTiming().GetWarpAtBeat( GetBeat() ) ), + std::to_string( GetAppropriateTiming().GetWarpAtBeat( GetBeat() ) ), 10 ); break; @@ -5854,7 +5855,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromSpeedPercentChange, ENTER_SPEED_PERCENT_VALUE, - FloatToString( GetAppropriateTiming().GetSpeedSegmentAtBeat( GetBeat() )->GetRatio() ), + std::to_string( GetAppropriateTiming().GetSpeedSegmentAtBeat( GetBeat() )->GetRatio() ), 10 ); break; @@ -5862,7 +5863,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromScrollChange, ENTER_SCROLL_VALUE, - FloatToString( GetAppropriateTiming().GetScrollSegmentAtBeat( GetBeat() )->GetRatio() ), + std::to_string( GetAppropriateTiming().GetScrollSegmentAtBeat( GetBeat() )->GetRatio() ), 10 ); break; @@ -5870,7 +5871,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromSpeedWaitChange, ENTER_SPEED_WAIT_VALUE, - FloatToString( GetAppropriateTiming().GetSpeedSegmentAtBeat( GetBeat() )->GetDelay() ), + std::to_string( GetAppropriateTiming().GetSpeedSegmentAtBeat( GetBeat() )->GetDelay() ), 10 ); break; @@ -5890,7 +5891,7 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice ScreenTextEntry::TextEntry( SM_BackFromFakeChange, ENTER_FAKE_VALUE, - FloatToString(GetAppropriateTiming().GetFakeAtBeat( GetBeat() ) ), + std::to_string(GetAppropriateTiming().GetFakeAtBeat( GetBeat() ) ), 10 ); break; @@ -6015,13 +6016,14 @@ void ScreenEdit::HandleBGChangeChoice( BGChangeChoice c, const vector &iAns { BackgroundChange newChange; - FOREACH( BackgroundChange, m_pSong->GetBackgroundChanges(g_CurrentBGChangeLayer), iter ) + auto &changes = m_pSong->GetBackgroundChanges(g_CurrentBGChangeLayer); + for (auto iter = changes.begin(); iter != changes.end(); ++iter) { if( iter->m_fStartBeat == GAMESTATE->m_Position.m_fSongBeat ) { newChange = *iter; // delete the old change. We'll add a new one below. - m_pSong->GetBackgroundChanges(g_CurrentBGChangeLayer).erase( iter ); + changes.erase( iter ); break; } } @@ -6116,8 +6118,8 @@ void ScreenEdit::SetupCourseAttacks() } } - FOREACH( Attack, Attacks, attack ) - GAMESTATE->m_pPlayerState[PLAYER_1]->LaunchAttack( *attack ); + for (Attack &attack: Attacks) + GAMESTATE->m_pPlayerState[PLAYER_1]->LaunchAttack( attack ); } else { @@ -6130,12 +6132,12 @@ void ScreenEdit::SetupCourseAttacks() if (attacks.size() > 0) { - FOREACH(Attack, attacks, attack) + for (Attack &attack : attacks) { // LaunchAttack is actually a misnomer. The function actually adds // the attack to a list in the PlayerState which is checked and // updated every tick to see which ones to actually activate. -Kyz - GAMESTATE->m_pPlayerState[PLAYER_1]->LaunchAttack( *attack ); + GAMESTATE->m_pPlayerState[PLAYER_1]->LaunchAttack( attack ); } } } @@ -6146,13 +6148,13 @@ void ScreenEdit::SetupCourseAttacks() void ScreenEdit::CopyToLastSave() { - ASSERT( GAMESTATE->m_pCurSong != NULL ); - ASSERT( GAMESTATE->m_pCurSteps[PLAYER_1] != NULL ); + ASSERT( GAMESTATE->m_pCurSong != nullptr ); + ASSERT( GAMESTATE->m_pCurSteps[PLAYER_1] != nullptr ); m_SongLastSave = *GAMESTATE->m_pCurSong; m_vStepsLastSave.clear(); const vector &vSteps = GAMESTATE->m_pCurSong->GetStepsByStepsType( GAMESTATE->m_pCurSteps[PLAYER_1]->m_StepsType ); - FOREACH_CONST( Steps*, vSteps, it ) - m_vStepsLastSave.push_back( **it ); + for (Steps *it : vSteps) + m_vStepsLastSave.push_back( *it ); } void ScreenEdit::CopyFromLastSave() @@ -6169,7 +6171,7 @@ void ScreenEdit::CopyFromLastSave() void ScreenEdit::RevertFromDisk() { - ASSERT( GAMESTATE->m_pCurSteps[PLAYER_1] != NULL ); + ASSERT( GAMESTATE->m_pCurSteps[PLAYER_1] != nullptr ); StepsID id; id.FromSteps( GAMESTATE->m_pCurSteps[PLAYER_1] ); ASSERT( id.IsValid() ); @@ -6355,7 +6357,7 @@ static const EditHelpLine g_EditHelpLines[] = EditHelpLine( "Play whole song", EDIT_BUTTON_PLAY_FROM_START ), EditHelpLine( "Record", EDIT_BUTTON_RECORD_SELECTION ), EditHelpLine( "Set selection", EDIT_BUTTON_LAY_SELECT ), - EditHelpLine( "Next/prev steps of same StepsType", EDIT_BUTTON_OPEN_PREV_STEPS, EDIT_BUTTON_OPEN_NEXT_STEPS ), + EditHelpLine( "Next/prev steps of same StepsType", EDIT_BUTTON_OPEN_PREV_STEPS, EDIT_BUTTON_OPEN_NEXT_STEPS ), EditHelpLine( "Decrease/increase BPM at cur beat", EDIT_BUTTON_BPM_DOWN, EDIT_BUTTON_BPM_UP ), EditHelpLine( "Decrease/increase stop at cur beat", EDIT_BUTTON_STOP_DOWN, EDIT_BUTTON_STOP_UP ), EditHelpLine( "Decrease/increase delay at cur beat", EDIT_BUTTON_DELAY_DOWN, EDIT_BUTTON_DELAY_UP ), @@ -6392,8 +6394,8 @@ static void ProcessKeyName( RString &s ) static void ProcessKeyNames( vector &vs, bool doSort ) { - FOREACH( RString, vs, s ) - ProcessKeyName( *s ); + for (RString &s : vs) + ProcessKeyName( s ); if (doSort) sort( vs.begin(), vs.end() ); @@ -6405,15 +6407,15 @@ static RString GetDeviceButtonsLocalized( const vector &veb, const M { vector vsPress; vector vsHold; - FOREACH_CONST( EditButton, veb, eb ) + for (EditButton const &eb : veb) { - if( !IsMapped( *eb, editmap ) ) + if( !IsMapped( eb, editmap ) ) continue; for( int s=0; sGetLocalizedInputString(diPress)) ); if( diHold.IsValid() ) @@ -6440,10 +6442,10 @@ void ScreenEdit::DoStepAttackMenu() g_AttackAtTimeMenu.rows.clear(); unsigned index = 0; - - FOREACH(int, points, i) + + for (int &i : points) { - const Attack &attack = attacks[*i]; + const Attack &attack = attacks[i]; RString desc = ssprintf("%g -> %g (%d mod[s])", startTime, startTime + attack.fSecsRemaining, attack.GetNumAttacks()); @@ -6465,7 +6467,7 @@ void ScreenEdit::DoStepAttackMenu() true, true, 0, - NULL)); + nullptr)); EditMiniMenu(&g_AttackAtTimeMenu, SM_BackFromAttackAtTime); } @@ -6480,9 +6482,9 @@ void ScreenEdit::DoKeyboardTrackMenu() vector &kses = m_pSong->m_vsKeysoundFile; vector choices; - FOREACH(RString, kses, ks) + for (RString const &ks : kses) { - choices.push_back(*ks); + choices.push_back(ks); } choices.push_back(NEWKEYSND); choices.push_back(NO_KEYSND); diff --git a/src/ScreenEditMenu.cpp b/src/ScreenEditMenu.cpp index 548329a9b8..fa4e92209d 100644 --- a/src/ScreenEditMenu.cpp +++ b/src/ScreenEditMenu.cpp @@ -32,7 +32,7 @@ REGISTER_SCREEN_CLASS( ScreenEditMenu ); void ScreenEditMenu::Init() { // HACK: Disable any style set by the editor. - GAMESTATE->SetCurrentStyle( NULL, PLAYER_INVALID ); + GAMESTATE->SetCurrentStyle( nullptr, PLAYER_INVALID ); // Enable all players. FOREACH_PlayerNumber( pn ) @@ -91,7 +91,7 @@ void ScreenEditMenu::HandleScreenMessage( const ScreenMessage SM ) Steps* pStepsToDelete = GAMESTATE->m_pCurSteps[PLAYER_1]; FOREACH_PlayerNumber(pn) { - GAMESTATE->m_pCurSteps[pn].Set(NULL); + GAMESTATE->m_pCurSteps[pn].Set(nullptr); } bool bSaveSong = !pStepsToDelete->WasLoadedFromProfile(); pSong->DeleteSteps( pStepsToDelete ); @@ -174,7 +174,7 @@ static void SetCurrentStepsDescription( const RString &s ) static void DeleteCurrentSteps() { GAMESTATE->m_pCurSong->DeleteSteps( GAMESTATE->m_pCurSteps[0] ); - GAMESTATE->m_pCurSteps[0].Set( NULL ); + GAMESTATE->m_pCurSteps[0].Set(nullptr); } static LocalizedString MISSING_MUSIC_FILE ( "ScreenEditMenu", "This song is missing a music file and cannot be edited." ); @@ -216,7 +216,7 @@ bool ScreenEditMenu::MenuStart( const InputEventPlus & ) } GAMESTATE->m_pCurSong.Set( pSong ); - GAMESTATE->m_pCurCourse.Set( NULL ); + GAMESTATE->m_pCurCourse.Set( nullptr ); GAMESTATE->SetCurrentStyle( GAMEMAN->GetEditorStyleForStepsType(st), PLAYER_INVALID ); GAMESTATE->m_pCurSteps[PLAYER_1].Set( pSteps ); @@ -252,7 +252,7 @@ bool ScreenEditMenu::MenuStart( const InputEventPlus & ) { case EditMenuAction_Delete: { - ASSERT( pSteps != NULL ); + ASSERT( pSteps != nullptr ); if( pSteps->IsAutogen() ) { SCREENMAN->PlayInvalidSound(); @@ -270,7 +270,7 @@ bool ScreenEditMenu::MenuStart( const InputEventPlus & ) case EditMenuAction_Practice: break; case EditMenuAction_Delete: - ASSERT( pSteps != NULL ); + ASSERT( pSteps != nullptr ); ScreenPrompt::Prompt( SM_None, STEPS_WILL_BE_LOST.GetValue() + "\n\n" + CONTINUE_WITH_DELETE.GetValue(), PROMPT_YES_NO, ANSWER_NO ); break; @@ -279,7 +279,7 @@ bool ScreenEditMenu::MenuStart( const InputEventPlus & ) { FOREACH_PlayerNumber(pn) { - GAMESTATE->m_pCurSteps[pn].Set(NULL); + GAMESTATE->m_pCurSteps[pn].Set(nullptr); } pSong->LoadAutosaveFile(); SONGMAN->Invalidate(pSong); @@ -327,7 +327,7 @@ bool ScreenEditMenu::MenuStart( const InputEventPlus & ) GAMESTATE->m_pCurSong.Set( pSong ); GAMESTATE->m_pCurSteps[PLAYER_1].Set( pSteps ); - GAMESTATE->m_pCurCourse.Set( NULL ); + GAMESTATE->m_pCurCourse.Set(nullptr); } break; default: @@ -342,7 +342,7 @@ bool ScreenEditMenu::MenuStart( const InputEventPlus & ) case EditMenuAction_Practice: { // Prepare for ScreenEdit - ASSERT( pSteps != NULL ); + ASSERT( pSteps != nullptr ); bool bPromptToNameSteps = (action == EditMenuAction_Create && dc == Difficulty_Edit); if( bPromptToNameSteps ) { diff --git a/src/ScreenGameplay.cpp b/src/ScreenGameplay.cpp index c267b46d7a..ec4e7d492f 100644 --- a/src/ScreenGameplay.cpp +++ b/src/ScreenGameplay.cpp @@ -38,7 +38,6 @@ #include "StatsManager.h" #include "PlayerAI.h" // for NUM_SKILL_LEVELS #include "NetworkSyncManager.h" -#include "Foreach.h" #include "DancingCharacters.h" #include "ScreenDimensions.h" #include "ThemeMetric.h" @@ -102,13 +101,13 @@ PlayerInfo::PlayerInfo(): m_pn(PLAYER_INVALID), m_mp(MultiPlayer_Invalid), m_bIsDummy(false), m_iDummyIndex(0), m_iAddToDifficulty(0), m_bPlayerEnabled(false), m_PlayerStateDummy(), m_PlayerStageStatsDummy(), m_SoundEffectControl(), - m_vpStepsQueue(), m_asModifiersQueue(), m_pLifeMeter(NULL), - m_ptextCourseSongNumber(NULL), m_ptextStepsDescription(NULL), - m_pPrimaryScoreDisplay(NULL), m_pSecondaryScoreDisplay(NULL), - m_pPrimaryScoreKeeper(NULL), m_pSecondaryScoreKeeper(NULL), - m_ptextPlayerOptions(NULL), m_pActiveAttackList(NULL), - m_NoteData(), m_pPlayer(NULL), m_pInventory(NULL), - m_pStepsDisplay(NULL), m_sprOniGameOver() {} + m_vpStepsQueue(), m_asModifiersQueue(), m_pLifeMeter(nullptr), + m_ptextCourseSongNumber(nullptr), m_ptextStepsDescription(nullptr), + m_pPrimaryScoreDisplay(nullptr), m_pSecondaryScoreDisplay(nullptr), + m_pPrimaryScoreKeeper(nullptr), m_pSecondaryScoreKeeper(nullptr), + m_ptextPlayerOptions(nullptr), m_pActiveAttackList(nullptr), + m_NoteData(), m_pPlayer(nullptr), m_pInventory(nullptr), + m_pStepsDisplay(nullptr), m_sprOniGameOver() {} void PlayerInfo::Load( PlayerNumber pn, MultiPlayer mp, bool bShowNoteField, int iAddToDifficulty ) { @@ -117,9 +116,9 @@ void PlayerInfo::Load( PlayerNumber pn, MultiPlayer mp, bool bShowNoteField, int m_bPlayerEnabled = IsEnabled(); m_bIsDummy = false; m_iAddToDifficulty = iAddToDifficulty; - m_pLifeMeter = NULL; - m_ptextCourseSongNumber = NULL; - m_ptextStepsDescription = NULL; + m_pLifeMeter = nullptr; + m_ptextCourseSongNumber = nullptr; + m_ptextStepsDescription = nullptr; if( !IsMultiPlayer() ) { @@ -175,11 +174,11 @@ void PlayerInfo::Load( PlayerNumber pn, MultiPlayer mp, bool bShowNoteField, int break; } - m_ptextPlayerOptions = NULL; - m_pActiveAttackList = NULL; + m_ptextPlayerOptions = nullptr; + m_pActiveAttackList = nullptr; m_pPlayer = new Player( m_NoteData, bShowNoteField ); - m_pInventory = NULL; - m_pStepsDisplay = NULL; + m_pInventory = nullptr; + m_pStepsDisplay = nullptr; if( IsMultiPlayer() ) { @@ -323,8 +322,8 @@ GetNextVisiblePlayerInfo( vector::iterator iter, vector ScreenGameplay::ScreenGameplay() { - m_pSongBackground = NULL; - m_pSongForeground = NULL; + m_pSongBackground = nullptr; + m_pSongForeground = nullptr; m_bForceNoNetwork = false; m_delaying_ready_announce= false; GAMESTATE->m_AdjustTokensBySongCostForFinalStageCheck= false; @@ -399,12 +398,12 @@ void ScreenGameplay::Init() if( !GAMESTATE->m_bDemonstrationOrJukebox ) MEMCARDMAN->PauseMountingThread(); - m_pSoundMusic = NULL; + m_pSoundMusic = nullptr; set_paused_internal(false); - m_pCombinedLifeMeter = NULL; + m_pCombinedLifeMeter = nullptr; - if( GAMESTATE->m_pCurSong == NULL && GAMESTATE->m_pCurCourse == NULL ) + if( GAMESTATE->m_pCurSong == nullptr && GAMESTATE->m_pCurCourse == nullptr ) return; // ScreenDemonstration will move us to the next screen. We just need to survive for one update without crashing. /* Save settings to the profile now. Don't do this on extra stages, since the @@ -458,7 +457,7 @@ void ScreenGameplay::Init() } FOREACH_EnabledPlayer(p) - ASSERT( GAMESTATE->m_pCurSteps[p].Get() != NULL ); + ASSERT( GAMESTATE->m_pCurSteps[p].Get() != nullptr ); } /* Increment the course play count. */ @@ -738,7 +737,7 @@ void ScreenGameplay::Init() { if( GAMESTATE->IsCourseMode() ) { - ASSERT( pi->m_ptextCourseSongNumber == NULL ); + ASSERT( pi->m_ptextCourseSongNumber == nullptr ); SONG_NUMBER_FORMAT.Load( m_sName, "SongNumberFormat" ); pi->m_ptextCourseSongNumber = new BitmapText; pi->m_ptextCourseSongNumber->LoadFromFont( THEME->GetPathF(m_sName,"SongNum") ); @@ -749,7 +748,7 @@ void ScreenGameplay::Init() this->AddChild( pi->m_ptextCourseSongNumber ); } - ASSERT( pi->m_ptextStepsDescription == NULL ); + ASSERT( pi->m_ptextStepsDescription == nullptr ); pi->m_ptextStepsDescription = new BitmapText; pi->m_ptextStepsDescription->LoadFromFont( THEME->GetPathF(m_sName,"StepsDescription") ); pi->m_ptextStepsDescription->SetName( ssprintf("StepsDescription%s",pi->GetName().c_str()) ); @@ -757,7 +756,7 @@ void ScreenGameplay::Init() this->AddChild( pi->m_ptextStepsDescription ); // Player/Song options - ASSERT( pi->m_ptextPlayerOptions == NULL ); + ASSERT( pi->m_ptextPlayerOptions == nullptr ); pi->m_ptextPlayerOptions = new BitmapText; pi->m_ptextPlayerOptions->LoadFromFont( THEME->GetPathF(m_sName,"player options") ); pi->m_ptextPlayerOptions->SetName( ssprintf("PlayerOptions%s",pi->GetName().c_str()) ); @@ -765,7 +764,7 @@ void ScreenGameplay::Init() this->AddChild( pi->m_ptextPlayerOptions ); // Difficulty icon and meter - ASSERT( pi->m_pStepsDisplay == NULL ); + ASSERT( pi->m_pStepsDisplay == nullptr ); pi->m_pStepsDisplay = new StepsDisplay; pi->m_pStepsDisplay->Load("StepsDisplayGameplay", pi->GetPlayerState() ); pi->m_pStepsDisplay->SetName( ssprintf("StepsDisplay%s",pi->GetName().c_str()) ); @@ -796,7 +795,7 @@ void ScreenGameplay::Init() FOREACH_VisiblePlayerInfo( m_vPlayerInfo, pi ) { - ASSERT( pi->m_pActiveAttackList == NULL ); + ASSERT( pi->m_pActiveAttackList == nullptr ); pi->m_pActiveAttackList = new ActiveAttackList; pi->m_pActiveAttackList->LoadFromFont( THEME->GetPathF(m_sName,"ActiveAttackList") ); pi->m_pActiveAttackList->Init( pi->GetPlayerState() ); @@ -880,10 +879,10 @@ void ScreenGameplay::Init() // Fill StageStats STATSMAN->m_CurStageStats.m_vpPossibleSongs = m_apSongsQueue; - FOREACH( PlayerInfo, m_vPlayerInfo, pi ) + for (PlayerInfo &pi : m_vPlayerInfo) { - if( pi->GetPlayerStageStats() ) - pi->GetPlayerStageStats()->m_vpPossibleSteps = pi->m_vpStepsQueue; + if( pi.GetPlayerStageStats() ) + pi.GetPlayerStageStats()->m_vpPossibleSteps = pi.m_vpStepsQueue; } FOREACH_EnabledPlayerInfo( m_vPlayerInfo, pi ) @@ -928,31 +927,31 @@ void ScreenGameplay::InitSongQueues() if( GAMESTATE->IsCourseMode() ) { Course* pCourse = GAMESTATE->m_pCurCourse; - ASSERT( pCourse != NULL ); + ASSERT( pCourse != nullptr ); m_apSongsQueue.clear(); PlayerNumber pnMaster = GAMESTATE->GetMasterPlayerNumber(); Trail *pTrail = GAMESTATE->m_pCurTrail[pnMaster]; - ASSERT( pTrail != NULL ); - FOREACH_CONST( TrailEntry, pTrail->m_vEntries, e ) + ASSERT( pTrail != nullptr ); + for (TrailEntry const &e : pTrail->m_vEntries) { - ASSERT( e->pSong != NULL ); - m_apSongsQueue.push_back( e->pSong ); + ASSERT( e.pSong != nullptr ); + m_apSongsQueue.push_back( e.pSong ); } FOREACH_EnabledPlayerInfo( m_vPlayerInfo, pi ) { Trail *lTrail = GAMESTATE->m_pCurTrail[ pi->GetStepsAndTrailIndex() ]; - ASSERT( lTrail != NULL ); + ASSERT( lTrail != nullptr ); pi->m_vpStepsQueue.clear(); pi->m_asModifiersQueue.clear(); - FOREACH_CONST( TrailEntry, lTrail->m_vEntries, e ) + for (TrailEntry const &e : lTrail->m_vEntries) { - ASSERT( e->pSteps != NULL ); - pi->m_vpStepsQueue.push_back( e->pSteps ); + ASSERT( e.pSteps != nullptr ); + pi->m_vpStepsQueue.push_back( e.pSteps ); AttackArray a; - e->GetAttackArray( a ); + e.GetAttackArray( a ); pi->m_asModifiersQueue.push_back( a ); } @@ -1214,7 +1213,7 @@ void ScreenGameplay::LoadNextSong() Steps* pSteps = GAMESTATE->m_pCurSteps[ pi->GetStepsAndTrailIndex() ]; ++pi->GetPlayerStageStats()->m_iStepsPlayed; - ASSERT( GAMESTATE->m_pCurSteps[ pi->GetStepsAndTrailIndex() ] != NULL ); + ASSERT( GAMESTATE->m_pCurSteps[ pi->GetStepsAndTrailIndex() ] != nullptr ); if( pi->m_ptextStepsDescription ) pi->m_ptextStepsDescription->SetText( pSteps->GetDescription() ); @@ -1390,7 +1389,7 @@ void ScreenGameplay::LoadNextSong() FOREACH_EnabledPlayerInfo( m_vPlayerInfo, pi ) { RageSoundReader *pPlayerSound = m_AutoKeysounds.GetPlayerSound(pi->m_pn); - if( pPlayerSound == NULL && pi->m_pn == GAMESTATE->GetMasterPlayerNumber() ) + if( pPlayerSound == nullptr && pi->m_pn == GAMESTATE->GetMasterPlayerNumber() ) pPlayerSound = m_AutoKeysounds.GetSharedSound(); pi->m_SoundEffectControl.SetSoundReader( pPlayerSound ); } @@ -1405,10 +1404,10 @@ void ScreenGameplay::LoadLights() // First, check if the song has explicit lights m_CabinetLightsNoteData.Init(); - ASSERT( GAMESTATE->m_pCurSong != NULL ); + ASSERT( GAMESTATE->m_pCurSong != nullptr ); const Steps *pSteps = SongUtil::GetClosestNotes( GAMESTATE->m_pCurSong, StepsType_lights_cabinet, Difficulty_Medium ); - if( pSteps != NULL ) + if( pSteps != nullptr ) { pSteps->GetNoteData( m_CabinetLightsNoteData ); return; @@ -1447,7 +1446,7 @@ void ScreenGameplay::LoadLights() pSteps = SongUtil::GetClosestNotes( GAMESTATE->m_pCurSong, st, d1 ); // If we can't find anything at all, stop. - if( pSteps == NULL ) + if( pSteps == nullptr ) return; NoteData TapNoteData1; @@ -1562,7 +1561,7 @@ void ScreenGameplay::PlayAnnouncer( const RString &type, float fSeconds, float * /* Don't play before the first beat, or after we're finished. */ if( m_DancingState != STATE_DANCING ) return; - if(GAMESTATE->m_pCurSong == NULL || // this will be true on ScreenDemonstration sometimes + if(GAMESTATE->m_pCurSong == nullptr || // this will be true on ScreenDemonstration sometimes GAMESTATE->m_Position.m_fSongBeat < GAMESTATE->m_pCurSong->GetFirstBeat()) return; @@ -1579,14 +1578,14 @@ void ScreenGameplay::UpdateSongPosition( float fDeltaTime ) return; RageTimer tm; - const float fSeconds = m_pSoundMusic->GetPositionSeconds( NULL, &tm ); + const float fSeconds = m_pSoundMusic->GetPositionSeconds( nullptr, &tm ); const float fAdjust = SOUND->GetFrameTimingAdjustment( fDeltaTime ); GAMESTATE->UpdateSongPosition( fSeconds+fAdjust, GAMESTATE->m_pCurSong->m_SongTiming, tm+fAdjust ); } void ScreenGameplay::BeginScreen() { - if( GAMESTATE->m_pCurSong == NULL ) + if( GAMESTATE->m_pCurSong == nullptr ) return; ScreenWithMenuElements::BeginScreen(); @@ -1663,7 +1662,7 @@ void ScreenGameplay::GetMusicEndTiming( float &fSecondsToStartFadingOutMusic, fl void ScreenGameplay::Update( float fDeltaTime ) { - if( GAMESTATE->m_pCurSong == NULL ) + if( GAMESTATE->m_pCurSong == nullptr ) { /* ScreenDemonstration will move us to the next screen. We just need to * survive for one update without crashing. We need to call Screen::Update @@ -1686,7 +1685,7 @@ void ScreenGameplay::Update( float fDeltaTime ) /* This happens if ScreenDemonstration::HandleScreenMessage sets a new screen when * PREFSMAN->m_bDelayedScreenLoad. */ - if( GAMESTATE->m_pCurSong == NULL ) + if( GAMESTATE->m_pCurSong == nullptr ) return; /* This can happen if ScreenDemonstration::HandleScreenMessage sets a new screen when * !PREFSMAN->m_bDelayedScreenLoad. (The new screen was loaded when we called Screen::Update, @@ -1767,7 +1766,7 @@ void ScreenGameplay::Update( float fDeltaTime ) continue; // check for individual fail - if( pi->m_pLifeMeter == NULL || !pi->m_pLifeMeter->IsFailing() ) + if( pi->m_pLifeMeter == nullptr || !pi->m_pLifeMeter->IsFailing() ) continue; /* isn't failing */ if( pi->GetPlayerStageStats()->m_bFailed ) continue; /* failed and is already dead */ @@ -1807,7 +1806,7 @@ void ScreenGameplay::Update( float fDeltaTime ) switch( ft ) { case FailType_Immediate: - if( pi->m_pLifeMeter == NULL || (pi->m_pLifeMeter && !pi->m_pLifeMeter->IsFailing()) ) + if( pi->m_pLifeMeter == nullptr || (pi->m_pLifeMeter && !pi->m_pLifeMeter->IsFailing()) ) bAllFailed = false; break; case FailType_ImmediateContinue: @@ -1881,10 +1880,10 @@ void ScreenGameplay::Update( float fDeltaTime ) // update 2d dancing characters FOREACH_EnabledPlayerNumberInfo( m_vPlayerInfo, pi ) { - DancingCharacters *pCharacter = NULL; + DancingCharacters *pCharacter = nullptr; if( m_pSongBackground ) pCharacter = m_pSongBackground->GetDancingCharacters(); - if( pCharacter != NULL ) + if( pCharacter != nullptr ) { TapNoteScore tns = pi->m_pPlayer->GetLastTapNoteScore(); @@ -2549,10 +2548,10 @@ bool ScreenGameplay::Input( const InputEventPlus &input ) { if( input.mp != MultiPlayer_Invalid && GAMESTATE->IsMultiPlayerEnabled(input.mp) && iCol != -1 ) { - FOREACH( PlayerInfo, m_vPlayerInfo, pi ) + for (PlayerInfo const &pi : m_vPlayerInfo) { - if( input.mp == pi->m_mp ) - pi->m_pPlayer->Step( iCol, -1, input.DeviceI.ts, false, bRelease ); + if( input.mp == pi.m_mp ) + pi.m_pPlayer->Step( iCol, -1, input.DeviceI.ts, false, bRelease ); } return true; } @@ -2623,7 +2622,7 @@ void ScreenGameplay::SaveStats() pss.m_radarPossible += rv; NoteDataWithScoring::GetActualRadarValues( nd, pss, fMusicLen, rv ); pss.m_radarActual += rv; - GAMESTATE->SetProcessedTimingData(NULL); + GAMESTATE->SetProcessedTimingData(nullptr); } } @@ -2810,7 +2809,7 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) { GAMESTATE->m_DanceDuration= GAMESTATE->m_DanceStartTime.Ago(); // update dancing characters for win / lose - DancingCharacters *pDancers = NULL; + DancingCharacters *pDancers = nullptr; if( m_pSongBackground ) pDancers = m_pSongBackground->GetDancingCharacters(); if( pDancers ) @@ -2878,7 +2877,7 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) GAMESTATE->GetCourseSongIndex() >= (int)m_apSongsQueue.size()-1) { Course* course= GAMESTATE->m_pCurCourse; - ASSERT(course != NULL); + ASSERT(course != nullptr); // Need to store these so they can be used to refetch the players' // trails after they're invalidated. vector trail_sts; @@ -2886,7 +2885,7 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) FOREACH_EnabledPlayerInfo(m_vPlayerInfo, pi) { Trail* trail= GAMESTATE->m_pCurTrail[pi->GetStepsAndTrailIndex()]; - ASSERT(trail != NULL); + ASSERT(trail != nullptr); trail_sts.push_back(trail->m_StepsType); trail_cds.push_back(trail->m_CourseDifficulty); } @@ -2899,31 +2898,31 @@ void ScreenGameplay::HandleScreenMessage( const ScreenMessage SM ) FOREACH_EnabledPlayerInfo(m_vPlayerInfo, pi) { Trail* trail= course->GetTrail(trail_sts[info_id], trail_cds[info_id]); - ASSERT(trail != NULL); + ASSERT(trail != nullptr); GAMESTATE->m_pCurTrail[pi->m_pn].Set(trail); ++info_id; } PlayerNumber master_pn = GAMESTATE->GetMasterPlayerNumber(); Trail *master_trail= GAMESTATE->m_pCurTrail[master_pn]; - ASSERT(master_trail != NULL); - FOREACH_CONST(TrailEntry, master_trail->m_vEntries, entry) + ASSERT(master_trail != nullptr); + for (TrailEntry const &entry : master_trail->m_vEntries) { - ASSERT(entry->pSong != NULL); - m_apSongsQueue.push_back(entry->pSong); - STATSMAN->m_CurStageStats.m_vpPossibleSongs.push_back(entry->pSong); + ASSERT(entry.pSong != nullptr); + m_apSongsQueue.push_back(entry.pSong); + STATSMAN->m_CurStageStats.m_vpPossibleSongs.push_back(entry.pSong); } FOREACH_EnabledPlayerInfo(m_vPlayerInfo, pi) { Trail* trail= GAMESTATE->m_pCurTrail[pi->GetStepsAndTrailIndex()]; - ASSERT(trail != NULL); - FOREACH_CONST(TrailEntry, trail->m_vEntries, entry) + ASSERT(trail != nullptr); + for (TrailEntry const &entry : master_trail->m_vEntries) { - ASSERT(entry->pSteps != NULL); - pi->m_vpStepsQueue.push_back(entry->pSteps); + ASSERT(entry.pSteps != nullptr); + pi->m_vpStepsQueue.push_back(entry.pSteps); AttackArray a; - entry->GetAttackArray(a); + entry.GetAttackArray(a); pi->m_asModifiersQueue.push_back(a); - pi->GetPlayerStageStats()->m_vpPossibleSteps.push_back(entry->pSteps); + pi->GetPlayerStageStats()->m_vpPossibleSteps.push_back(entry.pSteps); } // In a survival course, override stored mods if(course->GetCourseType() == COURSE_TYPE_SURVIVAL && @@ -3093,7 +3092,7 @@ void ScreenGameplay::HandleMessage( const Message &msg ) continue; RageSoundReader *pSoundReader = m_AutoKeysounds.GetPlayerSound( pn ); - if( pSoundReader == NULL ) + if( pSoundReader == nullptr ) pSoundReader = m_AutoKeysounds.GetSharedSound(); HoldNoteScore hns; @@ -3139,7 +3138,7 @@ PlayerInfo *ScreenGameplay::GetPlayerInfo( PlayerNumber pn ) if( pi->m_pn == pn ) return &*pi; } - return NULL; + return nullptr; } PlayerInfo *ScreenGameplay::GetDummyPlayerInfo( int iDummyIndex ) @@ -3149,7 +3148,7 @@ PlayerInfo *ScreenGameplay::GetDummyPlayerInfo( int iDummyIndex ) if( pi->m_bIsDummy && pi->m_iDummyIndex == iDummyIndex ) return &*pi; } - return NULL; + return nullptr; } void ScreenGameplay::SaveReplay() @@ -3213,7 +3212,7 @@ void ScreenGameplay::SaveReplay() continue; ASSERT( matches.size() == 1 ); - iIndex = StringToInt( matches[0] )+1; + iIndex = std::stoi( matches[0] )+1; break; } @@ -3248,10 +3247,10 @@ public: PlayerNumber pn = Enum::Check( L, 1 ); PlayerInfo *pi = p->GetPlayerInfo(pn); - if( pi == NULL ) + if( pi == nullptr ) return 0; LifeMeter *pLM = pi->m_pLifeMeter; - if( pLM == NULL ) + if( pLM == nullptr ) return 0; pLM->PushSelf( L ); @@ -3262,7 +3261,7 @@ public: PlayerNumber pn = Enum::Check( L, 1 ); PlayerInfo *pi = p->GetPlayerInfo(pn); - if( pi == NULL ) + if( pi == nullptr ) return 0; pi->PushSelf( L ); @@ -3272,7 +3271,7 @@ public: { int iDummyIndex = IArg(1); PlayerInfo *pi = p->GetDummyPlayerInfo(iDummyIndex); - if( pi == NULL ) + if( pi == nullptr ) return 0; pi->PushSelf( L ); return 1; diff --git a/src/ScreenGameplayLesson.cpp b/src/ScreenGameplayLesson.cpp index 937f17c1a4..b2e337fb89 100644 --- a/src/ScreenGameplayLesson.cpp +++ b/src/ScreenGameplayLesson.cpp @@ -15,8 +15,8 @@ ScreenGameplayLesson::ScreenGameplayLesson() void ScreenGameplayLesson::Init() { - ASSERT( GAMESTATE->GetCurrentStyle(GAMESTATE->GetMasterPlayerNumber()) != NULL ); - ASSERT( GAMESTATE->m_pCurSong != NULL ); + ASSERT( GAMESTATE->GetCurrentStyle(GAMESTATE->GetMasterPlayerNumber()) != nullptr ); + ASSERT( GAMESTATE->m_pCurSong != nullptr ); /* Now that we've set up, init the base class. */ ScreenGameplayNormal::Init(); @@ -33,24 +33,25 @@ void ScreenGameplayLesson::Init() vector vs; GetDirListing( sDir+"Page*", vs, true, true ); m_vPages.resize( vs.size() ); - FOREACH( RString, vs, s ) + int i = 0; + for (RString const &s : vs) { - int i = s - vs.begin(); AutoActor &aa = m_vPages[i]; - LuaThreadVariable iIndex( "PageIndex", LuaReference::Create(i) ); + LuaThreadVariable iIndex( "PageIndex", LuaReference::Create(i++) ); LuaThreadVariable iPages( "NumPages", LuaReference::Create( (int)vs.size() ) ); - aa.Load( *s ); + aa.Load( s ); aa->SetDrawOrder( DRAW_ORDER_OVERLAY+1 ); this->AddChild( aa ); } - - FOREACH( AutoActor, m_vPages, aa ) + + i = 0; + for (AutoActor &aa : m_vPages) { - bool bIsFirst = aa == m_vPages.begin(); - (*aa)->PlayCommand( bIsFirst ? "Show" : "Hide" ); - (*aa)->PlayCommand( "On" ); + bool bIsFirst = (i++ == 0); + aa->PlayCommand( bIsFirst ? "Show" : "Hide" ); + aa->PlayCommand( "On" ); } // Reset stage number (not relevant in lessons) diff --git a/src/ScreenGameplaySyncMachine.cpp b/src/ScreenGameplaySyncMachine.cpp index ad920962fe..ca18c24e96 100644 --- a/src/ScreenGameplaySyncMachine.cpp +++ b/src/ScreenGameplaySyncMachine.cpp @@ -98,11 +98,11 @@ void ScreenGameplaySyncMachine::HandleScreenMessage( const ScreenMessage SM ) { FOREACH_PlayerNumber( pn ) { - GAMESTATE->m_pCurSteps[pn].Set( NULL ); + GAMESTATE->m_pCurSteps[pn].Set( nullptr ); } GAMESTATE->m_PlayMode.Set( PlayMode_Invalid ); - GAMESTATE->SetCurrentStyle( NULL, PLAYER_INVALID ); - GAMESTATE->m_pCurSong.Set( NULL ); + GAMESTATE->SetCurrentStyle( nullptr, PLAYER_INVALID ); + GAMESTATE->m_pCurSong.Set( nullptr ); } } diff --git a/src/ScreenHighScores.cpp b/src/ScreenHighScores.cpp index 5dc17180dc..eb6d9609f0 100644 --- a/src/ScreenHighScores.cpp +++ b/src/ScreenHighScores.cpp @@ -24,13 +24,13 @@ REGISTER_SCREEN_CLASS( ScreenHighScores ); static void GetAllSongsToShow( vector &vpOut, int iNumMostRecentScoresToShow ) { vpOut.clear(); - FOREACH_CONST( Song*, SONGMAN->GetAllSongs(), s ) + for (Song *s : SONGMAN->GetAllSongs()) { - if( !(*s)->NormallyDisplayed() ) + if( !s->NormallyDisplayed() ) continue; // skip - if( !(*s)->ShowInDemonstrationAndRanking() ) + if( !s->ShowInDemonstrationAndRanking() ) continue; // skip - vpOut.push_back( *s ); + vpOut.push_back( s ); } if( (int)vpOut.size() > iNumMostRecentScoresToShow ) @@ -51,13 +51,13 @@ static void GetAllCoursesToShow( vector &vpOut, CourseType ct, int iNum else SONGMAN->GetCourses( ct, vpCourses, false ); - FOREACH_CONST( Course*, vpCourses, c) + for (Course *c : vpCourses) { - if( UNLOCKMAN->CourseIsLocked(*c) ) + if( UNLOCKMAN->CourseIsLocked(c) ) continue; // skip - if( !(*c)->ShowInDemonstrationAndRanking() ) + if( !c->ShowInDemonstrationAndRanking() ) continue; // skip - vpOut.push_back( *c ); + vpOut.push_back( c ); } if( (int)vpOut.size() > iNumMostRecentScoresToShow ) { @@ -116,9 +116,9 @@ void ScoreScroller::ConfigureActor( Actor *pActor, int iItem ) const ScoreRowItemData &data = m_vScoreRowItemData[iItem]; Message msg("Set"); - if( data.m_pSong != NULL ) + if( data.m_pSong != nullptr ) msg.SetParam( "Song", data.m_pSong ); - if( data.m_pCourse != NULL ) + if( data.m_pCourse != nullptr ) msg.SetParam( "Course", data.m_pCourse ); @@ -127,27 +127,27 @@ void ScoreScroller::ConfigureActor( Actor *pActor, int iItem ) lua_pushvalue( L, -1 ); msg.SetParamFromStack( L, "Entries" ); - FOREACH( DifficultyAndStepsType, m_DifficultiesToShow, iter ) + int i = 0; + for (DifficultyAndStepsType &iter : m_DifficultiesToShow) { - int i = iter-m_DifficultiesToShow.begin(); - Difficulty dc = iter->first; - StepsType st = iter->second; + Difficulty dc = iter.first; + StepsType st = iter.second; - if( data.m_pSong != NULL ) + if( data.m_pSong != nullptr ) { const Song* pSong = data.m_pSong; Steps *pSteps = SongUtil::GetStepsByDifficulty( pSong, st, dc, false ); if( pSteps && UNLOCKMAN->StepsIsLocked(pSong, pSteps) ) - pSteps = NULL; + pSteps = nullptr; LuaHelpers::Push( L, pSteps ); } - else if( data.m_pCourse != NULL ) + else if( data.m_pCourse != nullptr ) { const Course* pCourse = data.m_pCourse; Trail *pTrail = pCourse->GetTrail( st, dc ); LuaHelpers::Push( L, pTrail ); } - // Because pSteps or pTrail can be NULL, what we're creating in Lua is not an array. + // Because pSteps or pTrail can be nullptr, what we're creating in Lua is not an array. // It must be iterated using pairs(), not ipairs(). lua_setfield( L, -2, ssprintf("%d",i+1) ); } @@ -187,7 +187,7 @@ void ScoreScroller::Load( RString sMetricsGroup ) for( int i=0; iGetPathG(sMetricsGroup,"ScrollerItem") ); - if( pActor != NULL ) + if( pActor != nullptr ) this->AddChild( pActor ); } diff --git a/src/ScreenHighScores.h b/src/ScreenHighScores.h index 15c27d0730..096f04c57c 100644 --- a/src/ScreenHighScores.h +++ b/src/ScreenHighScores.h @@ -1,103 +1,103 @@ -#ifndef ScreenHighScores_H -#define ScreenHighScores_H - -#include "ScreenAttract.h" -#include "Course.h" -#include "DynamicActorScroller.h" - -typedef pair DifficultyAndStepsType; - -enum HighScoresType -{ - HighScoresType_AllSteps, // Top 1 HighScore for N Steps in each Song - HighScoresType_NonstopCourses, // Top 1 HighScore for N Trails in each Course - HighScoresType_OniCourses, - HighScoresType_SurvivalCourses, - HighScoresType_AllCourses, - NUM_HighScoresType, - HighScoresType_Invalid -}; -LuaDeclareType( HighScoresType ); - - -class ScoreScroller: public DynamicActorScroller -{ -public: - ScoreScroller(); - void LoadSongs( int iNumRecentScores ); - void LoadCourses( CourseType ct, int iNumRecentScores ); - void Load( RString sClassName ); - void SetDisplay( const vector &DifficultiesToShow ); - bool Scroll( int iDir ); - void ScrollTop(); - -protected: - virtual void ConfigureActor( Actor *pActor, int iItem ); - vector m_DifficultiesToShow; - - struct ScoreRowItemData // for all_steps and all_courses - { - ScoreRowItemData() { m_pSong = NULL; m_pCourse = NULL; } - - Song *m_pSong; - Course *m_pCourse; - }; - vector m_vScoreRowItemData; - - ThemeMetric SCROLLER_ITEMS_TO_DRAW; - ThemeMetric SCROLLER_SECONDS_PER_ITEM; -}; - -class ScreenHighScores: public ScreenAttract -{ -public: - virtual void Init(); - virtual void BeginScreen(); - - void HandleScreenMessage( const ScreenMessage SM ); - virtual bool Input( const InputEventPlus &input ); - virtual bool MenuStart( const InputEventPlus &input ); - virtual bool MenuBack( const InputEventPlus &input ); - virtual bool MenuLeft( const InputEventPlus &input ) { DoScroll(-1); return true; } - virtual bool MenuRight( const InputEventPlus &input ) { DoScroll(+1); return true; } - virtual bool MenuUp( const InputEventPlus &input ) { DoScroll(-1); return true; } - virtual bool MenuDown( const InputEventPlus &input ) { DoScroll(+1); return true; } - -private: - void DoScroll( int iDir ); - - ThemeMetric MANUAL_SCROLLING; - ThemeMetric HIGH_SCORES_TYPE; - ThemeMetric NUM_COLUMNS; - ThemeMetric1D COLUMN_DIFFICULTY; - ThemeMetric1D COLUMN_STEPS_TYPE; - ThemeMetric MAX_ITEMS_TO_SHOW; - ScoreScroller m_Scroller; -}; - -#endif - -/* - * (c) 2001-2007 Chris Danford, Ben Nordstrom, Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#ifndef ScreenHighScores_H +#define ScreenHighScores_H + +#include "ScreenAttract.h" +#include "Course.h" +#include "DynamicActorScroller.h" + +typedef pair DifficultyAndStepsType; + +enum HighScoresType +{ + HighScoresType_AllSteps, // Top 1 HighScore for N Steps in each Song + HighScoresType_NonstopCourses, // Top 1 HighScore for N Trails in each Course + HighScoresType_OniCourses, + HighScoresType_SurvivalCourses, + HighScoresType_AllCourses, + NUM_HighScoresType, + HighScoresType_Invalid +}; +LuaDeclareType( HighScoresType ); + + +class ScoreScroller: public DynamicActorScroller +{ +public: + ScoreScroller(); + void LoadSongs( int iNumRecentScores ); + void LoadCourses( CourseType ct, int iNumRecentScores ); + void Load( RString sClassName ); + void SetDisplay( const vector &DifficultiesToShow ); + bool Scroll( int iDir ); + void ScrollTop(); + +protected: + virtual void ConfigureActor( Actor *pActor, int iItem ); + vector m_DifficultiesToShow; + + struct ScoreRowItemData // for all_steps and all_courses + { + ScoreRowItemData() { m_pSong = nullptr; m_pCourse = nullptr; } + + Song *m_pSong; + Course *m_pCourse; + }; + vector m_vScoreRowItemData; + + ThemeMetric SCROLLER_ITEMS_TO_DRAW; + ThemeMetric SCROLLER_SECONDS_PER_ITEM; +}; + +class ScreenHighScores: public ScreenAttract +{ +public: + virtual void Init(); + virtual void BeginScreen(); + + void HandleScreenMessage( const ScreenMessage SM ); + virtual bool Input( const InputEventPlus &input ); + virtual bool MenuStart( const InputEventPlus &input ); + virtual bool MenuBack( const InputEventPlus &input ); + virtual bool MenuLeft( const InputEventPlus &input ) { DoScroll(-1); return true; } + virtual bool MenuRight( const InputEventPlus &input ) { DoScroll(+1); return true; } + virtual bool MenuUp( const InputEventPlus &input ) { DoScroll(-1); return true; } + virtual bool MenuDown( const InputEventPlus &input ) { DoScroll(+1); return true; } + +private: + void DoScroll( int iDir ); + + ThemeMetric MANUAL_SCROLLING; + ThemeMetric HIGH_SCORES_TYPE; + ThemeMetric NUM_COLUMNS; + ThemeMetric1D COLUMN_DIFFICULTY; + ThemeMetric1D COLUMN_STEPS_TYPE; + ThemeMetric MAX_ITEMS_TO_SHOW; + ScoreScroller m_Scroller; +}; + +#endif + +/* + * (c) 2001-2007 Chris Danford, Ben Nordstrom, Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/ScreenHowToPlay.cpp b/src/ScreenHowToPlay.cpp index c593ced493..83f878133d 100644 --- a/src/ScreenHowToPlay.cpp +++ b/src/ScreenHowToPlay.cpp @@ -69,9 +69,9 @@ ScreenHowToPlay::ScreenHowToPlay() m_iNumW2s = NUM_W2S; // initialize these because they might not be used. - m_pLifeMeterBar = NULL; - m_pmCharacter = NULL; - m_pmDancePad = NULL; + m_pLifeMeterBar = nullptr; + m_pmCharacter = nullptr; + m_pmDancePad = nullptr; } void ScreenHowToPlay::Init() @@ -149,7 +149,7 @@ void ScreenHowToPlay::Init() const Style* pStyle = GAMESTATE->GetCurrentStyle(PLAYER_INVALID); Steps *pSteps = SongUtil::GetClosestNotes( &m_Song, pStyle->m_StepsType, Difficulty_Beginner ); - if(pSteps == NULL) + if(pSteps == nullptr) { LuaHelpers::ReportScriptErrorFmt("No playable steps of StepsType '%s' for ScreenHowToPlay in file %s", StringConversion::ToString(pStyle->m_StepsType).c_str(), sStepsPath.c_str()); } @@ -167,7 +167,7 @@ void ScreenHowToPlay::Init() GAMESTATE->m_pPlayerState[PLAYER_1]->m_PlayerController = PC_AUTOPLAY; m_Player->Init("Player", GAMESTATE->m_pPlayerState[PLAYER_1], - NULL, m_pLifeMeterBar, NULL, NULL, NULL, NULL, NULL, NULL); + nullptr, m_pLifeMeterBar, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr); m_Player.Load( m_NoteData ); m_Player->SetName( "Player" ); this->AddChild( m_Player ); @@ -244,7 +244,7 @@ void ScreenHowToPlay::Step() void ScreenHowToPlay::Update( float fDelta ) { - if( GAMESTATE->m_pCurSong != NULL ) + if( GAMESTATE->m_pCurSong != nullptr ) { RageTimer tm; GAMESTATE->UpdateSongPosition( m_fFakeSecondsIntoSong, GAMESTATE->m_pCurSong->m_SongTiming, tm ); diff --git a/src/ScreenInstallOverlay.cpp b/src/ScreenInstallOverlay.cpp index 1756d39e0a..0cb5ebab80 100644 --- a/src/ScreenInstallOverlay.cpp +++ b/src/ScreenInstallOverlay.cpp @@ -68,23 +68,23 @@ static void InstallSmzip( const RString &sZipFile, PlayAfterLaunchInfo &out ) GetDirListingRecursive( TEMP_ZIP_MOUNT_POINT, "*", vsRawFiles); vector vsPrettyFiles; - FOREACH_CONST( RString, vsRawFiles, s ) + for (RString const &s : vsRawFiles) { - if( GetExtension(*s).EqualsNoCase("ctl") ) + if( GetExtension(s).EqualsNoCase("ctl") ) continue; - vsFiles.push_back( *s); + vsFiles.push_back( s); - RString s2 = s->Right( s->length() - TEMP_ZIP_MOUNT_POINT.length() ); + RString s2 = s.Right( s.length() - TEMP_ZIP_MOUNT_POINT.length() ); vsPrettyFiles.push_back( s2 ); } sort( vsPrettyFiles.begin(), vsPrettyFiles.end() ); } RString sResult = "Success installing " + sZipFile; - FOREACH_CONST( RString, vsFiles, sSrcFile ) + for (RString &tmpFile : vsFiles) { - RString sDestFile = *sSrcFile; + RString sDestFile = tmpFile; sDestFile = sDestFile.Right( sDestFile.length() - TEMP_ZIP_MOUNT_POINT.length() ); RString sDir, sThrowAway; @@ -95,7 +95,7 @@ static void InstallSmzip( const RString &sZipFile, PlayAfterLaunchInfo &out ) FILEMAN->CreateDir( sDir ); - if( !FileCopy( *sSrcFile, sDestFile ) ) + if( !FileCopy( tmpFile, sDestFile ) ) { sResult = "Error extracting " + sDestFile; break; @@ -154,7 +154,7 @@ public: } RString GetStatus() { - if( m_pTransfer == NULL ) + if( m_pTransfer == nullptr ) return ""; else return m_pTransfer->GetStatus(); @@ -187,9 +187,8 @@ public: Json::Value require = root["Require"]; if( require.isArray() ) { - for( unsigned i=0; iStartDownload( sUrl, m_sCurrentPackageTempFile ); } @@ -245,7 +244,7 @@ public: RString sUrl = m_vsQueuedPackageUrls.back(); m_vsQueuedPackageUrls.pop_back(); m_sCurrentPackageTempFile = MakeTempFileName(sUrl); - ASSERT(m_pTransfer == NULL); + ASSERT(m_pTransfer == nullptr); m_pTransfer = new FileTransfer(); m_pTransfer->StartDownload( sUrl, m_sCurrentPackageTempFile ); } @@ -254,7 +253,7 @@ public: } bool bFinished = m_DownloadState == packages && m_vsQueuedPackageUrls.empty() && - m_pTransfer == NULL; + m_pTransfer == nullptr; if( bFinished ) { Message msg( "DownloadFinished" ); @@ -363,19 +362,19 @@ void ScreenInstallOverlay::Update( float fDeltaTime ) { vector vsMessages; - FOREACH_CONST( DownloadTask*, g_pDownloadTasks, pDT ) + for (DownloadTask *pDT : g_pDownloadTasks) { - vsMessages.push_back( (*pDT)->GetStatus() ); + vsMessages.push_back( pDT->GetStatus() ); } m_textStatus.SetText( join("\n", vsMessages) ); } #endif if( playAfterLaunchInfo.bAnySongChanged ) - SONGMAN->Reload( false, NULL ); + SONGMAN->Reload( false, nullptr ); if( !playAfterLaunchInfo.sSongDir.empty() ) { - Song* pSong = NULL; + Song* pSong = nullptr; GAMESTATE->Reset(); RString sInitialScreen; if( playAfterLaunchInfo.sSongDir.length() > 0 ) diff --git a/src/ScreenJukebox.cpp b/src/ScreenJukebox.cpp index a25649d546..f2c3e4f43a 100644 --- a/src/ScreenJukebox.cpp +++ b/src/ScreenJukebox.cpp @@ -34,7 +34,7 @@ void ScreenJukebox::SetSong() /* Check to see if there is a theme course. If there is a course that has * the exact same name as the theme, then we pick a song from this course. */ Course *pCourse = SONGMAN->GetCourseFromName( THEME->GetCurThemeName() ); - if( pCourse != NULL ) + if( pCourse != nullptr ) for ( unsigned i = 0; i < pCourse->m_vEntries.size(); i++ ) if( pCourse->m_vEntries[i].IsFixedSong() ) vSongs.push_back( pCourse->m_vEntries[i].songID.ToSong() ); @@ -74,7 +74,7 @@ void ScreenJukebox::SetSong() { Song* pSong = vSongs[RandomInt(vSongs.size())]; - ASSERT( pSong != NULL ); + ASSERT( pSong != nullptr ); if( !pSong->HasMusic() ) continue; // skip if( !pSong->NormallyDisplayed() ) @@ -85,7 +85,7 @@ void ScreenJukebox::SetSong() Difficulty dc = vDifficultiesToShow[ RandomInt(vDifficultiesToShow.size()) ]; Steps* pSteps = SongUtil::GetStepsByDifficulty( pSong, GAMESTATE->GetCurrentStyle(PLAYER_INVALID)->m_StepsType, dc ); - if( pSteps == NULL ) + if( pSteps == nullptr ) continue; // skip if( !PREFSMAN->m_bAutogenSteps && pSteps->IsAutogen()) @@ -111,7 +111,7 @@ void ScreenJukebox::SetSong() { Course *lCourse = apCourses[j]; const CourseEntry *pEntry = lCourse->FindFixedSong( pSong ); - if( pEntry == NULL || pEntry->attacks.size() == 0 ) + if( pEntry == nullptr || pEntry->attacks.size() == 0 ) continue; if( !ALLOW_ADVANCED_MODIFIERS ) @@ -121,9 +121,9 @@ void ScreenJukebox::SetSong() AttackArray aAttacks = pEntry->attacks; if( !pEntry->sModifiers.empty() ) aAttacks.push_back( Attack::FromGlobalCourseModifier( pEntry->sModifiers ) ); - FOREACH_CONST( Attack, aAttacks, a ) + for (Attack const &a: aAttacks) { - RString s = a->sModifiers; + RString s = a.sModifiers; s.MakeLower(); // todo: allow themers to modify this list? -aj if( s.find("dark") != string::npos || @@ -153,7 +153,7 @@ void ScreenJukebox::SetSong() FOREACH_PlayerNumber( p ) { GAMESTATE->m_pCurTrail[p].Set( lCourse->GetTrail( GAMESTATE->GetCurrentStyle(PLAYER_INVALID)->m_StepsType ) ); - ASSERT( GAMESTATE->m_pCurTrail[p] != NULL ); + ASSERT( GAMESTATE->m_pCurTrail[p] != nullptr ); } } } @@ -167,7 +167,7 @@ void ScreenJukebox::SetSong() ScreenJukebox::ScreenJukebox() { m_bDemonstration = false; - m_pCourseEntry = NULL; + m_pCourseEntry = nullptr; } static LocalizedString NO_MATCHING_STEPS("ScreenJukebox", "NoMatchingSteps"); @@ -176,7 +176,7 @@ void ScreenJukebox::Init() // The server crashes if syncing is attempted while connected to SMO. -Kyz NSMAN->CloseConnection(); // ScreenJukeboxMenu must set this - ASSERT( GAMESTATE->GetCurrentStyle(PLAYER_INVALID) != NULL ); + ASSERT( GAMESTATE->GetCurrentStyle(PLAYER_INVALID) != nullptr ); GAMESTATE->m_PlayMode.Set( PLAY_MODE_REGULAR ); SetSong(); @@ -230,7 +230,7 @@ void ScreenJukebox::Init() // Now that we've set up, init the base class. ScreenGameplay::Init(); - if( GAMESTATE->m_pCurSong == NULL ) // we didn't find a song. + if( GAMESTATE->m_pCurSong == nullptr ) // we didn't find a song. { SCREENMAN->SystemMessage( NO_MATCHING_STEPS ); this->PostScreenMessage( SM_GoToPrevScreen, 0 ); // Abort demonstration. diff --git a/src/ScreenManager.cpp b/src/ScreenManager.cpp index a840751a08..aaa7981c00 100644 --- a/src/ScreenManager.cpp +++ b/src/ScreenManager.cpp @@ -70,17 +70,16 @@ #include "FontManager.h" #include "Screen.h" #include "ScreenDimensions.h" -#include "Foreach.h" #include "ActorUtil.h" #include "InputEventPlus.h" -ScreenManager* SCREENMAN = NULL; // global and accessible from anywhere in our program +ScreenManager* SCREENMAN = nullptr; // global and accessible from anywhere in our program static Preference g_bDelayedScreenLoad( "DelayedScreenLoad", false ); //static Preference g_bPruneFonts( "PruneFonts", true ); // Screen registration -static map *g_pmapRegistrees = NULL; +static map *g_pmapRegistrees = nullptr; /** @brief Utility functions for the ScreenManager. */ namespace ScreenManagerUtil @@ -98,7 +97,7 @@ namespace ScreenManagerUtil LoadedScreen() { - m_pScreen = NULL; + m_pScreen = nullptr; m_bDeleteWhenDone = true; m_SendOnPop = SM_None; } @@ -142,19 +141,16 @@ namespace ScreenManagerUtil bool ScreenIsPrepped( const RString &sScreenName ) { - FOREACH( LoadedScreen, g_vPreparedScreens, s ) - { - if( s->m_pScreen->GetName() == sScreenName ) - return true; - } - return false; + return std::any_of(g_vPreparedScreens.begin(), g_vPreparedScreens.end(), [&](LoadedScreen const &s) { + return s.m_pScreen->GetName() == sScreenName; + }); } /* If the named screen is loaded, remove it from the prepared list and * return it in ls. */ bool GetPreppedScreen( const RString &sScreenName, LoadedScreen &ls ) { - FOREACH( LoadedScreen, g_vPreparedScreens, s ) + for (vector::iterator s = g_vPreparedScreens.begin(); s != g_vPreparedScreens.end(); ++s) { if( s->m_pScreen->GetName() == sScreenName ) { @@ -191,12 +187,12 @@ namespace ScreenManagerUtil * freed by the caller. */ void GrabPreparedActors( vector &apOut ) { - FOREACH( LoadedScreen, g_vPreparedScreens, s ) - if( s->m_bDeleteWhenDone ) - apOut.push_back( s->m_pScreen ); + for (LoadedScreen const &s : g_vPreparedScreens) + if( s.m_bDeleteWhenDone ) + apOut.push_back( s.m_pScreen ); g_vPreparedScreens.clear(); - FOREACH( Actor*, g_vPreparedBackgrounds, a ) - apOut.push_back( *a ); + for (Actor *a : g_vPreparedBackgrounds) + apOut.push_back( a ); g_vPreparedBackgrounds.clear(); g_setGroupedScreens.clear(); @@ -211,8 +207,10 @@ namespace ScreenManagerUtil GrabPreparedActors( apActorsToDelete ); BeforeDeleteScreen(); - FOREACH( Actor*, apActorsToDelete, a ) - SAFE_DELETE( *a ); + for (Actor *a : apActorsToDelete) + { + SAFE_DELETE( a ); + } AfterDeleteScreen(); } }; @@ -220,7 +218,7 @@ using namespace ScreenManagerUtil; RegisterScreenClass::RegisterScreenClass( const RString& sClassName, CreateScreenFn pfn ) { - if( g_pmapRegistrees == NULL ) + if( g_pmapRegistrees == nullptr ) g_pmapRegistrees = new map; map::iterator iter = g_pmapRegistrees->find( sClassName ); @@ -327,26 +325,22 @@ void ScreenManager::ReloadOverlayScreensAfterInputFinishes() Screen *ScreenManager::GetTopScreen() { if( g_ScreenStack.empty() ) - return NULL; + return nullptr; return g_ScreenStack[g_ScreenStack.size()-1].m_pScreen; } Screen *ScreenManager::GetScreen( int iPosition ) { if( iPosition >= (int) g_ScreenStack.size() ) - return NULL; + return nullptr; return g_ScreenStack[iPosition].m_pScreen; } bool ScreenManager::AllowOperatorMenuButton() const { - FOREACH( LoadedScreen, g_ScreenStack, s ) - { - if( !s->m_pScreen->AllowOperatorMenuButton() ) - return false; - } - - return true; + return std::all_of(g_ScreenStack.begin(), g_ScreenStack.end(), [](LoadedScreen const &s) { + return s.m_pScreen->AllowOperatorMenuButton(); + }); } bool ScreenManager::IsScreenNameValid(RString const& name) const @@ -361,11 +355,9 @@ bool ScreenManager::IsScreenNameValid(RString const& name) const bool ScreenManager::IsStackedScreen( const Screen *pScreen ) const { - // True if the screen is in the screen stack, but not the first. - for( unsigned i = 1; i < g_ScreenStack.size(); ++i ) - if( g_ScreenStack[i].m_pScreen == pScreen ) - return true; - return false; + return std::any_of(g_ScreenStack.begin() + 1, g_ScreenStack.end(), [&](LoadedScreen const &s) { + return s.m_pScreen == pScreen; + }); } bool ScreenManager::get_input_redirected(PlayerNumber pn) @@ -453,7 +445,7 @@ void ScreenManager::Update( float fDeltaTime ) * So, let's just zero the first update for every screen. */ ASSERT( !g_ScreenStack.empty() || m_sDelayedScreen != "" ); // Why play the game if there is nothing showing? - Screen* pScreen = g_ScreenStack.empty() ? NULL : GetTopScreen(); + Screen* pScreen = g_ScreenStack.empty() ? nullptr : GetTopScreen(); bool bFirstUpdate = pScreen && pScreen->IsFirstUpdate(); @@ -573,7 +565,7 @@ Screen* ScreenManager::MakeNewScreen( const RString &sScreenName ) if( iter == g_pmapRegistrees->end() ) { LuaHelpers::ReportScriptErrorFmt("Screen \"%s\" has an invalid class \"%s\".", sScreenName.c_str(), sClassName.c_str()); - return NULL; + return nullptr; } this->ZeroNextUpdate(); @@ -593,7 +585,7 @@ void ScreenManager::PrepareScreen( const RString &sScreenName ) return; Screen* pNewScreen = MakeNewScreen(sScreenName); - if(pNewScreen == NULL) + if(pNewScreen == nullptr) { return; } @@ -612,23 +604,23 @@ void ScreenManager::PrepareScreen( const RString &sScreenName ) if( !sNewBGA.empty() && sNewBGA != g_pSharedBGA->GetName() ) { - Actor *pNewBGA = NULL; - FOREACH( Actor*, g_vPreparedBackgrounds, a ) + Actor *pNewBGA = nullptr; + for (Actor *a : g_vPreparedBackgrounds) { - if( (*a)->GetName() == sNewBGA ) + if( a->GetName() == sNewBGA ) { - pNewBGA = *a; + pNewBGA = a; break; } } // Create the new background before deleting the previous so that we keep // any common textures loaded. - if( pNewBGA == NULL ) + if( pNewBGA == nullptr ) { LOG->Trace( "Loading screen background \"%s\"", sNewBGA.c_str() ); Actor *pActor = ActorUtil::MakeActor( sNewBGA ); - if( pActor != NULL ) + if( pActor != nullptr ) { pActor->SetName( sNewBGA ); g_vPreparedBackgrounds.push_back( pActor ); @@ -669,7 +661,7 @@ bool ScreenManager::ActivatePreparedScreenAndBackground( const RString &sScreenN bool bLoadedBoth = true; // Find the prepped screen. - if( GetTopScreen() == NULL || GetTopScreen()->GetName() != sScreenName ) + if( GetTopScreen() == nullptr || GetTopScreen()->GetName() != sScreenName ) { LoadedScreen ls; if( !GetPreppedScreen(sScreenName, ls) ) @@ -686,14 +678,14 @@ bool ScreenManager::ActivatePreparedScreenAndBackground( const RString &sScreenN RString sNewBGA = THEME->GetPathB(sScreenName,"background"); if( sNewBGA != g_pSharedBGA->GetName() ) { - Actor *pNewBGA = NULL; + Actor *pNewBGA = nullptr; if( sNewBGA.empty() ) { pNewBGA = new Actor; } else { - FOREACH( Actor*, g_vPreparedBackgrounds, a ) + for (vector::iterator a = g_vPreparedBackgrounds.begin(); a != g_vPreparedBackgrounds.end(); ++a) { if( (*a)->GetName() == sNewBGA ) { @@ -706,7 +698,7 @@ bool ScreenManager::ActivatePreparedScreenAndBackground( const RString &sScreenN /* If the BGA isn't loaded yet, load a dummy actor. If we're not going to use the same * BGA for the new screen, always move the old BGA back to g_vPreparedBackgrounds now. */ - if( pNewBGA == NULL ) + if( pNewBGA == nullptr ) { bLoadedBoth = false; pNewBGA = new Actor; @@ -779,8 +771,10 @@ void ScreenManager::LoadDelayedScreen() if( !apActorsToDelete.empty() ) { BeforeDeleteScreen(); - FOREACH( Actor*, apActorsToDelete, a ) - SAFE_DELETE( *a ); + for (Actor *a : apActorsToDelete) + { + SAFE_DELETE( a ); + } AfterDeleteScreen(); } @@ -832,14 +826,14 @@ void ScreenManager::PopAllScreens() void ScreenManager::PostMessageToTopScreen( ScreenMessage SM, float fDelay ) { Screen* pTopScreen = GetTopScreen(); - if( pTopScreen != NULL ) + if( pTopScreen != nullptr ) pTopScreen->PostScreenMessage( SM, fDelay ); } void ScreenManager::SendMessageToTopScreen( ScreenMessage SM ) { Screen* pTopScreen = GetTopScreen(); - if( pTopScreen != NULL ) + if( pTopScreen != nullptr ) pTopScreen->HandleScreenMessage( SM ); } @@ -942,7 +936,7 @@ public: static int GetTopScreen( T* p, lua_State *L ) { Actor *pScreen = p->GetTopScreen(); - if( pScreen != NULL ) + if( pScreen != nullptr ) pScreen->PushSelf(L); else lua_pushnil( L ); diff --git a/src/ScreenManager.h b/src/ScreenManager.h index 7380629f69..ad1d8ce21e 100644 --- a/src/ScreenManager.h +++ b/src/ScreenManager.h @@ -74,7 +74,7 @@ public: void PlaySharedBackgroundOffCommand(); void ZeroNextUpdate(); private: - Screen *m_pInputFocus; // NULL = top of m_ScreenStack + Screen *m_pInputFocus; // nullptr = top of m_ScreenStack // Screen loads, removals, and concurrent prepares are delayed until the next update. RString m_sDelayedScreen; diff --git a/src/ScreenMapControllers.cpp b/src/ScreenMapControllers.cpp index 0160c06640..5b9889b7d8 100644 --- a/src/ScreenMapControllers.cpp +++ b/src/ScreenMapControllers.cpp @@ -799,9 +799,9 @@ bool ScreenMapControllers::SanityCheckWrapper() } else { - FOREACH(RString, reasons_not_sane, reason) + for (RString &reason : reasons_not_sane) { - *reason= THEME->GetString("ScreenMapControllers", *reason); + reason= THEME->GetString("ScreenMapControllers", reason); } RString joined_reasons= join("\n", reasons_not_sane); joined_reasons= THEME->GetString("ScreenMapControllers", "VitalButtons") + "\n" + joined_reasons; diff --git a/src/ScreenMessage.cpp b/src/ScreenMessage.cpp index 572f177055..c8b81f4d4b 100644 --- a/src/ScreenMessage.cpp +++ b/src/ScreenMessage.cpp @@ -1,7 +1,7 @@ #include "global.h" #include "ScreenMessage.h" #include "RageLog.h" -#include "Foreach.h" + #include const ScreenMessage SM_Invalid = ""; @@ -21,7 +21,7 @@ static map *m_pScreenMessages; ScreenMessage ScreenMessageHelpers::ToScreenMessage( const RString &sName ) { - if( m_pScreenMessages == NULL ) + if( m_pScreenMessages == nullptr ) m_pScreenMessages = new map; if( m_pScreenMessages->find( sName ) == m_pScreenMessages->end() ) @@ -32,9 +32,9 @@ ScreenMessage ScreenMessageHelpers::ToScreenMessage( const RString &sName ) RString ScreenMessageHelpers::ScreenMessageToString( ScreenMessage SM ) { - FOREACHM( RString, ScreenMessage, *m_pScreenMessages, it ) - if( SM == it->second ) - return (*it).first; + for (auto const & it : *m_pScreenMessages) + if( SM == it.second ) + return it.first; return RString(); } diff --git a/src/ScreenMiniMenu.cpp b/src/ScreenMiniMenu.cpp index 83be2dd4f0..d7102786dc 100644 --- a/src/ScreenMiniMenu.cpp +++ b/src/ScreenMiniMenu.cpp @@ -3,7 +3,7 @@ #include "ScreenManager.h" #include "GameConstantsAndTypes.h" #include "ThemeManager.h" -#include "Foreach.h" + #include "ScreenDimensions.h" #include "GameState.h" #include "FontCharAliases.h" @@ -27,7 +27,7 @@ void FinishedLoadingScreen() {} // Settings: namespace { - const MenuDef* g_pMenuDef = NULL; + const MenuDef* g_pMenuDef = nullptr; ScreenMessage g_SendOnOK; ScreenMessage g_SendOnCancel; }; @@ -59,12 +59,12 @@ void ScreenMiniMenu::Init() void ScreenMiniMenu::BeginScreen() { - ASSERT( g_pMenuDef != NULL ); + ASSERT( g_pMenuDef != nullptr ); LoadMenu( g_pMenuDef ); m_SMSendOnOK = g_SendOnOK; m_SMSendOnCancel = g_SendOnCancel; - g_pMenuDef = NULL; + g_pMenuDef = nullptr; ScreenOptions::BeginScreen(); diff --git a/src/ScreenMiniMenu.h b/src/ScreenMiniMenu.h index f7e8167e0a..9de080364b 100644 --- a/src/ScreenMiniMenu.h +++ b/src/ScreenMiniMenu.h @@ -1,217 +1,217 @@ -/* ScreenMiniMenu - Displays a simple menu over the top of another screen. */ - -#ifndef SCREEN_MINI_MENU_H -#define SCREEN_MINI_MENU_H - -#include "ScreenOptions.h" -#include "GameConstantsAndTypes.h" - -typedef bool (*MenuRowUpdateEnabled)(); - -struct MenuRowDef -{ - int iRowCode; - RString sName; - bool bEnabled; - MenuRowUpdateEnabled pfnEnabled; // if ! NULL, used instead of bEnabled - EditMode emShowIn; - int iDefaultChoice; - vector choices; - bool bThemeTitle; - bool bThemeItems; - - MenuRowDef(): iRowCode(0), sName(""), bEnabled(false), - pfnEnabled(), emShowIn(), iDefaultChoice(0), - choices(), bThemeTitle(false), bThemeItems(false) {} - MenuRowDef( int r, RString n, MenuRowUpdateEnabled pe, EditMode s, - bool bTT, bool bTI, int d, const char *c0=NULL, - const char *c1=NULL, const char *c2=NULL, - const char *c3=NULL, const char *c4=NULL, - const char *c5=NULL, const char *c6=NULL, - const char *c7=NULL, const char *c8=NULL, - const char *c9=NULL, const char *c10=NULL, - const char *c11=NULL, const char *c12=NULL, - const char *c13=NULL, const char *c14=NULL, - const char *c15=NULL, const char *c16=NULL, - const char *c17=NULL, const char *c18=NULL, - const char *c19=NULL, const char *c20=NULL, - const char *c21=NULL, const char *c22=NULL, - const char *c23=NULL, const char *c24=NULL, - const char *c25=NULL ): iRowCode(r), sName(n), - bEnabled(true), pfnEnabled(pe), emShowIn(s), - iDefaultChoice(d), choices(), - bThemeTitle(bTT), bThemeItems(bTI) - { -#define PUSH( c ) if(c) choices.push_back(c); - PUSH(c0);PUSH(c1);PUSH(c2);PUSH(c3);PUSH(c4);PUSH(c5); - PUSH(c6);PUSH(c7);PUSH(c8);PUSH(c9);PUSH(c10);PUSH(c11); - PUSH(c12);PUSH(c13);PUSH(c14);PUSH(c15);PUSH(c16);PUSH(c17); - PUSH(c18);PUSH(c19);PUSH(c20);PUSH(c21);PUSH(c22);PUSH(c22); - PUSH(c23);PUSH(c23);PUSH(c24);PUSH(c25); -#undef PUSH - } - - MenuRowDef(int r, RString n, bool e, EditMode s, - bool bTT, bool bTI, int d, vector options): - iRowCode(r), sName(n), bEnabled(e), pfnEnabled(NULL), - emShowIn(s), iDefaultChoice(d), choices(), - bThemeTitle(bTT), bThemeItems(bTI) - { - FOREACH(RString, options, str) - { - if (*str != "") choices.push_back(*str); - } - } - - MenuRowDef( int r, RString n, bool e, EditMode s, bool bTT, bool bTI, - int d, const char *c0=NULL, const char *c1=NULL, - const char *c2=NULL, const char *c3=NULL, - const char *c4=NULL, const char *c5=NULL, - const char *c6=NULL, const char *c7=NULL, - const char *c8=NULL, const char *c9=NULL, - const char *c10=NULL, const char *c11=NULL, - const char *c12=NULL, const char *c13=NULL, - const char *c14=NULL, const char *c15=NULL, - const char *c16=NULL, const char *c17=NULL, - const char *c18=NULL, const char *c19=NULL, - const char *c20=NULL, const char *c21=NULL, - const char *c22=NULL, const char *c23=NULL, - const char *c24=NULL, const char *c25=NULL ): - iRowCode(r), sName(n), bEnabled(e), pfnEnabled(NULL), - emShowIn(s), iDefaultChoice(d), choices(), - bThemeTitle(bTT), bThemeItems(bTI) - { -#define PUSH( c ) if(c) choices.push_back(c); - PUSH(c0);PUSH(c1);PUSH(c2);PUSH(c3);PUSH(c4);PUSH(c5); - PUSH(c6);PUSH(c7);PUSH(c8);PUSH(c9);PUSH(c10);PUSH(c11); - PUSH(c12);PUSH(c13);PUSH(c14);PUSH(c15);PUSH(c16);PUSH(c17); - PUSH(c18);PUSH(c19);PUSH(c20);PUSH(c21);PUSH(c22);PUSH(c22); - PUSH(c23);PUSH(c23);PUSH(c24);PUSH(c25); -#undef PUSH - } - - MenuRowDef( int r, RString n, bool e, EditMode s, bool bTT, bool bTI, - int d, int low, int high ): - iRowCode(r), sName(n), bEnabled(e), pfnEnabled(NULL), - emShowIn(s), iDefaultChoice(d), choices(), - bThemeTitle(bTT), bThemeItems(bTI) - { - for ( int i = low; i <= high; i++ ) - { - choices.push_back(IntToString(i).c_str()); - } - } - - void SetOneUnthemedChoice( const RString &sChoice ) - { - choices.resize(1); - choices[0] = "|" + sChoice; - } - - bool SetDefaultChoiceIfPresent( RString sChoice ) - { - iDefaultChoice = 0; - FOREACH_CONST( RString, choices, s ) - { - if( sChoice == *s ) - { - iDefaultChoice = s - choices.begin(); - return true; - } - } - return false; - } -}; - -struct MenuDef -{ - RString sClassName; - vector rows; - - MenuDef( RString c, MenuRowDef r0=MenuRowDef(), - MenuRowDef r1=MenuRowDef(), MenuRowDef r2=MenuRowDef(), - MenuRowDef r3=MenuRowDef(), MenuRowDef r4=MenuRowDef(), - MenuRowDef r5=MenuRowDef(), MenuRowDef r6=MenuRowDef(), - MenuRowDef r7=MenuRowDef(), MenuRowDef r8=MenuRowDef(), - MenuRowDef r9=MenuRowDef(), MenuRowDef r10=MenuRowDef(), - MenuRowDef r11=MenuRowDef(), MenuRowDef r12=MenuRowDef(), - MenuRowDef r13=MenuRowDef(), MenuRowDef r14=MenuRowDef(), - MenuRowDef r15=MenuRowDef(), MenuRowDef r16=MenuRowDef(), - MenuRowDef r17=MenuRowDef(), MenuRowDef r18=MenuRowDef(), - MenuRowDef r19=MenuRowDef(), MenuRowDef r20=MenuRowDef(), - MenuRowDef r21=MenuRowDef(), MenuRowDef r22=MenuRowDef(), - MenuRowDef r23=MenuRowDef(), MenuRowDef r24=MenuRowDef(), - MenuRowDef r25=MenuRowDef(), MenuRowDef r26=MenuRowDef(), - MenuRowDef r27=MenuRowDef(), MenuRowDef r28=MenuRowDef(), - MenuRowDef r29=MenuRowDef() ): sClassName(c), rows() - { -#define PUSH( r ) if(!r.sName.empty()) rows.push_back(r); - PUSH(r0);PUSH(r1);PUSH(r2);PUSH(r3);PUSH(r4);PUSH(r5);PUSH(r6); - PUSH(r7);PUSH(r8);PUSH(r9);PUSH(r10);PUSH(r11);PUSH(r12); - PUSH(r13);PUSH(r14);PUSH(r15);PUSH(r16);PUSH(r17);PUSH(r18); - PUSH(r19);PUSH(r20);PUSH(r21);PUSH(r22);PUSH(r23);PUSH(r24); - PUSH(r25);PUSH(r26);PUSH(r27);PUSH(r28);PUSH(r29); -#undef PUSH - } -}; - - -class ScreenMiniMenu : public ScreenOptions -{ -public: - static void MiniMenu( const MenuDef* pDef, ScreenMessage smSendOnOK, - ScreenMessage smSendOnCancel = SM_None, - float fX = 0, float fY = 0 ); - - void Init(); - void BeginScreen(); - void HandleScreenMessage( const ScreenMessage SM ); - -protected: - virtual void AfterChangeValueOrRow( PlayerNumber pn ); - virtual void ImportOptions( int iRow, const vector &vpns ); - virtual void ExportOptions( int iRow, const vector &vpns ); - - virtual bool FocusedItemEndsScreen( PlayerNumber pn ) const; - - void LoadMenu( const MenuDef* pDef ); - - ScreenMessage m_SMSendOnOK; - ScreenMessage m_SMSendOnCancel; - - vector m_vMenuRows; - -public: - ScreenMiniMenu(): m_SMSendOnOK(), m_SMSendOnCancel(), m_vMenuRows() {} - - static bool s_bCancelled; - static int s_iLastRowCode; - static vector s_viLastAnswers; -}; - -#endif - -/* - * (c) 2003-2004 Chris Danford - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +/* ScreenMiniMenu - Displays a simple menu over the top of another screen. */ + +#ifndef SCREEN_MINI_MENU_H +#define SCREEN_MINI_MENU_H + +#include "ScreenOptions.h" +#include "GameConstantsAndTypes.h" + +typedef bool (*MenuRowUpdateEnabled)(); + +struct MenuRowDef +{ + int iRowCode; + RString sName; + bool bEnabled; + MenuRowUpdateEnabled pfnEnabled; // if ! nullptr, used instead of bEnabled + EditMode emShowIn; + int iDefaultChoice; + vector choices; + bool bThemeTitle; + bool bThemeItems; + + MenuRowDef(): iRowCode(0), sName(""), bEnabled(false), + pfnEnabled(), emShowIn(), iDefaultChoice(0), + choices(), bThemeTitle(false), bThemeItems(false) {} + MenuRowDef( int r, RString n, MenuRowUpdateEnabled pe, EditMode s, + bool bTT, bool bTI, int d, const char *c0=nullptr, + const char *c1=nullptr, const char *c2=nullptr, + const char *c3=nullptr, const char *c4=nullptr, + const char *c5=nullptr, const char *c6=nullptr, + const char *c7=nullptr, const char *c8=nullptr, + const char *c9=nullptr, const char *c10=nullptr, + const char *c11=nullptr, const char *c12=nullptr, + const char *c13=nullptr, const char *c14=nullptr, + const char *c15=nullptr, const char *c16=nullptr, + const char *c17=nullptr, const char *c18=nullptr, + const char *c19=nullptr, const char *c20=nullptr, + const char *c21=nullptr, const char *c22=nullptr, + const char *c23=nullptr, const char *c24=nullptr, + const char *c25=nullptr ): iRowCode(r), sName(n), + bEnabled(true), pfnEnabled(pe), emShowIn(s), + iDefaultChoice(d), choices(), + bThemeTitle(bTT), bThemeItems(bTI) + { +#define PUSH( c ) if(c) choices.push_back(c); + PUSH(c0);PUSH(c1);PUSH(c2);PUSH(c3);PUSH(c4);PUSH(c5); + PUSH(c6);PUSH(c7);PUSH(c8);PUSH(c9);PUSH(c10);PUSH(c11); + PUSH(c12);PUSH(c13);PUSH(c14);PUSH(c15);PUSH(c16);PUSH(c17); + PUSH(c18);PUSH(c19);PUSH(c20);PUSH(c21);PUSH(c22);PUSH(c22); + PUSH(c23);PUSH(c23);PUSH(c24);PUSH(c25); +#undef PUSH + } + + MenuRowDef(int r, RString n, bool e, EditMode s, + bool bTT, bool bTI, int d, vector options): + iRowCode(r), sName(n), bEnabled(e), pfnEnabled(nullptr), + emShowIn(s), iDefaultChoice(d), choices(), + bThemeTitle(bTT), bThemeItems(bTI) + { + for (RString &str : options) + { + if (str != "") choices.push_back(str); + } + } + + MenuRowDef( int r, RString n, bool e, EditMode s, bool bTT, bool bTI, + int d, const char *c0=nullptr, const char *c1=nullptr, + const char *c2=nullptr, const char *c3=nullptr, + const char *c4=nullptr, const char *c5=nullptr, + const char *c6=nullptr, const char *c7=nullptr, + const char *c8=nullptr, const char *c9=nullptr, + const char *c10=nullptr, const char *c11=nullptr, + const char *c12=nullptr, const char *c13=nullptr, + const char *c14=nullptr, const char *c15=nullptr, + const char *c16=nullptr, const char *c17=nullptr, + const char *c18=nullptr, const char *c19=nullptr, + const char *c20=nullptr, const char *c21=nullptr, + const char *c22=nullptr, const char *c23=nullptr, + const char *c24=nullptr, const char *c25=nullptr ): + iRowCode(r), sName(n), bEnabled(e), pfnEnabled(nullptr), + emShowIn(s), iDefaultChoice(d), choices(), + bThemeTitle(bTT), bThemeItems(bTI) + { +#define PUSH( c ) if(c) choices.push_back(c); + PUSH(c0);PUSH(c1);PUSH(c2);PUSH(c3);PUSH(c4);PUSH(c5); + PUSH(c6);PUSH(c7);PUSH(c8);PUSH(c9);PUSH(c10);PUSH(c11); + PUSH(c12);PUSH(c13);PUSH(c14);PUSH(c15);PUSH(c16);PUSH(c17); + PUSH(c18);PUSH(c19);PUSH(c20);PUSH(c21);PUSH(c22);PUSH(c22); + PUSH(c23);PUSH(c23);PUSH(c24);PUSH(c25); +#undef PUSH + } + + MenuRowDef( int r, RString n, bool e, EditMode s, bool bTT, bool bTI, + int d, int low, int high ): + iRowCode(r), sName(n), bEnabled(e), pfnEnabled(nullptr), + emShowIn(s), iDefaultChoice(d), choices(), + bThemeTitle(bTT), bThemeItems(bTI) + { + for ( int i = low; i <= high; i++ ) + { + choices.push_back(std::to_string(i)); + } + } + + void SetOneUnthemedChoice( const RString &sChoice ) + { + choices.resize(1); + choices[0] = "|" + sChoice; + } + + bool SetDefaultChoiceIfPresent( RString sChoice ) + { + iDefaultChoice = 0; + for (unsigned i = 0; i < choices.size(); ++i) + { + if (choices[i] == sChoice) + { + iDefaultChoice = i; + return true; + } + } + return false; + } +}; + +struct MenuDef +{ + RString sClassName; + vector rows; + + MenuDef( RString c, MenuRowDef r0=MenuRowDef(), + MenuRowDef r1=MenuRowDef(), MenuRowDef r2=MenuRowDef(), + MenuRowDef r3=MenuRowDef(), MenuRowDef r4=MenuRowDef(), + MenuRowDef r5=MenuRowDef(), MenuRowDef r6=MenuRowDef(), + MenuRowDef r7=MenuRowDef(), MenuRowDef r8=MenuRowDef(), + MenuRowDef r9=MenuRowDef(), MenuRowDef r10=MenuRowDef(), + MenuRowDef r11=MenuRowDef(), MenuRowDef r12=MenuRowDef(), + MenuRowDef r13=MenuRowDef(), MenuRowDef r14=MenuRowDef(), + MenuRowDef r15=MenuRowDef(), MenuRowDef r16=MenuRowDef(), + MenuRowDef r17=MenuRowDef(), MenuRowDef r18=MenuRowDef(), + MenuRowDef r19=MenuRowDef(), MenuRowDef r20=MenuRowDef(), + MenuRowDef r21=MenuRowDef(), MenuRowDef r22=MenuRowDef(), + MenuRowDef r23=MenuRowDef(), MenuRowDef r24=MenuRowDef(), + MenuRowDef r25=MenuRowDef(), MenuRowDef r26=MenuRowDef(), + MenuRowDef r27=MenuRowDef(), MenuRowDef r28=MenuRowDef(), + MenuRowDef r29=MenuRowDef() ): sClassName(c), rows() + { +#define PUSH( r ) if(!r.sName.empty()) rows.push_back(r); + PUSH(r0);PUSH(r1);PUSH(r2);PUSH(r3);PUSH(r4);PUSH(r5);PUSH(r6); + PUSH(r7);PUSH(r8);PUSH(r9);PUSH(r10);PUSH(r11);PUSH(r12); + PUSH(r13);PUSH(r14);PUSH(r15);PUSH(r16);PUSH(r17);PUSH(r18); + PUSH(r19);PUSH(r20);PUSH(r21);PUSH(r22);PUSH(r23);PUSH(r24); + PUSH(r25);PUSH(r26);PUSH(r27);PUSH(r28);PUSH(r29); +#undef PUSH + } +}; + + +class ScreenMiniMenu : public ScreenOptions +{ +public: + static void MiniMenu( const MenuDef* pDef, ScreenMessage smSendOnOK, + ScreenMessage smSendOnCancel = SM_None, + float fX = 0, float fY = 0 ); + + void Init(); + void BeginScreen(); + void HandleScreenMessage( const ScreenMessage SM ); + +protected: + virtual void AfterChangeValueOrRow( PlayerNumber pn ); + virtual void ImportOptions( int iRow, const vector &vpns ); + virtual void ExportOptions( int iRow, const vector &vpns ); + + virtual bool FocusedItemEndsScreen( PlayerNumber pn ) const; + + void LoadMenu( const MenuDef* pDef ); + + ScreenMessage m_SMSendOnOK; + ScreenMessage m_SMSendOnCancel; + + vector m_vMenuRows; + +public: + ScreenMiniMenu(): m_SMSendOnOK(), m_SMSendOnCancel(), m_vMenuRows() {} + + static bool s_bCancelled; + static int s_iLastRowCode; + static vector s_viLastAnswers; +}; + +#endif + +/* + * (c) 2003-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/ScreenNameEntry.cpp b/src/ScreenNameEntry.cpp index 4c947274d0..cd39ab7473 100644 --- a/src/ScreenNameEntry.cpp +++ b/src/ScreenNameEntry.cpp @@ -85,9 +85,9 @@ void ScreenNameEntry::ScrollingText::DrawPrimitives() m_Stamp.SetDiffuseAlpha( fAlpha ); m_Stamp.SetText( c ); m_Stamp.SetY( fY ); - FOREACH_CONST( float, m_Xs, x ) + for (float const &x : m_Xs) { - m_Stamp.SetX( *x ); + m_Stamp.SetX( x ); m_Stamp.Draw(); } fY += g_fCharsSpacingY; diff --git a/src/ScreenNetRoom.cpp b/src/ScreenNetRoom.cpp index d71c7480fb..2a04e1781e 100644 --- a/src/ScreenNetRoom.cpp +++ b/src/ScreenNetRoom.cpp @@ -177,7 +177,7 @@ void ScreenNetRoom::HandleScreenMessage( const ScreenMessage SM ) { int i = m_RoomWheel.GetCurrentIndex() - m_RoomWheel.GetPerminateOffset(); const RoomWheelItemData* data = m_RoomWheel.GetItem(i); - if( data != NULL ) + if( data != nullptr ) m_roomInfo.SetRoom( data ); } @@ -262,7 +262,7 @@ bool ScreenNetRoom::MenuRight( const InputEventPlus &input ) void ScreenNetRoom::UpdateRoomsList() { int difference = 0; - RoomWheelItemData* itemData = NULL; + RoomWheelItemData* itemData = nullptr; difference = m_RoomWheel.GetNumItems() - m_Rooms.size(); diff --git a/src/ScreenNetSelectBase.cpp b/src/ScreenNetSelectBase.cpp index 6b4f05ed5f..9e6cf44a51 100644 --- a/src/ScreenNetSelectBase.cpp +++ b/src/ScreenNetSelectBase.cpp @@ -278,7 +278,7 @@ void ScreenNetSelectBase::SetInputText(RString text) /** ColorBitmapText ***********************************************************/ void ColorBitmapText::SetText( const RString& _sText, const RString& _sAlternateText, int iWrapWidthPixels ) { - ASSERT( m_pFont != NULL ); + ASSERT( m_pFont != nullptr ); RString sNewText = StringWillUseAlternate(_sText,_sAlternateText) ? _sAlternateText : _sText; @@ -339,55 +339,55 @@ void ColorBitmapText::SetText( const RString& _sText, const RString& _sAlternate switch( curChar ) { - case L' ': - if( /* iLineWidth == 0 &&*/ iWordWidth == 0 ) - break; - sCurrentLine += sCurrentWord + " "; - iLineWidth += iWordWidth + iCharWidth; - sCurrentWord = ""; - iWordWidth = 0; - iGlyphsSoFar++; - break; - case L'\n': - if( iLineWidth + iWordWidth > iWrapWidthPixels ) - { - SimpleAddLine( sCurrentLine, iLineWidth ); - if( iWordWidth > 0 ) - iLineWidth = iWordWidth + //Add the width of a space - m_pFont->GetLineWidthInSourcePixels( L" " ); - sCurrentLine = sCurrentWord + " "; - iWordWidth = 0; + case L' ': + if( /* iLineWidth == 0 &&*/ iWordWidth == 0 ) + break; + sCurrentLine += sCurrentWord + " "; + iLineWidth += iWordWidth + iCharWidth; sCurrentWord = ""; + iWordWidth = 0; iGlyphsSoFar++; - } - else - { - SimpleAddLine( sCurrentLine + sCurrentWord, iLineWidth + iWordWidth ); - sCurrentLine = ""; iLineWidth = 0; - sCurrentWord = ""; iWordWidth = 0; - } - break; - default: - if( iWordWidth + iCharWidth > iWrapWidthPixels && iLineWidth == 0 ) - { - SimpleAddLine( sCurrentWord, iWordWidth ); - sCurrentWord = curCharStr; iWordWidth = iCharWidth; - } - else if( iWordWidth + iLineWidth + iCharWidth > iWrapWidthPixels ) - { - SimpleAddLine( sCurrentLine, iLineWidth ); - sCurrentLine = ""; - iLineWidth = 0; - sCurrentWord += curCharStr; - iWordWidth += iCharWidth; - } - else - { - sCurrentWord += curCharStr; - iWordWidth += iCharWidth; - } - iGlyphsSoFar++; - break; + break; + case L'\n': + if( iLineWidth + iWordWidth > iWrapWidthPixels ) + { + SimpleAddLine( sCurrentLine, iLineWidth ); + if( iWordWidth > 0 ) + iLineWidth = iWordWidth + //Add the width of a space + m_pFont->GetLineWidthInSourcePixels( L" " ); + sCurrentLine = sCurrentWord + " "; + iWordWidth = 0; + sCurrentWord = ""; + iGlyphsSoFar++; + } + else + { + SimpleAddLine( sCurrentLine + sCurrentWord, iLineWidth + iWordWidth ); + sCurrentLine = ""; iLineWidth = 0; + sCurrentWord = ""; iWordWidth = 0; + } + break; + default: + if( iWordWidth + iCharWidth > iWrapWidthPixels && iLineWidth == 0 ) + { + SimpleAddLine( sCurrentWord, iWordWidth ); + sCurrentWord = curCharStr; iWordWidth = iCharWidth; + } + else if( iWordWidth + iLineWidth + iCharWidth > iWrapWidthPixels ) + { + SimpleAddLine( sCurrentLine, iLineWidth ); + sCurrentLine = ""; + iLineWidth = 0; + sCurrentWord += curCharStr; + iWordWidth += iCharWidth; + } + else + { + sCurrentWord += curCharStr; + iWordWidth += iCharWidth; + } + iGlyphsSoFar++; + break; } } @@ -408,7 +408,7 @@ void ColorBitmapText::SetText( const RString& _sText, const RString& _sAlternate void ColorBitmapText::ResetText() { - ASSERT(m_pFont != NULL); + ASSERT(m_pFont != nullptr); int iWrapWidthPixels = m_iWrapWidthPixels; diff --git a/src/ScreenNetSelectMusic.cpp b/src/ScreenNetSelectMusic.cpp index 1239fb5b83..3d9f626382 100644 --- a/src/ScreenNetSelectMusic.cpp +++ b/src/ScreenNetSelectMusic.cpp @@ -50,7 +50,7 @@ void ScreenNetSelectMusic::Init() m_DC[p] = GAMESTATE->m_PreferredDifficulty[p]; m_StepsDisplays[p].SetName( ssprintf("StepsDisplayP%d",p+1) ); - m_StepsDisplays[p].Load( "StepsDisplayNet", NULL ); + m_StepsDisplays[p].Load( "StepsDisplayNet", nullptr ); LOAD_ALL_COMMANDS_AND_SET_XY( m_StepsDisplays[p] ); this->AddChild( &m_StepsDisplays[p] ); } @@ -159,7 +159,7 @@ void ScreenNetSelectMusic::HandleScreenMessage( const ScreenMessage SM ) // you have multiple copies of the "same" song you can chose which copy to play. Song* CurSong = m_MusicWheel.GetSelectedSong(); - if(CurSong != NULL ) + if(CurSong != nullptr ) if( ( !CurSong->GetTranslitArtist().CompareNoCase( NSMAN->m_sArtist ) ) && ( !CurSong->GetTranslitMainTitle().CompareNoCase( NSMAN->m_sMainTitle ) ) && @@ -378,7 +378,7 @@ bool ScreenNetSelectMusic::MenuDown( const InputEventPlus &input ) } } - if( GAMESTATE->m_pCurSong == NULL ) + if( GAMESTATE->m_pCurSong == nullptr ) return false; StepsType st = GAMESTATE->GetCurrentStyle(pn)->m_StepsType; vector MultiSteps; @@ -441,7 +441,7 @@ bool ScreenNetSelectMusic::SelectCurrent() Song * pSong = m_MusicWheel.GetSelectedSong(); - if (pSong == NULL) + if (pSong == nullptr) return false; GAMESTATE->m_pCurSong.Set(pSong); @@ -509,10 +509,10 @@ void ScreenNetSelectMusic::StartSelectedSong() void ScreenNetSelectMusic::UpdateDifficulties( PlayerNumber pn ) { - if( GAMESTATE->m_pCurSong == NULL ) + if( GAMESTATE->m_pCurSong == nullptr ) { m_StepsDisplays[pn].SetFromStepsTypeAndMeterAndDifficultyAndCourseType( StepsType_Invalid, 0, Difficulty_Beginner, CourseType_Invalid ); - //m_DifficultyIcon[pn].SetFromSteps( pn, NULL ); // It will blank it out + //m_DifficultyIcon[pn].SetFromSteps( pn, nullptr ); // It will blank it out return; } @@ -529,14 +529,14 @@ void ScreenNetSelectMusic::UpdateDifficulties( PlayerNumber pn ) void ScreenNetSelectMusic::MusicChanged() { - if( GAMESTATE->m_pCurSong == NULL ) + if( GAMESTATE->m_pCurSong == nullptr ) { FOREACH_EnabledPlayer (pn) UpdateDifficulties( pn ); SOUND->StopMusic(); // todo: handle playing section music correctly. -aj - // SOUND->PlayMusic( m_sSectionMusicPath, NULL, true, 0, -1 ); + // SOUND->PlayMusic( m_sSectionMusicPath, nullptr, true, 0, -1 ); return; } @@ -589,7 +589,7 @@ void ScreenNetSelectMusic::MusicChanged() SOUND->StopMusic(); SOUND->PlayMusic( GAMESTATE->m_pCurSong->GetPreviewMusicPath(), - NULL, + nullptr, true, GAMESTATE->m_pCurSong->GetPreviewStartSeconds(), GAMESTATE->m_pCurSong->m_fMusicSampleLengthSeconds ); diff --git a/src/ScreenOptions.cpp b/src/ScreenOptions.cpp index 31fa458716..6baa43c04a 100644 --- a/src/ScreenOptions.cpp +++ b/src/ScreenOptions.cpp @@ -233,16 +233,15 @@ void ScreenOptions::InitMenu( const vector &vHands ) m_frameContainer.SortByDrawOrder(); - FOREACH( OptionRow*, m_pRows, p ) + int iIndex = 0; + for (OptionRow *p : m_pRows) { - int iIndex = p - m_pRows.begin(); - Lua *L = LUA->Get(); - LuaHelpers::Push( L, iIndex ); - (*p)->m_pLuaInstance->Set( L, "iIndex" ); + LuaHelpers::Push( L, iIndex++ ); + p->m_pLuaInstance->Set( L, "iIndex" ); LUA->Release( L ); - (*p)->RunCommands( ROW_INIT_COMMAND ); + p->RunCommands( ROW_INIT_COMMAND ); } // poke once at all the explanation metrics so that we catch missing ones early @@ -338,8 +337,8 @@ void ScreenOptions::TweenOnScreen() { ScreenWithMenuElements::TweenOnScreen(); - FOREACH( OptionRow*, m_pRows, p ) - (*p)->RunCommands( ROW_ON_COMMAND ); + for (OptionRow *p : m_pRows) + p->RunCommands( ROW_ON_COMMAND ); m_frameContainer.SortByDrawOrder(); } @@ -348,8 +347,8 @@ void ScreenOptions::TweenOffScreen() { ScreenWithMenuElements::TweenOffScreen(); - FOREACH( OptionRow*, m_pRows, p ) - (*p)->RunCommands( ROW_OFF_COMMAND ); + for (OptionRow *p : m_pRows) + p->RunCommands( ROW_OFF_COMMAND ); } ScreenOptions::~ScreenOptions() @@ -594,7 +593,7 @@ void ScreenOptions::PositionRows( bool bTween ) int P2Choice = GAMESTATE->IsHumanPlayer(PLAYER_2)? m_iCurrentRow[PLAYER_2]: m_iCurrentRow[PLAYER_1]; vector Rows( m_pRows ); - OptionRow *pSeparateExitRow = NULL; + OptionRow *pSeparateExitRow = nullptr; if( (bool)SEPARATE_EXIT_ROW && !Rows.empty() && Rows.back()->GetRowType() == OptionRow::RowType_Exit ) { @@ -758,7 +757,7 @@ void ScreenOptions::AfterChangeValueOrRow( PlayerNumber pn ) } const RString text = GetExplanationText( iCurRow ); - BitmapText *pText = NULL; + BitmapText *pText = nullptr; switch( m_InputMode ) { case INPUTMODE_INDIVIDUAL: @@ -1015,7 +1014,7 @@ RString ScreenOptions::GetNextScreenForFocusedItem( PlayerNumber pn ) const return RString(); const OptionRowHandler *pHand = pRow->GetHandler(); - if( pHand == NULL ) + if( pHand == nullptr ) return RString(); return pHand->GetScreen( iChoice ); } diff --git a/src/ScreenOptionsCourseOverview.cpp b/src/ScreenOptionsCourseOverview.cpp index 285eb274d7..9c19669924 100644 --- a/src/ScreenOptionsCourseOverview.cpp +++ b/src/ScreenOptionsCourseOverview.cpp @@ -32,19 +32,19 @@ enum CourseOverviewRow static bool CurrentCourseIsSaved() { Course *pCourse = GAMESTATE->m_pCurCourse; - if( pCourse == NULL ) + if( pCourse == nullptr ) return false; return !pCourse->m_sPath.empty(); } static const MenuRowDef g_MenuRows[] = { - MenuRowDef( -1, "Play", true, EditMode_Practice, true, false, 0, NULL ), - MenuRowDef( -1, "Edit Course", true, EditMode_Practice, true, false, 0, NULL ), - MenuRowDef( -1, "Shuffle", true, EditMode_Practice, true, false, 0, NULL ), - MenuRowDef( -1, "Rename", CurrentCourseIsSaved, EditMode_Practice, true, false, 0, NULL ), - MenuRowDef( -1, "Delete", CurrentCourseIsSaved, EditMode_Practice, true, false, 0, NULL ), - MenuRowDef( -1, "Save", true, EditMode_Practice, true, false, 0, NULL ), + MenuRowDef( -1, "Play", true, EditMode_Practice, true, false, 0, nullptr ), + MenuRowDef( -1, "Edit Course", true, EditMode_Practice, true, false, 0, nullptr ), + MenuRowDef( -1, "Shuffle", true, EditMode_Practice, true, false, 0, nullptr ), + MenuRowDef( -1, "Rename", CurrentCourseIsSaved, EditMode_Practice, true, false, 0, nullptr ), + MenuRowDef( -1, "Delete", CurrentCourseIsSaved, EditMode_Practice, true, false, 0, nullptr ), + MenuRowDef( -1, "Save", true, EditMode_Practice, true, false, 0, nullptr ), }; REGISTER_SCREEN_CLASS( ScreenOptionsCourseOverview ); @@ -88,7 +88,7 @@ void ScreenOptionsCourseOverview::BeginScreen() ScreenOptions::BeginScreen(); // clear the current song in case it's set when we back out from gameplay - GAMESTATE->m_pCurSong.Set( NULL ); + GAMESTATE->m_pCurSong.Set(nullptr); } ScreenOptionsCourseOverview::~ScreenOptionsCourseOverview() @@ -115,7 +115,7 @@ void ScreenOptionsCourseOverview::HandleScreenMessage( const ScreenMessage SM ) if( SM == SM_GoToPrevScreen ) { // If we're pointing to an unsaved course, it will be inaccessible once we're back on ScreenOptionsManageCourses. - GAMESTATE->m_pCurCourse.Set( NULL ); + GAMESTATE->m_pCurCourse.Set(nullptr); } else if( SM == SM_GoToNextScreen ) { @@ -169,8 +169,8 @@ void ScreenOptionsCourseOverview::HandleScreenMessage( const ScreenMessage SM ) return; } - GAMESTATE->m_pCurCourse.Set( NULL ); - GAMESTATE->m_pCurTrail[PLAYER_1].Set( NULL ); + GAMESTATE->m_pCurCourse.Set(nullptr); + GAMESTATE->m_pCurTrail[PLAYER_1].Set(nullptr); /* Our course is gone, so back out. */ StartTransitioningScreen( SM_GoToPrevScreen ); diff --git a/src/ScreenOptionsEditCourse.cpp b/src/ScreenOptionsEditCourse.cpp index d7ad5eb665..ee1953283e 100644 --- a/src/ScreenOptionsEditCourse.cpp +++ b/src/ScreenOptionsEditCourse.cpp @@ -40,14 +40,14 @@ public: if( pSong ) // playing a song { GetStepsForSong( pSong, m_vpSteps ); - FOREACH_CONST( Steps*, m_vpSteps, steps ) + for (Steps const *steps : m_vpSteps) { RString s; - if( (*steps)->GetDifficulty() == Difficulty_Edit ) - s = (*steps)->GetDescription(); + if( steps->GetDifficulty() == Difficulty_Edit ) + s = steps->GetDescription(); else - s = CustomDifficultyToLocalizedString( StepsToCustomDifficulty(*steps) ); - s += ssprintf( " %d", (*steps)->GetMeter() ); + s = CustomDifficultyToLocalizedString( StepsToCustomDifficulty(steps) ); + s += ssprintf( " %d", steps->GetMeter() ); m_Def.m_vsChoices.push_back( s ); } m_Def.m_vEnabledForPlayers.clear(); @@ -56,7 +56,7 @@ public: else { m_Def.m_vsChoices.push_back( "n/a" ); - m_vpSteps.push_back( NULL ); + m_vpSteps.push_back(nullptr); m_Def.m_vEnabledForPlayers.clear(); } @@ -152,7 +152,7 @@ void ScreenOptionsEditCourse::Init() const MenuRowDef g_MenuRows[] = { - MenuRowDef( -1, "Max Minutes", true, EditMode_Practice, true, false, 0, NULL ), + MenuRowDef( -1, "Max Minutes", true, EditMode_Practice, true, false, 0, nullptr ), }; static LocalizedString EMPTY ("ScreenOptionsEditCourse","-Empty-"); @@ -201,8 +201,8 @@ void ScreenOptionsEditCourse::BeginScreen() { { MenuRowDef mrd = MenuRowDef( -1, "---", true, EditMode_Practice, true, false, 0, EMPTY.GetValue() ); - FOREACH_CONST( Song*, m_vpSongs, s ) - mrd.choices.push_back( (*s)->GetDisplayFullTitle() ); + for (Song const *s : m_vpSongs) + mrd.choices.push_back( s->GetDisplayFullTitle() ); mrd.sName = ssprintf(SONG.GetValue() + " %d",i+1); OptionRowHandler *pHand = OptionRowHandlerUtil::MakeSimple( mrd ); pHand->m_Def.m_bAllowThemeTitle = false; // already themed @@ -274,7 +274,7 @@ void ScreenOptionsEditCourse::ImportOptions( int iRow, const vectorm_pCurCourse->m_vEntries.size() ) pSong = GAMESTATE->m_pCurCourse->m_vEntries[iEntryIndex].songID.ToSong(); @@ -335,7 +335,7 @@ void ScreenOptionsEditCourse::ExportOptions( int iRow, const vectorGetStepsForEntry( iEntryIndex ); - ASSERT_M( pSteps != NULL, "No Steps for this Song!" ); + ASSERT_M( pSteps != nullptr, "No Steps for this Song!" ); CourseEntry ce; ce.songID.FromSong( pSong ); ce.stepsCriteria.m_difficulty = pSteps->GetDifficulty(); @@ -379,14 +379,14 @@ void ScreenOptionsEditCourse::SetCurrentSong() if( row.GetRowType() == OptionRow::RowType_Exit ) { - GAMESTATE->m_pCurSong.Set( NULL ); - GAMESTATE->m_pCurSteps[PLAYER_1].Set( NULL ); + GAMESTATE->m_pCurSong.Set(nullptr); + GAMESTATE->m_pCurSteps[PLAYER_1].Set(nullptr); } else { iRow = m_iCurrentRow[PLAYER_1]; int iEntryIndex = RowToEntryIndex( iRow ); - Song *pSong = NULL; + Song *pSong = nullptr; if( iEntryIndex != -1 ) { int iCurrentSongRow = EntryIndexAndRowTypeToRow(iEntryIndex,RowType_Song); @@ -395,7 +395,7 @@ void ScreenOptionsEditCourse::SetCurrentSong() if( index != 0 ) pSong = m_vpSongs[ index - 1 ]; } - if ( pSong != NULL ) + if ( pSong != nullptr ) { GAMESTATE->m_pCurSong.Set( pSong ); } @@ -412,13 +412,13 @@ void ScreenOptionsEditCourse::SetCurrentSteps() OptionRow &row = *m_pRows[ EntryIndexAndRowTypeToRow(iEntryIndex, RowType_Steps) ]; int iStepsIndex = row.GetOneSharedSelection(); const EditCourseOptionRowHandlerSteps *pHand = dynamic_cast( row.GetHandler() ); - ASSERT( pHand != NULL ); + ASSERT( pHand != nullptr ); Steps *pSteps = pHand->GetSteps( iStepsIndex ); GAMESTATE->m_pCurSteps[PLAYER_1].Set( pSteps ); } else { - GAMESTATE->m_pCurSteps[PLAYER_1].Set( NULL ); + GAMESTATE->m_pCurSteps[PLAYER_1].Set(nullptr); } } @@ -429,7 +429,7 @@ Song *ScreenOptionsEditCourse::GetSongForEntry( int iEntryIndex ) int index = row.GetOneSharedSelection(); if( index == 0 ) - return NULL; + return nullptr; return m_vpSongs[ index - 1 ]; } diff --git a/src/ScreenOptionsEditProfile.cpp b/src/ScreenOptionsEditProfile.cpp index d5013a1827..178a28edc6 100644 --- a/src/ScreenOptionsEditProfile.cpp +++ b/src/ScreenOptionsEditProfile.cpp @@ -1,170 +1,170 @@ -#include "global.h" - -#include "ScreenOptionsEditProfile.h" -#include "ScreenManager.h" -#include "ProfileManager.h" -#include "ScreenPrompt.h" -#include "RageUtil.h" -#include "GameState.h" -#include "Profile.h" -#include "Character.h" -#include "CharacterManager.h" -#include "OptionRowHandler.h" - -enum EditProfileRow -{ - ROW_CHARACTER, -}; - -REGISTER_SCREEN_CLASS( ScreenOptionsEditProfile ); - -void ScreenOptionsEditProfile::Init() -{ - ScreenOptions::Init(); -} - -void ScreenOptionsEditProfile::BeginScreen() -{ - m_Original = *GAMESTATE->GetEditLocalProfile(); - - vector vHands; - - Profile *pProfile = PROFILEMAN->GetLocalProfile( GAMESTATE->m_sEditLocalProfileID ); - ASSERT( pProfile != NULL ); - - { - vHands.push_back( OptionRowHandlerUtil::MakeNull() ); - OptionRowDefinition &def = vHands.back()->m_Def; - def.m_layoutType = LAYOUT_SHOW_ONE_IN_ROW; - def.m_bOneChoiceForAllPlayers = true; - def.m_bAllowThemeItems = false; - def.m_bAllowThemeTitle = false; - def.m_bAllowExplanation = false; - def.m_bExportOnChange = true; - def.m_sName = "Character"; - def.m_vsChoices.clear(); - vector vpCharacters; - CHARMAN->GetCharacters( vpCharacters ); - FOREACH_CONST( Character*, vpCharacters, c ) - def.m_vsChoices.push_back( (*c)->GetDisplayName() ); - if( def.m_vsChoices.empty() ) - def.m_vsChoices.push_back( RString() ); - } - - InitMenu( vHands ); - - ScreenOptions::BeginScreen(); -} - -ScreenOptionsEditProfile::~ScreenOptionsEditProfile() -{ - -} - -void ScreenOptionsEditProfile::ImportOptions( int iRow, const vector &vpns ) -{ - Profile *pProfile = PROFILEMAN->GetLocalProfile( GAMESTATE->m_sEditLocalProfileID ); - ASSERT( pProfile != NULL ); - OptionRow &row = *m_pRows[iRow]; - - switch( iRow ) - { - case ROW_CHARACTER: - row.SetOneSharedSelectionIfPresent( pProfile->m_sCharacterID ); - break; - } -} - -void ScreenOptionsEditProfile::ExportOptions( int iRow, const vector &vpns ) -{ - Profile *pProfile = PROFILEMAN->GetLocalProfile( GAMESTATE->m_sEditLocalProfileID ); - ASSERT( pProfile != NULL ); - OptionRow &row = *m_pRows[iRow]; - int iIndex = row.GetOneSharedSelection( true ); - RString sValue; - if( iIndex >= 0 ) - sValue = row.GetRowDef().m_vsChoices[ iIndex ]; - - switch( iRow ) - { - case ROW_CHARACTER: - pProfile->m_sCharacterID = sValue; - break; - } -} - -void ScreenOptionsEditProfile::GoToNextScreen() -{ -} - -void ScreenOptionsEditProfile::GoToPrevScreen() -{ -} - -void ScreenOptionsEditProfile::HandleScreenMessage( const ScreenMessage SM ) -{ - if( SM == SM_GoToNextScreen ) - { - PROFILEMAN->SaveLocalProfile( GAMESTATE->m_sEditLocalProfileID ); - } - else if( SM == SM_GoToPrevScreen ) - { - *GAMESTATE->GetEditLocalProfile() = m_Original; - } - - ScreenOptions::HandleScreenMessage( SM ); -} - -void ScreenOptionsEditProfile::AfterChangeValueInRow( int iRow, PlayerNumber pn ) -{ - ScreenOptions::AfterChangeValueInRow( iRow, pn ); - - // cause the overlay to reload - GAMESTATE->m_sEditLocalProfileID.Set( GAMESTATE->m_sEditLocalProfileID ); -} - -void ScreenOptionsEditProfile::ProcessMenuStart( const InputEventPlus &input ) -{ - if( IsTransitioning() ) - return; - - int iRow = GetCurrentRow(); - //OptionRow &row = *m_pRows[iRow]; - - switch( iRow ) - { - case ROW_CHARACTER: - { - } - break; - default: - ScreenOptions::ProcessMenuStart( input ); - break; - } -} - - -/* - * (c) 2003-2004 Chris Danford - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" + +#include "ScreenOptionsEditProfile.h" +#include "ScreenManager.h" +#include "ProfileManager.h" +#include "ScreenPrompt.h" +#include "RageUtil.h" +#include "GameState.h" +#include "Profile.h" +#include "Character.h" +#include "CharacterManager.h" +#include "OptionRowHandler.h" + +enum EditProfileRow +{ + ROW_CHARACTER, +}; + +REGISTER_SCREEN_CLASS( ScreenOptionsEditProfile ); + +void ScreenOptionsEditProfile::Init() +{ + ScreenOptions::Init(); +} + +void ScreenOptionsEditProfile::BeginScreen() +{ + m_Original = *GAMESTATE->GetEditLocalProfile(); + + vector vHands; + + Profile *pProfile = PROFILEMAN->GetLocalProfile( GAMESTATE->m_sEditLocalProfileID ); + ASSERT( pProfile != nullptr ); + + { + vHands.push_back( OptionRowHandlerUtil::MakeNull() ); + OptionRowDefinition &def = vHands.back()->m_Def; + def.m_layoutType = LAYOUT_SHOW_ONE_IN_ROW; + def.m_bOneChoiceForAllPlayers = true; + def.m_bAllowThemeItems = false; + def.m_bAllowThemeTitle = false; + def.m_bAllowExplanation = false; + def.m_bExportOnChange = true; + def.m_sName = "Character"; + def.m_vsChoices.clear(); + vector vpCharacters; + CHARMAN->GetCharacters( vpCharacters ); + for (Character const *c : vpCharacters) + def.m_vsChoices.push_back( c->GetDisplayName() ); + if( def.m_vsChoices.empty() ) + def.m_vsChoices.push_back( RString() ); + } + + InitMenu( vHands ); + + ScreenOptions::BeginScreen(); +} + +ScreenOptionsEditProfile::~ScreenOptionsEditProfile() +{ + +} + +void ScreenOptionsEditProfile::ImportOptions( int iRow, const vector &vpns ) +{ + Profile *pProfile = PROFILEMAN->GetLocalProfile( GAMESTATE->m_sEditLocalProfileID ); + ASSERT( pProfile != nullptr ); + OptionRow &row = *m_pRows[iRow]; + + switch( iRow ) + { + case ROW_CHARACTER: + row.SetOneSharedSelectionIfPresent( pProfile->m_sCharacterID ); + break; + } +} + +void ScreenOptionsEditProfile::ExportOptions( int iRow, const vector &vpns ) +{ + Profile *pProfile = PROFILEMAN->GetLocalProfile( GAMESTATE->m_sEditLocalProfileID ); + ASSERT( pProfile != nullptr ); + OptionRow &row = *m_pRows[iRow]; + int iIndex = row.GetOneSharedSelection( true ); + RString sValue; + if( iIndex >= 0 ) + sValue = row.GetRowDef().m_vsChoices[ iIndex ]; + + switch( iRow ) + { + case ROW_CHARACTER: + pProfile->m_sCharacterID = sValue; + break; + } +} + +void ScreenOptionsEditProfile::GoToNextScreen() +{ +} + +void ScreenOptionsEditProfile::GoToPrevScreen() +{ +} + +void ScreenOptionsEditProfile::HandleScreenMessage( const ScreenMessage SM ) +{ + if( SM == SM_GoToNextScreen ) + { + PROFILEMAN->SaveLocalProfile( GAMESTATE->m_sEditLocalProfileID ); + } + else if( SM == SM_GoToPrevScreen ) + { + *GAMESTATE->GetEditLocalProfile() = m_Original; + } + + ScreenOptions::HandleScreenMessage( SM ); +} + +void ScreenOptionsEditProfile::AfterChangeValueInRow( int iRow, PlayerNumber pn ) +{ + ScreenOptions::AfterChangeValueInRow( iRow, pn ); + + // cause the overlay to reload + GAMESTATE->m_sEditLocalProfileID.Set( GAMESTATE->m_sEditLocalProfileID ); +} + +void ScreenOptionsEditProfile::ProcessMenuStart( const InputEventPlus &input ) +{ + if( IsTransitioning() ) + return; + + int iRow = GetCurrentRow(); + //OptionRow &row = *m_pRows[iRow]; + + switch( iRow ) + { + case ROW_CHARACTER: + { + } + break; + default: + ScreenOptions::ProcessMenuStart( input ); + break; + } +} + + +/* + * (c) 2003-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/ScreenOptionsExportPackage.cpp b/src/ScreenOptionsExportPackage.cpp index 976ad418f0..202c66add6 100644 --- a/src/ScreenOptionsExportPackage.cpp +++ b/src/ScreenOptionsExportPackage.cpp @@ -35,12 +35,12 @@ void ScreenOptionsExportPackage::BeginScreen() // announcers, characters, others? vector OptionRowHandlers; - FOREACH_CONST( RString, m_vsPackageTypes, s ) + for (RString const &s : m_vsPackageTypes) { OptionRowHandler *pHand = OptionRowHandlerUtil::MakeNull(); OptionRowDefinition &def = pHand->m_Def; - def.m_sName = *s; + def.m_sName = s; def.m_bAllowExplanation = false; //def.m_sExplanationName = "# files, # MB, # subdirs"; def.m_bAllowThemeTitle = false; @@ -117,8 +117,8 @@ void ScreenOptionsExportPackageSubPage::BeginScreen() // add noteskins vector vs; GetDirListing( SpecialFiles::NOTESKINS_DIR + "*", vs, true, true ); - FOREACH_CONST( RString, vs, s ) - GetDirListing( *s + "*", m_vsPossibleDirsToExport, true, true ); + for (RString const &s : vs) + GetDirListing( s + "*", m_vsPossibleDirsToExport, true, true ); } else if( *s_packageType == "Courses" ) { @@ -128,10 +128,10 @@ void ScreenOptionsExportPackageSubPage::BeginScreen() GetDirListing( SpecialFiles::COURSES_DIR + "*", vs, true, true ); StripCvsAndSvn( vs ); StripMacResourceForks( vs ); - FOREACH_CONST( RString, vs, s ) + for (RString const &s : vs) { - m_vsPossibleDirsToExport.push_back( *s ); - GetDirListing( *s + "/*", m_vsPossibleDirsToExport, true, true ); + m_vsPossibleDirsToExport.push_back( s ); + GetDirListing( s + "/*", m_vsPossibleDirsToExport, true, true ); } } else if( *s_packageType == "Songs" ) @@ -139,9 +139,9 @@ void ScreenOptionsExportPackageSubPage::BeginScreen() // Add song groups vector asAllGroups; SONGMAN->GetSongGroupNames(asAllGroups); - FOREACH_CONST( RString, asAllGroups , s ) + for (RString const &s : asAllGroups) { - m_vsPossibleDirsToExport.push_back(*s); + m_vsPossibleDirsToExport.push_back(s); } } else if( *s_packageType == "SubGroup" ) @@ -149,17 +149,17 @@ void ScreenOptionsExportPackageSubPage::BeginScreen() //ExportPackages::m_sFolder vector vs; GetDirListing( SpecialFiles::SONGS_DIR + "/" + ExportPackages::m_sFolder + "/*", vs, true, true ); - FOREACH_CONST( RString, vs, s ) + for (RString const &s : vs) { - m_vsPossibleDirsToExport.push_back( *s ); - GetDirListing( *s + "/*", m_vsPossibleDirsToExport, true, true ); + m_vsPossibleDirsToExport.push_back( s ); + GetDirListing( s + "/*", m_vsPossibleDirsToExport, true, true ); } } StripCvsAndSvn( m_vsPossibleDirsToExport ); StripMacResourceForks( m_vsPossibleDirsToExport ); vector OptionRowHandlers; - FOREACH_CONST( RString, m_vsPossibleDirsToExport, s ) + for (RString const &s : m_vsPossibleDirsToExport) { OptionRowHandler *pHand = OptionRowHandlerUtil::MakeNull(); OptionRowDefinition &def = pHand->m_Def; @@ -167,7 +167,7 @@ void ScreenOptionsExportPackageSubPage::BeginScreen() def.m_bAllowThemeTitle = false; def.m_bAllowThemeItems = false; def.m_bAllowExplanation = false; - def.m_sName = *s; + def.m_sName = s; def.m_sExplanationName = "# files, # MB, # subdirs"; def.m_vsChoices.push_back( "" ); @@ -213,11 +213,11 @@ static bool ExportPackage( RString sPackageName, RString sDirToExport, RString & GetDirListingRecursive( sDirToExport, "*", vs ); SMPackageUtil::StripIgnoredSmzipFiles( vs ); LOG->Trace("Adding files..."); - FOREACH( RString, vs, s ) + for (RString &s : vs) { - if( !zip.AddFile( *s ) ) + if( !zip.AddFile( s ) ) { - sErrorOut = ssprintf( "Couldn't add file: %s", s->c_str() ); + sErrorOut = ssprintf( "Couldn't add file: %s", s.c_str() ); return false; } } diff --git a/src/ScreenOptionsManageCourses.cpp b/src/ScreenOptionsManageCourses.cpp index becc2584b2..88068cf7e0 100644 --- a/src/ScreenOptionsManageCourses.cpp +++ b/src/ScreenOptionsManageCourses.cpp @@ -42,10 +42,10 @@ static void SetNextCombination() { vector v; { - FOREACH_CONST( StepsType, CommonMetrics::STEPS_TYPES_TO_SHOW.GetValue(), st ) + for (StepsType const &st : CommonMetrics::STEPS_TYPES_TO_SHOW.GetValue()) { - FOREACH_CONST( CourseDifficulty, CommonMetrics::COURSE_DIFFICULTIES_TO_SHOW.GetValue(), cd ) - v.push_back( StepsTypeAndDifficulty(*st, *cd) ); + for (CourseDifficulty const &cd : CommonMetrics::COURSE_DIFFICULTIES_TO_SHOW.GetValue()) + v.push_back( StepsTypeAndDifficulty(st, cd) ); } } @@ -125,12 +125,12 @@ void ScreenOptionsManageCourses::BeginScreen() break; } - FOREACH_CONST( Course*, m_vpCourses, p ) + for (Course const *p : m_vpCourses) { vHands.push_back( OptionRowHandlerUtil::MakeNull() ); OptionRowDefinition &def = vHands.back()->m_Def; - def.m_sName = (*p)->GetDisplayFullTitle(); + def.m_sName = p->GetDisplayFullTitle(); def.m_bAllowThemeTitle = false; // not themable def.m_sExplanationName = "Select Course"; def.m_vsChoices.clear(); @@ -204,7 +204,7 @@ void ScreenOptionsManageCourses::HandleScreenMessage( const ScreenMessage SM ) void ScreenOptionsManageCourses::AfterChangeRow( PlayerNumber pn ) { Course *pCourse = GetCourseWithFocus(); - Trail *pTrail = pCourse ? pCourse->GetTrail( GAMESTATE->m_stEdit, GAMESTATE->m_cdEdit ) : NULL; + Trail *pTrail = pCourse ? pCourse->GetTrail( GAMESTATE->m_stEdit, GAMESTATE->m_cdEdit ) : nullptr; GAMESTATE->m_pCurCourse.Set( pCourse ); GAMESTATE->m_pCurTrail[PLAYER_1].Set( pTrail ); @@ -271,9 +271,9 @@ Course *ScreenOptionsManageCourses::GetCourseWithFocus() const { int iCurRow = m_iCurrentRow[GAMESTATE->GetMasterPlayerNumber()]; if( iCurRow == 0 ) - return NULL; + return nullptr; else if( m_pRows[iCurRow]->GetRowType() == OptionRow::RowType_Exit ) - return NULL; + return nullptr; // a course int index = iCurRow - 1; diff --git a/src/ScreenOptionsManageEditSteps.cpp b/src/ScreenOptionsManageEditSteps.cpp index b34b3332aa..cb8d7390dd 100644 --- a/src/ScreenOptionsManageEditSteps.cpp +++ b/src/ScreenOptionsManageEditSteps.cpp @@ -61,8 +61,8 @@ void ScreenOptionsManageEditSteps::BeginScreen() SONGMAN->FreeAllLoadedFromProfile( ProfileSlot_Machine ); SONGMAN->LoadStepEditsFromProfileDir( PROFILEMAN->GetProfileDir(ProfileSlot_Machine), ProfileSlot_Machine ); SONGMAN->LoadCourseEditsFromProfileDir( PROFILEMAN->GetProfileDir(ProfileSlot_Machine), ProfileSlot_Machine ); - GAMESTATE->m_pCurSong.Set( NULL ); - GAMESTATE->m_pCurSteps[PLAYER_1].Set( NULL ); + GAMESTATE->m_pCurSong.Set(nullptr); + GAMESTATE->m_pCurSteps[PLAYER_1].Set(nullptr); vector vHands; @@ -82,18 +82,18 @@ void ScreenOptionsManageEditSteps::BeginScreen() SONGMAN->GetStepsLoadedFromProfile( m_vpSteps, ProfileSlot_Machine ); - FOREACH_CONST( Steps*, m_vpSteps, s ) + for (Steps const *s : m_vpSteps) { vHands.push_back( OptionRowHandlerUtil::MakeNull() ); OptionRowDefinition &def = vHands.back()->m_Def; - Song *pSong = (*s)->m_pSong; + Song *pSong = s->m_pSong; - def.m_sName = pSong->GetTranslitFullTitle() + " - " + (*s)->GetDescription(); + def.m_sName = pSong->GetTranslitFullTitle() + " - " + s->GetDescription(); def.m_bAllowThemeTitle = false; // not themable def.m_sExplanationName = "Select Edit Steps"; def.m_vsChoices.clear(); - StepsType st = (*s)->m_StepsType; + StepsType st = s->m_StepsType; RString sType = GAMEMAN->GetStepsTypeInfo(st).GetLocalizedString(); def.m_vsChoices.push_back( sType ); def.m_bAllowThemeItems = false; // already themed @@ -140,7 +140,7 @@ void ScreenOptionsManageEditSteps::HandleScreenMessage( const ScreenMessage SM ) else // a Steps { Steps *pSteps = GAMESTATE->m_pCurSteps[PLAYER_1]; - ASSERT( pSteps != NULL ); + ASSERT( pSteps != nullptr ); const Style *pStyle = GAMEMAN->GetEditorStyleForStepsType( pSteps->m_StepsType ); GAMESTATE->SetCurrentStyle( pStyle, PLAYER_INVALID ); // do base behavior @@ -177,7 +177,7 @@ void ScreenOptionsManageEditSteps::HandleScreenMessage( const ScreenMessage SM ) Steps *pSteps = GetStepsWithFocus(); FILEMAN->Remove( pSteps->GetFilename() ); SONGMAN->DeleteSteps( pSteps ); - GAMESTATE->m_pCurSteps[PLAYER_1].Set( NULL ); + GAMESTATE->m_pCurSteps[PLAYER_1].Set(nullptr); SCREENMAN->SetNewScreen( this->m_sName ); // reload } } @@ -230,7 +230,7 @@ void ScreenOptionsManageEditSteps::HandleScreenMessage( const ScreenMessage SM ) void ScreenOptionsManageEditSteps::AfterChangeRow( PlayerNumber pn ) { Steps *pSteps = GetStepsWithFocus(); - Song *pSong = pSteps ? pSteps->m_pSong : NULL; + Song *pSong = pSteps ? pSteps->m_pSong : nullptr; GAMESTATE->m_pCurSong.Set( pSong ); GAMESTATE->m_pCurSteps[PLAYER_1].Set( pSteps ); @@ -294,9 +294,9 @@ Steps *ScreenOptionsManageEditSteps::GetStepsWithFocus() const { int iCurRow = m_iCurrentRow[GAMESTATE->GetMasterPlayerNumber()]; if( iCurRow == 0 ) - return NULL; + return nullptr; else if( m_pRows[iCurRow]->GetRowType() == OptionRow::RowType_Exit ) - return NULL; + return nullptr; // a Steps int iStepsIndex = iCurRow - 1; diff --git a/src/ScreenOptionsManageProfiles.cpp b/src/ScreenOptionsManageProfiles.cpp index c508b5c547..552c90b7c1 100644 --- a/src/ScreenOptionsManageProfiles.cpp +++ b/src/ScreenOptionsManageProfiles.cpp @@ -79,7 +79,7 @@ static bool ValidateLocalProfileName( const RString &sAnswer, RString &sErrorOut } Profile *pProfile = PROFILEMAN->GetLocalProfile( GAMESTATE->m_sEditLocalProfileID ); - if( pProfile != NULL && sAnswer == pProfile->m_sDisplayName ) + if( pProfile != nullptr && sAnswer == pProfile->m_sDisplayName ) return true; // unchanged vector vsProfileNames; @@ -127,12 +127,12 @@ void ScreenOptionsManageProfiles::BeginScreen() PROFILEMAN->GetLocalProfileIDs( m_vsLocalProfileID ); - FOREACH_CONST( RString, m_vsLocalProfileID, s ) + for (RString const &s : m_vsLocalProfileID) { - Profile *pProfile = PROFILEMAN->GetLocalProfile( *s ); - ASSERT( pProfile != NULL ); + Profile *pProfile = PROFILEMAN->GetLocalProfile( s ); + ASSERT( pProfile != nullptr ); - RString sCommand = ssprintf( "gamecommand;screen,ScreenOptionsCustomizeProfile;profileid,%s;name,dummy", s->c_str() ); + RString sCommand = ssprintf( "gamecommand;screen,ScreenOptionsCustomizeProfile;profileid,%s;name,dummy", s.c_str() ); OptionRowHandler *pHand = OptionRowHandlerUtil::Make( ParseCommands(sCommand) ); OptionRowDefinition &def = pHand->m_Def; def.m_layoutType = LAYOUT_SHOW_ALL_IN_ROW; @@ -143,7 +143,7 @@ void ScreenOptionsManageProfiles::BeginScreen() PlayerNumber pn = PLAYER_INVALID; FOREACH_PlayerNumber( p ) - if( *s == ProfileManager::m_sDefaultLocalProfileID[p].Get() ) + if( s == ProfileManager::m_sDefaultLocalProfileID[p].Get() ) pn = p; if( pn != PLAYER_INVALID ) def.m_vsChoices.push_back( PlayerNumberToLocalizedString(pn) ); @@ -217,12 +217,13 @@ void ScreenOptionsManageProfiles::HandleScreenMessage( const ScreenMessage SM ) if( iNumProfiles < NUM_PLAYERS ) { int iFirstUnused = -1; - FOREACH_CONST( Preference*, PROFILEMAN->m_sDefaultLocalProfileID.m_v, i ) + int index = 0; + for (Preference const *i : PROFILEMAN->m_sDefaultLocalProfileID.m_v) { - RString sLocalProfileID = (*i)->Get(); + RString sLocalProfileID = i->Get(); if( sLocalProfileID.empty() ) { - iFirstUnused = i - PROFILEMAN->m_sDefaultLocalProfileID.m_v.begin(); + iFirstUnused = index; break; } } @@ -278,7 +279,7 @@ void ScreenOptionsManageProfiles::HandleScreenMessage( const ScreenMessage SM ) if( !ScreenMiniMenu::s_bCancelled ) { Profile *pProfile = PROFILEMAN->GetLocalProfile( GAMESTATE->m_sEditLocalProfileID ); - ASSERT( pProfile != NULL ); + ASSERT( pProfile != nullptr ); switch( ScreenMiniMenu::s_iLastRowCode ) { diff --git a/src/ScreenOptionsMaster.cpp b/src/ScreenOptionsMaster.cpp index dab02a287e..9f6bd58e57 100644 --- a/src/ScreenOptionsMaster.cpp +++ b/src/ScreenOptionsMaster.cpp @@ -11,7 +11,6 @@ #include "PrefsManager.h" #include "StepMania.h" #include "RageSoundManager.h" -#include "Foreach.h" #include "OptionRowHandler.h" #include "ScreenOptionsMasterPrefs.h" #include "CommonMetrics.h" @@ -60,7 +59,7 @@ void ScreenOptionsMaster::Init() ParseCommands( sRowCommands, cmds, false ); OptionRowHandler *pHand = OptionRowHandlerUtil::Make( cmds ); - if( pHand == NULL ) + if( pHand == nullptr ) { LuaHelpers::ReportScriptErrorFmt("Invalid OptionRowHandler \"%s\" in \"%s:Line:%s\".", cmds.GetOriginalCommandString().c_str(), m_sName.c_str(), sLineName.c_str()); } @@ -74,8 +73,10 @@ void ScreenOptionsMaster::Init() void ScreenOptionsMaster::ImportOptions( int r, const vector &vpns ) { - FOREACH_CONST( PlayerNumber, vpns, pn ) - ASSERT( GAMESTATE->IsHumanPlayer(*pn) ); + for (PlayerNumber const &pn : vpns) + { + ASSERT( GAMESTATE->IsHumanPlayer(pn) ); + } OptionRow &row = *m_pRows[r]; row.ImportOptions( vpns ); } @@ -87,10 +88,10 @@ void ScreenOptionsMaster::ExportOptions( int r, const vector &vpns OptionRow &row = *m_pRows[r]; bool bRowHasFocus[NUM_PLAYERS]; ZERO( bRowHasFocus ); - FOREACH_CONST( PlayerNumber, vpns, p ) + for (PlayerNumber const &p : vpns) { - int iCurRow = m_iCurrentRow[*p]; - bRowHasFocus[*p] = iCurRow == r; + int iCurRow = m_iCurrentRow[p]; + bRowHasFocus[p] = iCurRow == r; } m_iChangeMask |= row.ExportOptions( vpns, bRowHasFocus ); } diff --git a/src/ScreenOptionsMasterPrefs.cpp b/src/ScreenOptionsMasterPrefs.cpp index 67b9030a03..e9bd794607 100644 --- a/src/ScreenOptionsMasterPrefs.cpp +++ b/src/ScreenOptionsMasterPrefs.cpp @@ -12,7 +12,6 @@ #include "GameState.h" #include "StepMania.h" #include "Game.h" -#include "Foreach.h" #include "GameConstantsAndTypes.h" #include "DisplaySpec.h" #include "LocalizedString.h" @@ -103,9 +102,9 @@ static void MoveMap( int &sel, IPreference &opt, bool ToSel, const T *mapping, u template static void MoveMap( int &sel, const ConfOption *pConfOption, bool ToSel, const T *mapping, unsigned cnt ) { - ASSERT( pConfOption != NULL ); + ASSERT( pConfOption != nullptr ); IPreference *pPref = IPreference::GetPreferenceByName( pConfOption->m_sPrefName ); - ASSERT_M( pPref != NULL, pConfOption->m_sPrefName ); + ASSERT_M( pPref != nullptr, pConfOption->m_sPrefName ); MoveMap( sel, *pPref, ToSel, mapping, cnt ); } @@ -114,7 +113,7 @@ template static void MovePref( int &iSel, bool bToSel, const ConfOption *pConfOption ) { IPreference *pPref = IPreference::GetPreferenceByName( pConfOption->m_sPrefName ); - ASSERT_M( pPref != NULL, pConfOption->m_sPrefName ); + ASSERT_M( pPref != nullptr, pConfOption->m_sPrefName ); if( bToSel ) { @@ -134,7 +133,7 @@ template <> void MovePref( int &iSel, bool bToSel, const ConfOption *pConfOption ) { IPreference *pPref = IPreference::GetPreferenceByName( pConfOption->m_sPrefName ); - ASSERT_M( pPref != NULL, pConfOption->m_sPrefName ); + ASSERT_M( pPref != nullptr, pConfOption->m_sPrefName ); if( bToSel ) { @@ -165,9 +164,9 @@ static void GameChoices( vector &out ) { vector aGames; GAMEMAN->GetEnabledGames( aGames ); - FOREACH( const Game*, aGames, g ) + for (Game const *g : aGames) { - RString sGameName = (*g)->m_szName; + RString sGameName = g->m_szName; out.push_back( sGameName ); } } @@ -198,13 +197,13 @@ static void LanguageChoices( vector &out ) THEME->GetLanguages( vs ); SortRStringArray( vs, true ); - FOREACH_CONST( RString, vs, s ) + for (RString const &s : vs) { - const LanguageInfo *pLI = GetLanguageInfo( *s ); + const LanguageInfo *pLI = GetLanguageInfo( s ); if( pLI ) out.push_back( THEME->GetString("NativeLanguageNames", pLI->szEnglishName) ); else - out.push_back( *s ); + out.push_back( s ); } } @@ -244,8 +243,8 @@ static void Language( int &sel, bool ToSel, const ConfOption *pConfOption ) static void ThemeChoices( vector &out ) { THEME->GetSelectableThemeNames( out ); - FOREACH( RString, out, s ) - *s = THEME->GetThemeDisplayName( *s ); + for (RString &s : out) + s = THEME->GetThemeDisplayName( s ); } static DisplaySpecs display_specs; @@ -260,11 +259,11 @@ static void cache_display_specs() static void DisplayResolutionChoices( vector &out ) { cache_display_specs(); - FOREACHS_CONST( DisplaySpec, display_specs, iter ) + for (DisplaySpec const &iter : display_specs) { - if (iter->currentMode() != NULL) + if (iter.currentMode() != nullptr) { - RString s = ssprintf("%dx%d", iter->currentMode()->width, iter->currentMode()->height); + RString s = ssprintf("%dx%d", iter.currentMode()->width, iter.currentMode()->height); out.push_back(s); } } @@ -590,11 +589,11 @@ static void DisplayResolutionM( int &sel, bool ToSel, const ConfOption *pConfOpt if( res_choices.empty() ) { - FOREACHS_CONST( DisplaySpec, display_specs, iter ) + for ( DisplaySpec const &iter : display_specs) { - if ( iter->currentMode() != NULL ) + if ( iter.currentMode() != nullptr ) { - res_choices.push_back( res_t( iter->currentMode()->width, iter->currentMode()->height ) ); + res_choices.push_back( res_t( iter.currentMode()->width, iter.currentMode()->height ) ); } } } @@ -948,12 +947,12 @@ ConfOption *ConfOption::Find( RString name ) return opt; } - return NULL; + return nullptr; } void ConfOption::UpdateAvailableOptions() { - if( MakeOptionsListCB != NULL ) + if( MakeOptionsListCB != nullptr ) { names.clear(); MakeOptionsListCB( names ); diff --git a/src/ScreenOptionsMasterPrefs.h b/src/ScreenOptionsMasterPrefs.h index 56df43bbc4..ab0c82298d 100644 --- a/src/ScreenOptionsMasterPrefs.h +++ b/src/ScreenOptionsMasterPrefs.h @@ -48,12 +48,12 @@ struct ConfOption int GetEffects() const; ConfOption( const char *n, MoveData_t m, - const char *c0=NULL, const char *c1=NULL, const char *c2=NULL, const char *c3=NULL, const char *c4=NULL, const char *c5=NULL, const char *c6=NULL, const char *c7=NULL, const char *c8=NULL, const char *c9=NULL, const char *c10=NULL, const char *c11=NULL, const char *c12=NULL, const char *c13=NULL, const char *c14=NULL, const char *c15=NULL, const char *c16=NULL, const char *c17=NULL, const char *c18=NULL, const char *c19=NULL ) + const char *c0=nullptr, const char *c1=nullptr, const char *c2=nullptr, const char *c3=nullptr, const char *c4=nullptr, const char *c5=nullptr, const char *c6=nullptr, const char *c7=nullptr, const char *c8=nullptr, const char *c9=nullptr, const char *c10=nullptr, const char *c11=nullptr, const char *c12=nullptr, const char *c13=nullptr, const char *c14=nullptr, const char *c15=nullptr, const char *c16=nullptr, const char *c17=nullptr, const char *c18=nullptr, const char *c19=nullptr ) { name = n; m_sPrefName = name; // copy from name (not n), to allow refcounting MoveData = m; - MakeOptionsListCB = NULL; + MakeOptionsListCB = nullptr; m_iEffects = 0; m_bAllowThemeItems = true; #define PUSH( c ) if(c) names.push_back(c); diff --git a/src/ScreenOptionsMemoryCard.cpp b/src/ScreenOptionsMemoryCard.cpp index dea7444c81..5b03e0bf29 100644 --- a/src/ScreenOptionsMemoryCard.cpp +++ b/src/ScreenOptionsMemoryCard.cpp @@ -1,247 +1,247 @@ -#include "global.h" -#include "ScreenOptionsMemoryCard.h" -#include "RageLog.h" -#include "arch/MemoryCard/MemoryCardDriver.h" -#include "MemoryCardManager.h" -#include "GameState.h" -#include "ScreenManager.h" -#include "ScreenPrompt.h" -#include "LocalizedString.h" -#include "OptionRowHandler.h" - -REGISTER_SCREEN_CLASS( ScreenOptionsMemoryCard ); - -void ScreenOptionsMemoryCard::Init() -{ - ScreenOptions::Init(); - - m_textOsMountDir.SetName( "Mount" ); - m_textOsMountDir.LoadFromFont( THEME->GetPathF(m_sName,"mount") ); - ActorUtil::LoadAllCommands( m_textOsMountDir, m_sName ); - this->AddChild( &m_textOsMountDir ); - - this->SubscribeToMessage( Message_StorageDevicesChanged ); -} - -bool ScreenOptionsMemoryCard::UpdateCurrentUsbStorageDevices() -{ - vector aOldDevices = m_CurrentUsbStorageDevices; - - const vector &aNewDevices = MEMCARDMAN->GetStorageDevices(); - - m_CurrentUsbStorageDevices.clear(); - for( size_t i = 0; i < aNewDevices.size(); ++i ) - { - const UsbStorageDevice &dev = aNewDevices[i]; - if( dev.m_State == UsbStorageDevice::STATE_CHECKING ) - continue; - m_CurrentUsbStorageDevices.push_back( dev ); - } - - return aOldDevices != m_CurrentUsbStorageDevices; -} - -static LocalizedString NO_LABEL ("ScreenOptionsMemoryCard", "(no label)" ); -static LocalizedString SIZE_UNKNOWN ("ScreenOptionsMemoryCard", "size ???" ); -static LocalizedString VOLUME_SIZE ("ScreenOptionsMemoryCard", "%dMB" ); -void ScreenOptionsMemoryCard::CreateMenu() -{ - vector vHands; - - FOREACH_CONST( UsbStorageDevice, m_CurrentUsbStorageDevices, iter ) - { - vector vs; - if( iter->sVolumeLabel.empty() ) - vs.push_back( NO_LABEL ); - else - vs.push_back( iter->sVolumeLabel ); - if( iter->iVolumeSizeMB == 0 ) - vs.push_back( SIZE_UNKNOWN ); - else - vs.push_back( ssprintf(RString(VOLUME_SIZE).c_str(),iter->iVolumeSizeMB) ); - - vHands.push_back( OptionRowHandlerUtil::MakeNull() ); - - OptionRowDefinition &def = vHands.back()->m_Def; - RString sDescription = join(", ", vs); - def.m_sName = sDescription; - def.m_vsChoices.push_back( "" ); - def.m_sExplanationName = "Memory Card"; - def.m_bAllowThemeTitle = false; - def.m_bOneChoiceForAllPlayers = true; - } - - if( m_CurrentUsbStorageDevices.empty() ) - { - vHands.push_back( OptionRowHandlerUtil::MakeNull() ); - OptionRowDefinition &def = vHands.back()->m_Def; - def.m_sName = "No USB memory cards found"; - def.m_sExplanationName = "No Memory Card"; - def.m_vsChoices.push_back( "" ); - def.m_bAllowThemeTitle = true; - def.m_bOneChoiceForAllPlayers = true; - } - - InitMenu( vHands ); -} - -void ScreenOptionsMemoryCard::BeginScreen() -{ - UpdateCurrentUsbStorageDevices(); - CreateMenu(); - - ScreenOptions::BeginScreen(); - - // select the last chosen memory card (if present) - SelectRowWithMemoryCard( MEMCARDMAN->m_sEditorMemoryCardOsMountPoint.Get() ); -} - -void ScreenOptionsMemoryCard::HandleScreenMessage( const ScreenMessage SM ) -{ - ScreenOptions::HandleScreenMessage( SM ); -} - -void ScreenOptionsMemoryCard::AfterChangeRow( PlayerNumber pn ) -{ - ScreenOptions::AfterChangeRow( pn ); - - if( m_CurrentUsbStorageDevices.empty() ) - { - m_textOsMountDir.SetText( "" ); - } - else - { - int iRow = m_iCurrentRow[GAMESTATE->GetMasterPlayerNumber()]; - m_textOsMountDir.SetText( m_CurrentUsbStorageDevices[iRow].sOsMountDir ); - } -} - -void ScreenOptionsMemoryCard::HandleMessage( const Message &msg ) -{ - if( msg == Message_StorageDevicesChanged ) - { - if( !m_Out.IsTransitioning() ) - { - /* Remember the old mountpoint. */ - const vector &v = m_CurrentUsbStorageDevices; - int iRow = m_iCurrentRow[GAMESTATE->GetMasterPlayerNumber()]; - RString sOldMountPoint; - if( iRow < int(v.size()) ) - { - const UsbStorageDevice &dev = v[iRow]; - sOldMountPoint = dev.sOsMountDir; - } - - /* If the devices that we'd actually show haven't changed, don't recreate the menu. */ - if( !UpdateCurrentUsbStorageDevices() ) - return; - - CreateMenu(); - RestartOptions(); - - /* If the memory card that was selected previously is still there, select it. */ - SelectRowWithMemoryCard( sOldMountPoint ); - } - } - - ScreenOptions::HandleMessage( msg ); -} - -void ScreenOptionsMemoryCard::ImportOptions( int iRow, const vector &vpns ) -{ - -} - -void ScreenOptionsMemoryCard::ExportOptions( int iRow, const vector &vpns ) -{ - OptionRow &row = *m_pRows[iRow]; - if( row.GetRowType() == OptionRow::RowType_Exit ) - return; - - PlayerNumber pn = GAMESTATE->GetMasterPlayerNumber(); - if( m_iCurrentRow[pn] == iRow ) - { - const vector &v = m_CurrentUsbStorageDevices; - if( iRow < int(v.size()) ) - { - const UsbStorageDevice &dev = v[iRow]; - MEMCARDMAN->m_sEditorMemoryCardOsMountPoint.Set( dev.sOsMountDir ); - } - } -} - -void ScreenOptionsMemoryCard::SelectRowWithMemoryCard( const RString &sOsMountPoint ) -{ - if( sOsMountPoint.empty() ) - return; - - const vector &v = m_CurrentUsbStorageDevices; - for( unsigned i=0; iMoveRowAbsolute( PLAYER_1, i ); - return; - } - } -} - -static LocalizedString ERROR_MOUNTING_CARD ("ScreenOptionsMemoryCard", "Error mounting card: %s" ); -void ScreenOptionsMemoryCard::ProcessMenuStart( const InputEventPlus & ) -{ - if( IsTransitioning() ) - return; - - int iCurRow = m_iCurrentRow[GAMESTATE->GetMasterPlayerNumber()]; - - const vector &v = m_CurrentUsbStorageDevices; - if( iCurRow < int(v.size()) ) // a card - { - // Why is this statement in twice? Doubt it would change right after the if. -Wolfman2000 - const vector &vUSB = m_CurrentUsbStorageDevices; - const UsbStorageDevice &dev = vUSB[iCurRow]; - MEMCARDMAN->m_sEditorMemoryCardOsMountPoint.Set( dev.sOsMountDir ); - - /* The destination screen must UnmountCard. XXX: brittle */ - bool bSuccess = MEMCARDMAN->MountCard( PLAYER_1, dev ); - if( bSuccess ) - { - SCREENMAN->PlayStartSound(); - this->BeginFadingOut(); - } - else - { - RString s = ssprintf(ERROR_MOUNTING_CARD.GetValue(), MEMCARDMAN->GetCardError(PLAYER_1).c_str() ); - ScreenPrompt::Prompt( SM_None, s ); - } - } - else - { - SCREENMAN->PlayInvalidSound(); - } -} - -/* - * (c) 2005 Chris Danford - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "ScreenOptionsMemoryCard.h" +#include "RageLog.h" +#include "arch/MemoryCard/MemoryCardDriver.h" +#include "MemoryCardManager.h" +#include "GameState.h" +#include "ScreenManager.h" +#include "ScreenPrompt.h" +#include "LocalizedString.h" +#include "OptionRowHandler.h" + +REGISTER_SCREEN_CLASS( ScreenOptionsMemoryCard ); + +void ScreenOptionsMemoryCard::Init() +{ + ScreenOptions::Init(); + + m_textOsMountDir.SetName( "Mount" ); + m_textOsMountDir.LoadFromFont( THEME->GetPathF(m_sName,"mount") ); + ActorUtil::LoadAllCommands( m_textOsMountDir, m_sName ); + this->AddChild( &m_textOsMountDir ); + + this->SubscribeToMessage( Message_StorageDevicesChanged ); +} + +bool ScreenOptionsMemoryCard::UpdateCurrentUsbStorageDevices() +{ + vector aOldDevices = m_CurrentUsbStorageDevices; + + const vector &aNewDevices = MEMCARDMAN->GetStorageDevices(); + + m_CurrentUsbStorageDevices.clear(); + for( size_t i = 0; i < aNewDevices.size(); ++i ) + { + const UsbStorageDevice &dev = aNewDevices[i]; + if( dev.m_State == UsbStorageDevice::STATE_CHECKING ) + continue; + m_CurrentUsbStorageDevices.push_back( dev ); + } + + return aOldDevices != m_CurrentUsbStorageDevices; +} + +static LocalizedString NO_LABEL ("ScreenOptionsMemoryCard", "(no label)" ); +static LocalizedString SIZE_UNKNOWN ("ScreenOptionsMemoryCard", "size ???" ); +static LocalizedString VOLUME_SIZE ("ScreenOptionsMemoryCard", "%dMB" ); +void ScreenOptionsMemoryCard::CreateMenu() +{ + vector vHands; + + for (UsbStorageDevice const &iter : m_CurrentUsbStorageDevices) + { + vector vs; + if( iter.sVolumeLabel.empty() ) + vs.push_back( NO_LABEL ); + else + vs.push_back( iter.sVolumeLabel ); + if( iter.iVolumeSizeMB == 0 ) + vs.push_back( SIZE_UNKNOWN ); + else + vs.push_back( ssprintf(RString(VOLUME_SIZE).c_str(),iter.iVolumeSizeMB) ); + + vHands.push_back( OptionRowHandlerUtil::MakeNull() ); + + OptionRowDefinition &def = vHands.back()->m_Def; + RString sDescription = join(", ", vs); + def.m_sName = sDescription; + def.m_vsChoices.push_back( "" ); + def.m_sExplanationName = "Memory Card"; + def.m_bAllowThemeTitle = false; + def.m_bOneChoiceForAllPlayers = true; + } + + if( m_CurrentUsbStorageDevices.empty() ) + { + vHands.push_back( OptionRowHandlerUtil::MakeNull() ); + OptionRowDefinition &def = vHands.back()->m_Def; + def.m_sName = "No USB memory cards found"; + def.m_sExplanationName = "No Memory Card"; + def.m_vsChoices.push_back( "" ); + def.m_bAllowThemeTitle = true; + def.m_bOneChoiceForAllPlayers = true; + } + + InitMenu( vHands ); +} + +void ScreenOptionsMemoryCard::BeginScreen() +{ + UpdateCurrentUsbStorageDevices(); + CreateMenu(); + + ScreenOptions::BeginScreen(); + + // select the last chosen memory card (if present) + SelectRowWithMemoryCard( MEMCARDMAN->m_sEditorMemoryCardOsMountPoint.Get() ); +} + +void ScreenOptionsMemoryCard::HandleScreenMessage( const ScreenMessage SM ) +{ + ScreenOptions::HandleScreenMessage( SM ); +} + +void ScreenOptionsMemoryCard::AfterChangeRow( PlayerNumber pn ) +{ + ScreenOptions::AfterChangeRow( pn ); + + if( m_CurrentUsbStorageDevices.empty() ) + { + m_textOsMountDir.SetText( "" ); + } + else + { + int iRow = m_iCurrentRow[GAMESTATE->GetMasterPlayerNumber()]; + m_textOsMountDir.SetText( m_CurrentUsbStorageDevices[iRow].sOsMountDir ); + } +} + +void ScreenOptionsMemoryCard::HandleMessage( const Message &msg ) +{ + if( msg == Message_StorageDevicesChanged ) + { + if( !m_Out.IsTransitioning() ) + { + /* Remember the old mountpoint. */ + const vector &v = m_CurrentUsbStorageDevices; + int iRow = m_iCurrentRow[GAMESTATE->GetMasterPlayerNumber()]; + RString sOldMountPoint; + if( iRow < int(v.size()) ) + { + const UsbStorageDevice &dev = v[iRow]; + sOldMountPoint = dev.sOsMountDir; + } + + /* If the devices that we'd actually show haven't changed, don't recreate the menu. */ + if( !UpdateCurrentUsbStorageDevices() ) + return; + + CreateMenu(); + RestartOptions(); + + /* If the memory card that was selected previously is still there, select it. */ + SelectRowWithMemoryCard( sOldMountPoint ); + } + } + + ScreenOptions::HandleMessage( msg ); +} + +void ScreenOptionsMemoryCard::ImportOptions( int iRow, const vector &vpns ) +{ + +} + +void ScreenOptionsMemoryCard::ExportOptions( int iRow, const vector &vpns ) +{ + OptionRow &row = *m_pRows[iRow]; + if( row.GetRowType() == OptionRow::RowType_Exit ) + return; + + PlayerNumber pn = GAMESTATE->GetMasterPlayerNumber(); + if( m_iCurrentRow[pn] == iRow ) + { + const vector &v = m_CurrentUsbStorageDevices; + if( iRow < int(v.size()) ) + { + const UsbStorageDevice &dev = v[iRow]; + MEMCARDMAN->m_sEditorMemoryCardOsMountPoint.Set( dev.sOsMountDir ); + } + } +} + +void ScreenOptionsMemoryCard::SelectRowWithMemoryCard( const RString &sOsMountPoint ) +{ + if( sOsMountPoint.empty() ) + return; + + const vector &v = m_CurrentUsbStorageDevices; + for( unsigned i=0; iMoveRowAbsolute( PLAYER_1, i ); + return; + } + } +} + +static LocalizedString ERROR_MOUNTING_CARD ("ScreenOptionsMemoryCard", "Error mounting card: %s" ); +void ScreenOptionsMemoryCard::ProcessMenuStart( const InputEventPlus & ) +{ + if( IsTransitioning() ) + return; + + int iCurRow = m_iCurrentRow[GAMESTATE->GetMasterPlayerNumber()]; + + const vector &v = m_CurrentUsbStorageDevices; + if( iCurRow < int(v.size()) ) // a card + { + // Why is this statement in twice? Doubt it would change right after the if. -Wolfman2000 + const vector &vUSB = m_CurrentUsbStorageDevices; + const UsbStorageDevice &dev = vUSB[iCurRow]; + MEMCARDMAN->m_sEditorMemoryCardOsMountPoint.Set( dev.sOsMountDir ); + + /* The destination screen must UnmountCard. XXX: brittle */ + bool bSuccess = MEMCARDMAN->MountCard( PLAYER_1, dev ); + if( bSuccess ) + { + SCREENMAN->PlayStartSound(); + this->BeginFadingOut(); + } + else + { + RString s = ssprintf(ERROR_MOUNTING_CARD.GetValue(), MEMCARDMAN->GetCardError(PLAYER_1).c_str() ); + ScreenPrompt::Prompt( SM_None, s ); + } + } + else + { + SCREENMAN->PlayInvalidSound(); + } +} + +/* + * (c) 2005 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/ScreenOptionsReviewWorkout.cpp b/src/ScreenOptionsReviewWorkout.cpp index 49dc09a90e..434373b593 100644 --- a/src/ScreenOptionsReviewWorkout.cpp +++ b/src/ScreenOptionsReviewWorkout.cpp @@ -29,10 +29,10 @@ enum ReviewWorkoutRow static const MenuRowDef g_MenuRows[] = { - MenuRowDef( -1, "Play", true, EditMode_Practice, true, false, 0, NULL ), - MenuRowDef( -1, "Edit Workout", true, EditMode_Practice, true, false, 0, NULL ), - MenuRowDef( -1, "Shuffle", true, EditMode_Practice, true, false, 0, NULL ), - MenuRowDef( -1, "Save", true, EditMode_Practice, true, false, 0, NULL ), + MenuRowDef( -1, "Play", true, EditMode_Practice, true, false, 0, nullptr ), + MenuRowDef( -1, "Edit Workout", true, EditMode_Practice, true, false, 0, nullptr ), + MenuRowDef( -1, "Shuffle", true, EditMode_Practice, true, false, 0, nullptr ), + MenuRowDef( -1, "Save", true, EditMode_Practice, true, false, 0, nullptr ), }; REGISTER_SCREEN_CLASS( ScreenOptionsCourseOverview ); @@ -66,7 +66,7 @@ void ScreenOptionsCourseOverview::BeginScreen() ScreenOptions::BeginScreen(); // clear the current song in case it's set when we back out from gameplay - GAMESTATE->m_pCurSong.Set( NULL ); + GAMESTATE->m_pCurSong.Set(nullptr); } ScreenOptionsCourseOverview::~ScreenOptionsCourseOverview() diff --git a/src/ScreenOptionsToggleSongs.cpp b/src/ScreenOptionsToggleSongs.cpp index f3b42b6aed..3fa8b81bb6 100644 --- a/src/ScreenOptionsToggleSongs.cpp +++ b/src/ScreenOptionsToggleSongs.cpp @@ -1,153 +1,151 @@ -#include "global.h" -#include "ScreenOptionsToggleSongs.h" -#include "OptionRowHandler.h" -#include "RageUtil.h" -#include "ScreenManager.h" -#include "Song.h" -#include "SongManager.h" -#include "UnlockManager.h" -#include "PrefsManager.h" -#include "MessageManager.h" - -// main page (group list) -REGISTER_SCREEN_CLASS( ScreenOptionsToggleSongs ); - -void ScreenOptionsToggleSongs::BeginScreen() -{ - m_asGroups.clear(); - - vector vHands; - - vector asAllGroups; - SONGMAN->GetSongGroupNames(asAllGroups); - FOREACH_CONST( RString, asAllGroups , s ) - { - vHands.push_back( OptionRowHandlerUtil::MakeNull() ); - OptionRowDefinition &def = vHands.back()->m_Def; - RString sGroup = *s; - - def.m_sName = sGroup; - def.m_sExplanationName = "Select Group"; - def.m_bAllowThemeTitle = false; // not themable - def.m_bAllowThemeItems = false; // already themed - def.m_bOneChoiceForAllPlayers = true; - def.m_vsChoices.clear(); - def.m_vsChoices.push_back( "" ); - - m_asGroups.push_back( sGroup ); - } - ScreenOptions::InitMenu( vHands ); - - ScreenOptions::BeginScreen(); -} - -void ScreenOptionsToggleSongs::ProcessMenuStart( const InputEventPlus &input ) -{ - if( IsTransitioning() ) - return; - - // switch to the subpage with the specified group - int iRow = GetCurrentRow(); - if( m_pRows[iRow]->GetRowType() == OptionRow::RowType_Exit ) - { - ScreenOptions::ProcessMenuStart( input ); - return; - } - - ToggleSongs::m_sGroup = m_asGroups[iRow]; - SCREENMAN->SetNewScreen("ScreenOptionsToggleSongsSubPage"); -} - -void ScreenOptionsToggleSongs::ImportOptions( int row, const vector &vpns ) -{ - -} -void ScreenOptionsToggleSongs::ExportOptions( int row, const vector &vpns ) -{ - -} - -// subpage (has the songs in a specific group) -REGISTER_SCREEN_CLASS( ScreenOptionsToggleSongsSubPage ); -void ScreenOptionsToggleSongsSubPage::BeginScreen() -{ - m_apSongs.clear(); - - vector vHands; - - const vector &apAllSongs = SONGMAN->GetSongs(ToggleSongs::m_sGroup); - FOREACH_CONST( Song *, apAllSongs , s ) - { - Song *pSong = *s; - if( UNLOCKMAN->SongIsLocked(pSong) & ~LOCKED_DISABLED ) - continue; - - vHands.push_back( OptionRowHandlerUtil::MakeNull() ); - OptionRowDefinition &def = vHands.back()->m_Def; - - def.m_sName = pSong->GetTranslitFullTitle(); - def.m_bAllowThemeTitle = false; // not themable - def.m_sExplanationName = "Toggle Song"; - def.m_bOneChoiceForAllPlayers = true; - def.m_vsChoices.clear(); - def.m_vsChoices.push_back( "On" ); - def.m_vsChoices.push_back( "Off" ); - def.m_bAllowThemeItems = false; // already themed - - m_apSongs.push_back( pSong ); - } - - InitMenu( vHands ); - - ScreenOptions::BeginScreen(); -} - -void ScreenOptionsToggleSongsSubPage::ImportOptions( int iRow, const vector &vpns ) -{ - if( iRow >= (int)m_apSongs.size() ) // exit row - return; - - OptionRow &row = *m_pRows[iRow]; - bool bEnable = m_apSongs[iRow]->GetEnabled(); - int iSelection = bEnable? 0:1; - row.SetOneSharedSelection( iSelection ); -} - -void ScreenOptionsToggleSongsSubPage::ExportOptions( int iRow, const vector &vpns ) -{ - if( iRow >= (int)m_apSongs.size() ) // exit row - return; - - const OptionRow &row = *m_pRows[iRow]; - int iSelection = row.GetOneSharedSelection(); - bool bEnable = (iSelection == 0); - m_apSongs[iRow]->SetEnabled( bEnable ); - - SONGMAN->SaveEnabledSongsToPref(); - PREFSMAN->SavePrefsToDisk(); -} - -/* - * (c) 2007 Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "ScreenOptionsToggleSongs.h" +#include "OptionRowHandler.h" +#include "RageUtil.h" +#include "ScreenManager.h" +#include "Song.h" +#include "SongManager.h" +#include "UnlockManager.h" +#include "PrefsManager.h" +#include "MessageManager.h" + +// main page (group list) +REGISTER_SCREEN_CLASS( ScreenOptionsToggleSongs ); + +void ScreenOptionsToggleSongs::BeginScreen() +{ + m_asGroups.clear(); + + vector vHands; + + vector asAllGroups; + SONGMAN->GetSongGroupNames(asAllGroups); + for (RString const &sGroup : asAllGroups) + { + vHands.push_back( OptionRowHandlerUtil::MakeNull() ); + OptionRowDefinition &def = vHands.back()->m_Def; + + def.m_sName = sGroup; + def.m_sExplanationName = "Select Group"; + def.m_bAllowThemeTitle = false; // not themable + def.m_bAllowThemeItems = false; // already themed + def.m_bOneChoiceForAllPlayers = true; + def.m_vsChoices.clear(); + def.m_vsChoices.push_back( "" ); + + m_asGroups.push_back( sGroup ); + } + ScreenOptions::InitMenu( vHands ); + + ScreenOptions::BeginScreen(); +} + +void ScreenOptionsToggleSongs::ProcessMenuStart( const InputEventPlus &input ) +{ + if( IsTransitioning() ) + return; + + // switch to the subpage with the specified group + int iRow = GetCurrentRow(); + if( m_pRows[iRow]->GetRowType() == OptionRow::RowType_Exit ) + { + ScreenOptions::ProcessMenuStart( input ); + return; + } + + ToggleSongs::m_sGroup = m_asGroups[iRow]; + SCREENMAN->SetNewScreen("ScreenOptionsToggleSongsSubPage"); +} + +void ScreenOptionsToggleSongs::ImportOptions( int row, const vector &vpns ) +{ + +} +void ScreenOptionsToggleSongs::ExportOptions( int row, const vector &vpns ) +{ + +} + +// subpage (has the songs in a specific group) +REGISTER_SCREEN_CLASS( ScreenOptionsToggleSongsSubPage ); +void ScreenOptionsToggleSongsSubPage::BeginScreen() +{ + m_apSongs.clear(); + + vector vHands; + + const vector &apAllSongs = SONGMAN->GetSongs(ToggleSongs::m_sGroup); + for (Song *pSong : apAllSongs) + { + if( UNLOCKMAN->SongIsLocked(pSong) & ~LOCKED_DISABLED ) + continue; + + vHands.push_back( OptionRowHandlerUtil::MakeNull() ); + OptionRowDefinition &def = vHands.back()->m_Def; + + def.m_sName = pSong->GetTranslitFullTitle(); + def.m_bAllowThemeTitle = false; // not themable + def.m_sExplanationName = "Toggle Song"; + def.m_bOneChoiceForAllPlayers = true; + def.m_vsChoices.clear(); + def.m_vsChoices.push_back( "On" ); + def.m_vsChoices.push_back( "Off" ); + def.m_bAllowThemeItems = false; // already themed + + m_apSongs.push_back( pSong ); + } + + InitMenu( vHands ); + + ScreenOptions::BeginScreen(); +} + +void ScreenOptionsToggleSongsSubPage::ImportOptions( int iRow, const vector &vpns ) +{ + if( iRow >= (int)m_apSongs.size() ) // exit row + return; + + OptionRow &row = *m_pRows[iRow]; + bool bEnable = m_apSongs[iRow]->GetEnabled(); + int iSelection = bEnable? 0:1; + row.SetOneSharedSelection( iSelection ); +} + +void ScreenOptionsToggleSongsSubPage::ExportOptions( int iRow, const vector &vpns ) +{ + if( iRow >= (int)m_apSongs.size() ) // exit row + return; + + const OptionRow &row = *m_pRows[iRow]; + int iSelection = row.GetOneSharedSelection(); + bool bEnable = (iSelection == 0); + m_apSongs[iRow]->SetEnabled( bEnable ); + + SONGMAN->SaveEnabledSongsToPref(); + PREFSMAN->SavePrefsToDisk(); +} + +/* + * (c) 2007 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/ScreenPackages.cpp b/src/ScreenPackages.cpp index b9d1562938..a7409e0ec4 100644 --- a/src/ScreenPackages.cpp +++ b/src/ScreenPackages.cpp @@ -630,14 +630,14 @@ void ScreenPackages::HTTPUpdate() m_sResponseName = "Malformed response."; return; } - m_iResponseCode = StringToInt(m_sBUFFER.substr(i+1,j-i)); + m_iResponseCode = std::stoi(m_sBUFFER.substr(i+1,j-i)); m_sResponseName = m_sBUFFER.substr( j+1, k-j ); i = m_sBUFFER.find("Content-Length:"); j = m_sBUFFER.find("\n", i+1 ); if( i != string::npos ) - m_iTotalBytes = StringToInt(m_sBUFFER.substr(i+16,j-i)); + m_iTotalBytes = std::stoi(m_sBUFFER.substr(i+16,j-i)); else m_iTotalBytes = -1; //We don't know, so go until disconnect @@ -704,7 +704,7 @@ bool ScreenPackages::ParseHTTPAddress( const RString &URL, RString &sProto, RStr sServer = asMatches[1]; if( asMatches[3] != "" ) { - iPort = StringToInt(asMatches[3]); + iPort = std::stoi(asMatches[3]); if( iPort == 0 ) return false; } diff --git a/src/ScreenPlayerOptions.cpp b/src/ScreenPlayerOptions.cpp index d3b315ac38..5a1c8efb83 100644 --- a/src/ScreenPlayerOptions.cpp +++ b/src/ScreenPlayerOptions.cpp @@ -1,196 +1,189 @@ -#include "global.h" -#include "ScreenPlayerOptions.h" -#include "ScreenManager.h" -#include "RageLog.h" -#include "GameState.h" -#include "ThemeManager.h" -#include "AnnouncerManager.h" -#include "GameSoundManager.h" -#include "ScreenSongOptions.h" -#include "PrefsManager.h" -#include "CodeDetector.h" -#include "ScreenDimensions.h" -#include "PlayerState.h" -#include "Foreach.h" -#include "InputEventPlus.h" - -REGISTER_SCREEN_CLASS( ScreenPlayerOptions ); - -void ScreenPlayerOptions::Init() -{ - ScreenOptionsMaster::Init(); - - FOREACH_PlayerNumber( p ) - { - m_sprDisqualify[p].Load( THEME->GetPathG(m_sName,"disqualify") ); - m_sprDisqualify[p]->SetName( ssprintf("DisqualifyP%i",p+1) ); - LOAD_ALL_COMMANDS_AND_SET_XY( m_sprDisqualify[p] ); - m_sprDisqualify[p]->SetVisible( false ); // unhide later if handicapping options are discovered - m_sprDisqualify[p]->SetDrawOrder( 2 ); - m_frameContainer.AddChild( m_sprDisqualify[p] ); - } - - m_bAskOptionsMessage = - !GAMESTATE->IsEditing() && PREFSMAN->m_ShowSongOptions == Maybe_ASK; - - m_bAcceptedChoices = false; - m_bGoToOptions = ( PREFSMAN->m_ShowSongOptions == Maybe_YES ); - - SOUND->PlayOnceFromDir( ANNOUNCER->GetPathTo("player options intro") ); - - FOREACH_PlayerNumber( p ) - m_bRowCausesDisqualified[p].resize( m_pRows.size(), false ); -} - - -void ScreenPlayerOptions::BeginScreen() -{ - FOREACH_PlayerNumber( p ) - ON_COMMAND( m_sprDisqualify[p] ); - - ScreenOptionsMaster::BeginScreen(); - - FOREACH_HumanPlayer( p ) - { - for( unsigned r=0; rPlayCommand( "GoToOptions" ); - SCREENMAN->PlayStartSound(); - bHandled = true; - } - } - - PlayerNumber pn = input.pn; - if( GAMESTATE->IsHumanPlayer(pn) && CodeDetector::EnteredCode(input.GameI.controller,CODE_CANCEL_ALL_PLAYER_OPTIONS) ) - { - // apply the game default mods, but not the Profile saved mods - GAMESTATE->m_pPlayerState[pn]->ResetToDefaultPlayerOptions( ModsLevel_Preferred ); - - MESSAGEMAN->Broadcast( ssprintf("CancelAllP%i", pn+1) ); - - for( unsigned r=0; r v; - v.push_back( pn ); - int iOldFocus = m_pRows[r]->GetChoiceInRowWithFocus( pn ); - this->ImportOptions( r, v ); - m_pRows[r]->AfterImportOptions( pn ); - this->UpdateDisqualified( r, pn ); - m_pRows[r]->SetChoiceInRowWithFocus( pn, iOldFocus ); - } - bHandled = true; - } - - bHandled = ScreenOptionsMaster::Input( input ) || bHandled; - - // UGLY: Update m_Disqualified whenever Start is pressed - if( GAMESTATE->IsHumanPlayer(pn) && input.MenuI == GAME_BUTTON_START ) - { - int row = m_iCurrentRow[pn]; - UpdateDisqualified( row, pn ); - } - return bHandled; -} - -void ScreenPlayerOptions::HandleScreenMessage( const ScreenMessage SM ) -{ - if( SM == SM_BeginFadingOut && m_bAskOptionsMessage ) // user accepts the page of options - { - m_bAcceptedChoices = true; - - // show "hold START for options" - this->PlayCommand( "AskForGoToOptions" ); - } - - ScreenOptionsMaster::HandleScreenMessage( SM ); -} - -void ScreenPlayerOptions::UpdateDisqualified( int row, PlayerNumber pn ) -{ - ASSERT( GAMESTATE->IsHumanPlayer(pn) ); - - // save original player options - PlayerOptions poOrig = GAMESTATE->m_pPlayerState[pn]->m_PlayerOptions.GetPreferred(); - - // Find out if the current row when exported causes disqualification. - // Exporting the row will fill GAMESTATE->m_PlayerOptions. - PO_GROUP_CALL( GAMESTATE->m_pPlayerState[pn]->m_PlayerOptions, ModsLevel_Preferred, Init ); - vector v; - v.push_back( pn ); - ExportOptions( row, v ); - bool bRowCausesDisqualified = GAMESTATE->CurrentOptionsDisqualifyPlayer( pn ); - m_bRowCausesDisqualified[pn][row] = bRowCausesDisqualified; - - // Update disqualified graphic - bool bDisqualified = false; - FOREACH_CONST( bool, m_bRowCausesDisqualified[pn], b ) - { - if( *b ) - { - bDisqualified = true; - break; - } - } - m_sprDisqualify[pn]->SetVisible( bDisqualified ); - - // restore previous player options in case the user escapes back after this - GAMESTATE->m_pPlayerState[pn]->m_PlayerOptions.Assign( ModsLevel_Preferred, poOrig ); -} - -// lua start -#include "LuaBinding.h" - -/** @brief Allow Lua to have access to the ScreenPlayerOptions. */ -class LunaScreenPlayerOptions: public Luna -{ -public: - static int GetGoToOptions( T* p, lua_State *L ) { lua_pushboolean( L, p->GetGoToOptions() ); return 1; } - - LunaScreenPlayerOptions() - { - ADD_METHOD( GetGoToOptions ); - } -}; - -LUA_REGISTER_DERIVED_CLASS( ScreenPlayerOptions, ScreenOptions ) -// lua end - -/* - * (c) 2001-2004 Chris Danford - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "ScreenPlayerOptions.h" +#include "ScreenManager.h" +#include "RageLog.h" +#include "GameState.h" +#include "ThemeManager.h" +#include "AnnouncerManager.h" +#include "GameSoundManager.h" +#include "ScreenSongOptions.h" +#include "PrefsManager.h" +#include "CodeDetector.h" +#include "ScreenDimensions.h" +#include "PlayerState.h" + +#include "InputEventPlus.h" + +REGISTER_SCREEN_CLASS( ScreenPlayerOptions ); + +void ScreenPlayerOptions::Init() +{ + ScreenOptionsMaster::Init(); + + FOREACH_PlayerNumber( p ) + { + m_sprDisqualify[p].Load( THEME->GetPathG(m_sName,"disqualify") ); + m_sprDisqualify[p]->SetName( ssprintf("DisqualifyP%i",p+1) ); + LOAD_ALL_COMMANDS_AND_SET_XY( m_sprDisqualify[p] ); + m_sprDisqualify[p]->SetVisible( false ); // unhide later if handicapping options are discovered + m_sprDisqualify[p]->SetDrawOrder( 2 ); + m_frameContainer.AddChild( m_sprDisqualify[p] ); + } + + m_bAskOptionsMessage = + !GAMESTATE->IsEditing() && PREFSMAN->m_ShowSongOptions == Maybe_ASK; + + m_bAcceptedChoices = false; + m_bGoToOptions = ( PREFSMAN->m_ShowSongOptions == Maybe_YES ); + + SOUND->PlayOnceFromDir( ANNOUNCER->GetPathTo("player options intro") ); + + FOREACH_PlayerNumber( p ) + m_bRowCausesDisqualified[p].resize( m_pRows.size(), false ); +} + + +void ScreenPlayerOptions::BeginScreen() +{ + FOREACH_PlayerNumber( p ) + ON_COMMAND( m_sprDisqualify[p] ); + + ScreenOptionsMaster::BeginScreen(); + + FOREACH_HumanPlayer( p ) + { + for( unsigned r=0; rPlayCommand( "GoToOptions" ); + SCREENMAN->PlayStartSound(); + bHandled = true; + } + } + + PlayerNumber pn = input.pn; + if( GAMESTATE->IsHumanPlayer(pn) && CodeDetector::EnteredCode(input.GameI.controller,CODE_CANCEL_ALL_PLAYER_OPTIONS) ) + { + // apply the game default mods, but not the Profile saved mods + GAMESTATE->m_pPlayerState[pn]->ResetToDefaultPlayerOptions( ModsLevel_Preferred ); + + MESSAGEMAN->Broadcast( ssprintf("CancelAllP%i", pn+1) ); + + for( unsigned r=0; r v; + v.push_back( pn ); + int iOldFocus = m_pRows[r]->GetChoiceInRowWithFocus( pn ); + this->ImportOptions( r, v ); + m_pRows[r]->AfterImportOptions( pn ); + this->UpdateDisqualified( r, pn ); + m_pRows[r]->SetChoiceInRowWithFocus( pn, iOldFocus ); + } + bHandled = true; + } + + bHandled = ScreenOptionsMaster::Input( input ) || bHandled; + + // UGLY: Update m_Disqualified whenever Start is pressed + if( GAMESTATE->IsHumanPlayer(pn) && input.MenuI == GAME_BUTTON_START ) + { + int row = m_iCurrentRow[pn]; + UpdateDisqualified( row, pn ); + } + return bHandled; +} + +void ScreenPlayerOptions::HandleScreenMessage( const ScreenMessage SM ) +{ + if( SM == SM_BeginFadingOut && m_bAskOptionsMessage ) // user accepts the page of options + { + m_bAcceptedChoices = true; + + // show "hold START for options" + this->PlayCommand( "AskForGoToOptions" ); + } + + ScreenOptionsMaster::HandleScreenMessage( SM ); +} + +void ScreenPlayerOptions::UpdateDisqualified( int row, PlayerNumber pn ) +{ + ASSERT( GAMESTATE->IsHumanPlayer(pn) ); + + // save original player options + PlayerOptions poOrig = GAMESTATE->m_pPlayerState[pn]->m_PlayerOptions.GetPreferred(); + + // Find out if the current row when exported causes disqualification. + // Exporting the row will fill GAMESTATE->m_PlayerOptions. + PO_GROUP_CALL( GAMESTATE->m_pPlayerState[pn]->m_PlayerOptions, ModsLevel_Preferred, Init ); + vector v; + v.push_back( pn ); + ExportOptions( row, v ); + bool bRowCausesDisqualified = GAMESTATE->CurrentOptionsDisqualifyPlayer( pn ); + m_bRowCausesDisqualified[pn][row] = bRowCausesDisqualified; + + // Update disqualified graphic + bool disqualified = std::any_of(m_bRowCausesDisqualified[pn].begin(), m_bRowCausesDisqualified[pn].end(), [](bool const &b) { return b; }); + + m_sprDisqualify[pn]->SetVisible( disqualified ); + + // restore previous player options in case the user escapes back after this + GAMESTATE->m_pPlayerState[pn]->m_PlayerOptions.Assign( ModsLevel_Preferred, poOrig ); +} + +// lua start +#include "LuaBinding.h" + +/** @brief Allow Lua to have access to the ScreenPlayerOptions. */ +class LunaScreenPlayerOptions: public Luna +{ +public: + static int GetGoToOptions( T* p, lua_State *L ) { lua_pushboolean( L, p->GetGoToOptions() ); return 1; } + + LunaScreenPlayerOptions() + { + ADD_METHOD( GetGoToOptions ); + } +}; + +LUA_REGISTER_DERIVED_CLASS( ScreenPlayerOptions, ScreenOptions ) +// lua end + +/* + * (c) 2001-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/ScreenPrompt.h b/src/ScreenPrompt.h index 8d93cc6c84..4254354c6a 100644 --- a/src/ScreenPrompt.h +++ b/src/ScreenPrompt.h @@ -1,88 +1,88 @@ -/* ScreenPrompt - Displays a prompt on top of another screen. */ - -#ifndef SCREEN_PROMPT_H -#define SCREEN_PROMPT_H - -#include "ScreenWithMenuElements.h" -#include "BitmapText.h" -#include "RageSound.h" - -enum PromptType -{ - PROMPT_OK, - PROMPT_YES_NO, - PROMPT_YES_NO_CANCEL -}; - -enum PromptAnswer -{ - ANSWER_YES, - ANSWER_NO, - ANSWER_CANCEL, - NUM_PromptAnswer -}; - -class ScreenPrompt : public ScreenWithMenuElements -{ -public: - static void SetPromptSettings( const RString &sText, PromptType type = PROMPT_OK, PromptAnswer defaultAnswer = ANSWER_NO, void(*OnYes)(void*) = NULL, void(*OnNo)(void*) = NULL, void* pCallbackData = NULL ); - static void Prompt( ScreenMessage smSendOnPop, const RString &sText, PromptType type = PROMPT_OK, PromptAnswer defaultAnswer = ANSWER_NO, void(*OnYes)(void*) = NULL, void(*OnNo)(void*) = NULL, void* pCallbackData = NULL ); - - virtual void Init(); - virtual void BeginScreen(); - virtual bool Input( const InputEventPlus &input ); - - static PromptAnswer s_LastAnswer; - static bool s_bCancelledLast; - - // Lua - //virtual void PushSelf( lua_State *L ); - -protected: - bool CanGoLeft() { return m_Answer > 0; } - bool CanGoRight(); - void Change( int dir ); - bool MenuLeft( const InputEventPlus &input ); - bool MenuRight( const InputEventPlus &input ); - bool MenuBack( const InputEventPlus &input ); - bool MenuStart( const InputEventPlus &input ); - - virtual void End( bool bCancelled ); - void PositionCursor(); - - virtual void TweenOffScreen(); - - BitmapText m_textQuestion; - AutoActor m_sprCursor; - BitmapText m_textAnswer[NUM_PromptAnswer]; - PromptAnswer m_Answer; - - RageSound m_sndChange; -}; - -#endif - -/* - * (c) 2001-2004 Chris Danford - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +/* ScreenPrompt - Displays a prompt on top of another screen. */ + +#ifndef SCREEN_PROMPT_H +#define SCREEN_PROMPT_H + +#include "ScreenWithMenuElements.h" +#include "BitmapText.h" +#include "RageSound.h" + +enum PromptType +{ + PROMPT_OK, + PROMPT_YES_NO, + PROMPT_YES_NO_CANCEL +}; + +enum PromptAnswer +{ + ANSWER_YES, + ANSWER_NO, + ANSWER_CANCEL, + NUM_PromptAnswer +}; + +class ScreenPrompt : public ScreenWithMenuElements +{ +public: + static void SetPromptSettings( const RString &sText, PromptType type = PROMPT_OK, PromptAnswer defaultAnswer = ANSWER_NO, void(*OnYes)(void*) = nullptr, void(*OnNo)(void*) = nullptr, void* pCallbackData = nullptr ); + static void Prompt( ScreenMessage smSendOnPop, const RString &sText, PromptType type = PROMPT_OK, PromptAnswer defaultAnswer = ANSWER_NO, void(*OnYes)(void*) = nullptr, void(*OnNo)(void*) = nullptr, void* pCallbackData = nullptr ); + + virtual void Init(); + virtual void BeginScreen(); + virtual bool Input( const InputEventPlus &input ); + + static PromptAnswer s_LastAnswer; + static bool s_bCancelledLast; + + // Lua + //virtual void PushSelf( lua_State *L ); + +protected: + bool CanGoLeft() { return m_Answer > 0; } + bool CanGoRight(); + void Change( int dir ); + bool MenuLeft( const InputEventPlus &input ); + bool MenuRight( const InputEventPlus &input ); + bool MenuBack( const InputEventPlus &input ); + bool MenuStart( const InputEventPlus &input ); + + virtual void End( bool bCancelled ); + void PositionCursor(); + + virtual void TweenOffScreen(); + + BitmapText m_textQuestion; + AutoActor m_sprCursor; + BitmapText m_textAnswer[NUM_PromptAnswer]; + PromptAnswer m_Answer; + + RageSound m_sndChange; +}; + +#endif + +/* + * (c) 2001-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/ScreenRanking.cpp b/src/ScreenRanking.cpp index 3b78fbf86d..67fb3cd3b6 100644 --- a/src/ScreenRanking.cpp +++ b/src/ScreenRanking.cpp @@ -111,11 +111,11 @@ void ScreenRanking::Init() StepsType st = STEPS_TYPES_TO_SHOW.GetValue()[i]; pts.aTypes.push_back( make_pair(Difficulty_Invalid, st) ); pts.pCourse = SONGMAN->GetCourseFromPath( asCoursePaths[c] ); - if( pts.pCourse == NULL ) + if( pts.pCourse == nullptr ) continue; pts.pTrail = pts.pCourse->GetTrail( st ); - if( pts.pTrail == NULL ) + if( pts.pTrail == nullptr ) continue; m_vPagesToShow.push_back( pts ); diff --git a/src/ScreenRanking.h b/src/ScreenRanking.h index 628fc410af..85fab7fdf8 100644 --- a/src/ScreenRanking.h +++ b/src/ScreenRanking.h @@ -35,8 +35,8 @@ protected: { PageToShow() { - pCourse = NULL; - pTrail = NULL; + pCourse = nullptr; + pTrail = nullptr; } int colorIndex; diff --git a/src/ScreenSMOnlineLogin.cpp b/src/ScreenSMOnlineLogin.cpp index 248b9f4066..f69c91f509 100644 --- a/src/ScreenSMOnlineLogin.cpp +++ b/src/ScreenSMOnlineLogin.cpp @@ -136,7 +136,7 @@ void ScreenSMOnlineLogin::HandleScreenMessage(const ScreenMessage SM) m_iPlayer++; if( GAMESTATE->IsPlayerEnabled((PlayerNumber) m_iPlayer) && m_iPlayer < NUM_PLAYERS ) { - ScreenTextEntry::Password(SM_PasswordDone, sLoginQuestion, NULL ); + ScreenTextEntry::Password(SM_PasswordDone, sLoginQuestion, nullptr ); } else { @@ -147,7 +147,7 @@ void ScreenSMOnlineLogin::HandleScreenMessage(const ScreenMessage SM) else { RString Response = NSMAN->m_SMOnlinePacket.ReadNT(); - ScreenTextEntry::Password( SM_PasswordDone, Response + "\n\n" + sLoginQuestion, NULL ); + ScreenTextEntry::Password( SM_PasswordDone, Response + "\n\n" + sLoginQuestion, nullptr ); } } } @@ -177,7 +177,7 @@ void ScreenSMOnlineLogin::HandleScreenMessage(const ScreenMessage SM) while(!GAMESTATE->IsPlayerEnabled((PlayerNumber) m_iPlayer)) ++m_iPlayer; sLoginQuestion = YOU_ARE_LOGGING_ON_AS.GetValue() + "\n" + GAMESTATE->GetPlayerDisplayName((PlayerNumber) m_iPlayer) + "\n" + ENTER_YOUR_PASSWORD.GetValue(); - ScreenTextEntry::Password(SM_PasswordDone, sLoginQuestion, NULL ); + ScreenTextEntry::Password(SM_PasswordDone, sLoginQuestion, nullptr ); } return; } diff --git a/src/ScreenSaveSync.cpp b/src/ScreenSaveSync.cpp index a8929f949b..d829a52f4b 100644 --- a/src/ScreenSaveSync.cpp +++ b/src/ScreenSaveSync.cpp @@ -60,7 +60,7 @@ void ScreenSaveSync::Init() ANSWER_YES, SaveSyncChanges, RevertSyncChanges, - NULL ); + nullptr ); } void ScreenSaveSync::PromptSaveSync( ScreenMessage sm ) @@ -72,7 +72,7 @@ void ScreenSaveSync::PromptSaveSync( ScreenMessage sm ) ANSWER_YES, SaveSyncChanges, RevertSyncChanges, - NULL ); + nullptr ); } diff --git a/src/ScreenSelectLanguage.cpp b/src/ScreenSelectLanguage.cpp index 8b3000c8d4..118be9e206 100644 --- a/src/ScreenSelectLanguage.cpp +++ b/src/ScreenSelectLanguage.cpp @@ -13,18 +13,19 @@ void ScreenSelectLanguage::Init() THEME->GetLanguages( vs ); SortRStringArray( vs, true ); - FOREACH_CONST( RString, vs, s ) + int index = 0; + for (RString const &s : vs) { - const LanguageInfo *pLI = GetLanguageInfo( *s ); + const LanguageInfo *pLI = GetLanguageInfo( s ); GameCommand gc; - gc.m_iIndex = s - vs.begin(); - gc.m_sName = *s; + gc.m_iIndex = index++; + gc.m_sName = s; gc.m_bInvalid = false; if( pLI ) gc.m_sText = THEME->GetString("NativeLanguageNames", pLI->szEnglishName); else - gc.m_sText = *s; + gc.m_sText = s; m_aGameCommands.push_back( gc ); } diff --git a/src/ScreenSelectMaster.cpp b/src/ScreenSelectMaster.cpp index 5827ab6e56..ea977ee58f 100644 --- a/src/ScreenSelectMaster.cpp +++ b/src/ScreenSelectMaster.cpp @@ -10,7 +10,6 @@ #include "ActorUtil.h" #include "RageLog.h" #include -#include "Foreach.h" #include "InputEventPlus.h" static const char *MenuDirNames[] = { @@ -88,21 +87,21 @@ void ScreenSelectMaster::Init() // init cursor if( SHOW_CURSOR ) { - FOREACH( PlayerNumber, vpns, p ) + for (PlayerNumber const &p : vpns) { - RString sElement = "Cursor" + PLAYER_APPEND_NO_SPACE(*p); - m_sprCursor[*p].Load( THEME->GetPathG(m_sName,sElement) ); + RString sElement = "Cursor" + PLAYER_APPEND_NO_SPACE(p); + m_sprCursor[p].Load( THEME->GetPathG(m_sName,sElement) ); sElement.Replace( " ", "" ); - m_sprCursor[*p]->SetName( sElement ); - this->AddChild( m_sprCursor[*p] ); - LOAD_ALL_COMMANDS( m_sprCursor[*p] ); + m_sprCursor[p]->SetName( sElement ); + this->AddChild( m_sprCursor[p] ); + LOAD_ALL_COMMANDS( m_sprCursor[p] ); } } // Resize vectors depending on how many choices there are m_vsprIcon.resize( m_aGameCommands.size() ); - FOREACH( PlayerNumber, vpns, p ) - m_vsprScroll[*p].resize( m_aGameCommands.size() ); + for (PlayerNumber const &p : vpns) + m_vsprScroll[p].resize( m_aGameCommands.size() ); vector positions; bool positions_set_by_lua= false; @@ -210,21 +209,21 @@ void ScreenSelectMaster::Init() // init scroll if( SHOW_SCROLLER ) { - FOREACH( PlayerNumber, vpns, p ) + for (PlayerNumber const &p : vpns) { vector vs; vs.push_back( "Scroll" ); if( PER_CHOICE_SCROLL_ELEMENT ) vs.push_back( "Choice" + mc.m_sName ); if( !SHARED_SELECTION ) - vs.push_back( PLAYER_APPEND_NO_SPACE(*p) ); + vs.push_back( PLAYER_APPEND_NO_SPACE(p) ); RString sElement = join( " ", vs ); - m_vsprScroll[*p][c].Load( THEME->GetPathG(m_sName,sElement) ); + m_vsprScroll[p][c].Load( THEME->GetPathG(m_sName,sElement) ); RString sName = "Scroll" "Choice" + mc.m_sName; if( !SHARED_SELECTION ) - sName += PLAYER_APPEND_NO_SPACE(*p); - m_vsprScroll[*p][c]->SetName( sName ); - m_Scroller[*p].AddChild( m_vsprScroll[*p][c] ); + sName += PLAYER_APPEND_NO_SPACE(p); + m_vsprScroll[p][c]->SetName( sName ); + m_Scroller[p].AddChild( m_vsprScroll[p][c] ); } } @@ -233,17 +232,17 @@ void ScreenSelectMaster::Init() // init scroll if( SHOW_SCROLLER ) { - FOREACH( PlayerNumber, vpns, p ) + for (PlayerNumber const &p : vpns) { - m_Scroller[*p].SetLoop( LOOP_SCROLLER ); - m_Scroller[*p].SetNumItemsToDraw( SCROLLER_NUM_ITEMS_TO_DRAW ); - m_Scroller[*p].Load2(); - m_Scroller[*p].SetTransformFromReference( SCROLLER_TRANSFORM ); - m_Scroller[*p].SetSecondsPerItem( SCROLLER_SECONDS_PER_ITEM ); - m_Scroller[*p].SetNumSubdivisions( SCROLLER_SUBDIVISIONS ); - m_Scroller[*p].SetName( "Scroller"+PLAYER_APPEND_NO_SPACE(*p) ); - LOAD_ALL_COMMANDS_AND_SET_XY( m_Scroller[*p] ); - this->AddChild( &m_Scroller[*p] ); + m_Scroller[p].SetLoop( LOOP_SCROLLER ); + m_Scroller[p].SetNumItemsToDraw( SCROLLER_NUM_ITEMS_TO_DRAW ); + m_Scroller[p].Load2(); + m_Scroller[p].SetTransformFromReference( SCROLLER_TRANSFORM ); + m_Scroller[p].SetSecondsPerItem( SCROLLER_SECONDS_PER_ITEM ); + m_Scroller[p].SetNumSubdivisions( SCROLLER_SUBDIVISIONS ); + m_Scroller[p].SetName( "Scroller"+PLAYER_APPEND_NO_SPACE(p) ); + LOAD_ALL_COMMANDS_AND_SET_XY( m_Scroller[p] ); + this->AddChild( &m_Scroller[p] ); } } @@ -383,16 +382,16 @@ void ScreenSelectMaster::HandleScreenMessage( const ScreenMessage SM ) if( SHOW_CURSOR ) { - FOREACH( PlayerNumber, vpns, p ) - m_sprCursor[*p]->HandleMessage( msg ); + for (PlayerNumber const &p : vpns) + m_sprCursor[p]->HandleMessage( msg ); } if( SHOW_SCROLLER ) { - FOREACH( PlayerNumber, vpns, p ) + for (PlayerNumber const &p : vpns) { - int iChoice = m_iChoice[*p]; - m_vsprScroll[*p][iChoice]->HandleMessage( msg ); + int iChoice = m_iChoice[p]; + m_vsprScroll[p][iChoice]->HandleMessage( msg ); } } MESSAGEMAN->Broadcast(msg); @@ -459,23 +458,23 @@ void ScreenSelectMaster::UpdateSelectableChoices() m_vsprIcon[c]->PlayCommand(command); } - FOREACH( PlayerNumber, vpns, p ) + for ( PlayerNumber &p : vpns) { - if(disabled && m_iChoice[*p] == c) + if(disabled && m_iChoice[p] == c) { - on_unplayable[*p]= true; + on_unplayable[p]= true; } - if( m_vsprScroll[*p][c].IsLoaded() ) + if( m_vsprScroll[p][c].IsLoaded() ) { - m_vsprScroll[*p][c]->PlayCommand(command); + m_vsprScroll[p][c]->PlayCommand(command); } } } - FOREACH(PlayerNumber, vpns, pn) + for (PlayerNumber &pn : vpns) { - if(on_unplayable[*pn] && first_playable != -1) + if(on_unplayable[pn] && first_playable != -1) { - ChangeSelection(*pn, first_playable < m_iChoice[*pn] ? MenuDir_Left : + ChangeSelection(pn, first_playable < m_iChoice[pn] ? MenuDir_Left : MenuDir_Right, first_playable); } } @@ -682,18 +681,18 @@ bool ScreenSelectMaster::ChangePage( int iNewChoice ) msg.SetParam( "NewPageIndex", (int)newPage ); MESSAGEMAN->Broadcast( msg ); - FOREACH( PlayerNumber, vpns, p ) + for (PlayerNumber const &p : vpns) { - if( GAMESTATE->IsHumanPlayer(*p) || SHARED_SELECTION ) + if( GAMESTATE->IsHumanPlayer(p) || SHARED_SELECTION ) { if( SHOW_CURSOR ) { - m_sprCursor[*p]->HandleMessage( msg ); - m_sprCursor[*p]->SetXY( GetCursorX(*p), GetCursorY(*p) ); + m_sprCursor[p]->HandleMessage( msg ); + m_sprCursor[p]->SetXY( GetCursorX(p), GetCursorY(p) ); } if( SHOW_SCROLLER ) - m_vsprScroll[*p][m_iChoice[*p]]->HandleMessage( msg ); + m_vsprScroll[p][m_iChoice[p]]->HandleMessage( msg ); } } @@ -736,10 +735,10 @@ bool ScreenSelectMaster::ChangeSelection( PlayerNumber pn, MenuDir dir, int iNew vpns.push_back( pn ); } - FOREACH( PlayerNumber, vpns, p ) + for (PlayerNumber const &p : vpns) { - const int iOldChoice = m_iChoice[*p]; - m_iChoice[*p] = iNewChoice; + const int iOldChoice = m_iChoice[p]; + m_iChoice[p] = iNewChoice; if( SHOW_ICON ) { @@ -750,7 +749,7 @@ bool ScreenSelectMaster::ChangeSelection( PlayerNumber pn, MenuDir dir, int iNew bool bNewAlreadyHadFocus = false; FOREACH_HumanPlayer( p2 ) { - if( p2 == *p ) + if( p2 == p ) continue; bOldStillHasFocus |= m_iChoice[p2] == iOldChoice; bNewAlreadyHadFocus |= m_iChoice[p2] == iNewChoice; @@ -785,20 +784,20 @@ bool ScreenSelectMaster::ChangeSelection( PlayerNumber pn, MenuDir dir, int iNew if( SHOW_CURSOR ) { - if( GAMESTATE->IsHumanPlayer(*p) ) + if( GAMESTATE->IsHumanPlayer(p) ) { - PlayerNumber ep = *p; + PlayerNumber ep = p; if( SHARED_SELECTION ) ep = PLAYER_1; m_sprCursor[ep]->PlayCommand( "Change" ); - m_sprCursor[ep]->SetXY( GetCursorX(*p), GetCursorY(*p) ); + m_sprCursor[ep]->SetXY( GetCursorX(p), GetCursorY(p) ); } } if( SHOW_SCROLLER ) { - ActorScroller &scroller = (SHARED_SELECTION || page != PAGE_1 ? m_Scroller[0] : m_Scroller[*p]); - vector &vScroll = (SHARED_SELECTION || page != PAGE_1 ? m_vsprScroll[0] : m_vsprScroll[*p]); + ActorScroller &scroller = (SHARED_SELECTION || page != PAGE_1 ? m_Scroller[0] : m_Scroller[p]); + vector &vScroll = (SHARED_SELECTION || page != PAGE_1 ? m_vsprScroll[0] : m_vsprScroll[p]); if( WRAP_SCROLLER ) { @@ -891,7 +890,7 @@ float ScreenSelectMaster::DoMenuStart( PlayerNumber pn ) } if( SHOW_CURSOR ) { - if(m_sprCursor[pn] != NULL) + if(m_sprCursor[pn] != nullptr) { m_sprCursor[pn]->PlayCommand( "Choose" ); fSecs = max( fSecs, m_sprCursor[pn]->GetTweenTimeLeft() ); @@ -1023,27 +1022,27 @@ void ScreenSelectMaster::TweenOnScreen() if( SHOW_SCROLLER ) { - FOREACH( PlayerNumber, vpns, p ) + for (PlayerNumber const &p : vpns) { // Play Gain/LoseFocus before playing the on command. // Gain/Lose will often stop tweening, which ruins the OnCommand. for( unsigned c=0; cPlayCommand( int(c) == m_iChoice[*p]? "GainFocus":"LoseFocus" ); - m_vsprScroll[*p][c]->FinishTweening(); + m_vsprScroll[p][c]->PlayCommand( int(c) == m_iChoice[p]? "GainFocus":"LoseFocus" ); + m_vsprScroll[p][c]->FinishTweening(); } - m_Scroller[*p].SetCurrentAndDestinationItem( (float)m_iChoice[*p] ); + m_Scroller[p].SetCurrentAndDestinationItem( (float)m_iChoice[p] ); } } // Need to SetXY of Cursor after Icons since it depends on the Icons' positions. if( SHOW_CURSOR ) { - FOREACH( PlayerNumber, vpns, p ) + for (PlayerNumber const &p : vpns) { - if( GAMESTATE->IsHumanPlayer(*p) || SHARED_SELECTION ) - m_sprCursor[*p]->SetXY( GetCursorX(*p), GetCursorY(*p) ); + if( GAMESTATE->IsHumanPlayer(p) || SHARED_SELECTION ) + m_sprCursor[p]->SetXY( GetCursorX(p), GetCursorY(p) ); } } @@ -1062,20 +1061,17 @@ void ScreenSelectMaster::TweenOffScreen() if( GetPage(c) != GetCurrentPage() ) continue; // skip - bool bSelectedByEitherPlayer = false; - FOREACH( PlayerNumber, vpns, p ) - { - if( m_iChoice[*p] == (int)c ) - bSelectedByEitherPlayer = true; - } + bool bSelectedByEitherPlayer = std::any_of(vpns.begin(), vpns.end(), [&](PlayerNumber const &p) { + return m_iChoice[p] == static_cast(c); + }); if( SHOW_ICON ) m_vsprIcon[c]->PlayCommand( bSelectedByEitherPlayer? "OffFocused":"OffUnfocused" ); if( SHOW_SCROLLER ) { - FOREACH( PlayerNumber, vpns, p ) - m_vsprScroll[*p][c]->PlayCommand( bSelectedByEitherPlayer? "OffFocused":"OffUnfocused" ); + for (PlayerNumber const &p : vpns) + m_vsprScroll[p][c]->PlayCommand( bSelectedByEitherPlayer? "OffFocused":"OffUnfocused" ); } } } diff --git a/src/ScreenSelectMusic.cpp b/src/ScreenSelectMusic.cpp index bcc4b9056e..9d536aa4e5 100644 --- a/src/ScreenSelectMusic.cpp +++ b/src/ScreenSelectMusic.cpp @@ -21,7 +21,6 @@ #include "MenuTimer.h" #include "StatsManager.h" #include "StepsUtil.h" -#include "Foreach.h" #include "Style.h" #include "PlayerState.h" #include "CommonMetrics.h" @@ -235,14 +234,14 @@ void ScreenSelectMusic::BeginScreen() GAMESTATE->SetCompatibleStylesForPlayers(); } - if( GAMESTATE->GetCurrentStyle(PLAYER_INVALID) == NULL ) + if( GAMESTATE->GetCurrentStyle(PLAYER_INVALID) == nullptr ) { LuaHelpers::ReportScriptError("The Style has not been set. A theme must set the Style before loading ScreenSelectMusic."); // Instead of crashing, set the first compatible style. vector vst; GAMEMAN->GetStepsTypesForGame( GAMESTATE->m_pCurGame, vst ); const Style *pStyle = GAMEMAN->GetFirstCompatibleStyle( GAMESTATE->m_pCurGame, GAMESTATE->GetNumSidesJoined(), vst[0] ); - if(pStyle == NULL) + if(pStyle == nullptr) { FAIL_M( ssprintf("No compatible styles for %s with %d player%s.", GAMESTATE->m_pCurGame->m_szName, @@ -1098,9 +1097,9 @@ void ScreenSelectMusic::HandleMessage( const Message &msg ) // 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[master_pn].SetWithoutBroadcast( NULL ); + GAMESTATE->m_pCurSteps[master_pn].SetWithoutBroadcast(nullptr); FOREACH_ENUM( PlayerNumber, p ) - GAMESTATE->m_pCurSteps[p].SetWithoutBroadcast( NULL ); + GAMESTATE->m_pCurSteps[p].SetWithoutBroadcast(nullptr); /* If a course is selected, it may no longer be playable. * Let MusicWheel know about the late join. */ @@ -1123,12 +1122,12 @@ void ScreenSelectMusic::HandleMessage( const Message &msg ) m_iSelection[pn] = iSel; if( GAMESTATE->IsCourseMode() ) { - Trail* pTrail = m_vpTrails.empty()? NULL: m_vpTrails[m_iSelection[pn]]; + Trail* pTrail = m_vpTrails.empty()? nullptr: m_vpTrails[m_iSelection[pn]]; GAMESTATE->m_pCurTrail[pn].Set( pTrail ); } else { - Steps* pSteps = m_vpSteps.empty()? NULL: m_vpSteps[m_iSelection[pn]]; + Steps* pSteps = m_vpSteps.empty()? nullptr: m_vpSteps[m_iSelection[pn]]; // handle changing rave difficulty on join if(GAMESTATE->m_PlayMode == PLAY_MODE_RAVE) @@ -1155,7 +1154,7 @@ void ScreenSelectMusic::HandleScreenMessage( const ScreenMessage SM ) m_MenuTimer->SetSeconds( ROULETTE_TIMER_SECONDS ); m_MenuTimer->Start(); } - else if( DO_ROULETTE_ON_MENU_TIMER && m_MusicWheel.GetSelectedSong() == NULL && m_MusicWheel.GetSelectedCourse() == NULL ) + else if( DO_ROULETTE_ON_MENU_TIMER && m_MusicWheel.GetSelectedSong() == nullptr && m_MusicWheel.GetSelectedCourse() == nullptr ) { m_MusicWheel.StartRoulette(); m_MenuTimer->SetSeconds( ROULETTE_TIMER_SECONDS ); @@ -1166,7 +1165,7 @@ void ScreenSelectMusic::HandleScreenMessage( const ScreenMessage SM ) // 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 ) + if( m_MusicWheel.GetSelectedSong() == nullptr && m_MusicWheel.GetSelectedCourse() == nullptr ) m_MusicWheel.StartRandom(); MenuStart( InputEventPlus() ); @@ -1250,7 +1249,7 @@ bool ScreenSelectMusic::MenuStart( const InputEventPlus &input ) return false; // a song was selected - if( m_MusicWheel.GetSelectedSong() != NULL ) + if( m_MusicWheel.GetSelectedSong() != nullptr ) { if(TWO_PART_CONFIRMS_ONLY && SAMPLE_MUSIC_PREVIEW_MODE == SampleMusicPreviewMode_StartToPreview) { @@ -1295,12 +1294,12 @@ bool ScreenSelectMusic::MenuStart( const InputEventPlus &input ) if( GAMESTATE->IsCourseMode() ) GAMESTATE->m_PlayMode.Set( PLAY_MODE_REGULAR ); } - else if( m_MusicWheel.GetSelectedCourse() != NULL ) + else if( m_MusicWheel.GetSelectedCourse() != nullptr ) { SOUND->PlayOnceFromAnnouncer( "select course comment general" ); Course *pCourse = m_MusicWheel.GetSelectedCourse(); - ASSERT( pCourse != NULL ); + ASSERT( pCourse != nullptr ); GAMESTATE->m_PlayMode.Set( pCourse->GetPlayMode() ); // apply #LIVES @@ -1573,9 +1572,8 @@ void ScreenSelectMusic::AfterStepsOrTrailChange( const vector &vpn MESSAGEMAN->Broadcast("TwoPartConfirmCanceled"); } - FOREACH_CONST( PlayerNumber, vpns, p ) + for (PlayerNumber const &pn : vpns) { - PlayerNumber pn = *p; ASSERT( GAMESTATE->IsHumanPlayer(pn) ); if( GAMESTATE->m_pCurSong ) @@ -1583,10 +1581,10 @@ void ScreenSelectMusic::AfterStepsOrTrailChange( const vector &vpn CLAMP( m_iSelection[pn], 0, m_vpSteps.size()-1 ); Song* pSong = GAMESTATE->m_pCurSong; - Steps* pSteps = m_vpSteps.empty()? NULL: m_vpSteps[m_iSelection[pn]]; + Steps* pSteps = m_vpSteps.empty()? nullptr: m_vpSteps[m_iSelection[pn]]; GAMESTATE->m_pCurSteps[pn].Set( pSteps ); - GAMESTATE->m_pCurTrail[pn].Set( NULL ); + GAMESTATE->m_pCurTrail[pn].Set(nullptr); int iScore = 0; if( pSteps ) @@ -1602,9 +1600,9 @@ void ScreenSelectMusic::AfterStepsOrTrailChange( const vector &vpn CLAMP( m_iSelection[pn], 0, m_vpTrails.size()-1 ); Course* pCourse = GAMESTATE->m_pCurCourse; - Trail* pTrail = m_vpTrails.empty()? NULL: m_vpTrails[m_iSelection[pn]]; + Trail* pTrail = m_vpTrails.empty()? nullptr: m_vpTrails[m_iSelection[pn]]; - GAMESTATE->m_pCurSteps[pn].Set( NULL ); + GAMESTATE->m_pCurSteps[pn].Set(nullptr); GAMESTATE->m_pCurTrail[pn].Set( pTrail ); int iScore = 0; @@ -1618,7 +1616,7 @@ void ScreenSelectMusic::AfterStepsOrTrailChange( const vector &vpn } else { - // The numbers shouldn't stay if the current selection is NULL. + // The numbers shouldn't stay if the current selection is nullptr. m_textHighScore[pn].SetText( NULL_SCORE_STRING ); } } @@ -1633,12 +1631,11 @@ void ScreenSelectMusic::SwitchToPreferredDifficulty() // 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 = 0; + for (Steps *s : m_vpSteps) { - int i = s - m_vpSteps.begin(); - // If the current steps are listed, use them. - if( GAMESTATE->m_pCurSteps[pn] == *s ) + if( GAMESTATE->m_pCurSteps[pn] == s ) { iSelection = i; break; @@ -1646,10 +1643,10 @@ void ScreenSelectMusic::SwitchToPreferredDifficulty() if( GAMESTATE->m_PreferredDifficulty[pn] != Difficulty_Invalid ) { - int iDifficultyDifference = abs( (*s)->GetDifficulty() - GAMESTATE->m_PreferredDifficulty[pn] ); + int iDifficultyDifference = abs( s->GetDifficulty() - GAMESTATE->m_PreferredDifficulty[pn] ); int iStepsTypeDifference = 0; if( GAMESTATE->m_PreferredStepsType != StepsType_Invalid ) - iStepsTypeDifference = abs( (*s)->m_StepsType - GAMESTATE->m_PreferredStepsType ); + iStepsTypeDifference = abs( s->m_StepsType - GAMESTATE->m_PreferredStepsType ); int iTotalDifference = iStepsTypeDifference * NUM_Difficulty + iDifficultyDifference; if( iCurDifference == -1 || iTotalDifference < iCurDifference ) @@ -1658,6 +1655,7 @@ void ScreenSelectMusic::SwitchToPreferredDifficulty() iCurDifference = iTotalDifference; } } + i += 1; } CLAMP( iSelection, 0, m_vpSteps.size()-1 ); @@ -1670,10 +1668,9 @@ void ScreenSelectMusic::SwitchToPreferredDifficulty() // 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 = 0; + for (Trail *t : m_vpTrails) { - int i = t - m_vpTrails.begin(); - // If the current trail is listed, use it. if( GAMESTATE->m_pCurTrail[pn] == m_vpTrails[i] ) { @@ -1683,8 +1680,8 @@ void ScreenSelectMusic::SwitchToPreferredDifficulty() if( GAMESTATE->m_PreferredCourseDifficulty[pn] != Difficulty_Invalid && GAMESTATE->m_PreferredStepsType != StepsType_Invalid ) { - int iDifficultyDifference = abs( (*t)->m_CourseDifficulty - GAMESTATE->m_PreferredCourseDifficulty[pn] ); - int iStepsTypeDifference = abs( (*t)->m_StepsType - GAMESTATE->m_PreferredStepsType ); + int iDifficultyDifference = abs( t->m_CourseDifficulty - GAMESTATE->m_PreferredCourseDifficulty[pn] ); + int iStepsTypeDifference = abs( t->m_StepsType - GAMESTATE->m_PreferredStepsType ); int iTotalDifference = iStepsTypeDifference * NUM_CourseDifficulty + iDifficultyDifference; if( iCurDifference == -1 || iTotalDifference < iCurDifference ) @@ -1693,6 +1690,7 @@ void ScreenSelectMusic::SwitchToPreferredDifficulty() iCurDifference = iTotalDifference; } } + i += 1; } CLAMP( iSelection, 0, m_vpTrails.size()-1 ); @@ -1732,7 +1730,7 @@ void ScreenSelectMusic::AfterMusicChange() { m_sSampleMusicToPlay = ""; } - m_pSampleMusicTimingData = NULL; + m_pSampleMusicTimingData = nullptr; g_sCDTitlePath = ""; g_sBannerPath = ""; g_bWantFallbackCdTitle = false; @@ -1885,11 +1883,11 @@ void ScreenSelectMusic::AfterMusicChange() case WheelItemDataType_Course: { const Course *lCourse = m_MusicWheel.GetSelectedCourse(); - const Style *pStyle = NULL; + const Style *pStyle = nullptr; if(CommonMetrics::AUTO_SET_STYLE) { pStyle = pCourse->GetCourseStyle(GAMESTATE->m_pCurGame, GAMESTATE->GetNumPlayersEnabled()); - if(pStyle == NULL) + if(pStyle == nullptr) { lCourse->GetAllTrails(m_vpTrails); vector::iterator tra= m_vpTrails.begin(); @@ -1898,7 +1896,7 @@ void ScreenSelectMusic::AfterMusicChange() while(tra != m_vpTrails.end()) { if(GAMEMAN->GetFirstCompatibleStyle(cur_game, num_players, - (*tra)->m_StepsType) == NULL) + (*tra)->m_StepsType) == nullptr) { tra= m_vpTrails.erase(tra); } @@ -2019,7 +2017,7 @@ void ScreenSelectMusic::OnConfirmSongDeletion() // delete the song directory from disk FILEMAN->DeleteRecursive(deleteDir); - m_pSongAwaitingDeletionConfirmation = NULL; + m_pSongAwaitingDeletionConfirmation = nullptr; } bool ScreenSelectMusic::can_open_options_list(PlayerNumber pn) diff --git a/src/ScreenServiceAction.cpp b/src/ScreenServiceAction.cpp index 71bc884c04..de95df3974 100644 --- a/src/ScreenServiceAction.cpp +++ b/src/ScreenServiceAction.cpp @@ -37,26 +37,19 @@ RString ClearMachineStats() static LocalizedString MACHINE_EDITS_CLEARED( "ScreenServiceAction", "%d edits cleared, %d errors." ); static RString ClearMachineEdits() { - int iNumAttempted = 0; - int iNumSuccessful = 0; - vector vsEditFiles; GetDirListing( PROFILEMAN->GetProfileDir(ProfileSlot_Machine)+EDIT_STEPS_SUBDIR+"*.edit", vsEditFiles, false, true ); GetDirListing( PROFILEMAN->GetProfileDir(ProfileSlot_Machine)+EDIT_COURSES_SUBDIR+"*.crs", vsEditFiles, false, true ); - FOREACH_CONST( RString, vsEditFiles, i ) - { - iNumAttempted++; - bool bSuccess = FILEMAN->Remove( *i ); - if( bSuccess ) - iNumSuccessful++; - } + + int editCount = vsEditFiles.size(); + int removedCount = std::count_if(vsEditFiles.begin(), vsEditFiles.end(), [](RString const &i) { return FILEMAN->Remove(i); }); // reload the machine profile PROFILEMAN->SaveMachineProfile(); PROFILEMAN->LoadMachineProfile(); - int iNumErrors = iNumAttempted-iNumSuccessful; - return ssprintf(MACHINE_EDITS_CLEARED.GetValue(),iNumSuccessful,iNumErrors); + int errorCount = editCount - removedCount; + return ssprintf(MACHINE_EDITS_CLEARED.GetValue(), editCount, errorCount); } static PlayerNumber GetFirstReadyMemoryCard() @@ -82,9 +75,6 @@ static RString ClearMemoryCardEdits() if( pn == PLAYER_INVALID ) return MEMORY_CARD_EDITS_NOT_CLEARED.GetValue(); - int iNumAttempted = 0; - int iNumSuccessful = 0; - if( !MEMCARDMAN->IsMounted(pn) ) MEMCARDMAN->MountCard(pn); @@ -92,17 +82,12 @@ static RString ClearMemoryCardEdits() vector vsEditFiles; GetDirListing( sDir+EDIT_STEPS_SUBDIR+"*.edit", vsEditFiles, false, true ); GetDirListing( sDir+EDIT_COURSES_SUBDIR+"*.crs", vsEditFiles, false, true ); - FOREACH_CONST( RString, vsEditFiles, i ) - { - iNumAttempted++; - bool bSuccess = FILEMAN->Remove( *i ); - if( bSuccess ) - iNumSuccessful++; - } + int editCount = vsEditFiles.size(); + int removedCount = std::count_if(vsEditFiles.begin(), vsEditFiles.end(), [](RString const &i) { return FILEMAN->Remove(i); }); MEMCARDMAN->UnmountCard(pn); - return ssprintf(EDITS_CLEARED.GetValue(),iNumSuccessful,iNumAttempted-iNumSuccessful); + return ssprintf(EDITS_CLEARED.GetValue(), editCount, editCount - removedCount); } @@ -186,11 +171,11 @@ static void CopyEdits( const RString &sFromProfileDir, const RString &sToProfile vector vsFiles; GetDirListing( sFromDir+"*.edit", vsFiles, false, false ); - FOREACH_CONST( RString, vsFiles, i ) + for (RString const &i : vsFiles) { - if( DoesFileExist(sToDir+*i) ) + if( DoesFileExist(sToDir + i) ) iNumOverwritten++; - bool bSuccess = FileCopy( sFromDir+*i, sToDir+*i ); + bool bSuccess = FileCopy( sFromDir + i, sToDir + i ); if( bSuccess ) iNumSucceeded++; else @@ -198,7 +183,7 @@ static void CopyEdits( const RString &sFromProfileDir, const RString &sToProfile // Test whether the song we need for this edit is present and ignore this edit if not present. SSCLoader loaderSSC; - if( !loaderSSC.LoadEditFromFile( sFromDir+*i, ProfileSlot_Machine, false ) ) + if( !loaderSSC.LoadEditFromFile( sFromDir + i, ProfileSlot_Machine, false ) ) { iNumIgnored++; continue; @@ -214,11 +199,11 @@ static void CopyEdits( const RString &sFromProfileDir, const RString &sToProfile vector vsFiles; GetDirListing( sFromDir+"*.crs", vsFiles, false, false ); - FOREACH_CONST( RString, vsFiles, i ) + for (RString const &i : vsFiles) { - if( DoesFileExist(sToDir+*i) ) + if( DoesFileExist(sToDir + i) ) iNumOverwritten++; - bool bSuccess = FileCopy( sFromDir+*i, sToDir+*i ); + bool bSuccess = FileCopy( sFromDir + i, sToDir + i ); if( bSuccess ) iNumSucceeded++; else @@ -375,12 +360,12 @@ static RString CopyEditsMemoryCardToMachine() vector vs; vs.push_back( ssprintf( COPIED_FROM_CARD.GetValue(), pn+1 ) ); - FOREACH_CONST( RString, vsSubDirs, sSubDir ) + for (RString const &sSubDir : vsSubDirs) { - RString sFromDir = MEM_CARD_MOUNT_POINT[pn] + (RString)(*sSubDir) + "/"; + RString sFromDir = MEM_CARD_MOUNT_POINT[pn] + sSubDir + "/"; RString sToDir = PROFILEMAN->GetProfileDir(ProfileSlot_Machine); - RString s = CopyEdits( sFromDir, sToDir, *sSubDir ); + RString s = CopyEdits( sFromDir, sToDir, sSubDir ); vs.push_back( s ); } @@ -410,22 +395,22 @@ void ScreenServiceAction::BeginScreen() split( sActions, ",", vsActions ); vector vsResults; - FOREACH( RString, vsActions, s ) + for (RString const &s : vsActions) { - RString (*pfn)() = NULL; + RString (*pfn)() = nullptr; - if( *s == "ClearBookkeepingData" ) pfn = ClearBookkeepingData; - else if( *s == "ClearMachineStats" ) pfn = ClearMachineStats; - else if( *s == "ClearMachineEdits" ) pfn = ClearMachineEdits; - else if( *s == "ClearMemoryCardEdits" ) pfn = ClearMemoryCardEdits; - else if( *s == "TransferStatsMachineToMemoryCard" ) pfn = TransferStatsMachineToMemoryCard; - else if( *s == "TransferStatsMemoryCardToMachine" ) pfn = TransferStatsMemoryCardToMachine; - else if( *s == "CopyEditsMachineToMemoryCard" ) pfn = CopyEditsMachineToMemoryCard; - else if( *s == "CopyEditsMemoryCardToMachine" ) pfn = CopyEditsMemoryCardToMachine; - else if( *s == "SyncEditsMachineToMemoryCard" ) pfn = SyncEditsMachineToMemoryCard; - else if( *s == "ResetPreferences" ) pfn = ResetPreferences; + if( s == "ClearBookkeepingData" ) pfn = ClearBookkeepingData; + else if( s == "ClearMachineStats" ) pfn = ClearMachineStats; + else if( s == "ClearMachineEdits" ) pfn = ClearMachineEdits; + else if( s == "ClearMemoryCardEdits" ) pfn = ClearMemoryCardEdits; + else if( s == "TransferStatsMachineToMemoryCard" ) pfn = TransferStatsMachineToMemoryCard; + else if( s == "TransferStatsMemoryCardToMachine" ) pfn = TransferStatsMemoryCardToMachine; + else if( s == "CopyEditsMachineToMemoryCard" ) pfn = CopyEditsMachineToMemoryCard; + else if( s == "CopyEditsMemoryCardToMachine" ) pfn = CopyEditsMemoryCardToMachine; + else if( s == "SyncEditsMachineToMemoryCard" ) pfn = SyncEditsMachineToMemoryCard; + else if( s == "ResetPreferences" ) pfn = ResetPreferences; - ASSERT_M( pfn != NULL, *s ); + ASSERT_M( pfn != nullptr, s ); RString sResult = pfn(); vsResults.push_back( sResult ); diff --git a/src/ScreenSetTime.cpp b/src/ScreenSetTime.cpp index 9c0980fb33..4bb5ff027e 100644 --- a/src/ScreenSetTime.cpp +++ b/src/ScreenSetTime.cpp @@ -81,7 +81,7 @@ void ScreenSetTime::Update( float fDelta ) { Screen::Update( fDelta ); - time_t iNow = time(NULL); + time_t iNow = time(nullptr); iNow += m_TimeOffset; tm now; @@ -113,7 +113,7 @@ bool ScreenSetTime::Input( const InputEventPlus &input ) void ScreenSetTime::ChangeValue( int iDirection ) { - time_t iNow = time(NULL); + time_t iNow = time(nullptr); time_t iAdjusted = iNow + m_TimeOffset; tm adjusted; @@ -194,7 +194,7 @@ bool ScreenSetTime::MenuStart( const InputEventPlus &input ) else if( m_Selection == NUM_SetTimeSelection -1 ) // last row { /* Save the new time. */ - time_t iNow = time(NULL); + time_t iNow = time(nullptr); time_t iAdjusted = iNow + m_TimeOffset; tm adjusted; diff --git a/src/ScreenStatsOverlay.h b/src/ScreenStatsOverlay.h index 59ac00f9f6..a2a72b6e44 100644 --- a/src/ScreenStatsOverlay.h +++ b/src/ScreenStatsOverlay.h @@ -6,6 +6,7 @@ #include "Screen.h" #include "BitmapText.h" #include "Quad.h" +#include const int NUM_SKIPS_TO_SHOW = 5; @@ -22,7 +23,7 @@ private: BitmapText m_textStats; Quad m_quadSkipBackground; - BitmapText m_textSkips[NUM_SKIPS_TO_SHOW]; + std::array m_textSkips; RageTimer m_timerSkip; int m_LastSkip; diff --git a/src/ScreenSyncOverlay.cpp b/src/ScreenSyncOverlay.cpp index 74e7830893..8c268379ba 100644 --- a/src/ScreenSyncOverlay.cpp +++ b/src/ScreenSyncOverlay.cpp @@ -86,7 +86,7 @@ void ScreenSyncOverlay::UpdateText() FAIL_M(ssprintf("Invalid autosync type: %i", type)); } - if( GAMESTATE->m_pCurSong != NULL && !GAMESTATE->IsCourseMode() ) // sync controls available + if( GAMESTATE->m_pCurSong != nullptr && !GAMESTATE->IsCourseMode() ) // sync controls available { AdjustSync::GetSyncChangeTextGlobal( vs ); AdjustSync::GetSyncChangeTextSong( vs ); @@ -207,15 +207,15 @@ bool ScreenSyncOverlay::Input( const InputEventPlus &input ) } default: break; } - if( GAMESTATE->m_pCurSong != NULL ) + if( GAMESTATE->m_pCurSong != nullptr ) { TimingData &sTiming = GAMESTATE->m_pCurSong->m_SongTiming; BPMSegment * seg = sTiming.GetBPMSegmentAtBeat( GAMESTATE->m_Position.m_fSongBeat ); seg->SetBPS( seg->GetBPS() + fDelta ); const vector& vpSteps = GAMESTATE->m_pCurSong->GetAllSteps(); - FOREACH( Steps*, const_cast&>(vpSteps), s ) + for (Steps *s : vpSteps) { - TimingData &pTiming = (*s)->m_Timing; + TimingData &pTiming = s->m_Timing; // Empty means it inherits song timing, // which has already been updated. if( pTiming.empty() ) @@ -259,17 +259,17 @@ bool ScreenSyncOverlay::Input( const InputEventPlus &input ) case ChangeSongOffset: { - if( GAMESTATE->m_pCurSong != NULL ) + if( GAMESTATE->m_pCurSong != nullptr ) { GAMESTATE->m_pCurSong->m_SongTiming.m_fBeat0OffsetInSeconds += fDelta; const vector& vpSteps = GAMESTATE->m_pCurSong->GetAllSteps(); - FOREACH( Steps*, const_cast&>(vpSteps), s ) + for (Steps *s : vpSteps) { // Empty means it inherits song timing, // which has already been updated. - if( (*s)->m_Timing.empty() ) + if( s->m_Timing.empty() ) continue; - (*s)->m_Timing.m_fBeat0OffsetInSeconds += fDelta; + s->m_Timing.m_fBeat0OffsetInSeconds += fDelta; } } break; diff --git a/src/ScreenSystemLayer.cpp b/src/ScreenSystemLayer.cpp index 5e204e4e80..e47beecbdd 100644 --- a/src/ScreenSystemLayer.cpp +++ b/src/ScreenSystemLayer.cpp @@ -148,7 +148,7 @@ namespace const luaL_Reg ScreenSystemLayerHelpersTable[] = { LIST_METHOD( GetCreditsMessage ), - { NULL, NULL } + { nullptr, nullptr } }; } diff --git a/src/ScreenTestInput.cpp b/src/ScreenTestInput.cpp index 6105872250..2b03a22976 100644 --- a/src/ScreenTestInput.cpp +++ b/src/ScreenTestInput.cpp @@ -1,158 +1,158 @@ -#include "global.h" -#include "ScreenTestInput.h" -#include "ScreenManager.h" -#include "RageLog.h" -#include "InputMapper.h" -#include "ThemeManager.h" -#include "ScreenDimensions.h" -#include "PrefsManager.h" -#include "RageInput.h" -#include "InputEventPlus.h" -#include "LocalizedString.h" - -class DeviceList: public BitmapText -{ -public: - void Update( float fDeltaTime ) - { - // Update devices text - this->SetText( INPUTMAN->GetDisplayDevicesString() ); - - BitmapText::Update( fDeltaTime ); - } - - virtual DeviceList *Copy() const; -}; - -REGISTER_ACTOR_CLASS( DeviceList ); - -static LocalizedString CONTROLLER ( "ScreenTestInput", "Controller" ); -static LocalizedString SECONDARY ( "ScreenTestInput", "secondary" ); -static LocalizedString NOT_MAPPED ( "ScreenTestInput", "not mapped" ); -class InputList: public BitmapText -{ - virtual InputList *Copy() const; - - void Update( float fDeltaTime ) - { - // Update input texts - vector asInputs; - - vector DeviceInputs; - INPUTFILTER->GetPressedButtons( DeviceInputs ); - FOREACH( DeviceInput, DeviceInputs, di ) - { - if( !di->bDown && di->level == 0.0f ) - continue; - - RString sTemp; - sTemp += INPUTMAN->GetDeviceSpecificInputString(*di); - if( di->level == 1.0f ) - sTemp += ssprintf(" - 1 " ); - else - sTemp += ssprintf(" - %.3f ", di->level ); - - GameInput gi; - if( INPUTMAPPER->DeviceToGame(*di,gi) ) - { - RString sName = GameButtonToLocalizedString( INPUTMAPPER->GetInputScheme(), gi.button ); - sTemp += ssprintf(" - %s %d %s", CONTROLLER.GetValue().c_str(), gi.controller+1, sName.c_str() ); - - if( !PREFSMAN->m_bOnlyDedicatedMenuButtons ) - { - GameButton mb = INPUTMAPPER->GetInputScheme()->GameButtonToMenuButton( gi.button ); - if( mb != GameButton_Invalid && mb != gi.button ) - { - RString sGameButtonString = GameButtonToLocalizedString( INPUTMAPPER->GetInputScheme(), mb ); - sTemp += ssprintf( " - (%s %s)", sGameButtonString.c_str(), SECONDARY.GetValue().c_str() ); - } - } - } - else - { - sTemp += " - "+NOT_MAPPED.GetValue(); - } - - RString sComment = INPUTFILTER->GetButtonComment( *di ); - if( sComment != "" ) - sTemp += " - " + sComment; - - asInputs.push_back( sTemp ); - } - - this->SetText( join( "\n", asInputs ) ); - - BitmapText::Update( fDeltaTime ); - } -}; - -REGISTER_ACTOR_CLASS( InputList ); - -REGISTER_SCREEN_CLASS( ScreenTestInput ); - -bool ScreenTestInput::Input( const InputEventPlus &input ) -{ - RString sMessage = input.DeviceI.ToString(); - bool bHandled = false; - switch( input.type ) - { - case IET_FIRST_PRESS: - case IET_RELEASE: - { - switch( input.type ) - { - case IET_FIRST_PRESS: sMessage += "Pressed"; break; - case IET_RELEASE: sMessage += "Released"; break; - default: break; - } - MESSAGEMAN->Broadcast( sMessage ); - bHandled = true; - break; - } - default: break; - } - - return Screen::Input( input ) || bHandled; // default handler -} - -bool ScreenTestInput::MenuStart( const InputEventPlus &input ) -{ - return MenuBack( input ); -} - -bool ScreenTestInput::MenuBack( const InputEventPlus &input ) -{ - if( input.type != IET_REPEAT ) - return false; // ignore - - if( IsTransitioning() ) - return false; - SCREENMAN->PlayStartSound(); - StartTransitioningScreen( SM_GoToPrevScreen ); - return true; -} - -/* - * (c) 2003-2004 Chris Danford - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "ScreenTestInput.h" +#include "ScreenManager.h" +#include "RageLog.h" +#include "InputMapper.h" +#include "ThemeManager.h" +#include "ScreenDimensions.h" +#include "PrefsManager.h" +#include "RageInput.h" +#include "InputEventPlus.h" +#include "LocalizedString.h" + +class DeviceList: public BitmapText +{ +public: + void Update( float fDeltaTime ) + { + // Update devices text + this->SetText( INPUTMAN->GetDisplayDevicesString() ); + + BitmapText::Update( fDeltaTime ); + } + + virtual DeviceList *Copy() const; +}; + +REGISTER_ACTOR_CLASS( DeviceList ); + +static LocalizedString CONTROLLER ( "ScreenTestInput", "Controller" ); +static LocalizedString SECONDARY ( "ScreenTestInput", "secondary" ); +static LocalizedString NOT_MAPPED ( "ScreenTestInput", "not mapped" ); +class InputList: public BitmapText +{ + virtual InputList *Copy() const; + + void Update( float fDeltaTime ) + { + // Update input texts + vector asInputs; + + vector DeviceInputs; + INPUTFILTER->GetPressedButtons( DeviceInputs ); + for (DeviceInput const &di : DeviceInputs) + { + if( !di.bDown && di.level == 0.0f ) + continue; + + RString sTemp; + sTemp += INPUTMAN->GetDeviceSpecificInputString(di); + if( di.level == 1.0f ) + sTemp += ssprintf(" - 1 " ); + else + sTemp += ssprintf(" - %.3f ", di.level ); + + GameInput gi; + if( INPUTMAPPER->DeviceToGame(di,gi) ) + { + RString sName = GameButtonToLocalizedString( INPUTMAPPER->GetInputScheme(), gi.button ); + sTemp += ssprintf(" - %s %d %s", CONTROLLER.GetValue().c_str(), gi.controller+1, sName.c_str() ); + + if( !PREFSMAN->m_bOnlyDedicatedMenuButtons ) + { + GameButton mb = INPUTMAPPER->GetInputScheme()->GameButtonToMenuButton( gi.button ); + if( mb != GameButton_Invalid && mb != gi.button ) + { + RString sGameButtonString = GameButtonToLocalizedString( INPUTMAPPER->GetInputScheme(), mb ); + sTemp += ssprintf( " - (%s %s)", sGameButtonString.c_str(), SECONDARY.GetValue().c_str() ); + } + } + } + else + { + sTemp += " - "+NOT_MAPPED.GetValue(); + } + + RString sComment = INPUTFILTER->GetButtonComment( di ); + if( sComment != "" ) + sTemp += " - " + sComment; + + asInputs.push_back( sTemp ); + } + + this->SetText( join( "\n", asInputs ) ); + + BitmapText::Update( fDeltaTime ); + } +}; + +REGISTER_ACTOR_CLASS( InputList ); + +REGISTER_SCREEN_CLASS( ScreenTestInput ); + +bool ScreenTestInput::Input( const InputEventPlus &input ) +{ + RString sMessage = input.DeviceI.ToString(); + bool bHandled = false; + switch( input.type ) + { + case IET_FIRST_PRESS: + case IET_RELEASE: + { + switch( input.type ) + { + case IET_FIRST_PRESS: sMessage += "Pressed"; break; + case IET_RELEASE: sMessage += "Released"; break; + default: break; + } + MESSAGEMAN->Broadcast( sMessage ); + bHandled = true; + break; + } + default: break; + } + + return Screen::Input( input ) || bHandled; // default handler +} + +bool ScreenTestInput::MenuStart( const InputEventPlus &input ) +{ + return MenuBack( input ); +} + +bool ScreenTestInput::MenuBack( const InputEventPlus &input ) +{ + if( input.type != IET_REPEAT ) + return false; // ignore + + if( IsTransitioning() ) + return false; + SCREENMAN->PlayStartSound(); + StartTransitioningScreen( SM_GoToPrevScreen ); + return true; +} + +/* + * (c) 2003-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/ScreenTextEntry.cpp b/src/ScreenTextEntry.cpp index fa269e93e3..40a2b535e9 100644 --- a/src/ScreenTextEntry.cpp +++ b/src/ScreenTextEntry.cpp @@ -337,7 +337,7 @@ void ScreenTextEntry::End( bool bCancelled ) { RString sAnswer = WStringToRString(m_sAnswer); RString sError; - if( g_pValidate != NULL ) + if( g_pValidate != nullptr ) { bool bValidAnswer = g_pValidate( sAnswer, sError ); if( !bValidAnswer ) @@ -384,7 +384,7 @@ void ScreenTextEntry::TextEntrySettings::FromStack( lua_State *L ) // Get ScreenMessage lua_getfield( L, iTab, "SendOnPop" ); const char *pStr = lua_tostring( L, -1 ); - if( pStr == NULL ) + if( pStr == nullptr ) smSendOnPop = SM_None; else smSendOnPop = ScreenMessageHelpers::ToScreenMessage( pStr ); @@ -393,7 +393,7 @@ void ScreenTextEntry::TextEntrySettings::FromStack( lua_State *L ) // Get Question lua_getfield( L, iTab, "Question" ); pStr = lua_tostring( L, -1 ); - if( pStr == NULL ) + if( pStr == nullptr ) { LuaHelpers::ReportScriptError("ScreenTextEntry \"Question\" entry is not a string."); pStr= ""; @@ -404,7 +404,7 @@ void ScreenTextEntry::TextEntrySettings::FromStack( lua_State *L ) // Get Initial Answer lua_getfield( L, iTab, "InitialAnswer" ); pStr = lua_tostring( L, -1 ); - if( pStr == NULL ) + if( pStr == nullptr ) pStr = ""; sInitialAnswer = pStr; lua_settop( L, iTab ); diff --git a/src/ScreenTextEntry.h b/src/ScreenTextEntry.h index 7c15eef8b4..801aff2718 100644 --- a/src/ScreenTextEntry.h +++ b/src/ScreenTextEntry.h @@ -42,32 +42,32 @@ public: RString sQuestion, RString sInitialAnswer, int iMaxInputLength, - bool(*Validate)(const RString &sAnswer,RString &sErrorOut) = NULL, - void(*OnOK)(const RString &sAnswer) = NULL, - void(*OnCancel)() = NULL, + bool(*Validate)(const RString &sAnswer,RString &sErrorOut) = nullptr, + void(*OnOK)(const RString &sAnswer) = nullptr, + void(*OnCancel)() = nullptr, bool bPassword = false, - bool (*ValidateAppend)(const RString &sAnswerBeforeChar, RString &sAppend) = NULL, - RString (*FormatAnswerForDisplay)(const RString &sAnswer) = NULL + bool (*ValidateAppend)(const RString &sAnswerBeforeChar, RString &sAppend) = nullptr, + RString (*FormatAnswerForDisplay)(const RString &sAnswer) = nullptr ); static void TextEntry( ScreenMessage smSendOnPop, RString sQuestion, RString sInitialAnswer, int iMaxInputLength, - bool(*Validate)(const RString &sAnswer,RString &sErrorOut) = NULL, - void(*OnOK)(const RString &sAnswer) = NULL, - void(*OnCancel)() = NULL, + bool(*Validate)(const RString &sAnswer,RString &sErrorOut) = nullptr, + void(*OnOK)(const RString &sAnswer) = nullptr, + void(*OnCancel)() = nullptr, bool bPassword = false, - bool (*ValidateAppend)(const RString &sAnswerBeforeChar, RString &sAppend) = NULL, - RString (*FormatAnswerForDisplay)(const RString &sAnswer) = NULL + bool (*ValidateAppend)(const RString &sAnswerBeforeChar, RString &sAppend) = nullptr, + RString (*FormatAnswerForDisplay)(const RString &sAnswer) = nullptr ); static void Password( ScreenMessage smSendOnPop, const RString &sQuestion, - void(*OnOK)(const RString &sPassword) = NULL, - void(*OnCancel)() = NULL ) + void(*OnOK)(const RString &sPassword) = nullptr, + void(*OnCancel)() = nullptr ) { - TextEntry( smSendOnPop, sQuestion, "", 255, NULL, OnOK, OnCancel, true ); + TextEntry( smSendOnPop, sQuestion, "", 255, nullptr, OnOK, OnCancel, true ); } struct TextEntrySettings { diff --git a/src/ScreenUnlockBrowse.cpp b/src/ScreenUnlockBrowse.cpp index 20219bcc72..f9ed881d90 100644 --- a/src/ScreenUnlockBrowse.cpp +++ b/src/ScreenUnlockBrowse.cpp @@ -7,11 +7,12 @@ REGISTER_SCREEN_CLASS( ScreenUnlockBrowse ); void ScreenUnlockBrowse::Init() { + int index = 0; // fill m_aGameCommands before calling Init() - FOREACH_CONST( UnlockEntry, UNLOCKMAN->m_UnlockEntries, ue ) + for (UnlockEntry const &ue : UNLOCKMAN->m_UnlockEntries) { GameCommand gc; - UnlockEntryStatus st = ue->GetUnlockEntryStatus(); + UnlockEntryStatus st = ue.GetUnlockEntryStatus(); switch( st ) { default: @@ -23,7 +24,7 @@ void ScreenUnlockBrowse::Init() case UnlockEntryStatus_RequrementsNotMet: break; } - gc.m_iIndex = ue - UNLOCKMAN->m_UnlockEntries.begin(); + gc.m_iIndex = index++; // gc.m_sUnlockEntryID = ue->m_sEntryID; gc.m_sName = ssprintf("%d",gc.m_iIndex); diff --git a/src/ScreenUnlockStatus.cpp b/src/ScreenUnlockStatus.cpp index 0aa9e6a776..7fca210afc 100644 --- a/src/ScreenUnlockStatus.cpp +++ b/src/ScreenUnlockStatus.cpp @@ -1,359 +1,359 @@ -#include "global.h" -#include "PrefsManager.h" -#include "ScreenUnlockStatus.h" -#include "ThemeManager.h" -#include "GameState.h" -#include "RageLog.h" -#include "UnlockManager.h" -#include "SongManager.h" -#include "ActorUtil.h" -#include "Song.h" -#include "Course.h" - -#define UNLOCK_TEXT_SCROLL_X THEME->GetMetricF("ScreenUnlockStatus","UnlockTextScrollX"); -#define UNLOCK_TEXT_SCROLL_START_Y THEME->GetMetricF("ScreenUnlockStatus","UnlockTextScrollStartY") -#define UNLOCK_TEXT_SCROLL_END_Y THEME->GetMetricF("ScreenUnlockStatus","UnlockTextScrollEndY") -#define UNLOCK_TEXT_SCROLL_ZOOM THEME->GetMetricF("ScreenUnlockStatus","UnlockTextScrollZoom") -#define UNLOCK_TEXT_SCROLL_ROWS THEME->GetMetricF("ScreenUnlockStatus","UnlockTextScrollRows") -#define UNLOCK_TEXT_SCROLL_MAX_WIDTH THEME->GetMetricF("ScreenUnlockStatus","UnlockTextScrollMaxWidth") -#define UNLOCK_TEXT_SCROLL_ICON_X THEME->GetMetricF("ScreenUnlockStatus","UnlockTextScrollIconX") -#define UNLOCK_TEXT_SCROLL_ICON_SIZE THEME->GetMetricF("ScreenUnlockStatus","UnlockTextScrollIconSize") -#define UNLOCK_TEXT_SCROLL THEME->GetMetricI("ScreenUnlockStatus","UnlockTextScroll") -#define TYPE_TO_DISPLAY THEME->GetMetric ("ScreenUnlockStatus","TypeOfPointsToDisplay") -#define ICON_COMMAND THEME->GetMetricA("ScreenUnlockStatus","UnlockIconCommand") -#define TIME_TO_DISPLAY THEME->GetMetricF("ScreenUnlockStatus","TimeToDisplay") -#define POINTS_ZOOM THEME->GetMetricF("ScreenUnlockStatus","PointsZoom") - -REGISTER_SCREEN_CLASS( ScreenUnlockStatus ); - -void ScreenUnlockStatus::Init() -{ - ScreenAttract::Init(); - - unsigned iNumUnlocks = UNLOCKMAN->m_UnlockEntries.size(); - - if( !PREFSMAN->m_bUseUnlockSystem || iNumUnlocks == 0 ) - { - this->PostScreenMessage( SM_GoToNextScreen, 0 ); - return; - } - - unsigned NumUnlocks = UNLOCKMAN->m_UnlockEntries.size(); - - PointsUntilNextUnlock.LoadFromFont( THEME->GetPathF("Common","normal") ); - PointsUntilNextUnlock.SetHorizAlign( align_left ); - - apActorCommands IconCommand = ICON_COMMAND; - for( unsigned i=1; i <= NumUnlocks; i++ ) - { - // get pertaining UnlockEntry - const UnlockEntry &entry = UNLOCKMAN->m_UnlockEntries[i-1]; - const Song *pSong = entry.m_Song.ToSong(); - - if( pSong == NULL) - continue; - - Sprite* pSpr = new Sprite; - - // new unlock graphic - pSpr->Load( THEME->GetPathG("ScreenUnlockStatus",ssprintf("%04d icon", i)) ); - - // set graphic location - pSpr->SetName( ssprintf("Unlock%04d",i) ); - LOAD_ALL_COMMANDS_AND_SET_XY( pSpr ); - - pSpr->RunCommands(IconCommand); - Unlocks.push_back(pSpr); - - if ( !entry.IsLocked() ) - this->AddChild(Unlocks[Unlocks.size() - 1]); - } - - // scrolling text - if (UNLOCK_TEXT_SCROLL != 0) - { - float ScrollingTextX = UNLOCK_TEXT_SCROLL_X; - float ScrollingTextStartY = UNLOCK_TEXT_SCROLL_START_Y; - float ScrollingTextEndY = UNLOCK_TEXT_SCROLL_END_Y; - float ScrollingTextZoom = UNLOCK_TEXT_SCROLL_ZOOM; - float ScrollingTextRows = UNLOCK_TEXT_SCROLL_ROWS; - float MaxWidth = UNLOCK_TEXT_SCROLL_MAX_WIDTH; - - float SecondsToScroll = TIME_TO_DISPLAY; - - if (SecondsToScroll > 2) SecondsToScroll--; - - float SECS_PER_CYCLE = 0; - - if (UNLOCK_TEXT_SCROLL != 3) - SECS_PER_CYCLE = (float)SecondsToScroll/(ScrollingTextRows + NumUnlocks); - else - SECS_PER_CYCLE = (float)SecondsToScroll/(ScrollingTextRows * 3 + NumUnlocks + 4); - - for(unsigned i = 1; i <= NumUnlocks; i++) - { - const UnlockEntry &entry = UNLOCKMAN->m_UnlockEntries[i-1]; - - BitmapText* text = new BitmapText; - - text->LoadFromFont( THEME->GetPathF("ScreenUnlockStatus","text") ); - text->SetHorizAlign( align_left ); - text->SetZoom(ScrollingTextZoom); - - switch( entry.m_Type ) - { - case UnlockRewardType_Song: - { - const Song *pSong = entry.m_Song.ToSong(); - ASSERT( pSong != NULL ); - - RString title = pSong->GetDisplayMainTitle(); - RString subtitle = pSong->GetDisplaySubTitle(); - if( subtitle != "" ) - title = title + "\n" + subtitle; - text->SetMaxWidth( MaxWidth ); - text->SetText( title ); - } - break; - case UnlockRewardType_Course: - { - const Course *pCourse = entry.m_Course.ToCourse(); - ASSERT( pCourse != NULL ); - - text->SetMaxWidth( MaxWidth ); - text->SetText( pCourse->GetDisplayFullTitle() ); - text->SetDiffuse( RageColor(0,1,0,1) ); - } - break; - default: - text->SetText( "" ); - text->SetDiffuse( RageColor(0.5f,0,0,1) ); - break; - } - - if( entry.IsLocked() ) - { - text->SetText("???"); - text->SetZoomX(1); - } - else - { - // unlocked. change color - const Song *pSong = entry.m_Song.ToSong(); - RageColor color = RageColor(1,1,1,1); - if( pSong ) - color = SONGMAN->GetSongGroupColor(pSong->m_sGroupName); - text->SetGlobalDiffuseColor(color); - } - - text->SetXY( ScrollingTextX, ScrollingTextStartY ); - - if (UNLOCK_TEXT_SCROLL == 3 && UNLOCK_TEXT_SCROLL_ROWS + i > NumUnlocks) - { // special command for last unlocks when scrolling is in effect - float TargetRow = -0.5f + i + UNLOCK_TEXT_SCROLL_ROWS - NumUnlocks; - float StopOffPoint = ScrollingTextEndY - TargetRow / UNLOCK_TEXT_SCROLL_ROWS * (ScrollingTextEndY - ScrollingTextStartY); - float FirstCycleTime = (UNLOCK_TEXT_SCROLL_ROWS - TargetRow) * SECS_PER_CYCLE; - float SecondCycleTime = (6 + TargetRow) * SECS_PER_CYCLE - FirstCycleTime; - //LOG->Trace("Target Row: %f", TargetRow); - //LOG->Trace("command for icon %d: %s", i, ssprintf("diffusealpha,0;sleep,%f;diffusealpha,1;linear,%f;y,%f;linear,%f;y,%f;linear,0.1;diffusealpha,0", SECS_PER_CYCLE * (i - 1), FirstCycleTime, StopOffPoint, SecondCycleTime * 2, ScrollingTextEndY).c_str() ); - RString sCommand = ssprintf("diffusealpha,0;sleep,%f;diffusealpha,1;linear,%f;y,%f;linear,%f;y,%f;linear,0.1;diffusealpha,0", SECS_PER_CYCLE * (i - 1), FirstCycleTime, StopOffPoint, SecondCycleTime, ScrollingTextEndY); - text->RunCommands( ActorUtil::ParseActorCommands(sCommand) ); - } - else - { - RString sCommand = ssprintf("diffusealpha,0;sleep,%f;diffusealpha,1;linear,%f;y,%f;linear,0.1;diffusealpha,0", SECS_PER_CYCLE * (i - 1), SECS_PER_CYCLE * (ScrollingTextRows), ScrollingTextEndY); - text->RunCommands( ActorUtil::ParseActorCommands(sCommand) ); - } - - item.push_back(text); - - if (UNLOCK_TEXT_SCROLL >= 2) - { - Sprite* IconCount = new Sprite; - - // new unlock graphic - IconCount->Load( THEME->GetPathG("ScreenUnlockStatus",ssprintf("%04d icon", i)) ); - - // set graphic location - IconCount->SetXY( UNLOCK_TEXT_SCROLL_ICON_X, ScrollingTextStartY); - - IconCount->SetHeight(UNLOCK_TEXT_SCROLL_ICON_SIZE); - IconCount->SetWidth(UNLOCK_TEXT_SCROLL_ICON_SIZE); - - if (UNLOCK_TEXT_SCROLL == 3 && UNLOCK_TEXT_SCROLL_ROWS + i > NumUnlocks) - { - float TargetRow = -0.5f + i + UNLOCK_TEXT_SCROLL_ROWS - NumUnlocks; - float StopOffPoint = ScrollingTextEndY - TargetRow / UNLOCK_TEXT_SCROLL_ROWS * (ScrollingTextEndY - ScrollingTextStartY); - float FirstCycleTime = (UNLOCK_TEXT_SCROLL_ROWS - TargetRow) * SECS_PER_CYCLE; - float SecondCycleTime = (6 + TargetRow) * SECS_PER_CYCLE - FirstCycleTime; - //LOG->Trace("Target Row: %f", TargetRow); - //LOG->Trace("command for icon %d: %s", i, ssprintf("diffusealpha,0;sleep,%f;diffusealpha,1;linear,%f;y,%f;linear,%f;y,%f;linear,0.1;diffusealpha,0", SECS_PER_CYCLE * (i - 1), FirstCycleTime, StopOffPoint, SecondCycleTime * 2, ScrollingTextEndY).c_str() ); - RString sCommand = ssprintf("diffusealpha,0;sleep,%f;diffusealpha,1;linear,%f;y,%f;linear,%f;y,%f;linear,0.1;diffusealpha,0", SECS_PER_CYCLE * (i - 1), FirstCycleTime, StopOffPoint, SecondCycleTime, ScrollingTextEndY); - IconCount->RunCommands( ActorUtil::ParseActorCommands(sCommand) ); - } - else - { - RString sCommand = ssprintf("diffusealpha,0;sleep,%f;diffusealpha,1;linear,%f;y,%f;linear,0.1;diffusealpha,0", SECS_PER_CYCLE * (i - 1), SECS_PER_CYCLE * (ScrollingTextRows), ScrollingTextEndY); - IconCount->RunCommands( ActorUtil::ParseActorCommands(sCommand) ); - } - - ItemIcons.push_back(IconCount); - - //LOG->Trace("Added unlock text %d", i); - - if (UNLOCK_TEXT_SCROLL == 3) - { - if ( !entry.IsLocked() ) - LastUnlocks.push_back(i); - } - } - } - } - - if (UNLOCK_TEXT_SCROLL == 3) - { - float ScrollingTextX = UNLOCK_TEXT_SCROLL_X; - float ScrollingTextStartY = UNLOCK_TEXT_SCROLL_START_Y; - float ScrollingTextEndY = UNLOCK_TEXT_SCROLL_END_Y; - float ScrollingTextRows = UNLOCK_TEXT_SCROLL_ROWS; - float MaxWidth = UNLOCK_TEXT_SCROLL_MAX_WIDTH; - float SecondsToScroll = TIME_TO_DISPLAY - 1; - float SECS_PER_CYCLE = (float)SecondsToScroll/(ScrollingTextRows * 3 + NumUnlocks + 4); - - for(unsigned i=1; i <= UNLOCK_TEXT_SCROLL_ROWS; i++) - { - if (i > LastUnlocks.size()) - continue; - - unsigned NextIcon = LastUnlocks[LastUnlocks.size() - i]; - - const UnlockEntry &entry = UNLOCKMAN->m_UnlockEntries[NextIcon-1]; - const Song *pSong = entry.m_Song.ToSong(); - if( pSong == NULL ) - continue; - - BitmapText* NewText = new BitmapText; - - NewText->LoadFromFont( THEME->GetPathF("ScreenUnlockStatus","text") ); - NewText->SetHorizAlign( align_left ); - - RString title = pSong->GetDisplayMainTitle(); - RString subtitle = pSong->GetDisplaySubTitle(); - - if( subtitle != "" ) - title = title + "\n" + subtitle; - NewText->SetZoom(UNLOCK_TEXT_SCROLL_ZOOM); - NewText->SetMaxWidth( MaxWidth ); - NewText->SetText( title ); - - RageColor color = SONGMAN->GetSongGroupColor(pSong->m_sGroupName); - NewText->SetGlobalDiffuseColor(color); - - NewText->SetXY(ScrollingTextX, ScrollingTextStartY); - { - RString sCommand = ssprintf("diffusealpha,0;sleep,%f;diffusealpha,1;linear,%f;y,%f;", SECS_PER_CYCLE * (NumUnlocks + 2 * i - 2), SECS_PER_CYCLE * ((ScrollingTextRows - i) * 2 + 1 ), (ScrollingTextStartY + (ScrollingTextEndY - ScrollingTextStartY) * (ScrollingTextRows - i + 0.5) / ScrollingTextRows )); - NewText->RunCommands( ActorUtil::ParseActorCommands(sCommand) ); - } - - // new unlock graphic - Sprite* NewIcon = new Sprite; - NewIcon->Load( THEME->GetPathG("ScreenUnlockStatus",ssprintf("%04d icon", NextIcon)) ); - NewIcon->SetXY( UNLOCK_TEXT_SCROLL_ICON_X, ScrollingTextStartY); - NewIcon->SetHeight(UNLOCK_TEXT_SCROLL_ICON_SIZE); - NewIcon->SetWidth(UNLOCK_TEXT_SCROLL_ICON_SIZE); - { - RString sCommand = ssprintf("diffusealpha,0;sleep,%f;diffusealpha,1;linear,%f;y,%f;", SECS_PER_CYCLE * (NumUnlocks + 2 * i - 2), SECS_PER_CYCLE * ((ScrollingTextRows - i) * 2 + 1 ), (ScrollingTextStartY + (ScrollingTextEndY - ScrollingTextStartY) * (ScrollingTextRows - i + 0.5) / ScrollingTextRows )); - NewIcon->RunCommands( ActorUtil::ParseActorCommands(sCommand) ); - } - - ItemIcons.push_back(NewIcon); - item.push_back(NewText); - } - } - - // NOTE: the following two loops require the iterator to - // be ints because if you decrement an unsigned when it - // equals zero, you get the maximum value of an unsigned, - // which is still greater than 0. By typecasting it as - // an integer, you can achieve -1, which exits the loop. - - for(int i = item.size() - 1; (int)i >= 0; i--) - this->AddChild(item[i]); - - for(int i = ItemIcons.size() - 1; (int)i >= 0; i--) - this->AddChild(ItemIcons[i]); - - PointsUntilNextUnlock.SetName( "PointsDisplay" ); - - RString PointDisplay = TYPE_TO_DISPLAY; - if (PointDisplay == "DP" || PointDisplay == "Dance") - { - RString sDP = ssprintf( "%d", (int)UNLOCKMAN->PointsUntilNextUnlock(UnlockRequirement_DancePoints) ); - PointsUntilNextUnlock.SetText( sDP ); - } - else if (PointDisplay == "AP" || PointDisplay == "Arcade") - { - RString sAP = ssprintf( "%d", (int)UNLOCKMAN->PointsUntilNextUnlock(UnlockRequirement_ArcadePoints) ); - PointsUntilNextUnlock.SetText( sAP ); - } - else if (PointDisplay == "SP" || PointDisplay == "Song") - { - RString sSP = ssprintf( "%d", (int)UNLOCKMAN->PointsUntilNextUnlock(UnlockRequirement_SongPoints) ); - PointsUntilNextUnlock.SetText( sSP ); - } - - PointsUntilNextUnlock.SetZoom( POINTS_ZOOM ); - LOAD_ALL_COMMANDS_AND_SET_XY( PointsUntilNextUnlock ); - this->AddChild( &PointsUntilNextUnlock ); - - this->ClearMessageQueue( SM_BeginFadingOut ); // ignore ScreenAttract's SecsToShow - - this->PostScreenMessage( SM_BeginFadingOut, TIME_TO_DISPLAY ); -} - -ScreenUnlockStatus::~ScreenUnlockStatus() -{ - while (Unlocks.size() > 0) - { - Sprite* entry = Unlocks[Unlocks.size()-1]; - SAFE_DELETE(entry); - Unlocks.pop_back(); - } - while (item.size() > 0) - { - BitmapText* entry = item[item.size()-1]; - SAFE_DELETE(entry); - item.pop_back(); - } - while (ItemIcons.size() > 0) - { - Sprite* entry = ItemIcons[ItemIcons.size()-1]; - SAFE_DELETE(entry); - ItemIcons.pop_back(); - } -} - -/* - * (c) 2003 Andrew Wong - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "PrefsManager.h" +#include "ScreenUnlockStatus.h" +#include "ThemeManager.h" +#include "GameState.h" +#include "RageLog.h" +#include "UnlockManager.h" +#include "SongManager.h" +#include "ActorUtil.h" +#include "Song.h" +#include "Course.h" + +#define UNLOCK_TEXT_SCROLL_X THEME->GetMetricF("ScreenUnlockStatus","UnlockTextScrollX"); +#define UNLOCK_TEXT_SCROLL_START_Y THEME->GetMetricF("ScreenUnlockStatus","UnlockTextScrollStartY") +#define UNLOCK_TEXT_SCROLL_END_Y THEME->GetMetricF("ScreenUnlockStatus","UnlockTextScrollEndY") +#define UNLOCK_TEXT_SCROLL_ZOOM THEME->GetMetricF("ScreenUnlockStatus","UnlockTextScrollZoom") +#define UNLOCK_TEXT_SCROLL_ROWS THEME->GetMetricF("ScreenUnlockStatus","UnlockTextScrollRows") +#define UNLOCK_TEXT_SCROLL_MAX_WIDTH THEME->GetMetricF("ScreenUnlockStatus","UnlockTextScrollMaxWidth") +#define UNLOCK_TEXT_SCROLL_ICON_X THEME->GetMetricF("ScreenUnlockStatus","UnlockTextScrollIconX") +#define UNLOCK_TEXT_SCROLL_ICON_SIZE THEME->GetMetricF("ScreenUnlockStatus","UnlockTextScrollIconSize") +#define UNLOCK_TEXT_SCROLL THEME->GetMetricI("ScreenUnlockStatus","UnlockTextScroll") +#define TYPE_TO_DISPLAY THEME->GetMetric ("ScreenUnlockStatus","TypeOfPointsToDisplay") +#define ICON_COMMAND THEME->GetMetricA("ScreenUnlockStatus","UnlockIconCommand") +#define TIME_TO_DISPLAY THEME->GetMetricF("ScreenUnlockStatus","TimeToDisplay") +#define POINTS_ZOOM THEME->GetMetricF("ScreenUnlockStatus","PointsZoom") + +REGISTER_SCREEN_CLASS( ScreenUnlockStatus ); + +void ScreenUnlockStatus::Init() +{ + ScreenAttract::Init(); + + unsigned iNumUnlocks = UNLOCKMAN->m_UnlockEntries.size(); + + if( !PREFSMAN->m_bUseUnlockSystem || iNumUnlocks == 0 ) + { + this->PostScreenMessage( SM_GoToNextScreen, 0 ); + return; + } + + unsigned NumUnlocks = UNLOCKMAN->m_UnlockEntries.size(); + + PointsUntilNextUnlock.LoadFromFont( THEME->GetPathF("Common","normal") ); + PointsUntilNextUnlock.SetHorizAlign( align_left ); + + apActorCommands IconCommand = ICON_COMMAND; + for( unsigned i=1; i <= NumUnlocks; i++ ) + { + // get pertaining UnlockEntry + const UnlockEntry &entry = UNLOCKMAN->m_UnlockEntries[i-1]; + const Song *pSong = entry.m_Song.ToSong(); + + if( pSong == nullptr) + continue; + + Sprite* pSpr = new Sprite; + + // new unlock graphic + pSpr->Load( THEME->GetPathG("ScreenUnlockStatus",ssprintf("%04d icon", i)) ); + + // set graphic location + pSpr->SetName( ssprintf("Unlock%04d",i) ); + LOAD_ALL_COMMANDS_AND_SET_XY( pSpr ); + + pSpr->RunCommands(IconCommand); + Unlocks.push_back(pSpr); + + if ( !entry.IsLocked() ) + this->AddChild(Unlocks[Unlocks.size() - 1]); + } + + // scrolling text + if (UNLOCK_TEXT_SCROLL != 0) + { + float ScrollingTextX = UNLOCK_TEXT_SCROLL_X; + float ScrollingTextStartY = UNLOCK_TEXT_SCROLL_START_Y; + float ScrollingTextEndY = UNLOCK_TEXT_SCROLL_END_Y; + float ScrollingTextZoom = UNLOCK_TEXT_SCROLL_ZOOM; + float ScrollingTextRows = UNLOCK_TEXT_SCROLL_ROWS; + float MaxWidth = UNLOCK_TEXT_SCROLL_MAX_WIDTH; + + float SecondsToScroll = TIME_TO_DISPLAY; + + if (SecondsToScroll > 2) SecondsToScroll--; + + float SECS_PER_CYCLE = 0; + + if (UNLOCK_TEXT_SCROLL != 3) + SECS_PER_CYCLE = (float)SecondsToScroll/(ScrollingTextRows + NumUnlocks); + else + SECS_PER_CYCLE = (float)SecondsToScroll/(ScrollingTextRows * 3 + NumUnlocks + 4); + + for(unsigned i = 1; i <= NumUnlocks; i++) + { + const UnlockEntry &entry = UNLOCKMAN->m_UnlockEntries[i-1]; + + BitmapText* text = new BitmapText; + + text->LoadFromFont( THEME->GetPathF("ScreenUnlockStatus","text") ); + text->SetHorizAlign( align_left ); + text->SetZoom(ScrollingTextZoom); + + switch( entry.m_Type ) + { + case UnlockRewardType_Song: + { + const Song *pSong = entry.m_Song.ToSong(); + ASSERT( pSong != nullptr ); + + RString title = pSong->GetDisplayMainTitle(); + RString subtitle = pSong->GetDisplaySubTitle(); + if( subtitle != "" ) + title = title + "\n" + subtitle; + text->SetMaxWidth( MaxWidth ); + text->SetText( title ); + } + break; + case UnlockRewardType_Course: + { + const Course *pCourse = entry.m_Course.ToCourse(); + ASSERT( pCourse != nullptr ); + + text->SetMaxWidth( MaxWidth ); + text->SetText( pCourse->GetDisplayFullTitle() ); + text->SetDiffuse( RageColor(0,1,0,1) ); + } + break; + default: + text->SetText( "" ); + text->SetDiffuse( RageColor(0.5f,0,0,1) ); + break; + } + + if( entry.IsLocked() ) + { + text->SetText("???"); + text->SetZoomX(1); + } + else + { + // unlocked. change color + const Song *pSong = entry.m_Song.ToSong(); + RageColor color = RageColor(1,1,1,1); + if( pSong ) + color = SONGMAN->GetSongGroupColor(pSong->m_sGroupName); + text->SetGlobalDiffuseColor(color); + } + + text->SetXY( ScrollingTextX, ScrollingTextStartY ); + + if (UNLOCK_TEXT_SCROLL == 3 && UNLOCK_TEXT_SCROLL_ROWS + i > NumUnlocks) + { // special command for last unlocks when scrolling is in effect + float TargetRow = -0.5f + i + UNLOCK_TEXT_SCROLL_ROWS - NumUnlocks; + float StopOffPoint = ScrollingTextEndY - TargetRow / UNLOCK_TEXT_SCROLL_ROWS * (ScrollingTextEndY - ScrollingTextStartY); + float FirstCycleTime = (UNLOCK_TEXT_SCROLL_ROWS - TargetRow) * SECS_PER_CYCLE; + float SecondCycleTime = (6 + TargetRow) * SECS_PER_CYCLE - FirstCycleTime; + //LOG->Trace("Target Row: %f", TargetRow); + //LOG->Trace("command for icon %d: %s", i, ssprintf("diffusealpha,0;sleep,%f;diffusealpha,1;linear,%f;y,%f;linear,%f;y,%f;linear,0.1;diffusealpha,0", SECS_PER_CYCLE * (i - 1), FirstCycleTime, StopOffPoint, SecondCycleTime * 2, ScrollingTextEndY).c_str() ); + RString sCommand = ssprintf("diffusealpha,0;sleep,%f;diffusealpha,1;linear,%f;y,%f;linear,%f;y,%f;linear,0.1;diffusealpha,0", SECS_PER_CYCLE * (i - 1), FirstCycleTime, StopOffPoint, SecondCycleTime, ScrollingTextEndY); + text->RunCommands( ActorUtil::ParseActorCommands(sCommand) ); + } + else + { + RString sCommand = ssprintf("diffusealpha,0;sleep,%f;diffusealpha,1;linear,%f;y,%f;linear,0.1;diffusealpha,0", SECS_PER_CYCLE * (i - 1), SECS_PER_CYCLE * (ScrollingTextRows), ScrollingTextEndY); + text->RunCommands( ActorUtil::ParseActorCommands(sCommand) ); + } + + item.push_back(text); + + if (UNLOCK_TEXT_SCROLL >= 2) + { + Sprite* IconCount = new Sprite; + + // new unlock graphic + IconCount->Load( THEME->GetPathG("ScreenUnlockStatus",ssprintf("%04d icon", i)) ); + + // set graphic location + IconCount->SetXY( UNLOCK_TEXT_SCROLL_ICON_X, ScrollingTextStartY); + + IconCount->SetHeight(UNLOCK_TEXT_SCROLL_ICON_SIZE); + IconCount->SetWidth(UNLOCK_TEXT_SCROLL_ICON_SIZE); + + if (UNLOCK_TEXT_SCROLL == 3 && UNLOCK_TEXT_SCROLL_ROWS + i > NumUnlocks) + { + float TargetRow = -0.5f + i + UNLOCK_TEXT_SCROLL_ROWS - NumUnlocks; + float StopOffPoint = ScrollingTextEndY - TargetRow / UNLOCK_TEXT_SCROLL_ROWS * (ScrollingTextEndY - ScrollingTextStartY); + float FirstCycleTime = (UNLOCK_TEXT_SCROLL_ROWS - TargetRow) * SECS_PER_CYCLE; + float SecondCycleTime = (6 + TargetRow) * SECS_PER_CYCLE - FirstCycleTime; + //LOG->Trace("Target Row: %f", TargetRow); + //LOG->Trace("command for icon %d: %s", i, ssprintf("diffusealpha,0;sleep,%f;diffusealpha,1;linear,%f;y,%f;linear,%f;y,%f;linear,0.1;diffusealpha,0", SECS_PER_CYCLE * (i - 1), FirstCycleTime, StopOffPoint, SecondCycleTime * 2, ScrollingTextEndY).c_str() ); + RString sCommand = ssprintf("diffusealpha,0;sleep,%f;diffusealpha,1;linear,%f;y,%f;linear,%f;y,%f;linear,0.1;diffusealpha,0", SECS_PER_CYCLE * (i - 1), FirstCycleTime, StopOffPoint, SecondCycleTime, ScrollingTextEndY); + IconCount->RunCommands( ActorUtil::ParseActorCommands(sCommand) ); + } + else + { + RString sCommand = ssprintf("diffusealpha,0;sleep,%f;diffusealpha,1;linear,%f;y,%f;linear,0.1;diffusealpha,0", SECS_PER_CYCLE * (i - 1), SECS_PER_CYCLE * (ScrollingTextRows), ScrollingTextEndY); + IconCount->RunCommands( ActorUtil::ParseActorCommands(sCommand) ); + } + + ItemIcons.push_back(IconCount); + + //LOG->Trace("Added unlock text %d", i); + + if (UNLOCK_TEXT_SCROLL == 3) + { + if ( !entry.IsLocked() ) + LastUnlocks.push_back(i); + } + } + } + } + + if (UNLOCK_TEXT_SCROLL == 3) + { + float ScrollingTextX = UNLOCK_TEXT_SCROLL_X; + float ScrollingTextStartY = UNLOCK_TEXT_SCROLL_START_Y; + float ScrollingTextEndY = UNLOCK_TEXT_SCROLL_END_Y; + float ScrollingTextRows = UNLOCK_TEXT_SCROLL_ROWS; + float MaxWidth = UNLOCK_TEXT_SCROLL_MAX_WIDTH; + float SecondsToScroll = TIME_TO_DISPLAY - 1; + float SECS_PER_CYCLE = (float)SecondsToScroll/(ScrollingTextRows * 3 + NumUnlocks + 4); + + for(unsigned i=1; i <= UNLOCK_TEXT_SCROLL_ROWS; i++) + { + if (i > LastUnlocks.size()) + continue; + + unsigned NextIcon = LastUnlocks[LastUnlocks.size() - i]; + + const UnlockEntry &entry = UNLOCKMAN->m_UnlockEntries[NextIcon-1]; + const Song *pSong = entry.m_Song.ToSong(); + if( pSong == nullptr ) + continue; + + BitmapText* NewText = new BitmapText; + + NewText->LoadFromFont( THEME->GetPathF("ScreenUnlockStatus","text") ); + NewText->SetHorizAlign( align_left ); + + RString title = pSong->GetDisplayMainTitle(); + RString subtitle = pSong->GetDisplaySubTitle(); + + if( subtitle != "" ) + title = title + "\n" + subtitle; + NewText->SetZoom(UNLOCK_TEXT_SCROLL_ZOOM); + NewText->SetMaxWidth( MaxWidth ); + NewText->SetText( title ); + + RageColor color = SONGMAN->GetSongGroupColor(pSong->m_sGroupName); + NewText->SetGlobalDiffuseColor(color); + + NewText->SetXY(ScrollingTextX, ScrollingTextStartY); + { + RString sCommand = ssprintf("diffusealpha,0;sleep,%f;diffusealpha,1;linear,%f;y,%f;", SECS_PER_CYCLE * (NumUnlocks + 2 * i - 2), SECS_PER_CYCLE * ((ScrollingTextRows - i) * 2 + 1 ), (ScrollingTextStartY + (ScrollingTextEndY - ScrollingTextStartY) * (ScrollingTextRows - i + 0.5) / ScrollingTextRows )); + NewText->RunCommands( ActorUtil::ParseActorCommands(sCommand) ); + } + + // new unlock graphic + Sprite* NewIcon = new Sprite; + NewIcon->Load( THEME->GetPathG("ScreenUnlockStatus",ssprintf("%04d icon", NextIcon)) ); + NewIcon->SetXY( UNLOCK_TEXT_SCROLL_ICON_X, ScrollingTextStartY); + NewIcon->SetHeight(UNLOCK_TEXT_SCROLL_ICON_SIZE); + NewIcon->SetWidth(UNLOCK_TEXT_SCROLL_ICON_SIZE); + { + RString sCommand = ssprintf("diffusealpha,0;sleep,%f;diffusealpha,1;linear,%f;y,%f;", SECS_PER_CYCLE * (NumUnlocks + 2 * i - 2), SECS_PER_CYCLE * ((ScrollingTextRows - i) * 2 + 1 ), (ScrollingTextStartY + (ScrollingTextEndY - ScrollingTextStartY) * (ScrollingTextRows - i + 0.5) / ScrollingTextRows )); + NewIcon->RunCommands( ActorUtil::ParseActorCommands(sCommand) ); + } + + ItemIcons.push_back(NewIcon); + item.push_back(NewText); + } + } + + // NOTE: the following two loops require the iterator to + // be ints because if you decrement an unsigned when it + // equals zero, you get the maximum value of an unsigned, + // which is still greater than 0. By typecasting it as + // an integer, you can achieve -1, which exits the loop. + + for(int i = item.size() - 1; (int)i >= 0; i--) + this->AddChild(item[i]); + + for(int i = ItemIcons.size() - 1; (int)i >= 0; i--) + this->AddChild(ItemIcons[i]); + + PointsUntilNextUnlock.SetName( "PointsDisplay" ); + + RString PointDisplay = TYPE_TO_DISPLAY; + if (PointDisplay == "DP" || PointDisplay == "Dance") + { + RString sDP = ssprintf( "%d", (int)UNLOCKMAN->PointsUntilNextUnlock(UnlockRequirement_DancePoints) ); + PointsUntilNextUnlock.SetText( sDP ); + } + else if (PointDisplay == "AP" || PointDisplay == "Arcade") + { + RString sAP = ssprintf( "%d", (int)UNLOCKMAN->PointsUntilNextUnlock(UnlockRequirement_ArcadePoints) ); + PointsUntilNextUnlock.SetText( sAP ); + } + else if (PointDisplay == "SP" || PointDisplay == "Song") + { + RString sSP = ssprintf( "%d", (int)UNLOCKMAN->PointsUntilNextUnlock(UnlockRequirement_SongPoints) ); + PointsUntilNextUnlock.SetText( sSP ); + } + + PointsUntilNextUnlock.SetZoom( POINTS_ZOOM ); + LOAD_ALL_COMMANDS_AND_SET_XY( PointsUntilNextUnlock ); + this->AddChild( &PointsUntilNextUnlock ); + + this->ClearMessageQueue( SM_BeginFadingOut ); // ignore ScreenAttract's SecsToShow + + this->PostScreenMessage( SM_BeginFadingOut, TIME_TO_DISPLAY ); +} + +ScreenUnlockStatus::~ScreenUnlockStatus() +{ + while (Unlocks.size() > 0) + { + Sprite* entry = Unlocks[Unlocks.size()-1]; + SAFE_DELETE(entry); + Unlocks.pop_back(); + } + while (item.size() > 0) + { + BitmapText* entry = item[item.size()-1]; + SAFE_DELETE(entry); + item.pop_back(); + } + while (ItemIcons.size() > 0) + { + Sprite* entry = ItemIcons[ItemIcons.size()-1]; + SAFE_DELETE(entry); + ItemIcons.pop_back(); + } +} + +/* + * (c) 2003 Andrew Wong + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/ScreenWithMenuElements.cpp b/src/ScreenWithMenuElements.cpp index db5e328a6f..db3491720c 100644 --- a/src/ScreenWithMenuElements.cpp +++ b/src/ScreenWithMenuElements.cpp @@ -20,10 +20,10 @@ REGISTER_SCREEN_CLASS( ScreenWithMenuElements ); ScreenWithMenuElements::ScreenWithMenuElements() { - m_MenuTimer = NULL; + m_MenuTimer = nullptr; FOREACH_PlayerNumber( p ) - m_MemoryCardDisplay[p] = NULL; - m_MenuTimer = NULL; + m_MemoryCardDisplay[p] = nullptr; + m_MenuTimer = nullptr; m_bShouldAllowLateJoin= false; } @@ -43,7 +43,7 @@ void ScreenWithMenuElements::Init() { FOREACH_PlayerNumber( p ) { - ASSERT( m_MemoryCardDisplay[p] == NULL ); + ASSERT( m_MemoryCardDisplay[p] == nullptr ); m_MemoryCardDisplay[p] = new MemoryCardDisplay; m_MemoryCardDisplay[p]->Load( p ); m_MemoryCardDisplay[p]->SetName( ssprintf("MemoryCardDisplayP%d",p+1) ); @@ -54,7 +54,7 @@ void ScreenWithMenuElements::Init() if( TIMER_SECONDS != -1 ) { - ASSERT( m_MenuTimer == NULL ); // don't load twice + ASSERT( m_MenuTimer == nullptr ); // don't load twice m_MenuTimer = new MenuTimer; m_MenuTimer->Load( TIMER_METRICS_GROUP.GetValue() ); m_MenuTimer->SetName( "Timer" ); @@ -87,8 +87,8 @@ void ScreenWithMenuElements::Init() if( pFrame ) { m_vDecorations = pFrame->GetChildren(); - FOREACH( Actor*, m_vDecorations, child ) - this->AddChild( *child ); + for (Actor *child : m_vDecorations) + this->AddChild( child ); pFrame->RemoveAllChildren(); } } @@ -164,11 +164,11 @@ ScreenWithMenuElements::~ScreenWithMenuElements() SAFE_DELETE( m_MenuTimer ); FOREACH_PlayerNumber( p ) { - if( m_MemoryCardDisplay[p] != NULL ) + if( m_MemoryCardDisplay[p] != nullptr ) SAFE_DELETE( m_MemoryCardDisplay[p] ); } - FOREACH( Actor*, m_vDecorations, actor ) - delete *actor; + for (Actor *actor : m_vDecorations) + delete actor; } void ScreenWithMenuElements::SetHelpText( RString s ) @@ -255,7 +255,7 @@ void ScreenWithMenuElements::Update( float fDeltaTime ) void ScreenWithMenuElements::ResetTimer() { - if( m_MenuTimer == NULL ) + if( m_MenuTimer == nullptr ) return; if( TIMER_SECONDS > 0.0f && (PREFSMAN->m_bMenuTimer || FORCE_TIMER) ) diff --git a/src/Song.cpp b/src/Song.cpp index a4cba0ddaa..21817b0a7d 100644 --- a/src/Song.cpp +++ b/src/Song.cpp @@ -23,7 +23,6 @@ #include "SongUtil.h" #include "SongManager.h" #include "StepsUtil.h" -#include "Foreach.h" #include "BackgroundUtil.h" #include "SpecialFiles.h" #include "NotesLoader.h" @@ -95,12 +94,14 @@ Song::Song() Song::~Song() { - FOREACH( Steps*, m_vpSteps, s ) - SAFE_DELETE( *s ); - m_vpSteps.clear(); - FOREACH(Steps*, m_UnknownStyleSteps, s) + for (Steps *s : m_vpSteps) { - SAFE_DELETE(*s); + SAFE_DELETE( s ); + } + m_vpSteps.clear(); + for (Steps *s : m_UnknownStyleSteps) + { + SAFE_DELETE(s); } m_UnknownStyleSteps.clear(); @@ -164,14 +165,16 @@ void Song::SetSpecifiedLastSecond(const float f) // Reset to an empty song. void Song::Reset() { - FOREACH( Steps*, m_vpSteps, s ) - SAFE_DELETE( *s ); + for (Steps *s : m_vpSteps) + { + SAFE_DELETE( s ); + } m_vpSteps.clear(); FOREACH_ENUM( StepsType, st ) m_vpStepsByType[st].clear(); - FOREACH(Steps*, m_UnknownStyleSteps, s) + for (Steps *s : m_UnknownStyleSteps) { - SAFE_DELETE(*s); + SAFE_DELETE(s); } m_UnknownStyleSteps.clear(); @@ -186,7 +189,8 @@ void Song::Reset() void Song::AddBackgroundChange( BackgroundLayer iLayer, BackgroundChange seg ) { // Delete old background change at this start beat, if any. - FOREACH( BackgroundChange, GetBackgroundChanges(iLayer), bgc ) + auto &changes = GetBackgroundChanges(iLayer); + for (vector::iterator bgc = changes.begin(); bgc != changes.end(); ++bgc) { if( bgc->m_fStartBeat == seg.m_fStartBeat ) { @@ -417,15 +421,15 @@ bool Song::LoadFromSongDir(RString sDir, bool load_autosave, ProfileSlot from_pr m_sCDTitleFile.clear(); } - FOREACH( Steps*, m_vpSteps, s ) + for (Steps *s : m_vpSteps) { if(m_LoadedFromProfile != ProfileSlot_Invalid) { - (*s)->ChangeFilenamesForCustomSong(); + s->ChangeFilenamesForCustomSong(); } /* Compress all Steps. During initial caching, this will remove cached * NoteData; during cached loads, this will just remove cached SMData. */ - (*s)->Compress(); + s->Compress(); } // Load the cached Images, if it's not loaded already. @@ -638,9 +642,9 @@ void Song::TidyUpData( bool from_cache, bool /* duringCache */ ) m_SongTiming.TidyUpData(false); - FOREACH(Steps *, m_vpSteps, s) + for (Steps *s : m_vpSteps) { - (*s)->m_Timing.TidyUpData(true); + s->m_Timing.TidyUpData(true); } if(!from_cache) @@ -766,14 +770,14 @@ void Song::TidyUpData( bool from_cache, bool /* duringCache */ ) /* XXX: Checking if the music file exists eliminates a warning * originating from BMS files (which have no music file, per se) * but it's something of a hack. */ - if(Sample == NULL && m_sMusicFile != "") + if(Sample == nullptr && m_sMusicFile != "") { LOG->UserLog("Sound file", GetMusicPath(), "couldn't be opened: %s", error.c_str()); // Don't use this file. m_sMusicFile = ""; } - else if(Sample != NULL) + else if(Sample != nullptr) { m_fMusicLengthSeconds = Sample->GetLength() / 1000.0f; delete Sample; @@ -808,7 +812,7 @@ void Song::TidyUpData( bool from_cache, bool /* duringCache */ ) if(!m_PreviewFile.empty() && m_fMusicSampleLengthSeconds <= 0.00f) { // if there's a preview file and sample length isn't specified, set sample length to length of preview file RString error; RageSoundReader *Sample = RageSoundReader_FileReader::OpenFile(GetPreviewMusicPath(), error); - if(Sample == NULL && m_sMusicFile != "") + if(Sample == nullptr && m_sMusicFile != "") { LOG->UserLog("Sound file", GetPreviewMusicPath(), "couldn't be opened: %s", error.c_str()); @@ -816,7 +820,7 @@ void Song::TidyUpData( bool from_cache, bool /* duringCache */ ) m_PreviewFile = ""; m_fMusicSampleLengthSeconds = DEFAULT_MUSIC_SAMPLE_LENGTH; } - else if(Sample != NULL) + else if(Sample != nullptr) { m_fMusicSampleLengthSeconds = Sample->GetLength() / 1000.0f; delete Sample; @@ -1193,12 +1197,12 @@ bool Song::SongCompleteForStyle( const Style *st ) const bool Song::HasStepsType( StepsType st ) const { - return SongUtil::GetOneSteps( this, st ) != NULL; + return SongUtil::GetOneSteps( this, st ) != nullptr; } bool Song::HasStepsTypeAndDifficulty( StepsType st, Difficulty dc ) const { - return SongUtil::GetOneSteps( this, st, dc ) != NULL; + return SongUtil::GetOneSteps( this, st, dc ) != nullptr; } void Song::Save(bool autosave) @@ -1258,9 +1262,8 @@ bool Song::SaveToSMFile() FileCopy( sPath, sPath + ".old" ); vector vpStepsToSave; - FOREACH_CONST( Steps*, m_vpSteps, s ) + for (Steps *pSteps : m_vpSteps) { - Steps *pSteps = *s; if( pSteps->IsAutogen() ) continue; // don't write autogen notes @@ -1270,9 +1273,9 @@ bool Song::SaveToSMFile() vpStepsToSave.push_back( pSteps ); } - FOREACH_CONST(Steps*, m_UnknownStyleSteps, s) + for (Steps *s : m_UnknownStyleSteps) { - vpStepsToSave.push_back(*s); + vpStepsToSave.push_back(s); } return NotesWriterSM::Write( sPath, *this, vpStepsToSave ); @@ -1296,9 +1299,8 @@ bool Song::SaveToSSCFile( RString sPath, bool bSavingCache, bool autosave ) FileCopy( path, path + ".old" ); vector vpStepsToSave; - FOREACH_CONST( Steps*, m_vpSteps, s ) + for (Steps *pSteps : m_vpSteps) { - Steps *pSteps = *s; if( pSteps->IsAutogen() ) continue; // don't write autogen notes @@ -1310,9 +1312,9 @@ bool Song::SaveToSSCFile( RString sPath, bool bSavingCache, bool autosave ) pSteps->SetFilename(path); vpStepsToSave.push_back( pSteps ); } - FOREACH_CONST(Steps*, m_UnknownStyleSteps, s) + for (Steps *s : m_UnknownStyleSteps) { - vpStepsToSave.push_back(*s); + vpStepsToSave.push_back(s); } if(bSavingCache || autosave) @@ -1347,8 +1349,8 @@ bool Song::SaveToSSCFile( RString sPath, bool bSavingCache, bool autosave ) } // Mark these steps saved to disk. - FOREACH( Steps*, vpStepsToSave, s ) - (*s)->SetSavedToDisk( true ); + for (Steps *s : vpStepsToSave) + s->SetSavedToDisk( true ); return true; } @@ -1520,11 +1522,11 @@ bool Song::IsEasy( StepsType st ) const bool Song::IsTutorial() const { // A Song is considered a Tutorial if it has only Beginner steps. - FOREACH_CONST( Steps*, m_vpSteps, s ) + for (Steps const *s : m_vpSteps) { - if( (*s)->m_StepsType == StepsType_lights_cabinet ) + if( s->m_StepsType == StepsType_lights_cabinet ) continue; // ignore - if( (*s)->GetDifficulty() != Difficulty_Beginner ) + if( s->GetDifficulty() != Difficulty_Beginner ) return false; } @@ -1533,22 +1535,13 @@ bool Song::IsTutorial() const bool Song::HasEdits( StepsType st ) const { - for( unsigned i=0; im_StepsType == st && - pSteps->GetDifficulty() == Difficulty_Edit ) - { - return true; - } - } - - return false; + return std::any_of(m_vpSteps.begin(), m_vpSteps.end(), + [&](Steps const *step) { return step->m_StepsType == st && step->GetDifficulty() == Difficulty_Edit; }); } bool Song::NormallyDisplayed() const { - return UNLOCKMAN == NULL || !UNLOCKMAN->SongIsLocked(this); + return UNLOCKMAN == nullptr || !UNLOCKMAN->SongIsLocked(this); } bool Song::ShowInDemonstrationAndRanking() const { return !IsTutorial() && NormallyDisplayed(); } @@ -1631,9 +1624,9 @@ vector &Song::GetForegroundChanges() vector Song::GetChangesToVectorString(const vector & changes) const { vector ret; - FOREACH_CONST( BackgroundChange, changes, bgc ) + for (BackgroundChange const &bgc : changes) { - ret.push_back((*bgc).ToString()); + ret.push_back(bgc.ToString()); } return ret; } @@ -1990,7 +1983,7 @@ void Song::FreeAllLoadedFromProfile( ProfileSlot slot, const set *setInU continue; if( slot != ProfileSlot_Invalid && pSteps->GetLoadedFromProfileSlot() != slot ) continue; - if( setInUse != NULL && setInUse->find(pSteps) != setInUse->end() ) + if( setInUse != nullptr && setInUse->find(pSteps) != setInUse->end() ) continue; apToRemove.push_back( pSteps ); } @@ -2050,9 +2043,9 @@ bool Song::IsStepsUsingDifferentTiming(Steps *pSteps) const bool Song::AnyChartUsesSplitTiming() const { - FOREACH_CONST(Steps*, m_vpSteps, s) + for (Steps *s : m_vpSteps) { - if(!(*s)->m_Timing.empty()) + if(!s->m_Timing.empty()) { return true; } diff --git a/src/Song.h b/src/Song.h index 375a73305b..112ef03a4d 100644 --- a/src/Song.h +++ b/src/Song.h @@ -416,6 +416,7 @@ public: bool SongCompleteForStyle( const Style *st ) const; bool HasStepsType( StepsType st ) const; bool HasStepsTypeAndDifficulty( StepsType st, Difficulty dc ) const; + // TODO: Allow for a non const version. const vector& GetAllSteps() const { return m_vpSteps; } const vector& GetStepsByStepsType( StepsType st ) const { return m_vpStepsByType[st]; } bool IsEasy( StepsType st ) const; @@ -439,7 +440,7 @@ public: void AddSteps( Steps* pSteps ); void DeleteSteps( const Steps* pSteps, bool bReAutoGen = true ); - void FreeAllLoadedFromProfile( ProfileSlot slot = ProfileSlot_Invalid, const set *setInUse = NULL ); + void FreeAllLoadedFromProfile( ProfileSlot slot = ProfileSlot_Invalid, const set *setInUse = nullptr ); bool WasLoadedFromProfile() const { return m_LoadedFromProfile != ProfileSlot_Invalid; } void GetStepsLoadedFromProfile( ProfileSlot slot, vector &vpStepsOut ) const; int GetNumStepsLoadedFromProfile( ProfileSlot slot ) const; @@ -471,7 +472,7 @@ private: /** @brief the Steps that belong to this Song. */ vector m_vpSteps; /** @brief the Steps of a particular StepsType that belong to this Song. */ - vector m_vpStepsByType[NUM_StepsType]; + std::array, NUM_StepsType> m_vpStepsByType; /** @brief the Steps that are of unrecognized Styles. */ vector m_UnknownStyleSteps; }; diff --git a/src/SongManager.cpp b/src/SongManager.cpp index d596568c9e..6aa220d279 100644 --- a/src/SongManager.cpp +++ b/src/SongManager.cpp @@ -9,7 +9,6 @@ #include "Course.h" #include "CourseLoaderCRS.h" #include "CourseUtil.h" -#include "Foreach.h" #include "GameManager.h" #include "GameState.h" #include "LocalizedString.h" @@ -38,7 +37,7 @@ #include "UnlockManager.h" #include "SpecialFiles.h" -SongManager* SONGMAN = NULL; // global and accessible from anywhere in our program +SongManager* SONGMAN = nullptr; // global and accessible from anywhere in our program const RString ADDITIONAL_SONGS_DIR = "/AdditionalSongs/"; const RString ADDITIONAL_COURSES_DIR = "/AdditionalCourses/"; @@ -180,12 +179,12 @@ void SongManager::SanityCheckGroupDir( RString sDir ) const vector arrayFiles; GetDirListing( sDir + "/*", arrayFiles ); const vector& audio_exts= ActorUtil::GetTypeExtensionList(FT_Sound); - FOREACH(RString, arrayFiles, fname) + for (RString &fname : arrayFiles) { - const RString ext= GetExtension(*fname); - FOREACH_CONST(RString, audio_exts, aud) + const RString ext= GetExtension(fname); + for (RString const &aud : audio_exts) { - if(ext == *aud) + if(ext == aud) { RageException::Throw( FOLDER_CONTAINS_MUSIC_FILES.GetValue(), sDir.c_str()); @@ -296,9 +295,8 @@ void SongManager::LoadStepManiaSongDir( RString sDir, LoadingWindow *ld ) ld->SetTotalWork(arrayGroupDirs.size()); } int sanity_index= 0; - FOREACH_CONST( RString, arrayGroupDirs, s ) // foreach dir in /Songs/ + for (RString const &sGroupDirName : arrayGroupDirs) // foreach dir in /Songs/ { - RString sGroupDirName = *s; if(ld && loading_window_last_update_time.Ago() > next_loading_window_update) { loading_window_last_update_time.Touch(); @@ -330,9 +328,8 @@ void SongManager::LoadStepManiaSongDir( RString sDir, LoadingWindow *ld ) groupIndex = 0; songIndex = 0; - FOREACH_CONST( RString, arrayGroupDirs, s ) // foreach dir in /Songs/ + for (RString const &sGroupDirName : arrayGroupDirs) // foreach dir in /Songs/ { - RString sGroupDirName = *s; vector &arraySongDirs = arrayGroupSongDirs[groupIndex++]; LOG->Trace("Attempting to load %i songs from \"%s\"", int(arraySongDirs.size()), @@ -466,8 +463,10 @@ void SongManager::FreeSongs() m_sSongGroupBannerPaths.clear(); //m_sSongGroupBackgroundPaths.clear(); - for( unsigned i=0; iGetProfile(pn); - if(prof != NULL) + if(prof != nullptr) { if(prof->GetDisplayNameOrHighScoreName() == sSongGroup) { @@ -566,7 +565,7 @@ RageColor SongManager::GetSongGroupColor( const RString &sSongGroup ) const RageColor SongManager::GetSongColor( const Song* pSong ) const { - ASSERT( pSong != NULL ); + ASSERT( pSong != nullptr ); // protected by royal freem corporation. any modification/removal of // this code will result in prosecution. @@ -581,16 +580,15 @@ RageColor SongManager::GetSongColor( const Song* pSong ) const if( USE_PREFERRED_SORT_COLOR ) { - FOREACH_CONST( PreferredSortSection, m_vPreferredSongSort, v ) + int sortIndex = 0; + for (PreferredSortSection const &v : m_vPreferredSongSort) { - FOREACH_CONST( Song*, v->vpSongs, s ) + if (std::any_of(v.vpSongs.begin(), v.vpSongs.end(), [&](Song const *s) { return s == pSong; })) { - if( *s == pSong ) - { - int i = v - m_vPreferredSongSort.begin(); - return SONG_GROUP_COLOR.GetValue( i%NUM_SONG_GROUP_COLORS ); - } + return SONG_GROUP_COLOR.GetValue( sortIndex % NUM_SONG_GROUP_COLORS ); } + + sortIndex += 1; } int i = m_vPreferredSongSort.size(); @@ -648,8 +646,8 @@ RString SongManager::GetCourseGroupBannerPath( const RString &sCourseGroup ) con void SongManager::GetCourseGroupNames( vector &AddTo ) const { - FOREACHM_CONST( RString, CourseGroupInfo, m_mapCourseGroupToInfo, iter ) - AddTo.push_back( iter->first ); + for (std::pair const &iter : m_mapCourseGroupToInfo) + AddTo.push_back( iter.first ); } bool SongManager::DoesCourseGroupExist( const RString &sCourseGroup ) const @@ -660,9 +658,9 @@ bool SongManager::DoesCourseGroupExist( const RString &sCourseGroup ) const RageColor SongManager::GetCourseGroupColor( const RString &sCourseGroup ) const { int iIndex = 0; - FOREACHM_CONST( RString, CourseGroupInfo, m_mapCourseGroupToInfo, iter ) + for (std::pair const &iter : m_mapCourseGroupToInfo) { - if( iter->first == sCourseGroup ) + if( iter.first == sCourseGroup ) return SONG_GROUP_COLOR.GetValue( iIndex%NUM_SONG_GROUP_COLORS ); iIndex++; } @@ -680,17 +678,15 @@ RageColor SongManager::GetCourseColor( const Course* pCourse ) const if( USE_PREFERRED_SORT_COLOR ) { - FOREACH_CONST( CoursePointerVector, m_vPreferredCourseSort, v ) + int courseIndex = 0; + for (CoursePointerVector const &v : m_vPreferredCourseSort) { - FOREACH_CONST( Course*, *v, s ) + if (std::any_of(v.begin(), v.end(), [&](Course const *s) { return s == pCourse; })) { - if( *s == pCourse ) - { - int i = v - m_vPreferredCourseSort.begin(); - CHECKPOINT_M( ssprintf( "%i, NUM_COURSE_GROUP_COLORS = %i", i, NUM_COURSE_GROUP_COLORS.GetValue()) ); - return COURSE_GROUP_COLOR.GetValue( i % NUM_COURSE_GROUP_COLORS ); - } + CHECKPOINT_M( ssprintf( "%i, NUM_COURSE_GROUP_COLORS = %i", courseIndex, NUM_COURSE_GROUP_COLORS.GetValue()) ); + return COURSE_GROUP_COLOR.GetValue( courseIndex % NUM_COURSE_GROUP_COLORS ); } + courseIndex += 1; } int i = m_vPreferredCourseSort.size(); @@ -728,7 +724,7 @@ const vector &SongManager::GetSongs( const RString &sGroupName ) const FOREACH_EnabledPlayer(pn) { Profile* prof= PROFILEMAN->GetProfile(pn); - if(prof != NULL) + if(prof != nullptr) { if(prof->GetDisplayNameOrHighScoreName() == sGroupName) { @@ -746,19 +742,17 @@ void SongManager::GetPreferredSortSongs( vector &AddTo ) const AddTo.insert( AddTo.end(), m_pSongs.begin(), m_pSongs.end() ); return; } - - FOREACH_CONST( PreferredSortSection, m_vPreferredSongSort, v ) - AddTo.insert( AddTo.end(), v->vpSongs.begin(), v->vpSongs.end() ); + for (PreferredSortSection const &v : m_vPreferredSongSort) + AddTo.insert( AddTo.end(), v.vpSongs.begin(), v.vpSongs.end() ); } RString SongManager::SongToPreferredSortSectionName( const Song *pSong ) const { - FOREACH_CONST( PreferredSortSection, m_vPreferredSongSort, v ) + for (PreferredSortSection const &v : m_vPreferredSongSort) { - FOREACH_CONST( Song*, v->vpSongs, s ) + if (std::any_of(v.vpSongs.begin(), v.vpSongs.end(), [&](Song const *s) { return s == pSong; })) { - if( *s == pSong ) - return v->sName; + return v.sName; } } return RString(); @@ -772,11 +766,10 @@ void SongManager::GetPreferredSortCourses( CourseType ct, vector &AddTo return; } - FOREACH_CONST( CoursePointerVector, m_vPreferredCourseSort, v ) + for (CoursePointerVector const &v : m_vPreferredCourseSort) { - FOREACH_CONST( Course*, *v, c ) + for (Course *pCourse : v) { - Course *pCourse = *c; if( pCourse->GetCourseType() == ct ) AddTo.push_back( pCourse ); } @@ -790,51 +783,22 @@ int SongManager::GetNumSongs() const int SongManager::GetNumLockedSongs() const { - int iNum = 0; - FOREACH_CONST( Song*, m_pSongs, i ) - { - // If locked for any reason, regardless of how it's locked. - if( UNLOCKMAN->SongIsLocked(*i) ) - ++iNum; - } - return iNum; + return std::count_if(m_pSongs.begin(), m_pSongs.end(), [](Song const *s) { return UNLOCKMAN->SongIsLocked(s); }); } int SongManager::GetNumUnlockedSongs() const { - int iNum = 0; - FOREACH_CONST( Song*, m_pSongs, i ) - { - // If locked for any reason other than LOCKED_LOCK: - if( UNLOCKMAN->SongIsLocked(*i) & ~LOCKED_LOCK ) - continue; - ++iNum; - } - return iNum; + return std::count_if(m_pSongs.begin(), m_pSongs.end(), [](Song const *s) { return UNLOCKMAN->SongIsLocked(s) & ~LOCKED_LOCK; }); } int SongManager::GetNumSelectableAndUnlockedSongs() const { - int iNum = 0; - FOREACH_CONST( Song*, m_pSongs, i ) - { - // If locked for any reason other than LOCKED_LOCK or LOCKED_SELECTABLE: - if( UNLOCKMAN->SongIsLocked(*i) & ~(LOCKED_LOCK|LOCKED_SELECTABLE) ) - continue; - ++iNum; - } - return iNum; + return std::count_if(m_pSongs.begin(), m_pSongs.end(), [](Song const *s) { return UNLOCKMAN->SongIsLocked(s) & ~(LOCKED_LOCK | LOCKED_SELECTABLE); }); } int SongManager::GetNumAdditionalSongs() const { - int iNum = 0; - FOREACH_CONST( Song*, m_pSongs, i ) - { - if( WasLoadedFromAdditionalSongs( *i ) ) - ++iNum; - } - return iNum; + return std::count_if(m_pSongs.begin(), m_pSongs.end(), [&](Song const *s) { return WasLoadedFromAdditionalSongs(s); }); } int SongManager::GetNumSongGroups() const @@ -849,13 +813,7 @@ int SongManager::GetNumCourses() const int SongManager::GetNumAdditionalCourses() const { - int iNum = 0; - FOREACH_CONST( Course*, m_pCourses, i ) - { - if( WasLoadedFromAdditionalCourses( *i ) ) - ++iNum; - } - return iNum; + return std::count_if(m_pCourses.begin(), m_pCourses.end(), [&](Course const *c) { return WasLoadedFromAdditionalCourses(c); }); } int SongManager::GetNumCourseGroups() const @@ -885,10 +843,10 @@ void SongManager::InitCoursesFromDisk( LoadingWindow *ld ) vsCourseDirs.push_back( ADDITIONAL_COURSES_DIR ); vector vsCourseGroupNames; - FOREACH_CONST( RString, vsCourseDirs, sDir ) + for (RString const &sDir : vsCourseDirs) { // Find all group directories in Courses dir - GetDirListing( *sDir + "*", vsCourseGroupNames, true, true ); + GetDirListing( sDir + "*", vsCourseGroupNames, true, true ); StripCvsAndSvn( vsCourseGroupNames ); StripMacResourceForks( vsCourseGroupNames ); } @@ -898,11 +856,11 @@ void SongManager::InitCoursesFromDisk( LoadingWindow *ld ) SortRStringArray( vsCourseGroupNames ); int courseIndex = 0; - FOREACH_CONST( RString, vsCourseGroupNames, sCourseGroup ) // for each dir in /Courses/ + for (RString const &sCourseGroup : vsCourseGroupNames) // for each dir in /Courses/ { // Find all CRS files in this group directory vector vsCoursePaths; - GetDirListing( *sCourseGroup + "/*.crs", vsCoursePaths, false, true ); + GetDirListing( sCourseGroup + "/*.crs", vsCoursePaths, false, true ); SortRStringArray( vsCoursePaths ); if( ld ) @@ -911,8 +869,8 @@ void SongManager::InitCoursesFromDisk( LoadingWindow *ld ) ld->SetTotalWork( vsCoursePaths.size() ); } - RString base_course_group= Basename(*sCourseGroup); - FOREACH_CONST( RString, vsCoursePaths, sCoursePath ) + RString base_course_group= Basename(sCourseGroup); + for (RString const &sCoursePath : vsCoursePaths) { if(ld && loading_window_last_update_time.Ago() > next_loading_window_update) { @@ -920,11 +878,11 @@ void SongManager::InitCoursesFromDisk( LoadingWindow *ld ) ld->SetProgress(courseIndex); ld->SetText( LOADING_COURSES.GetValue()+ssprintf("\n%s\n%s", base_course_group.c_str(), - Basename(*sCoursePath).c_str())); + Basename(sCoursePath).c_str())); } Course* pCourse = new Course; - CourseLoaderCRS::LoadFromCRSFile( *sCoursePath, *pCourse ); + CourseLoaderCRS::LoadFromCRSFile( sCoursePath, *pCourse ); if( g_bHideIncompleteCourses.Get() && pCourse->m_bIncomplete ) { @@ -1116,12 +1074,10 @@ void SongManager::DeleteCourse( Course *pCourse ) void SongManager::InvalidateCachedTrails() { - FOREACH_CONST( Course *, m_pCourses, pCourse ) + for (Course *pCourse : m_pCourses) { - const Course &c = **pCourse; - - if( c.IsAnEdit() ) - c.m_TrailCache.clear(); + if( pCourse->IsAnEdit() ) + pCourse->m_TrailCache.clear(); } } @@ -1129,15 +1085,13 @@ void SongManager::InvalidateCachedTrails() * change screens. */ void SongManager::Cleanup() { - for( unsigned i=0; i& vpSteps = pSong->GetAllSteps(); - for( unsigned n=0; nCompress(); } } @@ -1154,9 +1108,9 @@ void SongManager::Invalidate( const Song *pStaleSong ) // Can we regenerate only the autogen courses that are affected? DeleteAutogenCourses(); - FOREACH( Course*, this->m_pCourses, pCourse ) + for (Course *c : this->m_pCourses) { - (*pCourse)->Invalidate( pStaleSong ); + c->Invalidate( pStaleSong ); } InitAutogenCourses(); @@ -1189,9 +1143,8 @@ void SongManager::SaveEnabledSongsToPref() // Intentionally drop disabled song entries for songs that aren't currently loaded. const vector &apSongs = SONGMAN->GetAllSongs(); - FOREACH_CONST( Song *, apSongs, s ) + for (Song *pSong : apSongs) { - Song *pSong = (*s); SongID sid; sid.FromSong( pSong ); if( !pSong->GetEnabled() ) @@ -1205,10 +1158,10 @@ void SongManager::LoadEnabledSongsFromPref() vector asDisabledSongs; split( g_sDisabledSongs, ";", asDisabledSongs, true ); - FOREACH_CONST( RString, asDisabledSongs, s ) + for (RString const &s : asDisabledSongs) { SongID sid; - sid.FromString( *s ); + sid.FromString( s ); Song *pSong = sid.ToSong(); if( pSong ) pSong->SetEnabled( false ); @@ -1218,9 +1171,9 @@ void SongManager::LoadEnabledSongsFromPref() void SongManager::GetStepsLoadedFromProfile( vector &AddTo, ProfileSlot slot ) const { const vector &vSongs = GetAllSongs(); - FOREACH_CONST( Song*, vSongs, song ) + for (Song *song : vSongs) { - (*song)->GetStepsLoadedFromProfile( slot, AddTo ); + song->GetStepsLoadedFromProfile( slot, AddTo ); } } @@ -1313,10 +1266,10 @@ void SongManager::GetExtraStageInfo( bool bExtra2, const Style *sd, Song*& pSong RString sGroup = GAMESTATE->m_sPreferredSongGroup; if( sGroup == GROUP_ALL ) { - if( GAMESTATE->m_pCurSong == NULL ) + if( GAMESTATE->m_pCurSong == nullptr ) { // This normally shouldn't happen, but it's helpful to permit it for testing. - LuaHelpers::ReportScriptErrorFmt( "GetExtraStageInfo() called in GROUP_ALL, but GAMESTATE->m_pCurSong == NULL" ); + LuaHelpers::ReportScriptErrorFmt( "GetExtraStageInfo() called in GROUP_ALL, but GAMESTATE->m_pCurSong == nullptr" ); GAMESTATE->m_pCurSong.Set( GetRandomSong() ); } sGroup = GAMESTATE->m_pCurSong->m_sGroupName; @@ -1336,10 +1289,10 @@ void SongManager::GetExtraStageInfo( bool bExtra2, const Style *sd, Song*& pSong return; // Choose a hard song for the extra stage - Song* pExtra1Song = NULL; // the absolute hardest Song and Steps. Use this for extra stage 1. - Steps* pExtra1Notes = NULL; - Song* pExtra2Song = NULL; // a medium-hard Song and Steps. Use this for extra stage 2. - Steps* pExtra2Notes = NULL; + Song* pExtra1Song = nullptr; // the absolute hardest Song and Steps. Use this for extra stage 1. + Steps* pExtra1Notes = nullptr; + Song* pExtra2Song = nullptr; // a medium-hard Song and Steps. Use this for extra stage 2. + Steps* pExtra2Notes = nullptr; const vector &apSongs = GetSongs( sGroup ); for( unsigned s=0; s 8 (assuming dance) if( bExtra2 && pSteps->GetMeter() > EXTRA_STAGE2_DIFFICULTY_MAX ) continue; // skip - if( pExtra2Notes == NULL || CompareNotesPointersForExtra(pExtra2Notes,pSteps) ) // pSteps is harder than pHardestNotes + if( pExtra2Notes == nullptr || CompareNotesPointersForExtra(pExtra2Notes,pSteps) ) // pSteps is harder than pHardestNotes { pExtra2Song = pSong; pExtra2Notes = pSteps; @@ -1369,7 +1322,7 @@ void SongManager::GetExtraStageInfo( bool bExtra2, const Style *sd, Song*& pSong } } - if( pExtra2Song == NULL && pExtra1Song != NULL ) + if( pExtra2Song == nullptr && pExtra1Song != nullptr ) { pExtra2Song = pExtra1Song; pExtra2Notes = pExtra1Notes; @@ -1387,7 +1340,7 @@ void SongManager::GetExtraStageInfo( bool bExtra2, const Style *sd, Song*& pSong Song* SongManager::GetRandomSong() { if( m_pShuffledSongs.empty() ) - return NULL; + return nullptr; static int i = 0; @@ -1403,13 +1356,13 @@ Song* SongManager::GetRandomSong() return pSong; } - return NULL; + return nullptr; } Course* SongManager::GetRandomCourse() { if( m_pShuffledCourses.empty() ) - return NULL; + return nullptr; static int i = 0; @@ -1427,7 +1380,7 @@ Course* SongManager::GetRandomCourse() return pCourse; } - return NULL; + return nullptr; } Song* SongManager::GetSongFromDir(RString dir) const @@ -1442,33 +1395,33 @@ Song* SongManager::GetSongFromDir(RString dir) const { return entry->second; } - return NULL; + return nullptr; } Course* SongManager::GetCourseFromPath( RString sPath ) const { if( sPath == "" ) - return NULL; + return nullptr; - FOREACH_CONST( Course*, m_pCourses, c ) + for (Course *c : m_pCourses) { - if( sPath.CompareNoCase((*c)->m_sPath) == 0 ) - return *c; + if( sPath.CompareNoCase(c->m_sPath) == 0 ) + return c; } - return NULL; + return nullptr; } Course* SongManager::GetCourseFromName( RString sName ) const { if( sName == "" ) - return NULL; + return nullptr; - for( unsigned int i=0; iGetDisplayFullTitle()) == 0 ) - return m_pCourses[i]; + for (Course *c : m_pCourses) + if( sName.CompareNoCase(c->GetDisplayFullTitle()) == 0 ) + return c; - return NULL; + return nullptr; } @@ -1496,20 +1449,20 @@ Song *SongManager::FindSong( RString sPath ) const else if( bits.size() == 2 ) return FindSong( bits[0], bits[1] ); - return NULL; + return nullptr; } Song *SongManager::FindSong( RString sGroup, RString sSong ) const { // foreach song const vector &vSongs = GetSongs( sGroup.empty()? GROUP_ALL:sGroup ); - FOREACH_CONST( Song*, vSongs, s ) + for (Song *s : vSongs) { - if( (*s)->Matches(sGroup, sSong) ) - return *s; + if( s->Matches(sGroup, sSong) ) + return s; } - return NULL; + return nullptr; } Course *SongManager::FindCourse( RString sPath ) const @@ -1523,18 +1476,18 @@ Course *SongManager::FindCourse( RString sPath ) const else if( bits.size() == 2 ) return FindCourse( bits[0], bits[1] ); - return NULL; + return nullptr; } Course *SongManager::FindCourse( RString sGroup, RString sName ) const { - FOREACH_CONST( Course*, m_pCourses, c ) + for (Course *c : m_pCourses) { - if( (*c)->Matches(sGroup, sName) ) - return *c; + if( c->Matches(sGroup, sName) ) + return c; } - return NULL; + return nullptr; } void SongManager::UpdatePopular() @@ -1588,7 +1541,7 @@ void SongManager::UpdateShuffled() void SongManager::UpdatePreferredSort(RString sPreferredSongs, RString sPreferredCourses) { - ASSERT( UNLOCKMAN != NULL ); + ASSERT( UNLOCKMAN != nullptr ); { m_vPreferredSongSort.clear(); @@ -1602,10 +1555,8 @@ void SongManager::UpdatePreferredSort(RString sPreferredSongs, RString sPreferre PreferredSortSection section; map mapSongToPri; - FOREACH( RString, asLines, s ) + for (RString sLine : asLines) { - RString sLine = *s; - bool bSectionDivider = BeginsWith(sLine, "---"); if( bSectionDivider ) { @@ -1630,17 +1581,17 @@ void SongManager::UpdatePreferredSort(RString sPreferredSongs, RString sPreferre { // add all songs in group const vector &vSongs = GetSongs( group ); - FOREACH_CONST( Song*, vSongs, song ) + for (Song *song : vSongs) { - if( UNLOCKMAN->SongIsLocked(*song) & LOCKED_SELECTABLE ) + if( UNLOCKMAN->SongIsLocked(song) & LOCKED_SELECTABLE ) continue; - section.vpSongs.push_back( *song ); + section.vpSongs.push_back( song ); } } } Song *pSong = FindSong( sLine ); - if( pSong == NULL ) + if( pSong == nullptr ) continue; if( UNLOCKMAN->SongIsLocked(pSong) & LOCKED_SELECTABLE ) continue; @@ -1659,17 +1610,17 @@ void SongManager::UpdatePreferredSort(RString sPreferredSongs, RString sPreferre // move all unlock songs to a group at the bottom PreferredSortSection PFSection; PFSection.sName = "Unlocks"; - FOREACH( UnlockEntry, UNLOCKMAN->m_UnlockEntries, ue ) + for (UnlockEntry const &ue : UNLOCKMAN->m_UnlockEntries) { - if( ue->m_Type == UnlockRewardType_Song ) + if( ue.m_Type == UnlockRewardType_Song ) { - Song *pSong = ue->m_Song.ToSong(); + Song *pSong = ue.m_Song.ToSong(); if( pSong ) PFSection.vpSongs.push_back( pSong ); } } - FOREACH( PreferredSortSection, m_vPreferredSongSort, v ) + for (vector::iterator v = m_vPreferredSongSort.begin(); v != m_vPreferredSongSort.end(); ++v) { for( int i=v->vpSongs.size()-1; i>=0; i-- ) { @@ -1689,9 +1640,11 @@ void SongManager::UpdatePreferredSort(RString sPreferredSongs, RString sPreferre if( m_vPreferredSongSort[i].vpSongs.empty() ) m_vPreferredSongSort.erase( m_vPreferredSongSort.begin()+i ); - FOREACH( PreferredSortSection, m_vPreferredSongSort, i ) - FOREACH( Song*, i->vpSongs, j ) - ASSERT( *j != NULL ); + for (PreferredSortSection const &i : m_vPreferredSongSort) + for (Song const *j : i.vpSongs) + { + ASSERT( j != nullptr ); + } } { @@ -1704,9 +1657,8 @@ void SongManager::UpdatePreferredSort(RString sPreferredSongs, RString sPreferre vector vpCourses; - FOREACH( RString, asLines, s ) + for (RString sLine : asLines) { - RString sLine = *s; bool bSectionDivider = BeginsWith( sLine, "---" ); if( bSectionDivider ) { @@ -1719,7 +1671,7 @@ void SongManager::UpdatePreferredSort(RString sPreferredSongs, RString sPreferre } Course *pCourse = FindCourse( sLine ); - if( pCourse == NULL ) + if( pCourse == nullptr ) continue; if( UNLOCKMAN->CourseIsLocked(pCourse) & LOCKED_SELECTABLE ) continue; @@ -1736,14 +1688,14 @@ void SongManager::UpdatePreferredSort(RString sPreferredSongs, RString sPreferre { // move all unlock Courses to a group at the bottom vector vpUnlockCourses; - FOREACH( UnlockEntry, UNLOCKMAN->m_UnlockEntries, ue ) + for (UnlockEntry const &ue : UNLOCKMAN->m_UnlockEntries) { - if( ue->m_Type == UnlockRewardType_Course ) - if( ue->m_Course.IsValid() ) - vpUnlockCourses.push_back( ue->m_Course.ToCourse() ); + if( ue.m_Type == UnlockRewardType_Course ) + if( ue.m_Course.IsValid() ) + vpUnlockCourses.push_back( ue.m_Course.ToCourse() ); } - FOREACH( CoursePointerVector, m_vPreferredCourseSort, v ) + for (auto v = m_vPreferredCourseSort.begin(); v != m_vPreferredCourseSort.end(); ++v) { for( int i=v->size()-1; i>=0; i-- ) { @@ -1763,9 +1715,11 @@ void SongManager::UpdatePreferredSort(RString sPreferredSongs, RString sPreferre if( m_vPreferredCourseSort[i].empty() ) m_vPreferredCourseSort.erase( m_vPreferredCourseSort.begin()+i ); - FOREACH( CoursePointerVector, m_vPreferredCourseSort, i ) - FOREACH( Course*, *i, j ) - ASSERT( *j != NULL ); + for (CoursePointerVector const &i : m_vPreferredCourseSort) + for (Course *j : i) + { + ASSERT( j != nullptr ); + } } } @@ -1781,14 +1735,14 @@ void SongManager::UpdateRankingCourses() vector RankingCourses; split( THEME->GetMetric("ScreenRanking","CoursesToShow"),",", RankingCourses); - FOREACH( Course*, m_pCourses, c ) + for (Course *c : m_pCourses) { - bool bLotsOfStages = (*c)->GetEstimatedNumStages() > 7; - (*c)->m_SortOrder_Ranking = bLotsOfStages? 3 : 2; + bool bLotsOfStages = c->GetEstimatedNumStages() > 7; + c->m_SortOrder_Ranking = bLotsOfStages? 3 : 2; for( unsigned j = 0; j < RankingCourses.size(); j++ ) - if( !RankingCourses[j].CompareNoCase((*c)->m_sPath) ) - (*c)->m_SortOrder_Ranking = 1; + if( !RankingCourses[j].CompareNoCase(c->m_sPath) ) + c->m_SortOrder_Ranking = 1; } } @@ -1796,14 +1750,9 @@ void SongManager::RefreshCourseGroupInfo() { m_mapCourseGroupToInfo.clear(); - FOREACH_CONST( Course*, m_pCourses, c ) - { - m_mapCourseGroupToInfo[(*c)->m_sGroupName]; // insert - } - - // TODO: Search for course group banners - FOREACHM( RString, CourseGroupInfo, m_mapCourseGroupToInfo, iter ) + for (Course const * c : m_pCourses) { + m_mapCourseGroupToInfo[c->m_sGroupName]; // insert } } @@ -1860,7 +1809,7 @@ void SongManager::LoadStepEditsFromProfileDir( const RString &sProfileDir, Profi // XXX There doesn't appear to be a songdir const? Song *given = GetSongFromDir( "/Songs/"+sSongDir ); // NOTE: We don't have to check the return value of GetSongFromDir here, - // because if it fails, it returns NULL, which is then passed to NotesLoader*.LoadEditFromFile(), + // because if it fails, it returns nullptr, which is then passed to NotesLoader*.LoadEditFromFile(), // which will interpret that as "we couldn't infer the song from the path", // which is what we want in that case anyway. GetDirListing(sDir+sSongDir+"/*.edit", vsEdits, false, true ); @@ -1938,14 +1887,13 @@ void SongManager::FreeAllLoadedFromProfile( ProfileSlot slot ) { // Profile courses may refer to profile steps, so free profile courses first. vector apToDelete; - FOREACH( Course*, m_pCourses, c ) + for (Course *pCourse : m_pCourses) { - Course *pCourse = *c; if( pCourse->GetLoadedFromProfileSlot() == ProfileSlot_Invalid ) continue; if( slot == ProfileSlot_Invalid || pCourse->GetLoadedFromProfileSlot() == slot ) - apToDelete.push_back( *c ); + apToDelete.push_back( pCourse ); } /* We don't use DeleteCourse here, so we don't UpdatePopular and @@ -1967,22 +1915,20 @@ void SongManager::FreeAllLoadedFromProfile( ProfileSlot slot ) set setInUse; if( STATSMAN ) STATSMAN->GetStepsInUse( setInUse ); - FOREACH( Song*, m_pSongs, s ) - (*s)->FreeAllLoadedFromProfile( slot, &setInUse ); + for (Song *s : m_pSongs) + s->FreeAllLoadedFromProfile( slot, &setInUse ); } int SongManager::GetNumStepsLoadedFromProfile() { int iCount = 0; - FOREACH( Song*, m_pSongs, s ) + for (Song const *s : m_pSongs) { - vector vpAllSteps = (*s)->GetAllSteps(); + vector vpAllSteps = s->GetAllSteps(); - FOREACH( Steps*, vpAllSteps, ss ) - { - if( (*ss)->GetLoadedFromProfileSlot() != ProfileSlot_Invalid ) - iCount++; - } + iCount += std::count_if(vpAllSteps.begin(), vpAllSteps.end(), [](Steps const *step) { + return step->GetLoadedFromProfileSlot() != ProfileSlot_Invalid; + }); } return iCount; @@ -2081,8 +2027,8 @@ public: /* Note: this could now be implemented as Luna::GetSong */ static int GetSongFromSteps( T* p, lua_State *L ) { - Song *pSong = NULL; - if( lua_isnil(L,1) ) { pSong = NULL; } + Song *pSong = nullptr; + if( lua_isnil(L,1) ) { pSong = nullptr; } else { Steps *pSteps = Luna::check(L,1); pSong = pSteps->m_pSong; } if(pSong) pSong->PushSelf(L); else lua_pushnil(L); diff --git a/src/SongManager.h b/src/SongManager.h index ffeba83e8d..82ca8b8478 100644 --- a/src/SongManager.h +++ b/src/SongManager.h @@ -65,7 +65,7 @@ public: void InvalidateCachedTrails(); void InitAll( LoadingWindow *ld ); // songs, courses, groups - everything. - void Reload( bool bAllowFastLoad, LoadingWindow *ld=NULL ); // songs, courses, groups - everything. + void Reload( bool bAllowFastLoad, LoadingWindow *ld=nullptr ); // songs, courses, groups - everything. void PreloadSongImages(); bool IsGroupNeverCached(const RString& group) const; diff --git a/src/SongOptions.cpp b/src/SongOptions.cpp index c7af4286b6..f1ad29292c 100644 --- a/src/SongOptions.cpp +++ b/src/SongOptions.cpp @@ -115,9 +115,9 @@ void SongOptions::GetMods( vector &AddTo ) const void SongOptions::GetLocalizedMods( vector &v ) const { GetMods( v ); - FOREACH( RString, v, s ) + for (RString &s : v) { - *s = CommonMetrics::LocalizeOptionItem( *s, true ); + s = CommonMetrics::LocalizeOptionItem( s, true ); } } @@ -144,9 +144,9 @@ void SongOptions::FromString( const RString &sMultipleMods ) vector vs; split( sTemp, ",", vs, true ); RString sThrowAway; - FOREACH( RString, vs, s ) + for (RString &s : vs) { - FromOneModString( *s, sThrowAway ); + FromOneModString( s, sThrowAway ); } } diff --git a/src/SongUtil.cpp b/src/SongUtil.cpp index 0130e76acb..87da39ee0e 100644 --- a/src/SongUtil.cpp +++ b/src/SongUtil.cpp @@ -9,7 +9,6 @@ #include "PrefsManager.h" #include "SongManager.h" #include "XmlFile.h" -#include "Foreach.h" #include "UnlockManager.h" #include "ThemeMetric.h" #include "LocalizedString.h" @@ -158,7 +157,7 @@ Steps* SongUtil::GetOneSteps( vector vpSteps; GetSteps( pSong, vpSteps, st, dc, iMeterLow, iMeterHigh, sDescription, sCredit, bIncludeAutoGen, uHash, 1 ); // get max 1 if( vpSteps.empty() ) - return NULL; + return nullptr; else return vpSteps[0]; } @@ -178,7 +177,7 @@ Steps* SongUtil::GetStepsByDifficulty( const Song *pSong, StepsType st, Difficul return pSteps; } - return NULL; + return nullptr; } Steps* SongUtil::GetStepsByMeter( const Song *pSong, StepsType st, int iMeterLow, int iMeterHigh ) @@ -196,7 +195,7 @@ Steps* SongUtil::GetStepsByMeter( const Song *pSong, StepsType st, int iMeterLow return pSteps; } - return NULL; + return nullptr; } Steps* SongUtil::GetStepsByDescription( const Song *pSong, StepsType st, RString sDescription ) @@ -204,7 +203,7 @@ Steps* SongUtil::GetStepsByDescription( const Song *pSong, StepsType st, RString vector vNotes; GetSteps( pSong, vNotes, st, Difficulty_Invalid, -1, -1, sDescription, "" ); if( vNotes.size() == 0 ) - return NULL; + return nullptr; else return vNotes[0]; } @@ -214,7 +213,7 @@ Steps* SongUtil::GetStepsByCredit( const Song *pSong, StepsType st, RString sCre vector vNotes; GetSteps(pSong, vNotes, st, Difficulty_Invalid, -1, -1, "", sCredit ); if( vNotes.size() == 0 ) - return NULL; + return nullptr; else return vNotes[0]; } @@ -225,7 +224,7 @@ Steps* SongUtil::GetClosestNotes( const Song *pSong, StepsType st, Difficulty dc ASSERT( dc != Difficulty_Invalid ); const vector& vpSteps = (st == StepsType_Invalid)? pSong->GetAllSteps() : pSong->GetStepsByStepsType(st); - Steps *pClosest = NULL; + Steps *pClosest = nullptr; int iClosestDistance = 999; for( unsigned i=0; i &vpSongsInOut, bool b int iCounts[NUM_Grade]; const Profile *pProfile = PROFILEMAN->GetMachineProfile(); - ASSERT( pProfile != NULL ); + ASSERT( pProfile != nullptr ); pProfile->GetGrades( pSong, GAMESTATE->GetCurrentStyle(GAMESTATE->GetMasterPlayerNumber())->m_StepsType, iCounts ); RString foo; @@ -552,7 +551,7 @@ void SongUtil::SortSongPointerArrayByNumPlays( vector &vpSongsInOut, Prof void SongUtil::SortSongPointerArrayByNumPlays( vector &vpSongsInOut, const Profile* pProfile, bool bDescending ) { - ASSERT( pProfile != NULL ); + ASSERT( pProfile != nullptr ); for(unsigned i = 0; i < vpSongsInOut.size(); ++i) g_mapSongSortVal[vpSongsInOut[i]] = ssprintf("%9i", pProfile->GetSongNumTimesPlayed(vpSongsInOut[i])); stable_sort( vpSongsInOut.begin(), vpSongsInOut.end(), bDescending ? CompareSongPointersBySortValueDescending : CompareSongPointersBySortValueAscending ); @@ -561,7 +560,7 @@ void SongUtil::SortSongPointerArrayByNumPlays( vector &vpSongsInOut, cons RString SongUtil::GetSectionNameFromSongAndSort( const Song* pSong, SortOrder so ) { - if( pSong == NULL ) + if( pSong == nullptr ) return RString(); switch( so ) @@ -718,11 +717,11 @@ void SongUtil::SortByMostRecentlyPlayedForMachine( vector &vpSongsInOut ) { Profile *pProfile = PROFILEMAN->GetMachineProfile(); - FOREACH_CONST( Song*, vpSongsInOut, s ) + for (Song const *s : vpSongsInOut) { - int iNumTimesPlayed = pProfile->GetSongNumTimesPlayed( *s ); - RString val = iNumTimesPlayed ? pProfile->GetSongLastPlayedDateTime(*s).GetString() : "0"; - g_mapSongSortVal[*s] = val; + int iNumTimesPlayed = pProfile->GetSongNumTimesPlayed( s ); + RString val = iNumTimesPlayed ? pProfile->GetSongLastPlayedDateTime(s).GetString() : "0"; + g_mapSongSortVal[s] = val; } stable_sort( vpSongsInOut.begin(), vpSongsInOut.end(), CompareSongPointersBySortValueDescending ); @@ -731,10 +730,8 @@ void SongUtil::SortByMostRecentlyPlayedForMachine( vector &vpSongsInOut ) bool SongUtil::IsEditDescriptionUnique( const Song* pSong, StepsType st, const RString &sPreferredDescription, const Steps *pExclude ) { - FOREACH_CONST( Steps*, pSong->GetAllSteps(), s ) + for (Steps const *pSteps : pSong->GetAllSteps()) { - Steps *pSteps = *s; - if( pSteps->GetDifficulty() != Difficulty_Edit ) continue; if( pSteps->m_StepsType != st ) @@ -749,10 +746,8 @@ bool SongUtil::IsEditDescriptionUnique( const Song* pSong, StepsType st, const R bool SongUtil::IsChartNameUnique( const Song* pSong, StepsType st, const RString &name, const Steps *pExclude ) { - FOREACH_CONST( Steps*, pSong->GetAllSteps(), s ) + for (Steps const *pSteps : pSong->GetAllSteps()) { - Steps *pSteps = *s; - if( pSteps->m_StepsType != st ) continue; if( pSteps == pExclude ) @@ -765,7 +760,7 @@ bool SongUtil::IsChartNameUnique( const Song* pSong, StepsType st, const RString RString SongUtil::MakeUniqueEditDescription( const Song *pSong, StepsType st, const RString &sPreferredDescription ) { - if( IsEditDescriptionUnique( pSong, st, sPreferredDescription, NULL ) ) + if( IsEditDescriptionUnique( pSong, st, sPreferredDescription, nullptr ) ) return sPreferredDescription; RString sTemp; @@ -776,7 +771,7 @@ RString SongUtil::MakeUniqueEditDescription( const Song *pSong, StepsType st, co RString sNum = ssprintf("%d", i+1); sTemp = sPreferredDescription.Left( MAX_STEPS_DESCRIPTION_LENGTH - sNum.size() ) + sNum; - if( IsEditDescriptionUnique(pSong, st, sTemp, NULL) ) + if( IsEditDescriptionUnique(pSong, st, sTemp, nullptr) ) return sTemp; } @@ -804,7 +799,7 @@ bool SongUtil::ValidateCurrentEditStepsDescription( const RString &sAnswer, RStr } static const RString sInvalidChars = "\\/:*?\"<>|"; - if( strpbrk(sAnswer, sInvalidChars) != NULL ) + if( strpbrk(sAnswer, sInvalidChars) != nullptr ) { sErrorOut = ssprintf( EDIT_NAME_CANNOT_CONTAIN.GetValue(), sInvalidChars.c_str() ); return false; @@ -813,12 +808,12 @@ bool SongUtil::ValidateCurrentEditStepsDescription( const RString &sAnswer, RStr // Steps name must be unique for this song. vector v; GetSteps( pSong, v, StepsType_Invalid, Difficulty_Edit ); - FOREACH_CONST( Steps*, v, s ) + for (Steps const *s : v) { - if( pSteps == *s ) + if( pSteps == s ) continue; // don't compare name against ourself - if( (*s)->GetDescription() == sAnswer ) + if( s->GetDescription() == sAnswer ) { sErrorOut = EDIT_NAME_CONFLICTS; return false; @@ -854,7 +849,7 @@ bool SongUtil::ValidateCurrentStepsChartName(const RString &answer, RString &err if (answer.empty()) return true; static const RString sInvalidChars = "\\/:*?\"<>|"; - if( strpbrk(answer, sInvalidChars) != NULL ) + if( strpbrk(answer, sInvalidChars) != nullptr ) { error = ssprintf( CHART_NAME_CANNOT_CONTAIN.GetValue(), sInvalidChars.c_str() ); return false; @@ -888,7 +883,7 @@ bool SongUtil::ValidateCurrentStepsCredit( const RString &sAnswer, RString &sErr // Borrow from EditDescription testing. Perhaps this should be abstracted? -Wolfman2000 static const RString sInvalidChars = "\\/:*?\"<>|"; - if( strpbrk(sAnswer, sInvalidChars) != NULL ) + if( strpbrk(sAnswer, sInvalidChars) != nullptr ) { sErrorOut = ssprintf( AUTHOR_NAME_CANNOT_CONTAIN.GetValue(), sInvalidChars.c_str() ); return false; @@ -936,15 +931,14 @@ bool SongUtil::ValidateCurrentStepsMusic(const RString &answer, RString &error) void SongUtil::GetAllSongGenres( vector &vsOut ) { set genres; - FOREACH_CONST( Song*, SONGMAN->GetAllSongs(), song ) + for (Song const *song : SONGMAN->GetAllSongs()) { - if( !(*song)->m_sGenre.empty() ) - genres.insert( (*song)->m_sGenre ); + if( !song->m_sGenre.empty() ) + genres.insert( song->m_sGenre ); } - - FOREACHS_CONST( RString, genres, s ) + for (RString const &genre : genres) { - vsOut.push_back( *s ); + vsOut.push_back( genre ); } } @@ -952,12 +946,11 @@ void SongUtil::FilterSongs( const SongCriteria &sc, const vector &in, vector &out, bool doCareAboutGame ) { out.reserve( in.size() ); - FOREACH_CONST( Song*, in, s ) + for (Song *s : in) { - if( sc.Matches( *s ) && (!doCareAboutGame || IsSongPlayable(*s) ) ) + if( sc.Matches( s ) && (!doCareAboutGame || IsSongPlayable(s) ) ) { - - out.push_back( *s ); + out.push_back( s ); } } } @@ -966,7 +959,7 @@ void SongUtil::GetPlayableStepsTypes( const Song *pSong, set &vOut ) { vector vpPossibleStyles; // If AutoSetStyle, or a Style hasn't been chosen, check StepsTypes for all Styles. - if( CommonMetrics::AUTO_SET_STYLE || GAMESTATE->GetCurrentStyle(PLAYER_INVALID) == NULL ) + if( CommonMetrics::AUTO_SET_STYLE || GAMESTATE->GetCurrentStyle(PLAYER_INVALID) == nullptr ) GAMEMAN->GetCompatibleStyles( GAMESTATE->m_pCurGame, GAMESTATE->GetNumPlayersEnabled(), vpPossibleStyles ); else vpPossibleStyles.push_back( GAMESTATE->GetCurrentStyle(PLAYER_INVALID) ); @@ -992,16 +985,16 @@ void SongUtil::GetPlayableStepsTypes( const Song *pSong, set &vOut ) } set vStepsTypes; - FOREACH( const Style*, vpPossibleStyles, s ) - vStepsTypes.insert( (*s)->m_StepsType ); + for (Style const *s : vpPossibleStyles) + vStepsTypes.insert( s->m_StepsType ); /* filter out hidden StepsTypes, and remove steps that we don't have enough * stages left to play. */ // this being const may have caused some problems... -aj const vector &vstToShow = CommonMetrics::STEPS_TYPES_TO_SHOW.GetValue(); - FOREACHS( StepsType, vStepsTypes, st ) + for (StepsType const &type : vStepsTypes) { - bool bShowThisStepsType = find( vstToShow.begin(), vstToShow.end(), *st ) != vstToShow.end(); + bool bShowThisStepsType = find( vstToShow.begin(), vstToShow.end(), type ) != vstToShow.end(); int iNumPlayers = GAMESTATE->GetNumPlayersEnabled(); iNumPlayers = max( iNumPlayers, 1 ); @@ -1011,7 +1004,7 @@ void SongUtil::GetPlayableStepsTypes( const Song *pSong, set &vOut ) GAMESTATE->GetNumStagesMultiplierForSong(pSong); if( bShowThisStepsType && bEnoughStages ) - vOut.insert( *st ); + vOut.insert( type ); } } @@ -1020,8 +1013,8 @@ void SongUtil::GetPlayableSteps( const Song *pSong, vector &vOut ) set vStepsType; GetPlayableStepsTypes( pSong, vStepsType ); - FOREACHS( StepsType, vStepsType, st ) - SongUtil::GetSteps( pSong, vOut, *st ); + for (StepsType const &type : vStepsType) + SongUtil::GetSteps( pSong, vOut, type ); StepsUtil::RemoveLockedSteps( pSong, vOut ); StepsUtil::SortNotesArrayByDifficulty( vOut ); @@ -1046,15 +1039,9 @@ bool SongUtil::IsSongPlayable( Song *s ) { const vector & steps = s->GetAllSteps(); // I'm sure there is a foreach loop, but I don't - FOREACH( Steps*, const_cast&>(steps), step ) - { - if (IsStepsPlayable(s, *step)) - { - return true; - } - } - - return false; + return std::any_of(steps.begin(), steps.end(), [&](Steps *step) { + return IsStepsPlayable(s, step); + }); } bool SongUtil::GetStepsTypeAndDifficultyFromSortOrder( SortOrder so, StepsType &stOut, Difficulty &dcOut ) @@ -1091,15 +1078,15 @@ bool SongUtil::GetStepsTypeAndDifficultyFromSortOrder( SortOrder so, StepsType & stOut = GAMESTATE->GetCurrentStyle(GAMESTATE->GetMasterPlayerNumber())->m_StepsType; // in case we don't find any matches below vector vpStyles; GAMEMAN->GetStylesForGame(GAMESTATE->m_pCurGame,vpStyles); - FOREACH_CONST( const Style*, vpStyles, i ) + for (Style const *i : vpStyles) { - if( (*i)->m_StyleType == StyleType_OnePlayerTwoSides ) + if( i->m_StyleType == StyleType_OnePlayerTwoSides ) { // Ugly hack to ignore pump's half-double. - bool bContainsHalf = ((RString)(*i)->m_szName).find("half") != RString::npos; + bool bContainsHalf = ((RString)i->m_szName).find("half") != RString::npos; if( bContainsHalf ) continue; - stOut = (*i)->m_StepsType; + stOut = i->m_StepsType; break; } } @@ -1129,7 +1116,7 @@ void SongID::FromSong( const Song *p ) Song *SongID::ToSong() const { - Song *pRet = NULL; + Song *pRet = nullptr; if( !m_Cache.Get(&pRet) ) { if(!sDir.empty()) @@ -1169,7 +1156,7 @@ RString SongID::ToString() const bool SongID::IsValid() const { - return ToSong() != NULL; + return ToSong() != nullptr; } // lua start @@ -1207,7 +1194,7 @@ namespace LIST_METHOD( GetPlayableSteps ), LIST_METHOD( IsStepsTypePlayable ), LIST_METHOD( IsStepsPlayable ), - { NULL, NULL } + { nullptr, nullptr } }; } diff --git a/src/SongUtil.h b/src/SongUtil.h index fa2f6b124d..44a686c4e2 100644 --- a/src/SongUtil.h +++ b/src/SongUtil.h @@ -203,7 +203,7 @@ public: * * This used to call Unset() to do the same thing. */ SongID(): sDir(""), m_Cache() { m_Cache.Unset(); } - void Unset() { FromSong(NULL); } + void Unset() { FromSong(nullptr); } void FromSong( const Song *p ); Song *ToSong() const; bool operator<( const SongID &other ) const diff --git a/src/SoundEffectControl.cpp b/src/SoundEffectControl.cpp index a6ede60fa3..9c910ccbb8 100644 --- a/src/SoundEffectControl.cpp +++ b/src/SoundEffectControl.cpp @@ -12,8 +12,8 @@ SoundEffectControl::SoundEffectControl() m_bLocked = false; m_fSample = 0.0f; m_fLastLevel = 0.0f; - m_pPlayerState = NULL; - m_pNoteData = NULL; + m_pPlayerState = nullptr; + m_pNoteData = nullptr; } void SoundEffectControl::Load( const RString &sType, PlayerState *pPlayerState, const NoteData *pNoteData ) diff --git a/src/SoundEffectControl.h b/src/SoundEffectControl.h index 97ab713991..e299b6e024 100644 --- a/src/SoundEffectControl.h +++ b/src/SoundEffectControl.h @@ -14,7 +14,7 @@ public: void Load( const RString &sType, PlayerState *pPlayerState, const NoteData *pNoteData ); void SetSoundReader( RageSoundReader *pPlayer ); - void ReleaseSound() { SetSoundReader(NULL); } + void ReleaseSound() { SetSoundReader(nullptr); } void Update( float fDeltaTime ); diff --git a/src/Sprite.cpp b/src/Sprite.cpp index baed505525..840e8a3c3d 100644 --- a/src/Sprite.cpp +++ b/src/Sprite.cpp @@ -11,11 +11,11 @@ #include "RageTimer.h" #include "RageUtil.h" #include "ActorUtil.h" -#include "Foreach.h" #include "LuaBinding.h" #include "LuaManager.h" #include "ImageCache.h" #include "ThemeMetric.h" +#include REGISTER_ACTOR_CLASS( Sprite ); @@ -23,7 +23,7 @@ const float min_state_delay= 0.0001f; Sprite::Sprite() { - m_pTexture = NULL; + m_pTexture = nullptr; m_iCurState = 0; m_fSecsIntoState = 0.0f; m_animation_length_seconds= 0.0f; @@ -80,10 +80,10 @@ Sprite::Sprite( const Sprite &cpy ): CPY(m_use_effect_clock_for_texcoords); #undef CPY - if( cpy.m_pTexture != NULL ) + if( cpy.m_pTexture != nullptr ) m_pTexture = TEXTUREMAN->CopyTexture( cpy.m_pTexture ); else - m_pTexture = NULL; + m_pTexture = nullptr; } Sprite &Sprite::operator=( Sprite other ) @@ -201,7 +201,7 @@ void Sprite::LoadFromNode( const XNode* pNode ) vector aStates; const XNode *pFrames = pNode->GetChild( "Frames" ); - if( pFrames != NULL ) + if( pFrames != nullptr ) { /* All attributes are optional. If Frame is omitted, use the previous state's * frame (or 0 if the first). @@ -213,7 +213,7 @@ void Sprite::LoadFromNode( const XNode* pNode ) for( int i=0; true; i++ ) { const XNode *pFrame = pFrames->GetChild( ssprintf("%i", i+1) ); // +1 for Lua's arrays - if( pFrame == NULL ) + if( pFrame == nullptr ) break; State newState; @@ -231,7 +231,7 @@ void Sprite::LoadFromNode( const XNode* pNode ) newState.rect = *m_pTexture->GetTextureCoordRect( iFrameIndex ); const XNode *pPoints[2] = { pFrame->GetChild( "1" ), pFrame->GetChild( "2" ) }; - if( pPoints[0] != NULL && pPoints[1] != NULL ) + if( pPoints[0] != nullptr && pPoints[1] != nullptr ) { RectF r = newState.rect; @@ -286,10 +286,10 @@ void Sprite::LoadFromNode( const XNode* pNode ) void Sprite::UnloadTexture() { - if( m_pTexture != NULL ) // If there was a previous bitmap... + if( m_pTexture != nullptr ) // If there was a previous bitmap... { TEXTUREMAN->UnloadTexture( m_pTexture ); // Unload it. - m_pTexture = NULL; + m_pTexture = nullptr; /* 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 @@ -327,7 +327,7 @@ void Sprite::EnableAnimation( bool bEnable ) void Sprite::SetTexture( RageTexture *pTexture ) { - ASSERT( pTexture != NULL ); + ASSERT( pTexture != nullptr ); if( m_pTexture != pTexture ) { @@ -355,7 +355,7 @@ void Sprite::LoadFromTexture( RageTextureID ID ) { // LOG->Trace( "Sprite::LoadFromTexture( %s )", ID.filename.c_str() ); - RageTexture *pTexture = NULL; + RageTexture *pTexture = nullptr; if( m_pTexture && m_pTexture->GetID() == ID ) pTexture = m_pTexture; else @@ -390,7 +390,7 @@ void Sprite::LoadStatesFromTexture() // Assume the frames of this animation play in sequential order with 0.1 second delay. m_States.clear(); - if( m_pTexture == NULL ) + if( m_pTexture == nullptr ) { State newState; newState.fDelay = 0.1f; @@ -664,7 +664,7 @@ void Sprite::DrawTexture( const TweenState *state ) bool Sprite::EarlyAbortDraw() const { - return m_pTexture == NULL; + return m_pTexture == nullptr; } void Sprite::DrawPrimitives() @@ -842,9 +842,9 @@ void Sprite::SetState( int iNewState ) void Sprite::RecalcAnimationLengthSeconds() { m_animation_length_seconds = 0; - FOREACH_CONST(State, m_States, s) + for (State const &s : m_States) { - m_animation_length_seconds += s->fDelay; + m_animation_length_seconds += s.fDelay; } } @@ -859,7 +859,7 @@ void Sprite::SetSecondsIntoAnimation( float fSeconds ) RString Sprite::GetTexturePath() const { - if( m_pTexture==NULL ) + if( m_pTexture == nullptr ) return RString(); return m_pTexture->GetID().filename; @@ -1275,7 +1275,7 @@ public: static int GetTexture( T* p, lua_State *L ) { RageTexture *pTexture = p->GetTexture(); - if( pTexture != NULL ) + if( pTexture != nullptr ) pTexture->PushSelf(L); else lua_pushnil( L ); diff --git a/src/StageStats.cpp b/src/StageStats.cpp index 67c4caed84..8863a3619c 100644 --- a/src/StageStats.cpp +++ b/src/StageStats.cpp @@ -1,7 +1,6 @@ #include "global.h" #include "StageStats.h" #include "GameState.h" -#include "Foreach.h" #include "Steps.h" #include "Song.h" #include "RageLog.h" @@ -51,7 +50,7 @@ void StageStats::AssertValid( PlayerNumber pn ) const CHECKPOINT_M( m_vpPlayedSongs[0]->GetTranslitFullTitle() ); ASSERT( m_player[pn].m_iStepsPlayed > 0 ); ASSERT( m_player[pn].m_vpPossibleSteps.size() != 0 ); - ASSERT( m_player[pn].m_vpPossibleSteps[0] != NULL ); + ASSERT( m_player[pn].m_vpPossibleSteps[0] != nullptr ); ASSERT_M( m_playMode < NUM_PlayMode, ssprintf("playmode %i", m_playMode) ); ASSERT_M( m_player[pn].m_vpPossibleSteps[0]->GetDifficulty() < NUM_Difficulty, ssprintf("Invalid Difficulty %i", m_player[pn].m_vpPossibleSteps[0]->GetDifficulty()) ); ASSERT_M( (int) m_vpPlayedSongs.size() == m_player[pn].m_iStepsPlayed, ssprintf("%i Songs Played != %i Steps Played for player %i", (int)m_vpPlayedSongs.size(), (int)m_player[pn].m_iStepsPlayed, pn) ); @@ -65,7 +64,7 @@ void StageStats::AssertValid( MultiPlayer pn ) const if( m_vpPlayedSongs[0] ) CHECKPOINT_M( m_vpPlayedSongs[0]->GetTranslitFullTitle() ); ASSERT( m_multiPlayer[pn].m_vpPossibleSteps.size() != 0 ); - ASSERT( m_multiPlayer[pn].m_vpPossibleSteps[0] != NULL ); + ASSERT( m_multiPlayer[pn].m_vpPossibleSteps[0] != nullptr ); ASSERT_M( m_playMode < NUM_PlayMode, ssprintf("playmode %i", m_playMode) ); ASSERT_M( m_player[pn].m_vpPossibleSteps[0]->GetDifficulty() < NUM_Difficulty, ssprintf("difficulty %i", m_player[pn].m_vpPossibleSteps[0]->GetDifficulty()) ); ASSERT( (int) m_vpPlayedSongs.size() == m_player[pn].m_iStepsPlayed ); @@ -91,10 +90,10 @@ int StageStats::GetAverageMeter( PlayerNumber pn ) const void StageStats::AddStats( const StageStats& other ) { ASSERT( !other.m_vpPlayedSongs.empty() ); - FOREACH_CONST( Song*, other.m_vpPlayedSongs, s ) - m_vpPlayedSongs.push_back( *s ); - FOREACH_CONST( Song*, other.m_vpPossibleSongs, s ) - m_vpPossibleSongs.push_back( *s ); + for (Song *s : other.m_vpPlayedSongs) + m_vpPlayedSongs.push_back( s ); + for (Song *s : other.m_vpPossibleSongs) + m_vpPossibleSongs.push_back( s ); m_Stage = Stage_Invalid; // meaningless m_iStageIndex = -1; // meaningless @@ -127,8 +126,8 @@ bool StageStats::AllFailed() const float StageStats::GetTotalPossibleStepsSeconds() const { float fSecs = 0; - FOREACH_CONST( Song*, m_vpPossibleSongs, s ) - fSecs += (*s)->GetStepsSeconds(); + for (Song const *s : m_vpPlayedSongs) + fSecs += s->GetStepsSeconds(); return fSecs / m_fMusicRate; } @@ -244,14 +243,14 @@ void StageStats::FinalizeScores( bool bSummary ) { // Save this stage to recent scores Course* pCourse = GAMESTATE->m_pCurCourse; - ASSERT( pCourse != NULL ); + ASSERT( pCourse != nullptr ); Trail* pTrail = GAMESTATE->m_pCurTrail[p]; PROFILEMAN->AddCourseScore( pCourse, pTrail, p, hs, m_player[p].m_iPersonalHighScoreIndex, m_player[p].m_iMachineHighScoreIndex ); } else { - ASSERT( pSteps != NULL ); + ASSERT( pSteps != nullptr ); PROFILEMAN->AddStepsScore( pSong, pSteps, p, hs, m_player[p].m_iPersonalHighScoreIndex, m_player[p].m_iMachineHighScoreIndex ); } @@ -269,7 +268,7 @@ void StageStats::FinalizeScores( bool bSummary ) Profile* pProfile = PROFILEMAN->GetMachineProfile(); StepsType st = GAMESTATE->GetCurrentStyle(p)->m_StepsType; - const HighScoreList *pHSL = NULL; + const HighScoreList *pHSL = nullptr; if( bSummary ) { pHSL = &pProfile->GetCategoryHighScoreList( st, m_player[p].m_rc ); @@ -277,9 +276,9 @@ void StageStats::FinalizeScores( bool bSummary ) else if( GAMESTATE->IsCourseMode() ) { Course* pCourse = GAMESTATE->m_pCurCourse; - ASSERT( pCourse != NULL ); + ASSERT( pCourse != nullptr ); Trail *pTrail = GAMESTATE->m_pCurTrail[p]; - ASSERT( pTrail != NULL ); + ASSERT( pTrail != nullptr ); pHSL = &pProfile->GetCourseHighScoreList( pCourse, pTrail ); } else diff --git a/src/StatsManager.cpp b/src/StatsManager.cpp index 68eaf3c0f5..c9316b6f9f 100644 --- a/src/StatsManager.cpp +++ b/src/StatsManager.cpp @@ -2,7 +2,6 @@ #include "StatsManager.h" #include "RageFileManager.h" #include "GameState.h" -#include "Foreach.h" #include "ProfileManager.h" #include "Profile.h" #include "PrefsManager.h" @@ -20,7 +19,7 @@ #include "PlayerState.h" #include "Player.h" -StatsManager* STATSMAN = NULL; // global object accessible from anywhere in the program +StatsManager* STATSMAN = nullptr; // global object accessible from anywhere in the program void AddPlayerStatsToProfile( Profile *pProfile, const StageStats &ss, PlayerNumber pn ); XNode* MakeRecentScoreNode( const StageStats &ss, Trail *pTrail, const PlayerStageStats &pss, MultiPlayer mp ); @@ -62,8 +61,8 @@ static StageStats AccumPlayedStageStats( const vector& vss ) ssreturn.m_playMode = vss[0].m_playMode; } - FOREACH_CONST( StageStats, vss, ss ) - ssreturn.AddStats( *ss ); + for (StageStats const &ss :vss) + ssreturn.AddStats( ss ); unsigned uNumSongs = ssreturn.m_vpPlayedSongs.size(); @@ -152,7 +151,7 @@ void AddPlayerStatsToProfile( Profile *pProfile, const StageStats &ss, PlayerNum XNode* MakeRecentScoreNode( const StageStats &ss, Trail *pTrail, const PlayerStageStats &pss, MultiPlayer mp ) { - XNode* pNode = NULL; + XNode* pNode = nullptr; if( GAMESTATE->IsCourseMode() ) { pNode = new XNode( "HighScoreForACourseAndTrail" ); @@ -253,10 +252,10 @@ void StatsManager::CommitStatsToProfiles( const StageStats *pSS ) void StatsManager::SaveUploadFile( const StageStats *pSS ) { // Save recent scores - auto_ptr xml( new XNode("Stats") ); + unique_ptr xml( new XNode("Stats") ); xml->AppendChild( "MachineGuid", PROFILEMAN->GetMachineProfile()->m_sGuid ); - XNode *recent = NULL; + XNode *recent = nullptr; if( GAMESTATE->IsCourseMode() ) recent = xml->AppendChild( new XNode("RecentCourseScores") ); else @@ -301,7 +300,7 @@ void StatsManager::SavePadmissScore( const StageStats *pSS, PlayerNumber pn ) { const PlayerStageStats *playerStats = &pSS->m_player[ pn ]; - auto_ptr xml( new XNode("SongScore") ); + std::unique_ptr xml( new XNode("SongScore") ); RString sDate = DateTime::GetNowDate().GetString(); sDate.Replace(":","-"); @@ -472,8 +471,8 @@ void StatsManager::UnjoinPlayer( PlayerNumber pn ) /* A player has been unjoined. Clear his data from m_vPlayedStageStats, and * purge any m_vPlayedStageStats that no longer have any player data because * all of the players that were playing at the time have been unjoined. */ - FOREACH( StageStats, m_vPlayedStageStats, ss ) - ss->m_player[pn] = PlayerStageStats(); + for(StageStats &ss : m_vPlayedStageStats) + ss.m_player[pn] = PlayerStageStats(); for( int i = 0; i < (int) m_vPlayedStageStats.size(); ++i ) { @@ -580,17 +579,8 @@ public: FOREACH_HumanPlayer( p ) { // If this player failed any stage, then their final grade is an F. - bool bPlayerFailedOneStage = false; - FOREACH_CONST( StageStats, STATSMAN->m_vPlayedStageStats, ss ) - { - if( ss->m_player[p].m_bFailed ) - { - bPlayerFailedOneStage = true; - break; - } - } - - if( bPlayerFailedOneStage ) + if (std::any_of(STATSMAN->m_vPlayedStageStats.begin(), STATSMAN->m_vPlayedStageStats.end(), + [&](StageStats const &ss) { return ss.m_player[p].m_bFailed; })) continue; top_grade = min( top_grade, stats.m_player[p].GetGrade() ); diff --git a/src/StepMania.cpp b/src/StepMania.cpp index 926dcea122..46c7971623 100644 --- a/src/StepMania.cpp +++ b/src/StepMania.cpp @@ -198,7 +198,7 @@ static void update_centering() static void StartDisplay() { - if( DISPLAY != NULL ) + if( DISPLAY != nullptr ) return; // already started DISPLAY = CreateDisplay(); @@ -277,7 +277,7 @@ void StepMania::ResetPreferences() /* Shutdown all global singletons. Note that this may be called partway through * initialization, due to an object failing to initialize, in which case some of - * these may still be NULL. */ + * these may still be nullptr. */ void ShutdownGame() { /* First, tell SOUNDMAN that we're shutting down. This signals sound drivers to @@ -759,7 +759,7 @@ RageDisplay *CreateDisplay() if( asRenderers.empty() ) RageException::Throw( "%s", ERROR_NO_VIDEO_RENDERERS.GetValue().c_str() ); - RageDisplay *pRet = NULL; + RageDisplay *pRet = nullptr; for( unsigned i=0; iInit( params, PREFSMAN->m_bAllowUnacceleratedRenderer ); @@ -807,7 +807,7 @@ RageDisplay *CreateDisplay() break; // the display is ready to go } - if( pRet == NULL) + if( pRet == nullptr) RageException::Throw( "%s", error.c_str() ); return pRet; @@ -818,7 +818,7 @@ static void SwitchToLastPlayedGame() const Game *pGame = GAMEMAN->StringToGame( PREFSMAN->GetCurrentGame() ); // If the active game type isn't actually available, revert to the default. - if( pGame == NULL ) + if( pGame == nullptr ) pGame = GAMEMAN->GetDefaultGame(); if( !GAMEMAN->IsGameEnabled( pGame ) && pGame != GAMEMAN->GetDefaultGame() ) @@ -836,10 +836,10 @@ static void SwitchToLastPlayedGame() // This function is meant to only be called during start up. void StepMania::InitializeCurrentGame( const Game* g ) { - ASSERT( g != NULL ); - ASSERT( GAMESTATE != NULL ); - ASSERT( ANNOUNCER != NULL ); - ASSERT( THEME != NULL ); + ASSERT( g != nullptr ); + ASSERT( GAMESTATE != nullptr ); + ASSERT( ANNOUNCER != nullptr ); + ASSERT( THEME != nullptr ); GAMESTATE->SetCurGame( g ); @@ -854,7 +854,7 @@ void StepMania::InitializeCurrentGame( const Game* g ) if( GetCommandlineArgument( "game", &argCurGame) && argCurGame != sGametype ) { Game const* new_game= GAMEMAN->StringToGame(argCurGame); - if(new_game == NULL) + if(new_game == nullptr) { LOG->Warn("%s is not a known game type, ignoring.", argCurGame.c_str()); } @@ -1061,10 +1061,10 @@ int sm_main(int argc, char* argv[]) // This requires PREFSMAN, for PREFSMAN->m_bShowLoadingWindow. LoadingWindow *pLoadingWindow = LoadingWindow::Create(); - if(pLoadingWindow == NULL) + if(pLoadingWindow == nullptr) RageException::Throw("%s", COULDNT_OPEN_LOADING_WINDOW.GetValue().c_str()); - srand( time(NULL) ); // seed number generator + srand( time(nullptr) ); // seed number generator /* Do this early, so we have debugging output if anything else fails. LOG and * Dialog must be set up first. It shouldn't take long, but it might take a @@ -1134,11 +1134,11 @@ int sm_main(int argc, char* argv[]) * theme into the loading window. */ RString sError; RageSurface *pSurface = RageSurfaceUtils::LoadFile( THEME->GetPathG( "Common", "window icon" ), sError ); - if( pSurface != NULL ) + if( pSurface != nullptr ) pLoadingWindow->SetIcon( pSurface ); delete pSurface; pSurface = RageSurfaceUtils::LoadFile( THEME->GetPathG("Common","splash"), sError ); - if( pSurface != NULL ) + if( pSurface != nullptr ) pLoadingWindow->SetSplash( pSurface ); delete pSurface; } diff --git a/src/Steps.cpp b/src/Steps.cpp index 5ac2430820..8b6643dfc9 100644 --- a/src/Steps.cpp +++ b/src/Steps.cpp @@ -46,7 +46,7 @@ XToString( DisplayBPM ); LuaXType( DisplayBPM ); Steps::Steps(Song *song): m_StepsType(StepsType_Invalid), m_pSong(song), - parent(NULL), m_pNoteData(new NoteData), m_bNoteDataIsFilled(false), + parent(nullptr), m_pNoteData(new NoteData), m_bNoteDataIsFilled(false), m_sNoteDataCompressed(""), m_sFilename(""), m_bSavedToDisk(false), m_LoadedFromProfile(ProfileSlot_Invalid), m_iHash(0), m_sDescription(""), m_sChartStyle(""), @@ -295,7 +295,7 @@ void Steps::TidyUpData() void Steps::CalculateRadarValues( float fMusicLengthSeconds ) { // If we're autogen, don't calculate values. GetRadarValues will take from our parent. - if( parent != NULL ) + if( parent != nullptr ) return; if( m_bAreCachedRadarValuesJustLoaded ) @@ -348,7 +348,7 @@ void Steps::CalculateRadarValues( float fMusicLengthSeconds ) NoteDataUtil::CalculateRadarValues( tempNoteData, fMusicLengthSeconds, m_CachedRadarValues[0] ); fill_n( m_CachedRadarValues + 1, NUM_PLAYERS-1, m_CachedRadarValues[0] ); } - GAMESTATE->SetProcessedTimingData(NULL); + GAMESTATE->SetProcessedTimingData(nullptr); } void Steps::ChangeFilenamesForCustomSong() @@ -501,7 +501,7 @@ void Steps::DeAutogen( bool bCopyNoteData ) m_iMeter = Real()->m_iMeter; copy( Real()->m_CachedRadarValues, Real()->m_CachedRadarValues + NUM_PLAYERS, m_CachedRadarValues ); m_sCredit = Real()->m_sCredit; - parent = NULL; + parent = nullptr; if( bCopyNoteData ) Compress(); @@ -522,7 +522,7 @@ void Steps::CopyFrom( Steps* pSource, StepsType ntTo, float fMusicLengthSeconds NoteData noteData; pSource->GetNoteData( noteData ); noteData.SetNumTracks( GAMEMAN->GetStepsTypeInfo(ntTo).iNumTracks ); - parent = NULL; + parent = nullptr; m_Timing = pSource->m_Timing; this->m_pSong = pSource->m_pSong; this->m_Attacks = pSource->m_Attacks; diff --git a/src/Steps.h b/src/Steps.h index b80d9f3b86..991d07fe6f 100644 --- a/src/Steps.h +++ b/src/Steps.h @@ -58,7 +58,7 @@ public: * @brief Determine if these steps were created by the autogenerator. * @return true if they were, false otherwise. */ - bool IsAutogen() const { return parent != NULL; } + bool IsAutogen() const { return parent != nullptr; } /** * @brief Determine if this set of Steps is an edit. diff --git a/src/StepsDisplay.cpp b/src/StepsDisplay.cpp index 6996e7f0e5..9e3da422d1 100644 --- a/src/StepsDisplay.cpp +++ b/src/StepsDisplay.cpp @@ -150,25 +150,25 @@ void StepsDisplay::SetFromGameState( PlayerNumber pn ) void StepsDisplay::SetFromSteps( const Steps* pSteps ) { - if( pSteps == NULL ) + if( pSteps == nullptr ) { Unset(); return; } - SetParams params = { pSteps, NULL, pSteps->GetMeter(), pSteps->m_StepsType, pSteps->GetDifficulty(), CourseType_Invalid }; + SetParams params = { pSteps, nullptr, pSteps->GetMeter(), pSteps->m_StepsType, pSteps->GetDifficulty(), CourseType_Invalid }; SetInternal( params ); } void StepsDisplay::SetFromTrail( const Trail* pTrail ) { - if( pTrail == NULL ) + if( pTrail == nullptr ) { Unset(); return; } - SetParams params = { NULL, pTrail, pTrail->GetMeter(), pTrail->m_StepsType, pTrail->m_CourseDifficulty, pTrail->m_CourseType }; + SetParams params = { nullptr, pTrail, pTrail->GetMeter(), pTrail->m_StepsType, pTrail->m_CourseDifficulty, pTrail->m_CourseType }; SetInternal( params ); } @@ -179,7 +179,7 @@ void StepsDisplay::Unset() void StepsDisplay::SetFromStepsTypeAndMeterAndDifficultyAndCourseType( StepsType st, int iMeter, Difficulty dc, CourseType ct ) { - SetParams params = { NULL, NULL, iMeter, st, dc, ct }; + SetParams params = { nullptr, nullptr, iMeter, st, dc, ct }; SetInternal( params ); } @@ -288,12 +288,12 @@ void StepsDisplay::SetInternal( const SetParams ¶ms ) class LunaStepsDisplay: public Luna { public: - static int Load( T* p, lua_State *L ) { p->Load( SArg(1), NULL ); COMMON_RETURN_SELF; } + static int Load( T* p, lua_State *L ) { p->Load( SArg(1), nullptr ); COMMON_RETURN_SELF; } static int SetFromSteps( T* p, lua_State *L ) { if( lua_isnil(L,1) ) { - p->SetFromSteps( NULL ); + p->SetFromSteps(nullptr); } else { @@ -306,7 +306,7 @@ public: { if( lua_isnil(L,1) ) { - p->SetFromTrail( NULL ); + p->SetFromTrail(nullptr); } else { diff --git a/src/StepsUtil.cpp b/src/StepsUtil.cpp index 57651263a5..6df151b2c5 100644 --- a/src/StepsUtil.cpp +++ b/src/StepsUtil.cpp @@ -41,13 +41,13 @@ bool StepsCriteria::Matches( const Song *pSong, const Steps *pSteps ) const void StepsUtil::GetAllMatching( const SongCriteria &soc, const StepsCriteria &stc, vector &out ) { const RString &sGroupName = soc.m_sGroupName.empty()? GROUP_ALL:soc.m_sGroupName; - const vector &songs = SONGMAN->GetSongs( sGroupName ); + const vector &songs = SONGMAN->GetSongs( sGroupName ); - FOREACH_CONST( Song*, songs, so ) + for (Song *so : songs) { - if( !soc.Matches(*so) ) + if( !soc.Matches(so) ) continue; - GetAllMatching( *so, stc, out ); + GetAllMatching( so, stc, out ); // TODO: Look into why this can't be const. } } @@ -56,9 +56,9 @@ void StepsUtil::GetAllMatching( Song *pSong, const StepsCriteria &stc, vector &vSteps = ( stc.m_st == StepsType_Invalid ? pSong->GetAllSteps() : pSong->GetStepsByStepsType(stc.m_st) ); - FOREACH_CONST( Steps*, vSteps, st ) - if( stc.Matches(pSong, *st) ) - out.push_back( SongAndSteps(pSong, *st) ); + for (Steps *st : vSteps) + if( stc.Matches(pSong, st) ) + out.push_back( SongAndSteps(pSong, st) ); } void StepsUtil::GetAllMatchingEndless( Song *pSong, const StepsCriteria &stc, vector &out ) @@ -80,7 +80,7 @@ void StepsUtil::GetAllMatchingEndless( Song *pSong, const StepsCriteria &stc, ve Difficulty previousDifficulty = difficulty; int lowestDifficultyIndex = 0; vector difficulties; - FOREACH_CONST( Steps*, vSteps, st ) + for (auto st = vSteps.begin(); st != vSteps.end(); ++st) { previousDifficulty = difficulty; difficulty = ( *st )->GetDifficulty(); @@ -100,26 +100,19 @@ void StepsUtil::GetAllMatchingEndless( Song *pSong, const StepsCriteria &stc, ve bool StepsUtil::HasMatching( const SongCriteria &soc, const StepsCriteria &stc ) { const RString &sGroupName = soc.m_sGroupName.empty()? GROUP_ALL:soc.m_sGroupName; - const vector &songs = SONGMAN->GetSongs( sGroupName ); + const vector &songs = SONGMAN->GetSongs( sGroupName ); - FOREACH_CONST( Song*, songs, so ) - { - if( soc.Matches(*so) && HasMatching(*so, stc) ) - return true; - } - return false; + return std::any_of(songs.begin(), songs.end(), [&](Song const *so) { + return soc.Matches(so) && HasMatching(so, stc); + }); } bool StepsUtil::HasMatching( const Song *pSong, const StepsCriteria &stc ) { const vector &vSteps = stc.m_st == StepsType_Invalid? pSong->GetAllSteps():pSong->GetStepsByStepsType( stc.m_st ); - - FOREACH_CONST( Steps*, vSteps, st ) - { - if( stc.Matches(pSong, *st) ) - return true; - } - return false; + return std::any_of(vSteps.begin(), vSteps.end(), [&](Steps const *st) { + return stc.Matches(pSong, st); + }); } // Sorting stuff @@ -165,7 +158,7 @@ void StepsUtil::SortStepsPointerArrayByNumPlays( vector &vStepsPointers, } } - ASSERT( pProfile != NULL ); + ASSERT( pProfile != nullptr ); for(unsigned i = 0; i < vStepsPointers.size(); ++i) { Steps* pSteps = vStepsPointers[i]; @@ -247,7 +240,7 @@ void StepsUtil::RemoveLockedSteps( const Song *pSong, vector &vpSteps ) void StepsID::FromSteps( const Steps *p ) { - if( p == NULL ) + if( p == nullptr ) { st = StepsType_Invalid; dc = Difficulty_Invalid; @@ -285,12 +278,12 @@ void StepsID::FromSteps( const Steps *p ) Steps *StepsID::ToSteps( const Song *p, bool bAllowNull ) const { if( st == StepsType_Invalid || dc == Difficulty_Invalid ) - return NULL; + return nullptr; SongID songID; songID.FromSong( p ); - Steps *pRet = NULL; + Steps *pRet = nullptr; if( dc == Difficulty_Edit ) { pRet = SongUtil::GetOneSteps( p, st, dc, -1, -1, sDescription, "", uHash, true ); @@ -300,7 +293,7 @@ Steps *StepsID::ToSteps( const Song *p, bool bAllowNull ) const pRet = SongUtil::GetOneSteps( p, st, dc, -1, -1, "", "", 0, true ); } - if( !bAllowNull && pRet == NULL ) + if( !bAllowNull && pRet == nullptr ) FAIL_M( ssprintf("%i, %i, \"%s\"", st, dc, sDescription.c_str()) ); m_Cache.Set( pRet ); diff --git a/src/StepsUtil.h b/src/StepsUtil.h index 216cc32751..21f7c0d0fc 100644 --- a/src/StepsUtil.h +++ b/src/StepsUtil.h @@ -90,7 +90,7 @@ public: Steps *pSteps; /** @brief Set up a blank Song and * Step. */ - SongAndSteps() : pSong(NULL), pSteps(NULL) { } + SongAndSteps() : pSong(nullptr), pSteps(nullptr) { } /** * @brief Set up the specified Song and * Step. @@ -177,7 +177,7 @@ public: * the same thing. */ StepsID(): st(StepsType_Invalid), dc(Difficulty_Invalid), sDescription(""), uHash(0), m_Cache() {} - void Unset() { FromSteps(NULL); } + void Unset() { FromSteps(nullptr); } void FromSteps( const Steps *p ); Steps *ToSteps( const Song *p, bool bAllowNull ) const; // FIXME: (interferes with unlimited charts per song) diff --git a/src/StreamDisplay.h b/src/StreamDisplay.h index 90aeb705a3..bd44e88e63 100644 --- a/src/StreamDisplay.h +++ b/src/StreamDisplay.h @@ -1,79 +1,79 @@ -/* StreamDisplay - */ -#ifndef StreamDisplay_H -#define StreamDisplay_H - -#include "ActorFrame.h" -#include "Sprite.h" -#include "Quad.h" -#include "LuaExpressionTransform.h" -#include "ThemeMetric.h" - -enum StreamType -{ - StreamType_Normal, - StreamType_Passing, - StreamType_Hot, - NUM_StreamType, -}; - -class StreamDisplay : public ActorFrame -{ -public: - StreamDisplay(); - - virtual void Update( float fDeltaSecs ); - - void Load( const RString &sMetricsGroup ); - - void SetPercent( float fPercent ); - void SetPassingAlpha( float fPassingAlpha ) { m_fPassingAlpha = fPassingAlpha; } - void SetHotAlpha( float fHotAlpha ) { m_fHotAlpha = fHotAlpha; } - - float GetPercent() { return m_fPercent; } - -private: - vector m_vpSprPill[NUM_StreamType]; - - LuaExpressionTransform m_transformPill; // params: self,offsetFromCenter,itemIndex,numItems - ThemeMetric VELOCITY_MULTIPLIER; - ThemeMetric VELOCITY_MIN; - ThemeMetric VELOCITY_MAX; - ThemeMetric SPRING_MULTIPLIER; - ThemeMetric VISCOSITY_MULTIPLIER; - - float m_fPercent; // percent filled - float m_fTrailingPercent; // this approaches m_fPercent, use this value to draw - float m_fVelocity; // velocity of m_fTrailingPercent - - float m_fPassingAlpha; - float m_fHotAlpha; - - bool m_bAlwaysBounce; -}; - -#endif - -/* - * (c) 2003-2004 Chris Danford - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +/* StreamDisplay - */ +#ifndef StreamDisplay_H +#define StreamDisplay_H + +#include "ActorFrame.h" +#include "Sprite.h" +#include "Quad.h" +#include "LuaExpressionTransform.h" +#include "ThemeMetric.h" + +enum StreamType +{ + StreamType_Normal, + StreamType_Passing, + StreamType_Hot, + NUM_StreamType, +}; + +class StreamDisplay : public ActorFrame +{ +public: + StreamDisplay(); + + virtual void Update( float fDeltaSecs ); + + void Load( const RString &sMetricsGroup ); + + void SetPercent( float fPercent ); + void SetPassingAlpha( float fPassingAlpha ) { m_fPassingAlpha = fPassingAlpha; } + void SetHotAlpha( float fHotAlpha ) { m_fHotAlpha = fHotAlpha; } + + float GetPercent() { return m_fPercent; } + +private: + vector m_vpSprPill[NUM_StreamType]; + + LuaExpressionTransform m_transformPill; // params: self,offsetFromCenter,itemIndex,numItems + ThemeMetric VELOCITY_MULTIPLIER; + ThemeMetric VELOCITY_MIN; + ThemeMetric VELOCITY_MAX; + ThemeMetric SPRING_MULTIPLIER; + ThemeMetric VISCOSITY_MULTIPLIER; + + float m_fPercent; // percent filled + float m_fTrailingPercent; // this approaches m_fPercent, use this value to draw + float m_fVelocity; // velocity of m_fTrailingPercent + + float m_fPassingAlpha; + float m_fHotAlpha; + + bool m_bAlwaysBounce; +}; + +#endif + +/* + * (c) 2003-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/Style.cpp b/src/Style.cpp index a628307574..3d5e4acc4f 100644 --- a/src/Style.cpp +++ b/src/Style.cpp @@ -127,7 +127,7 @@ float Style::GetWidth(PlayerNumber pn) const RString Style::ColToButtonName( int iCol ) const { const char *pzColumnName = m_ColumnInfo[PLAYER_1][iCol].pzName; - if( pzColumnName != NULL ) + if( pzColumnName != nullptr ) return pzColumnName; vector GI; diff --git a/src/Style.h b/src/Style.h index 2562d2bb8d..187450820f 100644 --- a/src/Style.h +++ b/src/Style.h @@ -54,7 +54,7 @@ public: { int track; /**< Take note data from this track. */ float fXOffset; /**< This is the x position of the column relative to the player's center. */ - const char *pzName; /**< The name of the column, or NULL to use the button name mapped to it. */ + const char *pzName; /**< The name of the column, or nullptr to use the button name mapped to it. */ }; /** @brief Map each players' colun to a track in the NoteData. */ diff --git a/src/StyleUtil.cpp b/src/StyleUtil.cpp index 114803e8d2..d96ddce726 100644 --- a/src/StyleUtil.cpp +++ b/src/StyleUtil.cpp @@ -1,91 +1,91 @@ -#include "global.h" -#include "StyleUtil.h" -#include "GameManager.h" -#include "XmlFile.h" -#include "Game.h" -#include "Style.h" - - -void StyleID::FromStyle( const Style *p ) -{ - if( p ) - { - sGame = GAMEMAN->GetGameForStyle(p)->m_szName; - sStyle = p->m_szName; - } - else - { - sGame = ""; - sStyle = ""; - } -} - -const Style *StyleID::ToStyle() const -{ - const Game* pGame = GAMEMAN->StringToGame( sGame ); - if( pGame == NULL ) - return NULL; - - return GAMEMAN->GameAndStringToStyle( pGame, sStyle ); -} - -XNode* StyleID::CreateNode() const -{ - XNode* pNode = new XNode( "Style" ); - - pNode->AppendAttr( "Game", sGame ); - pNode->AppendAttr( "Style", sStyle ); - - return pNode; -} - -void StyleID::LoadFromNode( const XNode* pNode ) -{ - Unset(); - ASSERT( pNode->GetName() == "Style" ); - - sGame = ""; - pNode->GetAttrValue("Game", sGame); - - sStyle = ""; - pNode->GetAttrValue("Style", sStyle); -} - -bool StyleID::IsValid() const -{ - return !sGame.empty() && !sStyle.empty(); -} - -bool StyleID::operator<( const StyleID &rhs ) const -{ -#define COMP(a) if(arhs.a) return false; - COMP(sGame); - COMP(sStyle); -#undef COMP - return false; -} - -/* - * (c) 2001-2004 Chris Danford, Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "StyleUtil.h" +#include "GameManager.h" +#include "XmlFile.h" +#include "Game.h" +#include "Style.h" + + +void StyleID::FromStyle( const Style *p ) +{ + if( p ) + { + sGame = GAMEMAN->GetGameForStyle(p)->m_szName; + sStyle = p->m_szName; + } + else + { + sGame = ""; + sStyle = ""; + } +} + +const Style *StyleID::ToStyle() const +{ + const Game* pGame = GAMEMAN->StringToGame( sGame ); + if( pGame == nullptr ) + return nullptr; + + return GAMEMAN->GameAndStringToStyle( pGame, sStyle ); +} + +XNode* StyleID::CreateNode() const +{ + XNode* pNode = new XNode( "Style" ); + + pNode->AppendAttr( "Game", sGame ); + pNode->AppendAttr( "Style", sStyle ); + + return pNode; +} + +void StyleID::LoadFromNode( const XNode* pNode ) +{ + Unset(); + ASSERT( pNode->GetName() == "Style" ); + + sGame = ""; + pNode->GetAttrValue("Game", sGame); + + sStyle = ""; + pNode->GetAttrValue("Style", sStyle); +} + +bool StyleID::IsValid() const +{ + return !sGame.empty() && !sStyle.empty(); +} + +bool StyleID::operator<( const StyleID &rhs ) const +{ +#define COMP(a) if(arhs.a) return false; + COMP(sGame); + COMP(sStyle); +#undef COMP + return false; +} + +/* + * (c) 2001-2004 Chris Danford, Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/StyleUtil.h b/src/StyleUtil.h index 6051d17617..ee102a9707 100644 --- a/src/StyleUtil.h +++ b/src/StyleUtil.h @@ -12,7 +12,7 @@ class StyleID public: StyleID(): sGame(""), sStyle("") { } - void Unset() { FromStyle(NULL); } + void Unset() { FromStyle(nullptr); } void FromStyle( const Style *p ); const Style *ToStyle() const; bool operator<( const StyleID &rhs ) const; diff --git a/src/SubscriptionManager.h b/src/SubscriptionManager.h index 58ca1e5e46..67e7778356 100644 --- a/src/SubscriptionManager.h +++ b/src/SubscriptionManager.h @@ -17,21 +17,21 @@ public: // impossible to enfore that in C++. Instead, we'll allocate the // collection ourself on first use. SubscriptionHandler itself is // a POD type, so a static SubscriptionHandler will always have - // m_pSubscribers == NULL (before any static constructors are called). + // m_pSubscribers == nullptr (before any static constructors are called). set* m_pSubscribers; // Use this to access m_pSubscribers, so you don't have to worry about - // it being NULL. + // it being nullptr. set &Get() { - if( m_pSubscribers == NULL ) + if( m_pSubscribers == nullptr ) m_pSubscribers = new set; return *m_pSubscribers; } void Subscribe( T* p ) { - if( m_pSubscribers == NULL ) + if( m_pSubscribers == nullptr ) m_pSubscribers = new set; #ifdef DEBUG typename set::iterator iter = m_pSubscribers->find( p ); diff --git a/src/TextBanner.cpp b/src/TextBanner.cpp index 5fa8fbc32f..f0ae2ed152 100644 --- a/src/TextBanner.cpp +++ b/src/TextBanner.cpp @@ -73,7 +73,7 @@ void TextBanner::SetFromString( void TextBanner::SetFromSong( const Song *pSong ) { - if( pSong == NULL ) + if( pSong == nullptr ) { SetFromString( "", "", "", "", "", "" ); return; diff --git a/src/ThemeManager.cpp b/src/ThemeManager.cpp index 17f2054775..0ae222ff55 100644 --- a/src/ThemeManager.cpp +++ b/src/ThemeManager.cpp @@ -16,7 +16,6 @@ #include "Profile.h" #include "ActorUtil.h" #endif -#include "Foreach.h" #include "GameLoop.h" // For ChangeTheme #include "ThemeMetric.h" #include "SubscriptionManager.h" @@ -29,7 +28,7 @@ #include "XmlFileUtil.h" #include -ThemeManager* THEME = NULL; // global object accessible from anywhere in the program +ThemeManager* THEME = nullptr; // global object accessible from anywhere in the program static const RString THEME_INFO_INI = "ThemeInfo.ini"; @@ -61,7 +60,7 @@ public: iniStrings.Clear(); } }; -LoadedThemeData *g_pLoadedThemeData = NULL; +LoadedThemeData *g_pLoadedThemeData = nullptr; // For self-registering metrics @@ -284,7 +283,7 @@ bool ThemeManager::DoesLanguageExist( const RString &sLanguage ) void ThemeManager::LoadThemeMetrics( const RString &sThemeName_, const RString &sLanguage_ ) { - if( g_pLoadedThemeData == NULL ) + if( g_pLoadedThemeData == nullptr ) g_pLoadedThemeData = new LoadedThemeData; // Don't delete and recreate LoadedThemeData. There are references iniMetrics and iniStrings @@ -314,8 +313,8 @@ void ThemeManager::LoadThemeMetrics( const RString &sThemeName_, const RString & { vector vs; GetOptionalLanguageIniPaths(vs,sThemeName,sLanguage); - FOREACH_CONST(RString,vs,s) - iniStrings.ReadFile( *s ); + for (RString const &s : vs) + iniStrings.ReadFile( s ); } iniStrings.ReadFile( GetLanguageIniPath(sThemeName,SpecialFiles::BASE_LANGUAGE) ); if( sLanguage.CompareNoCase(SpecialFiles::BASE_LANGUAGE) ) @@ -445,7 +444,7 @@ void ThemeManager::SwitchThemeAndLanguage( const RString &sThemeName_, const RSt { #if !defined(SMPACKAGE) // reload common sounds - if( SCREENMAN != NULL ) + if( SCREENMAN != nullptr ) SCREENMAN->ThemeChanged(); #endif @@ -456,7 +455,7 @@ void ThemeManager::SwitchThemeAndLanguage( const RString &sThemeName_, const RSt UpdateLuaGlobals(); // Reload MachineProfile with new theme's CustomLoadFunction - if( PROFILEMAN != NULL ) + if( PROFILEMAN != nullptr ) { Profile* pProfile = PROFILEMAN->GetMachineProfile(); pProfile->LoadCustomFunction("/Save/MachineProfile/", PlayerNumber_Invalid); @@ -474,8 +473,8 @@ void ThemeManager::ReloadSubscribers() // reload subscribers if( g_Subscribers.m_pSubscribers ) { - FOREACHS_CONST( IThemeMetric*, *g_Subscribers.m_pSubscribers, p ) - (*p)->Read(); + for (IThemeMetric *metric : *g_Subscribers.m_pSubscribers) + metric->Read(); } } @@ -483,8 +482,8 @@ void ThemeManager::ClearSubscribers() { if( g_Subscribers.m_pSubscribers ) { - FOREACHS_CONST( IThemeMetric*, *g_Subscribers.m_pSubscribers, p ) - (*p)->Clear(); + for (IThemeMetric *metric : *g_Subscribers.m_pSubscribers) + metric->Clear(); } } @@ -516,10 +515,9 @@ void ThemeManager::RunLuaScripts( const RString &sMask, bool bUseThemeDir ) SortRStringArray( arrayScriptDirs ); StripCvsAndSvn( arrayScriptDirs ); StripMacResourceForks( arrayScriptDirs ); - FOREACH_CONST( RString, arrayScriptDirs, s ) // foreach dir in /Scripts/ + for( RString const &sScriptDirName : arrayScriptDirs ) // foreach dir in /Scripts/ { // Find all Lua files in this directory, add them to asElementPaths - RString sScriptDirName = *s; GetDirListing( sScriptDir + "Scripts/" + sScriptDirName + "/" + sMask, asElementChildPaths, false, true ); for( unsigned i = 0; i < asElementChildPaths.size(); ++i ) { @@ -781,10 +779,10 @@ bool ThemeManager::GetPathInfoToAndFallback( PathInfo &out, ElementCategory cate int n = 100; while( n-- ) { - FOREACHD_CONST( Theme, g_vThemes, iter ) + for (Theme const &theme : g_vThemes) { // search with requested name - if( GetPathInfoToRaw( out, iter->sThemeName, category, sMetricsGroup, sElement ) ) + if( GetPathInfoToRaw( out, theme.sThemeName, category, sMetricsGroup, sElement ) ) return true; } @@ -943,7 +941,7 @@ void ThemeManager::ReloadMetrics() RString ThemeManager::GetMetricsGroupFallback( const RString &sMetricsGroup ) { - ASSERT( g_pLoadedThemeData != NULL ); + ASSERT( g_pLoadedThemeData != nullptr ); // always look in iniMetrics for "Fallback" RString sFallback; @@ -1172,18 +1170,18 @@ void ThemeManager::GetLanguagesForTheme( const RString &sThemeName, vector as; GetDirListing( sLanguageDir + "*.ini", as ); - FOREACH_CONST( RString, as, s ) + for (RString const &s : as) { // ignore metrics.ini - if( s->CompareNoCase(SpecialFiles::METRICS_FILE)==0 ) + if( s.CompareNoCase(SpecialFiles::METRICS_FILE)==0 ) continue; // Ignore filenames with a space. These are optional language inis that probably came from a mounted package. - if( s->find(" ") != RString::npos ) + if( s.find(" ") != RString::npos ) continue; // strip ".ini" - RString s2 = s->Left( s->size()-4 ); + RString s2 = s.Left( s.size()-4 ); asLanguagesOut.push_back( s2 ); } @@ -1250,7 +1248,7 @@ RString ThemeManager::GetString( const RString &sMetricsGroup, const RString &sV sValueName.Replace( "\r\n", "\\n" ); sValueName.Replace( "\n", "\\n" ); - ASSERT( g_pLoadedThemeData != NULL ); + ASSERT( g_pLoadedThemeData != nullptr ); RString s = GetMetricRaw( g_pLoadedThemeData->iniStrings, sMetricsGroup, sValueName ); FontCharAliases::ReplaceMarkers( s ); @@ -1296,7 +1294,7 @@ void ThemeManager::GetMetricsThatBeginWith( const RString &sMetricsGroup_, const while( !sMetricsGroup.empty() ) { const XNode *cur = g_pLoadedThemeData->iniMetrics.GetChild( sMetricsGroup ); - if( cur != NULL ) + if( cur != nullptr ) { // Iterate over all metrics that match. for( XAttrs::const_iterator j = cur->m_attrs.lower_bound( sValueName ); j != cur->m_attrs.end(); ++j ) @@ -1405,7 +1403,7 @@ public: { RString group_name= SArg(1); const XNode* metric_node= ini.GetChild(group_name); - if(metric_node != NULL) + if(metric_node != nullptr) { // Placed in a table indexed by number, so the order is always the same. lua_createtable(L, metric_node->m_attrs.size(), 0); diff --git a/src/ThemeMetric.h b/src/ThemeMetric.h index f74d1c4e0b..83115ac926 100644 --- a/src/ThemeMetric.h +++ b/src/ThemeMetric.h @@ -5,7 +5,7 @@ #include "ThemeManager.h" #include -#include "Foreach.h" + #include "LuaManager.h" #include "RageUtil.h" @@ -194,7 +194,7 @@ public: } ThemeMetric1D() { - Load( RString(), NULL, 0 ); + Load( RString(), nullptr, 0 ); } void Load( const RString& sGroup, MetricName1D pfn, size_t N ) { @@ -228,7 +228,7 @@ class ThemeMetric2D : public IThemeMetric vector m_metric; public: - ThemeMetric2D( const RString& sGroup = "", MetricName2D pfn = NULL, size_t N = 0, size_t M = 0 ) + ThemeMetric2D( const RString& sGroup = "", MetricName2D pfn = nullptr, size_t N = 0, size_t M = 0 ) { Load( sGroup, pfn, N, M ); } @@ -269,15 +269,15 @@ class ThemeMetricMap : public IThemeMetric map m_metric; public: - ThemeMetricMap( const RString& sGroup = "", MetricNameMap pfn = NULL, const vector vsValueNames = vector() ) + ThemeMetricMap( const RString& sGroup = "", MetricNameMap pfn = nullptr, const vector vsValueNames = vector() ) { Load( sGroup, pfn, vsValueNames ); } void Load( const RString& sGroup, MetricNameMap pfn, const vector vsValueNames ) { m_metric.clear(); - FOREACH_CONST( RString, vsValueNames, s ) - m_metric[*s].Load( sGroup, pfn(*s) ); + for (RString const &s : vsValueNames) + m_metric[s].Load( sGroup, pfn(s) ); } void Read() { diff --git a/src/TimingData.cpp b/src/TimingData.cpp index 2885c64607..4a725868d6 100644 --- a/src/TimingData.cpp +++ b/src/TimingData.cpp @@ -6,7 +6,6 @@ #include "RageLog.h" #include "ThemeManager.h" #include "NoteTypes.h" -#include "Foreach.h" #include static void EraseSegment(vector &vSegs, int index, TimingSegment *cur); @@ -63,10 +62,9 @@ bool TimingData::IsSafeFullTiming() needed_segments.push_back(SEGMENT_SPEED); needed_segments.push_back(SEGMENT_SCROLL); } - vector *segs = m_avpTimingSegments; for(size_t s= 0; s < needed_segments.size(); ++s) { - if(segs[needed_segments[s]].empty()) + if(m_avpTimingSegments[needed_segments[s]].empty()) { return false; } @@ -86,11 +84,10 @@ void TimingData::PrepareLookup() // thing. So release the lookups. -Kyz ReleaseLookup(); const unsigned int segments_per_lookup= 16; - const vector* segs= m_avpTimingSegments; - const vector& bpms= segs[SEGMENT_BPM]; - const vector& warps= segs[SEGMENT_WARP]; - const vector& stops= segs[SEGMENT_STOP]; - const vector& delays= segs[SEGMENT_DELAY]; + const vector& bpms= m_avpTimingSegments[SEGMENT_BPM]; + const vector& warps= m_avpTimingSegments[SEGMENT_WARP]; + const vector& stops= m_avpTimingSegments[SEGMENT_STOP]; + const vector& delays= m_avpTimingSegments[SEGMENT_DELAY]; unsigned int total_segments= bpms.size() + warps.size() + stops.size() + delays.size(); unsigned int lookup_entries= total_segments / segments_per_lookup; @@ -148,11 +145,10 @@ RString SegInfoStr(const vector& segs, unsigned int index, const void TimingData::DumpOneTable(const beat_start_lookup_t& lookup, const RString& name) { - const vector* segs= m_avpTimingSegments; - const vector& bpms= segs[SEGMENT_BPM]; - const vector& warps= segs[SEGMENT_WARP]; - const vector& stops= segs[SEGMENT_STOP]; - const vector& delays= segs[SEGMENT_DELAY]; + const vector& bpms= m_avpTimingSegments[SEGMENT_BPM]; + const vector& warps= m_avpTimingSegments[SEGMENT_WARP]; + const vector& stops= m_avpTimingSegments[SEGMENT_STOP]; + const vector& delays= m_avpTimingSegments[SEGMENT_DELAY]; LOG->Trace("%s lookup table:", name.c_str()); for(size_t lit= 0; lit < lookup.size(); ++lit) { @@ -529,21 +525,21 @@ bool TimingData::IsFakeAtRow( int iNoteRow ) const * indiscriminate calls to get segments at arbitrary rows, I think it's the * best solution we've got for now. * - * Note that types whose SegmentEffectAreas are "Indefinite" are NULL here, + * Note that types whose SegmentEffectAreas are "Indefinite" are nullptr here, * because they should never need to be used; we always have at least one such * segment in the TimingData, and if not, we'll crash anyway. -- vyhd */ static const TimingSegment* DummySegments[NUM_TimingSegmentType] = { - NULL, // BPMSegment + nullptr, // BPMSegment new StopSegment, new DelaySegment, - NULL, // TimeSignatureSegment + nullptr, // TimeSignatureSegment new WarpSegment, - NULL, // LabelSegment - NULL, // TickcountSegment - NULL, // ComboSegment - NULL, // SpeedSegment - NULL, // ScrollSegment + nullptr, // LabelSegment + nullptr, // TickcountSegment + nullptr, // ComboSegment + nullptr, // SpeedSegment + nullptr, // ScrollSegment new FakeSegment }; @@ -814,11 +810,10 @@ void FindEvent(int& event_row, int& event_type, void TimingData::GetBeatInternal(GetBeatStarts& start, GetBeatArgs& args, unsigned int max_segment) const { - const vector* segs= m_avpTimingSegments; - const vector& bpms= segs[SEGMENT_BPM]; - const vector& warps= segs[SEGMENT_WARP]; - const vector& stops= segs[SEGMENT_STOP]; - const vector& delays= segs[SEGMENT_DELAY]; + const vector& bpms= m_avpTimingSegments[SEGMENT_BPM]; + const vector& warps= m_avpTimingSegments[SEGMENT_WARP]; + const vector& stops= m_avpTimingSegments[SEGMENT_STOP]; + const vector& delays= m_avpTimingSegments[SEGMENT_DELAY]; unsigned int curr_segment= start.bpm+start.warp+start.stop+start.delay; float bps= GetBPMAtRow(start.last_row) / 60.0f; @@ -932,11 +927,10 @@ void TimingData::GetBeatAndBPSFromElapsedTimeNoOffset(GetBeatArgs& args) const float TimingData::GetElapsedTimeInternal(GetBeatStarts& start, float beat, unsigned int max_segment) const { - const vector* segs= m_avpTimingSegments; - const vector& bpms= segs[SEGMENT_BPM]; - const vector& warps= segs[SEGMENT_WARP]; - const vector& stops= segs[SEGMENT_STOP]; - const vector& delays= segs[SEGMENT_DELAY]; + const vector& bpms= m_avpTimingSegments[SEGMENT_BPM]; + const vector& warps= m_avpTimingSegments[SEGMENT_WARP]; + const vector& stops= m_avpTimingSegments[SEGMENT_STOP]; + const vector& delays= m_avpTimingSegments[SEGMENT_DELAY]; unsigned int curr_segment= start.bpm+start.warp+start.stop+start.delay; float bps= GetBPMAtRow(start.last_row) / 60.0f; @@ -1103,7 +1097,7 @@ void TimingData::DeleteRows( int iStartRow, int iRowsToDelete ) // Don't delete the indefinite segments that are still in effect // at the end row; rather, shift them so they start there. TimingSegment *tsEnd = GetSegmentAtRow(iStartRow + iRowsToDelete, tst); - if (tsEnd != NULL && tsEnd->GetEffectType() == SegmentEffectType_Indefinite && + if (tsEnd != nullptr && tsEnd->GetEffectType() == SegmentEffectType_Indefinite && iStartRow <= tsEnd->GetRow() && tsEnd->GetRow() < iStartRow + iRowsToDelete) { @@ -1209,7 +1203,7 @@ void TimingData::TidyUpData(bool allowEmpty) return; // If there are no BPM segments, provide a default. - vector *segs = m_avpTimingSegments; + auto &segs = m_avpTimingSegments; if( segs[SEGMENT_BPM].empty() ) { LOG->UserLog( "Song file", m_sFile, "has no BPM segments, default provided." ); diff --git a/src/TimingData.h b/src/TimingData.h index d73997b47b..db22b1bd6b 100644 --- a/src/TimingData.h +++ b/src/TimingData.h @@ -5,6 +5,7 @@ #include "TimingSegments.h" #include "PrefsManager.h" #include // max float +#include struct lua_State; /** @brief Compare a TimingData segment's properties with one another. */ @@ -454,7 +455,7 @@ public: * * This is for informational purposes only. */ - RString m_sFile; + std::string m_sFile; /** @brief The initial offset of a song. */ float m_fBeat0OffsetInSeconds; @@ -466,7 +467,7 @@ protected: void AddSegment( const TimingSegment *seg ); // All of the following vectors must be sorted before gameplay. - vector m_avpTimingSegments[NUM_TimingSegmentType]; + std::array, NUM_TimingSegmentType> m_avpTimingSegments; }; #undef COMPARE diff --git a/src/TimingSegments.cpp b/src/TimingSegments.cpp index edb1dc4eaf..696ab32157 100644 --- a/src/TimingSegments.cpp +++ b/src/TimingSegments.cpp @@ -121,8 +121,8 @@ void FakeSegment::DebugPrint() const RString FakeSegment::ToString(int dec) const { - RString str = "%.0" + IntToString(dec) - + "f=%.0" + IntToString(dec) + "f"; + RString str = "%.0" + std::to_string(dec) + + "f=%.0" + std::to_string(dec) + "f"; return ssprintf(str.c_str(), GetBeat(), GetLength()); } @@ -138,8 +138,8 @@ void FakeSegment::Scale( int start, int length, int newLength ) RString WarpSegment::ToString(int dec) const { - RString str = "%.0" + IntToString(dec) - + "f=%.0" + IntToString(dec) + "f"; + RString str = "%.0" + std::to_string(dec) + + "f=%.0" + std::to_string(dec) + "f"; return ssprintf(str.c_str(), GetBeat(), GetLength()); } @@ -156,12 +156,12 @@ void WarpSegment::Scale( int start, int length, int newLength ) RString TickcountSegment::ToString(int dec) const { - const RString str = "%.0" + IntToString(dec) + "f=%i"; + const RString str = "%.0" + std::to_string(dec) + "f=%i"; return ssprintf(str.c_str(), GetBeat(), GetTicks()); } RString ComboSegment::ToString(int dec) const { - RString str = "%.0" + IntToString(dec) + "f=%i"; + RString str = "%.0" + std::to_string(dec) + "f=%i"; if (GetCombo() == GetMissCombo()) { return ssprintf(str.c_str(), GetBeat(), GetCombo()); @@ -180,20 +180,20 @@ vector ComboSegment::GetValues() const RString LabelSegment::ToString(int dec) const { - const RString str = "%.0" + IntToString(dec) + "f=%s"; + const RString str = "%.0" + std::to_string(dec) + "f=%s"; return ssprintf(str.c_str(), GetBeat(), GetLabel().c_str()); } RString BPMSegment::ToString(int dec) const { - const RString str = "%.0" + IntToString(dec) - + "f=%.0" + IntToString(dec) + "f"; + const RString str = "%.0" + std::to_string(dec) + + "f=%.0" + std::to_string(dec) + "f"; return ssprintf(str.c_str(), GetBeat(), GetBPM()); } RString TimeSignatureSegment::ToString(int dec) const { - const RString str = "%.0" + IntToString(dec) + "f=%i=%i"; + const RString str = "%.0" + std::to_string(dec) + "f=%i=%i"; return ssprintf(str.c_str(), GetBeat(), GetNum(), GetDen()); } @@ -207,9 +207,9 @@ vector TimeSignatureSegment::GetValues() const RString SpeedSegment::ToString(int dec) const { - const RString str = "%.0" + IntToString(dec) - + "f=%.0" + IntToString(dec) + "f=%.0" - + IntToString(dec) + "f=%u"; + const RString str = "%.0" + std::to_string(dec) + + "f=%.0" + std::to_string(dec) + "f=%.0" + + std::to_string(dec) + "f=%u"; return ssprintf(str.c_str(), GetBeat(), GetRatio(), GetDelay(), static_cast(GetUnit())); } @@ -245,22 +245,22 @@ void SpeedSegment::Scale( int start, int oldLength, int newLength ) RString ScrollSegment::ToString(int dec) const { - const RString str = "%.0" + IntToString(dec) - + "f=%.0" + IntToString(dec) + "f"; + const RString str = "%.0" + std::to_string(dec) + + "f=%.0" + std::to_string(dec) + "f"; return ssprintf(str.c_str(), GetBeat(), GetRatio()); } RString StopSegment::ToString(int dec) const { - const RString str = "%.0" + IntToString(dec) - + "f=%.0" + IntToString(dec) + "f"; + const RString str = "%.0" + std::to_string(dec) + + "f=%.0" + std::to_string(dec) + "f"; return ssprintf(str.c_str(), GetBeat(), GetPause()); } RString DelaySegment::ToString(int dec) const { - const RString str = "%.0" + IntToString(dec) - + "f=%.0" + IntToString(dec) + "f"; + const RString str = "%.0" + std::to_string(dec) + + "f=%.0" + std::to_string(dec) + "f"; return ssprintf(str.c_str(), GetBeat(), GetPause()); } diff --git a/src/TimingSegments.h b/src/TimingSegments.h index ad46bb31c1..454bd05d29 100644 --- a/src/TimingSegments.h +++ b/src/TimingSegments.h @@ -80,7 +80,7 @@ struct TimingSegment virtual RString ToString(int /* dec */) const { - return FloatToString(GetBeat()); + return std::to_string(GetBeat()); } virtual vector GetValues() const diff --git a/src/TitleSubstitution.cpp b/src/TitleSubstitution.cpp index b06380fbd6..cff3fd94da 100644 --- a/src/TitleSubstitution.cpp +++ b/src/TitleSubstitution.cpp @@ -5,7 +5,6 @@ #include "RageLog.h" #include "FontCharAliases.h" #include "RageFile.h" -#include "Foreach.h" #include "LuaManager.h" #include "XmlFile.h" #include "XmlFileUtil.h" @@ -75,10 +74,8 @@ void TitleSubst::AddTrans(const TitleTrans &tr) void TitleSubst::Subst( TitleFields &tf ) { - FOREACH_CONST( TitleTrans*, ttab, iter ) + for (TitleTrans *tt : ttab) { - TitleTrans* tt = *iter; - TitleFields to; if( !tt->Matches(tf,to) ) continue; @@ -146,7 +143,7 @@ void TitleSubst::Load(const RString &filename, const RString §ion) } XNode *pGroup = xml.GetChild( section ); - if( pGroup == NULL ) + if( pGroup == nullptr ) return; FOREACH_CONST_Child( pGroup, child ) { diff --git a/src/Trail.cpp b/src/Trail.cpp index 2e33d60185..3d03fc86c6 100644 --- a/src/Trail.cpp +++ b/src/Trail.cpp @@ -1,6 +1,5 @@ #include "global.h" #include "Trail.h" -#include "Foreach.h" #include "GameState.h" #include "Steps.h" #include "Song.h" @@ -8,6 +7,7 @@ #include "NoteData.h" #include "NoteDataUtil.h" #include "CommonMetrics.h" +#include void TrailEntry::GetAttackArray( AttackArray &out ) const { @@ -105,28 +105,28 @@ const RadarValues &Trail::GetRadarValues() const RadarValues rv; rv.Zero(); - FOREACH_CONST( TrailEntry, m_vEntries, e ) + for (TrailEntry const &e : m_vEntries) { - const Steps *pSteps = e->pSteps; - ASSERT( pSteps != NULL ); + const Steps *pSteps = e.pSteps; + ASSERT( pSteps != nullptr ); // Hack: don't calculate for autogen entries - if( !pSteps->IsAutogen() && e->ContainsTransformOrTurn() ) + if( !pSteps->IsAutogen() && e.ContainsTransformOrTurn() ) { NoteData nd; pSteps->GetNoteData( nd ); RadarValues rv_orig; GAMESTATE->SetProcessedTimingData(const_cast(pSteps->GetTimingData())); - NoteDataUtil::CalculateRadarValues( nd, e->pSong->m_fMusicLengthSeconds, rv_orig ); + NoteDataUtil::CalculateRadarValues( nd, e.pSong->m_fMusicLengthSeconds, rv_orig ); PlayerOptions po; - po.FromString( e->Modifiers ); + po.FromString( e.Modifiers ); if( po.ContainsTransformOrTurn() ) { NoteDataUtil::TransformNoteData(nd, *(pSteps->GetTimingData()), po, pSteps->m_StepsType); } - NoteDataUtil::TransformNoteData(nd, *(pSteps->GetTimingData()), e->Attacks, pSteps->m_StepsType, e->pSong); + NoteDataUtil::TransformNoteData(nd, *(pSteps->GetTimingData()), e.Attacks, pSteps->m_StepsType, e.pSong); RadarValues transformed_rv; - NoteDataUtil::CalculateRadarValues( nd, e->pSong->m_fMusicLengthSeconds, transformed_rv ); - GAMESTATE->SetProcessedTimingData(NULL); + NoteDataUtil::CalculateRadarValues( nd, e.pSong->m_fMusicLengthSeconds, transformed_rv ); + GAMESTATE->SetProcessedTimingData(nullptr); rv += transformed_rv; } else @@ -159,37 +159,30 @@ int Trail::GetMeter() const int Trail::GetTotalMeter() const { - int iTotalMeter = 0; - FOREACH_CONST( TrailEntry, m_vEntries, e ) - { - iTotalMeter += e->pSteps->GetMeter(); - } - - return iTotalMeter; + return std::accumulate(m_vEntries.begin(), m_vEntries.end(), 0, [](int total, TrailEntry const &e) { + return total + e.pSteps->GetMeter(); + }); } float Trail::GetLengthSeconds() const { - float fSecs = 0; - FOREACH_CONST( TrailEntry, m_vEntries, e ) - { - fSecs += e->pSong->m_fMusicLengthSeconds; - } - return fSecs; + return std::accumulate(m_vEntries.begin(), m_vEntries.end(), 0.f, [](float total, TrailEntry const &e) { + return total + e.pSong->m_fMusicLengthSeconds; + }); } void Trail::GetDisplayBpms( DisplayBpms &AddTo ) const { - FOREACH_CONST( TrailEntry, m_vEntries, e ) + for (TrailEntry const &e : m_vEntries) { - if( e->bSecret ) + if( e.bSecret ) { AddTo.Add( -1 ); continue; } - Song *pSong = e->pSong; - ASSERT( pSong != NULL ); + Song *pSong = e.pSong; + ASSERT( pSong != nullptr ); switch( pSong->m_DisplayBPMType ) { case DISPLAY_BPM_ACTUAL: @@ -206,22 +199,16 @@ void Trail::GetDisplayBpms( DisplayBpms &AddTo ) const bool Trail::IsSecret() const { - FOREACH_CONST( TrailEntry, m_vEntries, e ) - { - if( e->bSecret ) - return true; - } - return false; + return std::any_of(m_vEntries.begin(), m_vEntries.end(), [](TrailEntry const &e) { + return e.bSecret; + }); } bool Trail::ContainsSong( const Song *pSong ) const { - FOREACH_CONST( TrailEntry, m_vEntries, e ) - { - if( e->pSong == pSong ) - return true; - } - return false; + return std::any_of(m_vEntries.begin(), m_vEntries.end(), [&](TrailEntry const &e) { + return e.pSong == pSong; + }); } // lua start @@ -244,17 +231,17 @@ public: static int GetArtists( T* p, lua_State *L ) { vector asArtists, asAltArtists; - FOREACH_CONST( TrailEntry, p->m_vEntries, e ) + for (TrailEntry const &e : p->m_vEntries) { - if( e->bSecret ) + if( e.bSecret ) { asArtists.push_back( "???" ); asAltArtists.push_back( "???" ); } else { - asArtists.push_back( e->pSong->GetDisplayArtist() ); - asAltArtists.push_back( e->pSong->GetTranslitArtist() ); + asArtists.push_back( e.pSong->GetDisplayArtist() ); + asAltArtists.push_back( e.pSong->GetTranslitArtist() ); } } diff --git a/src/Trail.h b/src/Trail.h index 8c9b8a1095..e447496216 100644 --- a/src/Trail.h +++ b/src/Trail.h @@ -1,129 +1,129 @@ -#ifndef TRAIL_H -#define TRAIL_H - -#include "Attack.h" -#include "RadarValues.h" -#include "Difficulty.h" -#include "RageUtil_CachedObject.h" - -class Song; -class Steps; -struct lua_State; - -/** @brief One such Song and - * Step in the entire Trail. */ -struct TrailEntry -{ - TrailEntry(): - pSong(NULL), - pSteps(NULL), - Modifiers(""), - Attacks(), - bSecret(false), - iLowMeter(-1), - iHighMeter(-1), - dc(Difficulty_Invalid) - { - } - void GetAttackArray( AttackArray &out ) const; - - /** @brief The Song involved in the entry. */ - Song* pSong; - /** @brief The Step involved in the entry. */ - Steps* pSteps; - /** @brief The Modifiers applied for the whole Song. */ - RString Modifiers; - /** @brief The Attacks that will take place durring the Song. */ - AttackArray Attacks; - /** - * @brief Is this Song and its Step meant to be a secret? - * If so, it will show text such as "???" to indicate that it's a mystery. */ - bool bSecret; - - /* These represent the meter and difficulty used by the course to pick the - * steps; if you want the real difficulty and meter, look at pSteps. */ - int iLowMeter; - int iHighMeter; - Difficulty dc; - bool operator== ( const TrailEntry &rhs ) const; - bool operator!= ( const TrailEntry &rhs ) const { return !(*this==rhs); } - bool ContainsTransformOrTurn() const; - - // Lua - void PushSelf( lua_State *L ); -}; - -/** @brief A queue of Songs and Steps that are generated from a Course. */ -class Trail -{ -public: - StepsType m_StepsType; - CourseType m_CourseType; - CourseDifficulty m_CourseDifficulty; - vector m_vEntries; - int m_iSpecifiedMeter; // == -1 if no meter specified - mutable bool m_bRadarValuesCached; - mutable RadarValues m_CachedRadarValues; - - /** - * @brief Set up the Trail with default values. - * - * This used to call Init(), which is still available. */ - Trail(): m_StepsType(StepsType_Invalid), - m_CourseType(CourseType_Invalid), - m_CourseDifficulty(Difficulty_Invalid), - m_vEntries(), m_iSpecifiedMeter(-1), - m_bRadarValuesCached(false), m_CachedRadarValues(), - m_CachedObject() {} - void Init() - { - m_StepsType = StepsType_Invalid; - m_CourseDifficulty = Difficulty_Invalid; - m_iSpecifiedMeter = -1; - m_vEntries.clear(); - m_bRadarValuesCached = false; - } - - const RadarValues &GetRadarValues() const; - void SetRadarValues( const RadarValues &rv ); // for pre-populating cache - int GetMeter() const; - int GetTotalMeter() const; - float GetLengthSeconds() const; - void GetDisplayBpms( DisplayBpms &AddTo ) const; - bool IsSecret() const; - bool ContainsSong( const Song *pSong ) const; - - CachedObject m_CachedObject; - - // Lua - void PushSelf( lua_State *L ); -}; - -#endif - -/** - * @file - * @author Chris Danford, Glenn Maynard (c) 2001-2004 - * @section LICENSE - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#ifndef TRAIL_H +#define TRAIL_H + +#include "Attack.h" +#include "RadarValues.h" +#include "Difficulty.h" +#include "RageUtil_CachedObject.h" + +class Song; +class Steps; +struct lua_State; + +/** @brief One such Song and + * Step in the entire Trail. */ +struct TrailEntry +{ + TrailEntry(): + pSong(nullptr), + pSteps(nullptr), + Modifiers(""), + Attacks(), + bSecret(false), + iLowMeter(-1), + iHighMeter(-1), + dc(Difficulty_Invalid) + { + } + void GetAttackArray( AttackArray &out ) const; + + /** @brief The Song involved in the entry. */ + Song* pSong; + /** @brief The Step involved in the entry. */ + Steps* pSteps; + /** @brief The Modifiers applied for the whole Song. */ + RString Modifiers; + /** @brief The Attacks that will take place durring the Song. */ + AttackArray Attacks; + /** + * @brief Is this Song and its Step meant to be a secret? + * If so, it will show text such as "???" to indicate that it's a mystery. */ + bool bSecret; + + /* These represent the meter and difficulty used by the course to pick the + * steps; if you want the real difficulty and meter, look at pSteps. */ + int iLowMeter; + int iHighMeter; + Difficulty dc; + bool operator== ( const TrailEntry &rhs ) const; + bool operator!= ( const TrailEntry &rhs ) const { return !(*this==rhs); } + bool ContainsTransformOrTurn() const; + + // Lua + void PushSelf( lua_State *L ); +}; + +/** @brief A queue of Songs and Steps that are generated from a Course. */ +class Trail +{ +public: + StepsType m_StepsType; + CourseType m_CourseType; + CourseDifficulty m_CourseDifficulty; + vector m_vEntries; + int m_iSpecifiedMeter; // == -1 if no meter specified + mutable bool m_bRadarValuesCached; + mutable RadarValues m_CachedRadarValues; + + /** + * @brief Set up the Trail with default values. + * + * This used to call Init(), which is still available. */ + Trail(): m_StepsType(StepsType_Invalid), + m_CourseType(CourseType_Invalid), + m_CourseDifficulty(Difficulty_Invalid), + m_vEntries(), m_iSpecifiedMeter(-1), + m_bRadarValuesCached(false), m_CachedRadarValues(), + m_CachedObject() {} + void Init() + { + m_StepsType = StepsType_Invalid; + m_CourseDifficulty = Difficulty_Invalid; + m_iSpecifiedMeter = -1; + m_vEntries.clear(); + m_bRadarValuesCached = false; + } + + const RadarValues &GetRadarValues() const; + void SetRadarValues( const RadarValues &rv ); // for pre-populating cache + int GetMeter() const; + int GetTotalMeter() const; + float GetLengthSeconds() const; + void GetDisplayBpms( DisplayBpms &AddTo ) const; + bool IsSecret() const; + bool ContainsSong( const Song *pSong ) const; + + CachedObject m_CachedObject; + + // Lua + void PushSelf( lua_State *L ); +}; + +#endif + +/** + * @file + * @author Chris Danford, Glenn Maynard (c) 2001-2004 + * @section LICENSE + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/TrailUtil.cpp b/src/TrailUtil.cpp index 0ea7864a3e..adc16d974a 100644 --- a/src/TrailUtil.cpp +++ b/src/TrailUtil.cpp @@ -1,157 +1,155 @@ -#include "global.h" -#include "TrailUtil.h" -#include "Trail.h" -#include "Course.h" -#include "XmlFile.h" -#include "GameManager.h" -#include "Song.h" - - -int TrailUtil::GetNumSongs( const Trail *pTrail ) -{ - return pTrail->m_vEntries.size(); -} - -float TrailUtil::GetTotalSeconds( const Trail *pTrail ) -{ - float fSecs = 0; - FOREACH_CONST( TrailEntry, pTrail->m_vEntries, e ) - fSecs += e->pSong->m_fMusicLengthSeconds; - return fSecs; -} - -/////////////////////////////////////////////////////////////////////// - -void TrailID::FromTrail( const Trail *p ) -{ - if( p == NULL ) - { - st = StepsType_Invalid; - cd = Difficulty_Invalid; - } - else - { - st = p->m_StepsType; - cd = p->m_CourseDifficulty; - } - m_Cache.Unset(); -} - -Trail *TrailID::ToTrail( const Course *p, bool bAllowNull ) const -{ - ASSERT( p != NULL ); - - Trail *pRet = NULL; - if( !m_Cache.Get(&pRet) ) - { - if( st != StepsType_Invalid && cd != Difficulty_Invalid ) - pRet = p->GetTrail( st, cd ); - m_Cache.Set( pRet ); - } - - if( !bAllowNull && pRet == NULL ) - RageException::Throw( "%i, %i, \"%s\"", st, cd, p->GetDisplayFullTitle().c_str() ); - - return pRet; -} - -XNode* TrailID::CreateNode() const -{ - XNode* pNode = new XNode( "Trail" ); - - pNode->AppendAttr( "StepsType", GAMEMAN->GetStepsTypeInfo(st).szName ); - pNode->AppendAttr( "CourseDifficulty", DifficultyToString(cd) ); - - return pNode; -} - -void TrailID::LoadFromNode( const XNode* pNode ) -{ - ASSERT( pNode->GetName() == "Trail" ); - - RString sTemp; - - pNode->GetAttrValue( "StepsType", sTemp ); - st = GAMEMAN->StringToStepsType( sTemp ); - - pNode->GetAttrValue( "CourseDifficulty", sTemp ); - cd = StringToDifficulty( sTemp ); - m_Cache.Unset(); -} - -RString TrailID::ToString() const -{ - RString s = GAMEMAN->GetStepsTypeInfo(st).szName; - s += " " + DifficultyToString( cd ); - return s; -} - -bool TrailID::IsValid() const -{ - return st != StepsType_Invalid && cd != Difficulty_Invalid; -} - -bool TrailID::operator<( const TrailID &rhs ) const -{ -#define COMP(a) if(arhs.a) return false; - COMP(st); - COMP(cd); -#undef COMP - return false; -} - - -// lua start -#include "LuaBinding.h" - -namespace -{ - int GetNumSongs( lua_State *L ) - { - Trail *pTrail = Luna::check( L, 1, true ); - int iNum = TrailUtil::GetNumSongs( pTrail ); - LuaHelpers::Push( L, iNum ); - return 1; - } - int GetTotalSeconds( lua_State *L ) - { - Trail *pTrail = Luna::check( L, 1, true ); - float fSecs = TrailUtil::GetTotalSeconds( pTrail ); - LuaHelpers::Push( L, fSecs ); - return 1; - } - - const luaL_Reg TrailUtilTable[] = - { - LIST_METHOD( GetNumSongs ), - LIST_METHOD( GetTotalSeconds ), - { NULL, NULL } - }; -} - -LUA_REGISTER_NAMESPACE( TrailUtil ) - -/* - * (c) 2004 Chris Danford - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "TrailUtil.h" +#include "Trail.h" +#include "Course.h" +#include "XmlFile.h" +#include "GameManager.h" +#include "Song.h" +#include + +int TrailUtil::GetNumSongs( const Trail *pTrail ) +{ + return pTrail->m_vEntries.size(); +} + +float TrailUtil::GetTotalSeconds( const Trail *pTrail ) +{ + auto const &entries = pTrail->m_vEntries; + return std::accumulate(entries.begin(), entries.end(), 0.f, [](float total, TrailEntry const &e) { return total + e.pSong->m_fMusicLengthSeconds; }); +} + +/////////////////////////////////////////////////////////////////////// + +void TrailID::FromTrail( const Trail *p ) +{ + if( p == nullptr ) + { + st = StepsType_Invalid; + cd = Difficulty_Invalid; + } + else + { + st = p->m_StepsType; + cd = p->m_CourseDifficulty; + } + m_Cache.Unset(); +} + +Trail *TrailID::ToTrail( const Course *p, bool bAllowNull ) const +{ + ASSERT( p != nullptr ); + + Trail *pRet = nullptr; + if( !m_Cache.Get(&pRet) ) + { + if( st != StepsType_Invalid && cd != Difficulty_Invalid ) + pRet = p->GetTrail( st, cd ); + m_Cache.Set( pRet ); + } + + if( !bAllowNull && pRet == nullptr ) + RageException::Throw( "%i, %i, \"%s\"", st, cd, p->GetDisplayFullTitle().c_str() ); + + return pRet; +} + +XNode* TrailID::CreateNode() const +{ + XNode* pNode = new XNode( "Trail" ); + + pNode->AppendAttr( "StepsType", GAMEMAN->GetStepsTypeInfo(st).szName ); + pNode->AppendAttr( "CourseDifficulty", DifficultyToString(cd) ); + + return pNode; +} + +void TrailID::LoadFromNode( const XNode* pNode ) +{ + ASSERT( pNode->GetName() == "Trail" ); + + RString sTemp; + + pNode->GetAttrValue( "StepsType", sTemp ); + st = GAMEMAN->StringToStepsType( sTemp ); + + pNode->GetAttrValue( "CourseDifficulty", sTemp ); + cd = StringToDifficulty( sTemp ); + m_Cache.Unset(); +} + +RString TrailID::ToString() const +{ + RString s = GAMEMAN->GetStepsTypeInfo(st).szName; + s += " " + DifficultyToString( cd ); + return s; +} + +bool TrailID::IsValid() const +{ + return st != StepsType_Invalid && cd != Difficulty_Invalid; +} + +bool TrailID::operator<( const TrailID &rhs ) const +{ +#define COMP(a) if(arhs.a) return false; + COMP(st); + COMP(cd); +#undef COMP + return false; +} + + +// lua start +#include "LuaBinding.h" + +namespace +{ + int GetNumSongs( lua_State *L ) + { + Trail *pTrail = Luna::check( L, 1, true ); + int iNum = TrailUtil::GetNumSongs( pTrail ); + LuaHelpers::Push( L, iNum ); + return 1; + } + int GetTotalSeconds( lua_State *L ) + { + Trail *pTrail = Luna::check( L, 1, true ); + float fSecs = TrailUtil::GetTotalSeconds( pTrail ); + LuaHelpers::Push( L, fSecs ); + return 1; + } + + const luaL_Reg TrailUtilTable[] = + { + LIST_METHOD( GetNumSongs ), + LIST_METHOD( GetTotalSeconds ), + { nullptr, nullptr } + }; +} + +LUA_REGISTER_NAMESPACE( TrailUtil ) + +/* + * (c) 2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/TrailUtil.h b/src/TrailUtil.h index 12c4a7dd76..3dfd97c5fc 100644 --- a/src/TrailUtil.h +++ b/src/TrailUtil.h @@ -35,7 +35,7 @@ class TrailID public: TrailID(): st(StepsType_Invalid), cd(Difficulty_Invalid), m_Cache() { m_Cache.Unset(); } - void Unset() { FromTrail(NULL); } + void Unset() { FromTrail(nullptr); } void FromTrail( const Trail *p ); Trail *ToTrail( const Course *p, bool bAllowNull ) const; bool operator<( const TrailID &rhs ) const; diff --git a/src/Tween.cpp b/src/Tween.cpp index 99828d29f6..45cd74beb7 100644 --- a/src/Tween.cpp +++ b/src/Tween.cpp @@ -99,7 +99,7 @@ ITween *ITween::CreateFromStack( Lua *L, int iStackPos ) if( iArgs != 4 && iArgs != 8 ) { LuaHelpers::ReportScriptErrorFmt("Tween::CreateFromStack: table argument must have 4 or 8 entries"); - return NULL; + return nullptr; } float fC[8]; diff --git a/src/UnlockManager.cpp b/src/UnlockManager.cpp index fca32edc61..3e167821e3 100644 --- a/src/UnlockManager.cpp +++ b/src/UnlockManager.cpp @@ -11,7 +11,6 @@ #include "ProfileManager.h" #include "Profile.h" #include "ThemeManager.h" -#include "Foreach.h" #include "Steps.h" #include #include "CommonMetrics.h" @@ -19,7 +18,7 @@ #include "GameManager.h" #include "Style.h" -UnlockManager* UNLOCKMAN = NULL; // global and accessible from anywhere in our program +UnlockManager* UNLOCKMAN = nullptr; // global and accessible from anywhere in our program #define UNLOCK_NAMES THEME->GetMetric ("UnlockManager","UnlockNames") #define UNLOCK(x) THEME->GetMetricR("UnlockManager", ssprintf("Unlock%sCommand",x.c_str())); @@ -91,20 +90,20 @@ void UnlockManager::UnlockSong( const Song *song ) RString UnlockManager::FindEntryID( const RString &sName ) const { - const UnlockEntry *pEntry = NULL; + const UnlockEntry *pEntry = nullptr; const Song *pSong = SONGMAN->FindSong( sName ); - if( pSong != NULL ) + if( pSong != nullptr ) pEntry = FindSong( pSong ); const Course *pCourse = SONGMAN->FindCourse( sName ); - if( pCourse != NULL ) + if( pCourse != nullptr ) pEntry = FindCourse( pCourse ); - if( pEntry == NULL ) + if( pEntry == nullptr ) pEntry = FindModifier( sName ); - if( pEntry == NULL ) + if( pEntry == nullptr ) { LuaHelpers::ReportScriptErrorFmt( "Couldn't find locked entry \"%s\"", sName.c_str() ); return ""; @@ -120,18 +119,17 @@ int UnlockManager::CourseIsLocked( const Course *pCourse ) const if( PREFSMAN->m_bUseUnlockSystem ) { const UnlockEntry *p = FindCourse( pCourse ); - if( p == NULL ) + if( p == nullptr ) return false; if( p->IsLocked() ) iRet |= LOCKED_LOCK; } /* If a course uses a song that is disabled, disable the course too. */ - FOREACH_CONST( CourseEntry, pCourse->m_vEntries, e ) + for (CourseEntry const &ce : pCourse->m_vEntries) { - const CourseEntry &ce = *e; const Song *pSong = ce.songID.ToSong(); - if( pSong == NULL ) + if( pSong == nullptr ) continue; int iSongLock = SongIsLocked( pSong ); if( iSongLock & LOCKED_DISABLED ) @@ -147,7 +145,7 @@ int UnlockManager::SongIsLocked( const Song *pSong ) const if( PREFSMAN->m_bUseUnlockSystem ) { const UnlockEntry *p = FindSong( pSong ); - if( p != NULL && p->IsLocked() ) + if( p != nullptr && p->IsLocked() ) { iRet |= LOCKED_LOCK; if( !p->m_sEntryID.empty() && m_RouletteCodes.find( p->m_sEntryID ) != m_RouletteCodes.end() ) @@ -169,7 +167,7 @@ bool UnlockManager::StepsIsLocked( const Song *pSong, const Steps *pSteps ) cons return false; const UnlockEntry *p = FindSteps( pSong, pSteps ); - if( p == NULL ) + if( p == nullptr ) return false; return p->IsLocked(); @@ -181,7 +179,7 @@ bool UnlockManager::StepsTypeIsLocked(const Song *pSong, const Steps *pSteps, co return false; const UnlockEntry *p = FindStepsType( pSong, pSteps, pSType ); - if( p == NULL ) + if( p == nullptr ) return false; return p->IsLocked(); @@ -193,7 +191,7 @@ bool UnlockManager::ModifierIsLocked( const RString &sOneMod ) const return false; const UnlockEntry *p = FindModifier( sOneMod ); - if( p == NULL ) + if( p == nullptr ) return false; return p->IsLocked(); @@ -201,19 +199,19 @@ bool UnlockManager::ModifierIsLocked( const RString &sOneMod ) const const UnlockEntry *UnlockManager::FindSong( const Song *pSong ) const { - FOREACH_CONST( UnlockEntry, m_UnlockEntries, e ) - if( e->m_Song.ToSong() == pSong && e->m_dc == Difficulty_Invalid ) - return &(*e); - return NULL; + for (UnlockEntry const &e : m_UnlockEntries) + if( e.m_Song.ToSong() == pSong && e.m_dc == Difficulty_Invalid ) + return &e; + return nullptr; } const UnlockEntry *UnlockManager::FindSteps( const Song *pSong, const Steps *pSteps ) const { ASSERT( pSong && pSteps ); - FOREACH_CONST( UnlockEntry, m_UnlockEntries, e ) - if( e->m_Song.ToSong() == pSong && e->m_dc == pSteps->GetDifficulty() ) - return &(*e); - return NULL; + for (UnlockEntry const &e : m_UnlockEntries) + if( e.m_Song.ToSong() == pSong && e.m_dc == pSteps->GetDifficulty() ) + return &e; + return nullptr; } const UnlockEntry *UnlockManager::FindStepsType(const Song *pSong, @@ -221,28 +219,28 @@ const UnlockEntry *UnlockManager::FindStepsType(const Song *pSong, const StepsType *pSType ) const { ASSERT( pSong && pSteps && pSType ); - FOREACH_CONST( UnlockEntry, m_UnlockEntries, e ) - if(e->m_Song.ToSong() == pSong && - e->m_dc == pSteps->GetDifficulty() && - e->m_StepsType == pSteps->m_StepsType) - return &(*e); - return NULL; + for (UnlockEntry const &e : m_UnlockEntries) + if(e.m_Song.ToSong() == pSong && + e.m_dc == pSteps->GetDifficulty() && + e.m_StepsType == pSteps->m_StepsType) + return &e; + return nullptr; } const UnlockEntry *UnlockManager::FindCourse( const Course *pCourse ) const { - FOREACH_CONST( UnlockEntry, m_UnlockEntries, e ) - if( e->m_Course.ToCourse() == pCourse ) - return &(*e); - return NULL; + for (UnlockEntry const &e : m_UnlockEntries) + if( e.m_Course.ToCourse() == pCourse ) + return &e; + return nullptr; } const UnlockEntry *UnlockManager::FindModifier( const RString &sOneMod ) const { - FOREACH_CONST( UnlockEntry, m_UnlockEntries, e ) - if( e->GetModifier().CompareNoCase(sOneMod) == 0 ) - return &(*e); - return NULL; + for (UnlockEntry const &e : m_UnlockEntries) + if( e.GetModifier().CompareNoCase(sOneMod) == 0 ) + return &e; + return nullptr; } static float GetArcadePoints( const Profile *pProfile ) @@ -389,8 +387,8 @@ UnlockEntryStatus UnlockEntry::GetUnlockEntryStatus() const StepsType_Invalid, Difficulty_Hard ); - FOREACH_CONST( Steps*, vp, s ) - if( PROFILEMAN->GetMachineProfile()->HasPassedSteps(pSong, *s) ) + for (Steps const *s : vp) + if( PROFILEMAN->GetMachineProfile()->HasPassedSteps(pSong, s) ) return UnlockEntryStatus_Unlocked; } @@ -402,9 +400,9 @@ UnlockEntryStatus UnlockEntry::GetUnlockEntryStatus() const vp, StepsType_Invalid, Difficulty_Challenge); - FOREACH_CONST(Steps*, vp, s) + for (Steps const *s : vp) { - if (PROFILEMAN->GetMachineProfile()->HasPassedSteps(pSong, *s)) + if (PROFILEMAN->GetMachineProfile()->HasPassedSteps(pSong, s)) return UnlockEntryStatus_Unlocked; } } @@ -514,23 +512,23 @@ void UnlockManager::Load() if( AUTO_LOCK_CHALLENGE_STEPS ) { - FOREACH_CONST( Song*, SONGMAN->GetAllSongs(), s ) + for (Song const *s : SONGMAN->GetAllSongs()) { // If no hard steps to play to unlock, skip - if( SongUtil::GetOneSteps(*s, StepsType_Invalid, Difficulty_Hard) == NULL ) + if( SongUtil::GetOneSteps(s, StepsType_Invalid, Difficulty_Hard) == nullptr ) continue; // If no challenge steps to unlock, skip - if( SongUtil::GetOneSteps(*s, StepsType_Invalid, Difficulty_Challenge) == NULL ) + if( SongUtil::GetOneSteps(s, StepsType_Invalid, Difficulty_Challenge) == nullptr ) continue; - if( SONGS_NOT_ADDITIONAL && SONGMAN->WasLoadedFromAdditionalSongs(*s) ) + if( SONGS_NOT_ADDITIONAL && SONGMAN->WasLoadedFromAdditionalSongs(s) ) continue; UnlockEntry ue; - ue.m_sEntryID = "_challenge_" + (*s)->GetSongDir(); + ue.m_sEntryID = "_challenge_" + s->GetSongDir(); ue.m_Type = UnlockRewardType_Steps; - ue.m_cmd.Load( (*s)->m_sGroupName+"/"+(*s)->GetTranslitFullTitle()+",expert" ); + ue.m_cmd.Load( s->m_sGroupName+"/"+ s->GetTranslitFullTitle()+",expert" ); ue.m_bRequirePassHardSteps = true; m_UnlockEntries.push_back( ue ); @@ -539,24 +537,24 @@ void UnlockManager::Load() if (AUTO_LOCK_EDIT_STEPS) { - FOREACH_CONST( Song*, SONGMAN->GetAllSongs(), s ) + for (Song const *s : SONGMAN->GetAllSongs()) { // no challenge steps to play: skip. - if (SongUtil::GetOneSteps(*s, StepsType_Invalid, Difficulty_Challenge) == NULL) + if (SongUtil::GetOneSteps(s, StepsType_Invalid, Difficulty_Challenge) == nullptr) continue; // no edit steps to unlock: skip. - if (SongUtil::GetOneSteps(*s, StepsType_Invalid, Difficulty_Edit) == NULL) + if (SongUtil::GetOneSteps(s, StepsType_Invalid, Difficulty_Edit) == nullptr) continue; // don't add additional songs. - if (SONGS_NOT_ADDITIONAL && SONGMAN->WasLoadedFromAdditionalSongs(*s)) + if (SONGS_NOT_ADDITIONAL && SONGMAN->WasLoadedFromAdditionalSongs(s)) continue; UnlockEntry ue; - ue.m_sEntryID = "_edit_" + (*s)->GetSongDir(); + ue.m_sEntryID = "_edit_" + s->GetSongDir(); ue.m_Type = UnlockRewardType_Steps; - ue.m_cmd.Load( (*s)->m_sGroupName+"/"+(*s)->GetTranslitFullTitle()+",edit" ); + ue.m_cmd.Load( s->m_sGroupName+"/"+ s->GetTranslitFullTitle()+",edit" ); ue.m_bRequirePassChallengeSteps = true; m_UnlockEntries.push_back(ue); @@ -566,90 +564,101 @@ void UnlockManager::Load() // Make sure that we don't have duplicate unlock IDs. This can cause problems // with UnlockCelebrate and with codes. - FOREACH_CONST( UnlockEntry, m_UnlockEntries, ue ) - FOREACH_CONST( UnlockEntry, m_UnlockEntries, ue2 ) - if( ue != ue2 ) - ASSERT_M( ue->m_sEntryID != ue2->m_sEntryID, ssprintf("duplicate unlock entry id %s",ue->m_sEntryID.c_str()) ); - - FOREACH( UnlockEntry, m_UnlockEntries, e ) + unsigned size = m_UnlockEntries.size(); + if (size > 1) { - switch( e->m_Type ) + for (unsigned i = 0; i < size - 1; ++i) + { + UnlockEntry const &ue1 = m_UnlockEntries[i]; + for (unsigned j = i + 1; j < size; ++j) + { + UnlockEntry const &ue2 = m_UnlockEntries[j]; + // at this point, these two are definitely different. Assert. + ASSERT_M( ue1.m_sEntryID != ue2.m_sEntryID, ssprintf("duplicate unlock entry id %s", ue1.m_sEntryID.c_str())); + + } + } + } + + for (UnlockEntry &e : m_UnlockEntries) + { + switch( e.m_Type ) { case UnlockRewardType_Song: - e->m_Song.FromSong( SONGMAN->FindSong( e->m_cmd.GetArg(0).s ) ); - if( !e->m_Song.IsValid() ) - LuaHelpers::ReportScriptErrorFmt( "Unlock: Cannot find song matching \"%s\"", e->m_cmd.GetArg(0).s.c_str() ); + e.m_Song.FromSong( SONGMAN->FindSong( e.m_cmd.GetArg(0).s ) ); + if( !e.m_Song.IsValid() ) + LuaHelpers::ReportScriptErrorFmt( "Unlock: Cannot find song matching \"%s\"", e.m_cmd.GetArg(0).s.c_str() ); break; case UnlockRewardType_Steps: - e->m_Song.FromSong( SONGMAN->FindSong( e->m_cmd.GetArg(0).s ) ); - if( !e->m_Song.IsValid() ) + e.m_Song.FromSong( SONGMAN->FindSong( e.m_cmd.GetArg(0).s ) ); + if( !e.m_Song.IsValid() ) { - LuaHelpers::ReportScriptErrorFmt( "Unlock: Cannot find song matching \"%s\"", e->m_cmd.GetArg(0).s.c_str() ); + LuaHelpers::ReportScriptErrorFmt( "Unlock: Cannot find song matching \"%s\"", e.m_cmd.GetArg(0).s.c_str() ); break; } - e->m_dc = StringToDifficulty( e->m_cmd.GetArg(1).s ); - if( e->m_dc == Difficulty_Invalid ) + e.m_dc = StringToDifficulty( e.m_cmd.GetArg(1).s ); + if( e.m_dc == Difficulty_Invalid ) { - LuaHelpers::ReportScriptErrorFmt( "Unlock: Invalid difficulty \"%s\"", e->m_cmd.GetArg(1).s.c_str() ); + LuaHelpers::ReportScriptErrorFmt( "Unlock: Invalid difficulty \"%s\"", e.m_cmd.GetArg(1).s.c_str() ); break; } break; case UnlockRewardType_Steps_Type: { - e->m_Song.FromSong( SONGMAN->FindSong( e->m_cmd.GetArg(0).s ) ); - if( !e->m_Song.IsValid() ) + e.m_Song.FromSong( SONGMAN->FindSong( e.m_cmd.GetArg(0).s ) ); + if( !e.m_Song.IsValid() ) { - LuaHelpers::ReportScriptErrorFmt( "Unlock: Cannot find song matching \"%s\"", e->m_cmd.GetArg(0).s.c_str() ); + LuaHelpers::ReportScriptErrorFmt( "Unlock: Cannot find song matching \"%s\"", e.m_cmd.GetArg(0).s.c_str() ); break; } - e->m_dc = StringToDifficulty( e->m_cmd.GetArg(1).s ); - if( e->m_dc == Difficulty_Invalid ) + e.m_dc = StringToDifficulty( e.m_cmd.GetArg(1).s ); + if( e.m_dc == Difficulty_Invalid ) { - LuaHelpers::ReportScriptErrorFmt( "Unlock: Invalid difficulty \"%s\"", e->m_cmd.GetArg(1).s.c_str() ); + LuaHelpers::ReportScriptErrorFmt( "Unlock: Invalid difficulty \"%s\"", e.m_cmd.GetArg(1).s.c_str() ); break; } - e->m_StepsType = GAMEMAN->StringToStepsType(e->m_cmd.GetArg(2).s); - if (e->m_StepsType == StepsType_Invalid) + e.m_StepsType = GAMEMAN->StringToStepsType(e.m_cmd.GetArg(2).s); + if (e.m_StepsType == StepsType_Invalid) { - LuaHelpers::ReportScriptErrorFmt( "Unlock: Invalid steps type \"%s\"", e->m_cmd.GetArg(2).s.c_str() ); + LuaHelpers::ReportScriptErrorFmt( "Unlock: Invalid steps type \"%s\"", e.m_cmd.GetArg(2).s.c_str() ); break; } break; } case UnlockRewardType_Course: - e->m_Course.FromCourse( SONGMAN->FindCourse(e->m_cmd.GetArg(0).s) ); - if( !e->m_Course.IsValid() ) - LuaHelpers::ReportScriptErrorFmt( "Unlock: Cannot find course matching \"%s\"", e->m_cmd.GetArg(0).s.c_str() ); + e.m_Course.FromCourse( SONGMAN->FindCourse(e.m_cmd.GetArg(0).s) ); + if( !e.m_Course.IsValid() ) + LuaHelpers::ReportScriptErrorFmt( "Unlock: Cannot find course matching \"%s\"", e.m_cmd.GetArg(0).s.c_str() ); break; case UnlockRewardType_Modifier: // nothing to cache break; default: - FAIL_M(ssprintf("Invalid UnlockRewardType: %i", e->m_Type)); + FAIL_M(ssprintf("Invalid UnlockRewardType: %i", e.m_Type)); } } // Log unlocks - FOREACH_CONST( UnlockEntry, m_UnlockEntries, e ) + for (UnlockEntry &e : m_UnlockEntries) { - RString str = ssprintf( "Unlock: %s; ", join("\n",e->m_cmd.m_vsArgs).c_str() ); + RString str = ssprintf( "Unlock: %s; ", join("\n",e.m_cmd.m_vsArgs).c_str() ); FOREACH_ENUM( UnlockRequirement, j ) - if( e->m_fRequirement[j] ) - str += ssprintf( "%s = %f; ", UnlockRequirementToString(j).c_str(), e->m_fRequirement[j] ); - if( e->m_bRequirePassHardSteps ) + if( e.m_fRequirement[j] ) + str += ssprintf( "%s = %f; ", UnlockRequirementToString(j).c_str(), e.m_fRequirement[j] ); + if( e.m_bRequirePassHardSteps ) str += "RequirePassHardSteps; "; - if (e->m_bRequirePassChallengeSteps) + if (e.m_bRequirePassChallengeSteps) str += "RequirePassChallengeSteps; "; - str += ssprintf( "entryID = %s ", e->m_sEntryID.c_str() ); - str += e->IsLocked()? "locked":"unlocked"; - if( e->m_Song.IsValid() ) + str += ssprintf( "entryID = %s ", e.m_sEntryID.c_str() ); + str += e.IsLocked()? "locked":"unlocked"; + if( e.m_Song.IsValid() ) str += ( " (found song)" ); - if( e->m_Course.IsValid() ) + if( e.m_Course.IsValid() ) str += ( " (found course)" ); LOG->Trace( "%s", str.c_str() ); } @@ -715,7 +724,7 @@ void UnlockManager::PreferUnlockEntryID( RString sUnlockEntryID ) if( pEntry.m_sEntryID != sUnlockEntryID ) continue; - if( pEntry.m_Song.ToSong() != NULL ) + if( pEntry.m_Song.ToSong() != nullptr ) GAMESTATE->m_pPreferredSong = pEntry.m_Song.ToSong(); if( pEntry.m_Course.ToCourse() ) GAMESTATE->m_pPreferredCourse = pEntry.m_Course.ToCourse(); @@ -729,21 +738,19 @@ int UnlockManager::GetNumUnlocks() const int UnlockManager::GetNumUnlocked() const { - int count = 0; - FOREACH_CONST( UnlockEntry, m_UnlockEntries, ue ) - { - if( !ue->IsLocked() ) - count++; - } - return count; + return std::count_if(m_UnlockEntries.begin(), m_UnlockEntries.end(), [](UnlockEntry const &ue) { + return !ue.IsLocked(); + }); } int UnlockManager::GetUnlockEntryIndexToCelebrate() const { - FOREACH_CONST( UnlockEntry, m_UnlockEntries, ue ) + int i = 0; + for (UnlockEntry const &ue : m_UnlockEntries) { - if( ue->GetUnlockEntryStatus() == UnlockEntryStatus_RequirementsMet ) - return ue - m_UnlockEntries.begin(); + if( ue.GetUnlockEntryStatus() == UnlockEntryStatus_RequirementsMet ) + return i; + ++i; } return -1; } @@ -755,9 +762,9 @@ bool UnlockManager::AnyUnlocksToCelebrate() const void UnlockManager::GetUnlocksByType( UnlockRewardType t, vector &apEntries ) { - for( unsigned i = 0; i < m_UnlockEntries.size(); ++i ) - if( m_UnlockEntries[i].IsValid() && m_UnlockEntries[i].m_Type == t ) - apEntries.push_back( &m_UnlockEntries[i] ); + for (UnlockEntry &entry : m_UnlockEntries) + if( entry.IsValid() && entry.m_Type == t ) + apEntries.push_back( &entry ); } void UnlockManager::GetSongsUnlockedByEntryID( vector &apSongsOut, RString sUnlockEntryID ) @@ -765,9 +772,9 @@ void UnlockManager::GetSongsUnlockedByEntryID( vector &apSongsOut, RStri vector apEntries; GetUnlocksByType( UnlockRewardType_Song, apEntries ); - for( unsigned i = 0; i < apEntries.size(); ++i ) - if( apEntries[i]->m_sEntryID == sUnlockEntryID ) - apSongsOut.push_back( apEntries[i]->m_Song.ToSong() ); + for (UnlockEntry const *ue : apEntries) + if( ue->m_sEntryID == sUnlockEntryID ) + apSongsOut.push_back( ue->m_Song.ToSong() ); } void UnlockManager::GetStepsUnlockedByEntryID( vector &apSongsOut, vector &apDifficultyOut, RString sUnlockEntryID ) @@ -775,12 +782,12 @@ void UnlockManager::GetStepsUnlockedByEntryID( vector &apSongsOut, vecto vector apEntries; GetUnlocksByType( UnlockRewardType_Steps, apEntries ); - for( unsigned i = 0; i < apEntries.size(); ++i ) + for (UnlockEntry const *entry : apEntries) { - if( apEntries[i]->m_sEntryID == sUnlockEntryID ) + if( entry->m_sEntryID == sUnlockEntryID ) { - apSongsOut.push_back( apEntries[i]->m_Song.ToSong() ); - apDifficultyOut.push_back( apEntries[i]->m_dc ); + apSongsOut.push_back( entry->m_Song.ToSong() ); + apDifficultyOut.push_back( entry->m_dc ); } } } @@ -817,11 +824,11 @@ public: { const vector& allSteps = pSong->GetAllSteps(); vector toRet; - FOREACH_CONST(Steps*, allSteps, step) + for (Steps *step : allSteps) { - if ((*step)->GetDifficulty() == p->m_dc) + if (step->GetDifficulty() == p->m_dc) { - toRet.push_back(*step); + toRet.push_back(step); } } LuaHelpers::CreateTableFromArray( toRet, L ); @@ -837,11 +844,11 @@ public: if (pSong) { const vector& allStepsType = pSong->GetStepsByStepsType(p->m_StepsType); - FOREACH_CONST(Steps*, allStepsType, step) + for (Steps *step : allStepsType) { - if ((*step)->GetDifficulty() == p->m_dc) + if (step->GetDifficulty() == p->m_dc) { - (*step)->PushSelf(L); return 1; + step->PushSelf(L); return 1; } } } diff --git a/src/UnlockManager.h b/src/UnlockManager.h index 940ffa86c5..184216b160 100644 --- a/src/UnlockManager.h +++ b/src/UnlockManager.h @@ -73,7 +73,7 @@ public: Command m_cmd; /* A cached pointer to the song or course this entry refers to. Only one of - * these will be non-NULL. */ + * these will be non-nullptr. */ SongID m_Song; Difficulty m_dc; CourseID m_Course; diff --git a/src/WheelBase.cpp b/src/WheelBase.cpp index 6c8578341d..4c4dc1d00d 100644 --- a/src/WheelBase.cpp +++ b/src/WheelBase.cpp @@ -11,7 +11,6 @@ #include "ThemeManager.h" #include "RageTextureManager.h" #include "ActorUtil.h" -#include "Foreach.h" #include "Style.h" #include "ThemeMetric.h" #include "ScreenDimensions.h" @@ -34,10 +33,12 @@ LuaXType( WheelState ); WheelBase::~WheelBase() { - FOREACH( WheelItemBase*, m_WheelBaseItems, i ) - SAFE_DELETE( *i ); + for (WheelItemBase *i : m_WheelBaseItems) + { + SAFE_DELETE( i ); + } m_WheelBaseItems.clear(); - m_LastSelection = NULL; + m_LastSelection = nullptr; } void WheelBase::Load( RString sType ) @@ -46,7 +47,7 @@ void WheelBase::Load( RString sType ) ASSERT( this->GetNumChildren() == 0 ); // only load once m_bEmpty = false; - m_LastSelection = NULL; + m_LastSelection = nullptr; m_iSelection = 0; m_fTimeLeftInState = 0; m_fPositionOffsetFromSelection = 0; @@ -306,7 +307,7 @@ WheelItemBaseData* WheelBase::GetItem( unsigned int iIndex ) if( !m_bEmpty && iIndex < m_CurWheelItemData.size() ) return m_CurWheelItemData[iIndex]; - return NULL; + return nullptr; } int WheelBase::IsMoving() const @@ -488,7 +489,7 @@ void WheelBase::RebuildWheelItems( int iDist ) WheelItemBaseData* WheelBase::LastSelected() { if( m_bEmpty ) - return NULL; + return nullptr; else return m_LastSelection; } @@ -520,7 +521,7 @@ public: int iItem = IArg(1); WheelItemBase *pItem = p->GetWheelItem( iItem ); - if( pItem == NULL ) + if( pItem == nullptr ) luaL_error( L, "%i out of bounds", iItem ); pItem->PushSelf( L ); diff --git a/src/WheelBase.h b/src/WheelBase.h index 73a9ae98ac..e984ee2d30 100644 --- a/src/WheelBase.h +++ b/src/WheelBase.h @@ -63,7 +63,7 @@ public: bool IsEmpty() { return m_bEmpty; } WheelItemBaseData* GetItem(unsigned int index); WheelItemBaseData* LastSelected(); - WheelItemBase *GetWheelItem( int i ) { if( i < 0 || i >= (int) m_WheelBaseItems.size() ) return NULL; return m_WheelBaseItems[i]; } + WheelItemBase *GetWheelItem( int i ) { if( i < 0 || i >= (int) m_WheelBaseItems.size() ) return nullptr; return m_WheelBaseItems[i]; } RString GetExpandedSectionName() { return m_sExpandedSectionName; } int GetCurrentIndex() { return m_iSelection; } diff --git a/src/WheelItemBase.cpp b/src/WheelItemBase.cpp index 08bb71d362..85e3280892 100644 --- a/src/WheelItemBase.cpp +++ b/src/WheelItemBase.cpp @@ -38,9 +38,9 @@ WheelItemBase::WheelItemBase( const WheelItemBase &cpy ): WheelItemBase::WheelItemBase(RString sType) { SetName( sType ); - m_pData = NULL; + m_pData = nullptr; m_bExpanded = false; - m_pGrayBar = NULL; + m_pGrayBar = nullptr; Load(sType); } @@ -51,7 +51,7 @@ void WheelItemBase::Load( RString sType ) void WheelItemBase::LoadFromWheelItemData( const WheelItemBaseData* pWID, int iIndex, bool bHasFocus, int iDrawIndex ) { - ASSERT( pWID != NULL ); + ASSERT( pWID != nullptr ); m_pData = pWID; } @@ -76,7 +76,7 @@ void WheelItemBase::DrawPrimitives() { ActorFrame::DrawPrimitives(); - if( m_pGrayBar != NULL ) + if( m_pGrayBar != nullptr ) DrawGrayBar( *m_pGrayBar ); } diff --git a/src/WheelItemBase.h b/src/WheelItemBase.h index 2eea82e4db..a732bd5d34 100644 --- a/src/WheelItemBase.h +++ b/src/WheelItemBase.h @@ -51,10 +51,10 @@ public: RageColor m_colorLocked; - const RString GetText(){ ASSERT(m_pData != NULL); return m_pData->m_sText; } - const RageColor GetColor(){ ASSERT(m_pData != NULL); return m_pData->m_color; } - WheelItemDataType GetType(){ ASSERT(m_pData != NULL); return m_pData->m_Type; } - bool IsLoaded(){ return m_pData != NULL; } + const RString GetText(){ ASSERT(m_pData != nullptr); return m_pData->m_sText; } + const RageColor GetColor(){ ASSERT(m_pData != nullptr); return m_pData->m_color; } + WheelItemDataType GetType(){ ASSERT(m_pData != nullptr); return m_pData->m_Type; } + bool IsLoaded(){ return m_pData != nullptr; } // Lua void PushSelf( lua_State *L ); diff --git a/src/WorkoutGraph.cpp b/src/WorkoutGraph.cpp index 0d00555a35..e1ee230fcf 100644 --- a/src/WorkoutGraph.cpp +++ b/src/WorkoutGraph.cpp @@ -8,7 +8,6 @@ #include "GameState.h" #include "ThemeManager.h" #include "StatsManager.h" -#include "Foreach.h" #include "Course.h" #include "Style.h" @@ -23,8 +22,10 @@ WorkoutGraph::WorkoutGraph() WorkoutGraph::~WorkoutGraph() { - FOREACH( Sprite*, m_vpBars, a ) - delete *a; + for (Sprite *s : m_vpBars) + { + delete s; + } m_vpBars.clear(); } @@ -48,22 +49,22 @@ void WorkoutGraph::SetFromCurrentWorkout() void WorkoutGraph::SetInternal( int iMinSongsPlayed ) { - FOREACH( Sprite*, m_vpBars, p ) + for (Sprite *s : m_vpBars) { - this->RemoveChild( *p ); - delete *p; + this->RemoveChild( s ); + delete s; } m_vpBars.clear(); Trail *pTrail = GAMESTATE->m_pCurTrail[PLAYER_1]; - if( pTrail == NULL ) + if( pTrail == nullptr ) return; vector viMeters; - FOREACH_CONST( TrailEntry, pTrail->m_vEntries, e ) + for (TrailEntry const &e : pTrail->m_vEntries) { - ASSERT( e->pSteps != NULL ); - viMeters.push_back( e->pSteps->GetMeter() ); + ASSERT( e.pSteps != nullptr ); + viMeters.push_back( e.pSteps->GetMeter() ); } int iBlocksWide = viMeters.size(); @@ -84,17 +85,17 @@ void WorkoutGraph::SetInternal( int iMinSongsPlayed ) m_sprEmpty.ZoomToWidth( iBlocksWide * fBlockSize ); m_sprEmpty.ZoomToHeight( iBlocksHigh * fBlockSize ); - FOREACH_CONST( int, viMeters, iter ) + int index = 0; + for (int const &meter : viMeters) { - int iIndex = iter - viMeters.begin(); - float fOffsetFromCenter = iIndex - (iBlocksWide-1)/2.0f; + float fOffsetFromCenter = (index++) - (iBlocksWide-1)/2.0f; Sprite *p = new Sprite; p->Load( THEME->GetPathG("WorkoutGraph","bar") ); p->SetVertAlign( align_bottom ); p->ZoomToWidth( fBlockSize ); - int iMetersToCover = (MAX_METER - *iter); + int iMetersToCover = (MAX_METER - meter); p->SetCustomImageRect( RectF(0,(float)iMetersToCover/(float)iBlocksHigh,1,1) ); - p->ZoomToHeight( *iter * fBlockSize ); + p->ZoomToHeight( meter * fBlockSize ); p->SetX( fOffsetFromCenter * fBlockSize ); m_vpBars.push_back( p ); this->AddChild( p ); @@ -105,8 +106,8 @@ void WorkoutGraph::SetFromGameStateAndHighlightSong( int iSongIndex ) { SetInternal( iSongIndex+1 ); - FOREACH( Sprite*, m_vpBars, spr ) - (*spr)->StopEffect(); + for (Sprite *s : m_vpBars) + s->StopEffect(); int iBarIndex = iSongIndex - m_iSongsChoppedOffAtBeginning; diff --git a/src/XmlFile.cpp b/src/XmlFile.cpp index b57ec74b16..728e6cdd0e 100644 --- a/src/XmlFile.cpp +++ b/src/XmlFile.cpp @@ -11,7 +11,6 @@ #include "RageLog.h" #include "RageUtil.h" #include "DateTime.h" -#include "Foreach.h" #include "LuaManager.h" const RString XNode::TEXT_ATTRIBUTE = "__TEXT__"; @@ -51,10 +50,10 @@ void XNode::Free() } void XNodeStringValue::GetValue( RString &out ) const { out = m_sValue; } -void XNodeStringValue::GetValue( int &out ) const { out = StringToInt(m_sValue); } +void XNodeStringValue::GetValue( int &out ) const { out = std::stoi(m_sValue); } void XNodeStringValue::GetValue( float &out ) const { out = StringToFloat(m_sValue); } -void XNodeStringValue::GetValue( bool &out ) const { out = StringToInt(m_sValue) != 0; } -void XNodeStringValue::GetValue( unsigned &out ) const { out = strtoul(m_sValue,NULL,0); } +void XNodeStringValue::GetValue( bool &out ) const { out = std::stoi(m_sValue) != 0; } +void XNodeStringValue::GetValue( unsigned &out ) const { out = strtoul(m_sValue,nullptr,0); } void XNodeStringValue::PushValue( lua_State *L ) const { LuaHelpers::Push( L, m_sValue ); @@ -74,13 +73,13 @@ const XNodeValue *XNode::GetAttr( const RString &attrname ) const XAttrs::const_iterator it = m_attrs.find( attrname ); if( it != m_attrs.end() ) return it->second; - return NULL; + return nullptr; } bool XNode::PushAttrValue( lua_State *L, const RString &sName ) const { const XNodeValue *pAttr = GetAttr(sName); - if( pAttr == NULL ) + if( pAttr == nullptr ) { lua_pushnil( L ); return false; @@ -94,7 +93,7 @@ XNodeValue *XNode::GetAttr( const RString &attrname ) XAttrs::iterator it = m_attrs.find( attrname ); if( it != m_attrs.end() ) return it->second; - return NULL; + return nullptr; } XNode *XNode::GetChild( const RString &sName ) @@ -105,13 +104,13 @@ XNode *XNode::GetChild( const RString &sName ) { return by_name->second; } - return NULL; + return nullptr; } bool XNode::PushChildValue( lua_State *L, const RString &sName ) const { const XNode *pChild = GetChild(sName); - if( pChild == NULL ) + if( pChild == nullptr ) { lua_pushnil( L ); return false; @@ -128,7 +127,7 @@ const XNode *XNode::GetChild( const RString &sName ) const { return by_name->second; } - return NULL; + return nullptr; } XNode *XNode::AppendChild( XNode *node ) @@ -193,7 +192,7 @@ bool XNode::RemoveAttr( const RString &sName ) XNodeValue *XNode::AppendAttrFrom( const RString &sName, XNodeValue *pValue, bool bOverwrite ) { DEBUG_ASSERT( sName.size() ); - pair ret = m_attrs.insert( make_pair(sName, (XNodeValue *) NULL) ); + pair ret = m_attrs.insert( make_pair(sName, (XNodeValue *) nullptr) ); if( !ret.second ) // already existed { if( bOverwrite ) @@ -215,7 +214,7 @@ XNodeValue *XNode::AppendAttrFrom( const RString &sName, XNodeValue *pValue, boo XNodeValue *XNode::AppendAttr( const RString &sName ) { DEBUG_ASSERT( sName.size() ); - pair ret = m_attrs.insert( make_pair(sName, (XNodeValue *) NULL) ); + pair ret = m_attrs.insert( make_pair(sName, (XNodeValue *) nullptr) ); if( ret.second ) ret.first->second = new XNodeStringValue; return ret.first->second; // already existed diff --git a/src/XmlFile.h b/src/XmlFile.h index 5b15b8de69..bce2b4a50e 100644 --- a/src/XmlFile.h +++ b/src/XmlFile.h @@ -67,16 +67,16 @@ typedef vector XNodes; ++Var ) /** @brief Loop through each child. */ #define FOREACH_Child( pNode, Var ) \ - XNode *Var = NULL; \ + XNode *Var = nullptr; \ for( XNodes::iterator Var##Iter = (pNode)->GetChildrenBegin(); \ - Var = (Var##Iter != (pNode)->GetChildrenEnd())? *Var##Iter:NULL, \ + Var = (Var##Iter != (pNode)->GetChildrenEnd())? *Var##Iter:nullptr, \ Var##Iter != (pNode)->GetChildrenEnd(); \ ++Var##Iter ) /** @brief Loop through each child, using a constant iterator. */ #define FOREACH_CONST_Child( pNode, Var ) \ - const XNode *Var = NULL; \ + const XNode *Var = nullptr; \ for( XNodes::const_iterator Var##Iter = (pNode)->GetChildrenBegin(); \ - Var = (Var##Iter != (pNode)->GetChildrenEnd())? *Var##Iter:NULL, \ + Var = (Var##Iter != (pNode)->GetChildrenEnd())? *Var##Iter:nullptr, \ Var##Iter != (pNode)->GetChildrenEnd(); \ ++Var##Iter ) @@ -101,7 +101,7 @@ public: const XNodeValue *GetAttr( const RString &sAttrName ) const; XNodeValue *GetAttr( const RString &sAttrName ); template - bool GetAttrValue( const RString &sName, T &out ) const { const XNodeValue *pAttr=GetAttr(sName); if(pAttr==NULL) return false; pAttr->GetValue(out); return true; } + bool GetAttrValue( const RString &sName, T &out ) const { const XNodeValue *pAttr=GetAttr(sName); if(pAttr== nullptr) return false; pAttr->GetValue(out); return true; } bool PushAttrValue( lua_State *L, const RString &sName ) const; XNodes::iterator GetChildrenBegin() { return m_childs.begin(); } @@ -114,7 +114,7 @@ public: const XNode *GetChild( const RString &sName ) const; XNode *GetChild( const RString &sName ); template - bool GetChildValue( const RString &sName, T &out ) const { const XNode *pChild=GetChild(sName); if(pChild==NULL) return false; pChild->GetTextValue(out); return true; } + bool GetChildValue( const RString &sName, T &out ) const { const XNode *pChild=GetChild(sName); if(pChild== nullptr) return false; pChild->GetTextValue(out); return true; } bool PushChildValue( lua_State *L, const RString &sName ) const; // modify DOM diff --git a/src/XmlFileUtil.cpp b/src/XmlFileUtil.cpp index d3d1308ee8..776d9b9088 100644 --- a/src/XmlFileUtil.cpp +++ b/src/XmlFileUtil.cpp @@ -6,7 +6,6 @@ #include "RageUtil.h" #include "RageLog.h" #include "arch/Dialog/Dialog.h" -#include "Foreach.h" #include "LuaManager.h" bool XmlFileUtil::LoadFromFileShowErrors( XNode &xml, RageFileBasic &f ) @@ -285,7 +284,7 @@ RString::size_type LoadInternal( XNode *pNode, const RString &xml, RString &sErr // open/close tag ... // ^- current pointer - if( pNode->GetAttr(XNode::TEXT_ATTRIBUTE) == NULL ) + if( pNode->GetAttr(XNode::TEXT_ATTRIBUTE) == nullptr ) { // Text Value ++iOffset; @@ -368,7 +367,7 @@ RString::size_type LoadInternal( XNode *pNode, const RString &xml, RString &sErr } else // Alone child Tag Loaded { - if( pNode->GetAttr(XNode::TEXT_ATTRIBUTE) == NULL && iOffset < xml.size() && xml[iOffset] != chXMLTagOpen ) + if( pNode->GetAttr(XNode::TEXT_ATTRIBUTE) == nullptr && iOffset < xml.size() && xml[iOffset] != chXMLTagOpen ) { // Text Value RString::size_type iEnd = xml.find( chXMLTagOpen, iOffset ); @@ -420,7 +419,7 @@ bool GetXMLInternal( const XNode *pNode, RageFileBasic &f, bool bWriteTabs, int WRITE( "'" ); } - if( pNode->ChildrenEmpty() && pNode->GetAttr(XNode::TEXT_ATTRIBUTE) == NULL ) + if( pNode->ChildrenEmpty() && pNode->GetAttr(XNode::TEXT_ATTRIBUTE) == nullptr ) { // alone tag WRITE( "/>" ); @@ -439,7 +438,7 @@ bool GetXMLInternal( const XNode *pNode, RageFileBasic &f, bool bWriteTabs, int // Text Value const XNodeValue *pText = pNode->GetAttr( XNode::TEXT_ATTRIBUTE ); - if( pText != NULL ) + if( pText != nullptr ) { if( !pNode->ChildrenEmpty() ) { @@ -789,7 +788,7 @@ void XmlFileUtil::MergeIniUnder( XNode *pFrom, XNode *pTo ) // If this node doesn't exist in pTo, just move the whole node. XNode *pSectionNode = *it; XNode *pChildNode = pTo->GetChild( pSectionNode->GetName() ); - if( pChildNode == NULL ) + if( pChildNode == nullptr ) { aToMove.push_back( it ); } diff --git a/src/XmlToLua.cpp b/src/XmlToLua.cpp index 44f376111f..13cd54994c 100644 --- a/src/XmlToLua.cpp +++ b/src/XmlToLua.cpp @@ -1,6 +1,5 @@ #include "global.h" #include "ActorUtil.h" -#include "Foreach.h" #include "IniFile.h" #include "RageFile.h" #include "RageFileManager.h" @@ -63,12 +62,12 @@ void convert_xmls_in_dir(RString const& dirname) RString convert_xpos(float x) { - return "SCREEN_CENTER_X + " + FloatToString(x - 320.0f); + return "SCREEN_CENTER_X + " + std::to_string(x - 320.0f); } RString convert_ypos(float y) { - return "SCREEN_CENTER_Y + " + FloatToString(y - 240.0f); + return "SCREEN_CENTER_Y + " + std::to_string(y - 240.0f); } RString maybe_conv_pos(RString pos, RString (*conv_func)(float p)) @@ -444,7 +443,7 @@ void actor_template_t::load_frames_from_file(RString const& fname, RString const return; } XNode const* sprite_node= ini.GetChild("Sprite"); - if(sprite_node != NULL) + if(sprite_node != nullptr) { FOREACH_CONST_Attr(sprite_node, attr) { @@ -453,13 +452,13 @@ void actor_template_t::load_frames_from_file(RString const& fname, RString const RString field_type= attr->first.Left(5); if(field_type == "Frame") { - int id= StringToInt(attr->first.Right(attr->first.size()-5)); + int id= std::stoi(attr->first.Right(attr->first.size()-5)); make_space_for_frame(id); attr->second->GetValue(frames[id].frame); } else if(field_type == "Delay") { - int id= StringToInt(attr->first.Right(attr->first.size()-5)); + int id= std::stoi(attr->first.Right(attr->first.size()-5)); make_space_for_frame(id); attr->second->GetValue(frames[id].delay); } @@ -484,7 +483,7 @@ void actor_template_t::load_model_from_file(RString const& fname, RString const& return; } XNode const* model_node= ini.GetChild("Model"); - if(model_node != NULL) + if(model_node != nullptr) { FOREACH_CONST_Attr(model_node, attr) { @@ -639,7 +638,7 @@ void actor_template_t::load_node(XNode const& node, RString const& dirname, cond rename_field("File", "Texture"); } XNode const* xren= node.GetChild("children"); - if(xren != NULL) + if(xren != nullptr) { FOREACH_CONST_Child(xren, child) { @@ -688,8 +687,8 @@ void actor_template_t::output_to_file(RageFile* file, RString const& indent) for(vector::iterator frame= frames.begin(); frame != frames.end(); ++frame) { - file->Write(frameindent + "{Frame= " + IntToString(frame->frame) + - ", Delay= " + FloatToString(frame->delay) + "},\n"); + file->Write(frameindent + "{Frame= " + std::to_string(frame->frame) + + ", Delay= " + std::to_string(frame->delay) + "},\n"); } file->Write(indent + "},\n"); } diff --git a/src/arch/ArchHooks/ArchHooks.cpp b/src/arch/ArchHooks/ArchHooks.cpp index 5ba40f84b1..a47f6125d4 100644 --- a/src/arch/ArchHooks/ArchHooks.cpp +++ b/src/arch/ArchHooks/ArchHooks.cpp @@ -9,7 +9,7 @@ bool ArchHooks::g_bQuitting = false; bool ArchHooks::g_bToggleWindowed = false; // Keep from pulling RageThreads.h into ArchHooks.h static RageMutex g_Mutex( "ArchHooks" ); -ArchHooks *HOOKS = NULL; // global and accessible from anywhere in our program +ArchHooks *HOOKS = nullptr; // global and accessible from anywhere in our program ArchHooks::ArchHooks(): m_bHasFocus(true), m_bFocusChanged(false) { diff --git a/src/arch/ArchHooks/ArchHooks_MacOSX.mm b/src/arch/ArchHooks/ArchHooks_MacOSX.mm index d434b622f1..def9a1b7a5 100644 --- a/src/arch/ArchHooks/ArchHooks_MacOSX.mm +++ b/src/arch/ArchHooks/ArchHooks_MacOSX.mm @@ -81,7 +81,7 @@ void ArchHooks_MacOSX::Init() CFBundleRef bundle = CFBundleGetMainBundle(); CFStringRef appID = CFBundleGetIdentifier( bundle ); - if( appID == NULL ) + if( appID == nil) { // We were probably launched through a symlink. Don't bother hunting down the real path. return; @@ -90,12 +90,12 @@ void ArchHooks_MacOSX::Init() CFPropertyListRef old = CFPreferencesCopyAppValue( key, appID ); CFURLRef path = CFBundleCopyBundleURL( bundle ); CFPropertyListRef value = CFURLCopyFileSystemPath( path, kCFURLPOSIXPathStyle ); - CFMutableDictionaryRef newDict = NULL; + CFMutableDictionaryRef newDict = nil; if( old && CFGetTypeID(old) != CFDictionaryGetTypeID() ) { CFRelease( old ); - old = NULL; + old = nil; } if( !old ) @@ -152,7 +152,7 @@ void ArchHooks_MacOSX::DumpDebugInfo() } size_t size; -#define GET_PARAM( name, var ) (size = sizeof(var), sysctlbyname(name, &var, &size, NULL, 0) ) +#define GET_PARAM( name, var ) (size = sizeof(var), sysctlbyname(name, &var, &size, nil, 0) ) // Get memory float fRam; char ramPower; @@ -202,27 +202,27 @@ void ArchHooks_MacOSX::DumpDebugInfo() break; } sModel = szModel; - CFURLRef urlRef = CFBundleCopyResourceURL( CFBundleGetMainBundle(), CFSTR("Hardware.plist"), NULL, NULL ); + CFURLRef urlRef = CFBundleCopyResourceURL( CFBundleGetMainBundle(), CFSTR("Hardware.plist"), nil, nil); - if( urlRef == NULL ) + if( urlRef == nil) break; - CFDataRef dataRef = NULL; + CFDataRef dataRef = nil; SInt32 error; - CFURLCreateDataAndPropertiesFromResource( NULL, urlRef, &dataRef, NULL, NULL, &error ); + CFURLCreateDataAndPropertiesFromResource( nil, urlRef, &dataRef, nil, nil, &error ); CFRelease( urlRef ); - if( dataRef == NULL ) + if( dataRef == nil) break; // This also works with binary property lists for some reason. - CFPropertyListRef plRef = CFPropertyListCreateFromXMLData( NULL, dataRef, kCFPropertyListImmutable, NULL ); + CFPropertyListRef plRef = CFPropertyListCreateFromXMLData( nil, dataRef, kCFPropertyListImmutable, nil); CFRelease( dataRef ); - if( plRef == NULL ) + if( plRef == nil) break; if( CFGetTypeID(plRef) != CFDictionaryGetTypeID() ) { CFRelease( plRef ); break; } - CFStringRef keyRef = CFStringCreateWithCStringNoCopy( NULL, szModel, kCFStringEncodingMacRoman, kCFAllocatorNull ); + CFStringRef keyRef = CFStringCreateWithCStringNoCopy( nil, szModel, kCFStringEncodingMacRoman, kCFAllocatorNull ); CFStringRef modelRef = (CFStringRef)CFDictionaryGetValue( (CFDictionaryRef)plRef, keyRef ); if( modelRef ) sModel = CFStringGetCStringPtr( modelRef, kCFStringEncodingMacRoman ); @@ -244,7 +244,7 @@ RString ArchHooks::GetPreferredLanguage() CFTypeRef t = CFPreferencesCopyAppValue( CFSTR("AppleLanguages"), app ); RString ret = "en"; - if( t == NULL ) + if( t == nil) return ret; if( CFGetTypeID(t) != CFArrayGetTypeID() ) { @@ -256,7 +256,7 @@ RString ArchHooks::GetPreferredLanguage() CFStringRef lang; if( CFArrayGetCount(languages) > 0 && - (lang = (CFStringRef)CFArrayGetValueAtIndex(languages, 0)) != NULL ) + (lang = (CFStringRef)CFArrayGetValueAtIndex(languages, 0)) != nil) { // MacRoman agrees with ASCII in the low-order 7 bits. const char *str = CFStringGetCStringPtr( lang, kCFStringEncodingMacRoman ); @@ -273,8 +273,8 @@ RString ArchHooks::GetPreferredLanguage() bool ArchHooks_MacOSX::GoToURL( RString sUrl ) { CFURLRef url = CFURLCreateWithBytes( kCFAllocatorDefault, (const UInt8*)sUrl.data(), - sUrl.length(), kCFStringEncodingUTF8, NULL ); - OSStatus result = LSOpenCFURLRef( url, NULL ); + sUrl.length(), kCFStringEncodingUTF8, nil); + OSStatus result = LSOpenCFURLRef( url, nil); CFRelease( url ); return result == 0; @@ -310,7 +310,7 @@ static void PathForFolderType( char dir[PATH_MAX], OSType folderType ) void ArchHooks::MountInitialFilesystems( const RString &sDirOfExecutable ) { char dir[PATH_MAX]; - CFURLRef dataUrl = CFBundleCopyResourceURL( CFBundleGetMainBundle(), CFSTR("StepMania"), CFSTR("smzip"), NULL ); + CFURLRef dataUrl = CFBundleCopyResourceURL( CFBundleGetMainBundle(), CFSTR("StepMania"), CFSTR("smzip"), nil); FILEMAN->Mount( "dir", sDirOfExecutable, "/" ); diff --git a/src/arch/ArchHooks/ArchHooks_Unix.cpp b/src/arch/ArchHooks/ArchHooks_Unix.cpp index 30dcf91ea3..8f67a19c2f 100644 --- a/src/arch/ArchHooks/ArchHooks_Unix.cpp +++ b/src/arch/ArchHooks/ArchHooks_Unix.cpp @@ -110,7 +110,7 @@ static void TestTLS() RageThread TestThread; TestThread.SetName( "TestTLS" ); - TestThread.Create( TestTLSThread, NULL ); + TestThread.Create( TestTLSThread, nullptr ); TestThread.Wait(); if( g_iTestTLS == 1 ) @@ -167,7 +167,7 @@ int64_t ArchHooks::GetMicrosecondsSinceStart( bool bAccurate ) int64_t ArchHooks::GetMicrosecondsSinceStart( bool bAccurate ) { struct timeval tv; - gettimeofday( &tv, NULL ); + gettimeofday( &tv, nullptr ); int64_t iRet = int64_t(tv.tv_sec) * 1000000 + int64_t(tv.tv_usec); ret = FixupTimeIfBackwards( ret ); @@ -224,7 +224,7 @@ bool ArchHooks_Unix::GoToURL( RString sUrl ) else if ( p == 0 ) { // Child - const char * const argv[] = { "xdg-open", sUrl.c_str(), NULL }; + const char * const argv[] = { "xdg-open", sUrl.c_str(), nullptr }; execv( "/usr/bin/xdg-open", const_cast( argv )); // If we reach here, the call to execvp failed exit( 1 ); diff --git a/src/arch/ArchHooks/ArchHooks_Win32.cpp b/src/arch/ArchHooks/ArchHooks_Win32.cpp index 4919f75f11..15865eca4d 100644 --- a/src/arch/ArchHooks/ArchHooks_Win32.cpp +++ b/src/arch/ArchHooks/ArchHooks_Win32.cpp @@ -42,7 +42,7 @@ ArchHooks_Win32::ArchHooks_Win32() * the main thread. */ SetThreadPriorityBoost( GetCurrentThread(), TRUE ); - g_hInstanceMutex = CreateMutex( NULL, TRUE, PRODUCT_ID ); + g_hInstanceMutex = CreateMutex( nullptr, TRUE, PRODUCT_ID ); g_bIsMultipleInstance = false; if( GetLastError() == ERROR_ALREADY_EXISTS ) @@ -90,20 +90,20 @@ bool ArchHooks_Win32::CheckForMultipleInstances(int argc, char* argv[]) /* Search for the existing window. Prefer to use the class name, which is less likely to * have a false match, and will match the gameplay window. If that fails, try the window * name, which should match the loading window. */ - HWND hWnd = FindWindow( PRODUCT_ID, NULL ); - if( hWnd == NULL ) - hWnd = FindWindow( NULL, PRODUCT_ID ); + HWND hWnd = FindWindow( PRODUCT_ID, nullptr ); + if( hWnd == nullptr ) + hWnd = FindWindow( nullptr, PRODUCT_ID ); - if( hWnd != NULL ) + if( hWnd != nullptr ) { /* If the application has a model dialog box open, we want to be sure to give focus to it, * not the main window. */ CallbackData data; data.hParent = hWnd; - data.hResult = NULL; + data.hResult = nullptr; EnumWindows( GetEnabledPopup, (LPARAM) &data ); - if( data.hResult != NULL ) + if( data.hResult != nullptr ) SetForegroundWindow( data.hResult ); else SetForegroundWindow( hWnd ); @@ -120,7 +120,7 @@ bool ArchHooks_Win32::CheckForMultipleInstances(int argc, char* argv[]) SendMessage( (HWND)hWnd, // HWND hWnd = handle of destination window WM_COPYDATA, - (WPARAM)NULL, // HANDLE OF SENDING WINDOW + (WPARAM)nullptr, // HANDLE OF SENDING WINDOW (LPARAM)&cds ); // 2nd msg parameter = pointer to COPYDATASTRUCT } @@ -193,7 +193,7 @@ float ArchHooks_Win32::GetDisplayAspectRatio() DEVMODE dm; ZERO( dm ); dm.dmSize = sizeof(dm); - BOOL bResult = EnumDisplaySettings( NULL, ENUM_REGISTRY_SETTINGS, &dm ); + BOOL bResult = EnumDisplaySettings( nullptr, ENUM_REGISTRY_SETTINGS, &dm ); ASSERT( bResult != 0 ); return dm.dmPelsWidth / (float)dm.dmPelsHeight; } @@ -210,15 +210,15 @@ RString ArchHooks_Win32::GetClipboard() // Yes. All this mess just to gain access to the string stored by the clipboard. // I'm having flashbacks to Berkeley sockets. - if(unlikely( !OpenClipboard( NULL ) )) + if(unlikely( !OpenClipboard( nullptr ) )) { LOG->Warn(werr_ssprintf( GetLastError(), "InputHandler_DirectInput: OpenClipboard() failed" )); return ""; } hgl = GetClipboardData( CF_TEXT ); - if(unlikely( hgl == NULL )) + if(unlikely( hgl == nullptr )) { LOG->Warn(werr_ssprintf( GetLastError(), "InputHandler_DirectInput: GetClipboardData() failed" )); CloseClipboard(); return ""; } lpstr = (LPTSTR) GlobalLock( hgl ); - if(unlikely( lpstr == NULL )) + if(unlikely( lpstr == nullptr )) { LOG->Warn(werr_ssprintf( GetLastError(), "InputHandler_DirectInput: GlobalLock() failed" )); CloseClipboard(); return ""; } // And finally, we have a char (or wchar_t) array of the clipboard contents, diff --git a/src/arch/Dialog/Dialog.cpp b/src/arch/Dialog/Dialog.cpp index dd8d44f17f..58b996e266 100644 --- a/src/arch/Dialog/Dialog.cpp +++ b/src/arch/Dialog/Dialog.cpp @@ -21,9 +21,9 @@ DialogDriver *MakeDialogDriver() ASSERT( asDriversToTry.size() != 0 ); RString sDriver; - DialogDriver *pRet = NULL; + DialogDriver *pRet = nullptr; - for( unsigned i = 0; pRet == NULL && i < asDriversToTry.size(); ++i ) + for( unsigned i = 0; pRet == nullptr && i < asDriversToTry.size(); ++i ) { sDriver = asDriversToTry[i]; @@ -37,7 +37,7 @@ DialogDriver *MakeDialogDriver() if( !asDriversToTry[i].CompareNoCase("Null") ) pRet = new DialogDriver_Null; #endif - if( pRet == NULL ) + if( pRet == nullptr ) { continue; } @@ -54,7 +54,7 @@ DialogDriver *MakeDialogDriver() return pRet; } -static DialogDriver *g_pImpl = NULL; +static DialogDriver *g_pImpl = nullptr; static DialogDriver_Null g_NullDriver; static bool g_bWindowed = true; // Start out true so that we'll show errors before DISPLAY is init'd. @@ -65,19 +65,19 @@ static bool DialogsEnabled() void Dialog::Init() { - if( g_pImpl != NULL ) + if( g_pImpl != nullptr ) return; g_pImpl = DialogDriver::Create(); // DialogDriver_Null should have worked, at least. - ASSERT( g_pImpl != NULL ); + ASSERT( g_pImpl != nullptr ); } void Dialog::Shutdown() { delete g_pImpl; - g_pImpl = NULL; + g_pImpl = nullptr; } static bool MessageIsIgnored( RString sID ) @@ -96,7 +96,7 @@ void Dialog::IgnoreMessage( RString sID ) { // We can't ignore messages before PREFSMAN is around. #if !defined(SMPACKAGE) - if( PREFSMAN == NULL ) + if( PREFSMAN == nullptr ) { if( sID != "" && LOG ) LOG->Warn( "Dialog: message \"%s\" set ID too early for ignorable messages", sID.c_str() ); diff --git a/src/arch/Dialog/DialogDriver.cpp b/src/arch/Dialog/DialogDriver.cpp index 4a2f7b4a04..e4fdd11866 100644 --- a/src/arch/Dialog/DialogDriver.cpp +++ b/src/arch/Dialog/DialogDriver.cpp @@ -1,12 +1,12 @@ #include "global.h" #include "DialogDriver.h" -#include "Foreach.h" + #include "RageLog.h" map *RegisterDialogDriver::g_pRegistrees; RegisterDialogDriver::RegisterDialogDriver( const istring &sName, CreateDialogDriverFn pfn ) { - if( g_pRegistrees == NULL ) + if( g_pRegistrees == nullptr ) g_pRegistrees = new map; ASSERT( g_pRegistrees->find(sName) == g_pRegistrees->end() ); @@ -23,9 +23,9 @@ DialogDriver *DialogDriver::Create() ASSERT( asDriversToTry.size() != 0 ); - FOREACH_CONST( RString, asDriversToTry, Driver ) + for (RString const &Driver : asDriversToTry) { - map::const_iterator iter = RegisterDialogDriver::g_pRegistrees->find( istring(*Driver) ); + map::const_iterator iter = RegisterDialogDriver::g_pRegistrees->find( istring(Driver) ); if( iter == RegisterDialogDriver::g_pRegistrees->end() ) continue; @@ -37,10 +37,10 @@ DialogDriver *DialogDriver::Create() if( sError.empty() ) return pRet; if( LOG ) - LOG->Info( "Couldn't load driver %s: %s", Driver->c_str(), sError.c_str() ); + LOG->Info( "Couldn't load driver %s: %s", Driver.c_str(), sError.c_str() ); SAFE_DELETE( pRet ); } - return NULL; + return nullptr; } diff --git a/src/arch/Dialog/DialogDriver_MacOSX.cpp b/src/arch/Dialog/DialogDriver_MacOSX.cpp index 57340a9c51..96b346b258 100644 --- a/src/arch/Dialog/DialogDriver_MacOSX.cpp +++ b/src/arch/Dialog/DialogDriver_MacOSX.cpp @@ -1,169 +1,169 @@ -#include "global.h" -#include "RageUtil.h" -#include "DialogDriver_MacOSX.h" -#include "RageThreads.h" -#include "ProductInfo.h" -#include "InputFilter.h" -#include - -REGISTER_DIALOG_DRIVER_CLASS( MacOSX ); - -static CFOptionFlags ShowAlert( CFOptionFlags flags, const RString& sMessage, CFStringRef OK, - CFStringRef alt = NULL, CFStringRef other = NULL) -{ - CFOptionFlags result; - CFStringRef text = CFStringCreateWithCString( NULL, sMessage, kCFStringEncodingUTF8 ); - - if( text == NULL ) - { - RString error = ssprintf( "CFString for dialog string \"%s\" could not be created.", sMessage.c_str() ); - WARN( error ); - DEBUG_ASSERT_M( false, error ); - return kCFUserNotificationDefaultResponse; // Is this better than displaying an "unknown error" message? - } - CFUserNotificationDisplayAlert( 0.0, flags, NULL, NULL, NULL, CFSTR(PRODUCT_FAMILY), - text, OK, alt, other, &result ); - CFRelease( text ); - - // Flush all input that's accumulated while the dialog box was up. - if( INPUTFILTER ) - { - vector dummy; - INPUTFILTER->Reset(); - INPUTFILTER->GetInputEvents( dummy ); - } - - return result; -} - -#define LSTRING(b,x) CFBundleCopyLocalizedString( (b), CFSTR(x), NULL, CFSTR("Localizable") ) - -void DialogDriver_MacOSX::OK( RString sMessage, RString sID ) -{ - CFBundleRef bundle = CFBundleGetMainBundle(); - CFStringRef sDSA = LSTRING( bundle, "Don't show again" ); - CFOptionFlags result = ShowAlert( kCFUserNotificationNoteAlertLevel, sMessage, CFSTR("OK"), sDSA ); - - CFRelease( sDSA ); - if( result == kCFUserNotificationAlternateResponse ) - Dialog::IgnoreMessage( sID ); -} - -void DialogDriver_MacOSX::Error( RString sError, RString sID ) -{ - ShowAlert( kCFUserNotificationStopAlertLevel, sError, CFSTR("OK") ); -} - -Dialog::Result DialogDriver_MacOSX::OKCancel( RString sMessage, RString sID ) -{ - CFBundleRef bundle = CFBundleGetMainBundle(); - CFStringRef sOK = LSTRING( bundle, "OK" ); - CFStringRef sCancel = LSTRING( bundle, "Cancel" ); - CFOptionFlags result = ShowAlert( kCFUserNotificationNoteAlertLevel, sMessage, sOK, sCancel ); - - CFRelease( sOK ); - CFRelease( sCancel ); - switch( result ) - { - case kCFUserNotificationDefaultResponse: - case kCFUserNotificationCancelResponse: - return Dialog::cancel; - case kCFUserNotificationAlternateResponse: - return Dialog::ok; - default: - FAIL_M( ssprintf("Invalid response: %d.", int(result)) ); - } -} - -Dialog::Result DialogDriver_MacOSX::AbortRetryIgnore( RString sMessage, RString sID ) -{ - CFBundleRef bundle = CFBundleGetMainBundle(); - CFStringRef sIgnore = LSTRING( bundle, "Ignore" ); - CFStringRef sRetry = LSTRING( bundle, "Retry" ); - CFStringRef sAbort = LSTRING( bundle, "Abort" ); - CFOptionFlags result = ShowAlert( kCFUserNotificationNoteAlertLevel, sMessage, sIgnore, sRetry, sAbort ); - - CFRelease( sIgnore ); - CFRelease( sRetry ); - CFRelease( sAbort ); - switch( result ) - { - case kCFUserNotificationDefaultResponse: - Dialog::IgnoreMessage( sID ); - return Dialog::ignore; - case kCFUserNotificationAlternateResponse: - return Dialog::retry; - case kCFUserNotificationOtherResponse: - case kCFUserNotificationCancelResponse: - return Dialog::abort; - default: - FAIL_M( ssprintf("Invalid response: %d.", int(result)) ); - } -} - -Dialog::Result DialogDriver_MacOSX::AbortRetry( RString sMessage, RString sID ) -{ - CFBundleRef bundle = CFBundleGetMainBundle(); - CFStringRef sRetry = LSTRING( bundle, "Retry" ); - CFStringRef sAbort = LSTRING( bundle, "Abort" ); - CFOptionFlags result = ShowAlert( kCFUserNotificationNoteAlertLevel, sMessage, sRetry, sAbort ); - - CFRelease( sRetry ); - CFRelease( sAbort ); - switch( result ) - { - case kCFUserNotificationDefaultResponse: - case kCFUserNotificationCancelResponse: - return Dialog::abort; - case kCFUserNotificationAlternateResponse: - return Dialog::retry; - default: - FAIL_M( ssprintf("Invalid response: %d.", int(result)) ); - } -} - -Dialog::Result DialogDriver_MacOSX::YesNo( RString sMessage, RString sID ) -{ - CFBundleRef bundle = CFBundleGetMainBundle(); - CFStringRef sYes = LSTRING( bundle, "Yes" ); - CFStringRef sNo = LSTRING( bundle, "No" ); - CFOptionFlags result = ShowAlert( kCFUserNotificationNoteAlertLevel, sMessage, sYes, sNo ); - - CFRelease( sYes ); - CFRelease( sNo ); - switch( result ) - { - case kCFUserNotificationDefaultResponse: - case kCFUserNotificationCancelResponse: - return Dialog::no; - case kCFUserNotificationAlternateResponse: - return Dialog::yes; - default: - FAIL_M( ssprintf("Invalid response: %d.", int(result)) ); - } -} - -/* - * (c) 2003-2006 Steve Checkoway - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "RageUtil.h" +#include "DialogDriver_MacOSX.h" +#include "RageThreads.h" +#include "ProductInfo.h" +#include "InputFilter.h" +#include + +REGISTER_DIALOG_DRIVER_CLASS( MacOSX ); + +static CFOptionFlags ShowAlert( CFOptionFlags flags, const RString& sMessage, CFStringRef OK, + CFStringRef alt = nullptr, CFStringRef other = nullptr) +{ + CFOptionFlags result; + CFStringRef text = CFStringCreateWithCString( nullptr, sMessage, kCFStringEncodingUTF8 ); + + if( text == nullptr ) + { + RString error = ssprintf( "CFString for dialog string \"%s\" could not be created.", sMessage.c_str() ); + WARN( error ); + DEBUG_ASSERT_M( false, error ); + return kCFUserNotificationDefaultResponse; // Is this better than displaying an "unknown error" message? + } + CFUserNotificationDisplayAlert( 0.0, flags, nullptr, nullptr, nullptr, CFSTR(PRODUCT_FAMILY), + text, OK, alt, other, &result ); + CFRelease( text ); + + // Flush all input that's accumulated while the dialog box was up. + if( INPUTFILTER ) + { + vector dummy; + INPUTFILTER->Reset(); + INPUTFILTER->GetInputEvents( dummy ); + } + + return result; +} + +#define LSTRING(b,x) CFBundleCopyLocalizedString( (b), CFSTR(x), nullptr, CFSTR("Localizable") ) + +void DialogDriver_MacOSX::OK( RString sMessage, RString sID ) +{ + CFBundleRef bundle = CFBundleGetMainBundle(); + CFStringRef sDSA = LSTRING( bundle, "Don't show again" ); + CFOptionFlags result = ShowAlert( kCFUserNotificationNoteAlertLevel, sMessage, CFSTR("OK"), sDSA ); + + CFRelease( sDSA ); + if( result == kCFUserNotificationAlternateResponse ) + Dialog::IgnoreMessage( sID ); +} + +void DialogDriver_MacOSX::Error( RString sError, RString sID ) +{ + ShowAlert( kCFUserNotificationStopAlertLevel, sError, CFSTR("OK") ); +} + +Dialog::Result DialogDriver_MacOSX::OKCancel( RString sMessage, RString sID ) +{ + CFBundleRef bundle = CFBundleGetMainBundle(); + CFStringRef sOK = LSTRING( bundle, "OK" ); + CFStringRef sCancel = LSTRING( bundle, "Cancel" ); + CFOptionFlags result = ShowAlert( kCFUserNotificationNoteAlertLevel, sMessage, sOK, sCancel ); + + CFRelease( sOK ); + CFRelease( sCancel ); + switch( result ) + { + case kCFUserNotificationDefaultResponse: + case kCFUserNotificationCancelResponse: + return Dialog::cancel; + case kCFUserNotificationAlternateResponse: + return Dialog::ok; + default: + FAIL_M( ssprintf("Invalid response: %d.", int(result)) ); + } +} + +Dialog::Result DialogDriver_MacOSX::AbortRetryIgnore( RString sMessage, RString sID ) +{ + CFBundleRef bundle = CFBundleGetMainBundle(); + CFStringRef sIgnore = LSTRING( bundle, "Ignore" ); + CFStringRef sRetry = LSTRING( bundle, "Retry" ); + CFStringRef sAbort = LSTRING( bundle, "Abort" ); + CFOptionFlags result = ShowAlert( kCFUserNotificationNoteAlertLevel, sMessage, sIgnore, sRetry, sAbort ); + + CFRelease( sIgnore ); + CFRelease( sRetry ); + CFRelease( sAbort ); + switch( result ) + { + case kCFUserNotificationDefaultResponse: + Dialog::IgnoreMessage( sID ); + return Dialog::ignore; + case kCFUserNotificationAlternateResponse: + return Dialog::retry; + case kCFUserNotificationOtherResponse: + case kCFUserNotificationCancelResponse: + return Dialog::abort; + default: + FAIL_M( ssprintf("Invalid response: %d.", int(result)) ); + } +} + +Dialog::Result DialogDriver_MacOSX::AbortRetry( RString sMessage, RString sID ) +{ + CFBundleRef bundle = CFBundleGetMainBundle(); + CFStringRef sRetry = LSTRING( bundle, "Retry" ); + CFStringRef sAbort = LSTRING( bundle, "Abort" ); + CFOptionFlags result = ShowAlert( kCFUserNotificationNoteAlertLevel, sMessage, sRetry, sAbort ); + + CFRelease( sRetry ); + CFRelease( sAbort ); + switch( result ) + { + case kCFUserNotificationDefaultResponse: + case kCFUserNotificationCancelResponse: + return Dialog::abort; + case kCFUserNotificationAlternateResponse: + return Dialog::retry; + default: + FAIL_M( ssprintf("Invalid response: %d.", int(result)) ); + } +} + +Dialog::Result DialogDriver_MacOSX::YesNo( RString sMessage, RString sID ) +{ + CFBundleRef bundle = CFBundleGetMainBundle(); + CFStringRef sYes = LSTRING( bundle, "Yes" ); + CFStringRef sNo = LSTRING( bundle, "No" ); + CFOptionFlags result = ShowAlert( kCFUserNotificationNoteAlertLevel, sMessage, sYes, sNo ); + + CFRelease( sYes ); + CFRelease( sNo ); + switch( result ) + { + case kCFUserNotificationDefaultResponse: + case kCFUserNotificationCancelResponse: + return Dialog::no; + case kCFUserNotificationAlternateResponse: + return Dialog::yes; + default: + FAIL_M( ssprintf("Invalid response: %d.", int(result)) ); + } +} + +/* + * (c) 2003-2006 Steve Checkoway + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/arch/Dialog/DialogDriver_Win32.cpp b/src/arch/Dialog/DialogDriver_Win32.cpp index d58eb4c38f..4a744b6b84 100644 --- a/src/arch/Dialog/DialogDriver_Win32.cpp +++ b/src/arch/Dialog/DialogDriver_Win32.cpp @@ -120,7 +120,7 @@ Dialog::Result DialogDriver_Win32::OKCancel( RString sMessage, RString sID ) #if !defined(SMPACKAGE) //DialogBox( handle.Get(), MAKEINTRESOURCE(IDD_OK), ::GetHwnd(), OKWndProc ); - int result = ::MessageBox( NULL, sMessage, GetWindowTitle(), MB_OKCANCEL ); + int result = ::MessageBox( nullptr, sMessage, GetWindowTitle(), MB_OKCANCEL ); #else int result = ::AfxMessageBox( ConvertUTF8ToACP(sMessage).c_str(), MB_OKCANCEL, 0 ); #endif @@ -165,14 +165,14 @@ static BOOL CALLBACK ErrorWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP RString sAppDataDir = SpecialDirs::GetAppDataDir(); RString sCommand = "notepad \"" + sAppDataDir + PRODUCT_ID + "/Logs/log.txt\""; CreateProcess( - NULL, // pointer to name of executable module + nullptr, // pointer to name of executable module const_cast(sCommand.c_str()), // pointer to command line string - NULL, // process security attributes - NULL, // thread security attributes + nullptr, // process security attributes + nullptr, // thread security attributes false, // handle inheritance flag 0, // creation flags - NULL, // pointer to new environment block - NULL, // pointer to current directory name + nullptr, // pointer to new environment block + nullptr, // pointer to current directory name &si, // pointer to STARTUPINFO &pi // pointer to PROCESS_INFORMATION ); @@ -194,7 +194,7 @@ static BOOL CALLBACK ErrorWndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP { HDC hdc = (HDC)wParam; HWND hwndStatic = (HWND)lParam; - HBRUSH hbr = NULL; + HBRUSH hbr = nullptr; // TODO: Change any attributes of the DC here switch( GetDlgCtrlID(hwndStatic) ) @@ -222,7 +222,7 @@ void DialogDriver_Win32::Error( RString sError, RString sID ) // throw up a pretty error dialog AppInstance handle; - DialogBox( handle.Get(), MAKEINTRESOURCE(IDD_ERROR_DIALOG), NULL, ErrorWndProc ); + DialogBox( handle.Get(), MAKEINTRESOURCE(IDD_ERROR_DIALOG), nullptr, ErrorWndProc ); #else ::AfxMessageBox( ConvertUTF8ToACP(sError).c_str(), MB_OK, 0 ); #endif diff --git a/src/arch/InputHandler/InputHandler.cpp b/src/arch/InputHandler/InputHandler.cpp index c8eca4eb26..6e8a445281 100644 --- a/src/arch/InputHandler/InputHandler.cpp +++ b/src/arch/InputHandler/InputHandler.cpp @@ -6,7 +6,7 @@ #include "LocalizedString.h" #include "arch/arch_default.h" #include "InputHandler_MonkeyKeyboard.h" -#include "Foreach.h" + void InputHandler::UpdateTimer() { @@ -176,12 +176,12 @@ void InputHandler::Create( const RString &drivers_, vector &Add if( DriversToTry.empty() ) RageException::Throw( "%s", INPUT_HANDLERS_EMPTY.GetValue().c_str() ); - FOREACH_CONST( RString, DriversToTry, s ) + for (RString const &s : DriversToTry) { - RageDriver *pDriver = InputHandler::m_pDriverList.Create( *s ); - if( pDriver == NULL ) + RageDriver *pDriver = InputHandler::m_pDriverList.Create( s ); + if( pDriver == nullptr ) { - LOG->Trace( "Unknown Input Handler name: %s", s->c_str() ); + LOG->Trace( "Unknown Input Handler name: %s", s.c_str() ); continue; } diff --git a/src/arch/InputHandler/InputHandler_DirectInput.cpp b/src/arch/InputHandler/InputHandler_DirectInput.cpp index a7716ad4b7..86872fda52 100644 --- a/src/arch/InputHandler/InputHandler_DirectInput.cpp +++ b/src/arch/InputHandler/InputHandler_DirectInput.cpp @@ -11,7 +11,6 @@ #include "InputFilter.h" #include "PrefsManager.h" #include "GamePreferences.h" //needed for Axis Fix -#include "Foreach.h" #include "InputHandler_DirectInputHelper.h" @@ -32,13 +31,13 @@ static int g_iNumJoysticks; #define SAFE_RELEASE(p) { if ( (p) ) { (p)->Release(); (p) = 0; } } static BOOL IsXInputDevice(const GUID* pGuidProductFromDirectInput) { - IWbemLocator* pIWbemLocator = NULL; - IEnumWbemClassObject* pEnumDevices = NULL; + IWbemLocator* pIWbemLocator = nullptr; + IEnumWbemClassObject* pEnumDevices = nullptr; IWbemClassObject* pDevices[20] = { 0 }; - IWbemServices* pIWbemServices = NULL; - BSTR bstrNamespace = NULL; - BSTR bstrDeviceID = NULL; - BSTR bstrClassName = NULL; + IWbemServices* pIWbemServices = nullptr; + BSTR bstrNamespace = nullptr; + BSTR bstrDeviceID = nullptr; + BSTR bstrClassName = nullptr; DWORD uReturned = 0; bool bIsXinputDevice = false; UINT iDevice = 0; @@ -46,34 +45,34 @@ static BOOL IsXInputDevice(const GUID* pGuidProductFromDirectInput) HRESULT hr; // CoInit if needed - hr = CoInitialize(NULL); + hr = CoInitialize(nullptr); bool bCleanupCOM = SUCCEEDED(hr); // Create WMI hr = CoCreateInstance(__uuidof(WbemLocator), - NULL, + nullptr, CLSCTX_INPROC_SERVER, __uuidof(IWbemLocator), (LPVOID*)&pIWbemLocator); - if (FAILED(hr) || pIWbemLocator == NULL) + if (FAILED(hr) || pIWbemLocator == nullptr) goto LCleanup; - bstrNamespace = SysAllocString(L"\\\\.\\root\\cimv2"); if (bstrNamespace == NULL) goto LCleanup; - bstrClassName = SysAllocString(L"Win32_PNPEntity"); if (bstrClassName == NULL) goto LCleanup; - bstrDeviceID = SysAllocString(L"DeviceID"); if (bstrDeviceID == NULL) goto LCleanup; + bstrNamespace = SysAllocString(L"\\\\.\\root\\cimv2"); if (bstrNamespace == nullptr) goto LCleanup; + bstrClassName = SysAllocString(L"Win32_PNPEntity"); if (bstrClassName == nullptr) goto LCleanup; + bstrDeviceID = SysAllocString(L"DeviceID"); if (bstrDeviceID == nullptr) goto LCleanup; // Connect to WMI - hr = pIWbemLocator->ConnectServer(bstrNamespace, NULL, NULL, 0L, - 0L, NULL, NULL, &pIWbemServices); - if (FAILED(hr) || pIWbemServices == NULL) + hr = pIWbemLocator->ConnectServer(bstrNamespace, nullptr, nullptr, 0L, + 0L, nullptr, nullptr, &pIWbemServices); + if (FAILED(hr) || pIWbemServices == nullptr) goto LCleanup; // Switch security level to IMPERSONATE. - CoSetProxyBlanket(pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, - RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE); + CoSetProxyBlanket(pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, + RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE); - hr = pIWbemServices->CreateInstanceEnum(bstrClassName, 0, NULL, &pEnumDevices); - if (FAILED(hr) || pEnumDevices == NULL) + hr = pIWbemServices->CreateInstanceEnum(bstrClassName, 0, nullptr, &pEnumDevices); + if (FAILED(hr) || pEnumDevices == nullptr) goto LCleanup; // Loop over all devices @@ -89,8 +88,8 @@ static BOOL IsXInputDevice(const GUID* pGuidProductFromDirectInput) for (iDevice = 0; iDeviceGet(bstrDeviceID, 0L, &var, NULL, NULL); - if (SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != NULL) + hr = pDevices[iDevice]->Get(bstrDeviceID, 0L, &var, nullptr, nullptr); + if (SUCCEEDED(hr) && var.vt == VT_BSTR && var.bstrVal != nullptr) { // Check if the device ID contains "IG_". If it does, then it's an XInput device // This information can not be found from DirectInput @@ -257,23 +256,23 @@ InputHandler_DInput::InputHandler_DInput() LOG->Info( "Found %u XInput devices.", XDevices.size() ); AppInstance inst; - HRESULT hr = DirectInput8Create(inst.Get(), DIRECTINPUT_VERSION, IID_IDirectInput8, (LPVOID *) &g_dinput, NULL); + HRESULT hr = DirectInput8Create(inst.Get(), DIRECTINPUT_VERSION, IID_IDirectInput8, (LPVOID *) &g_dinput, nullptr); if( hr != DI_OK ) RageException::Throw( hr_ssprintf(hr, "InputHandler_DInput: DirectInputCreate") ); LOG->Trace( "InputHandler_DInput: IDirectInput::EnumDevices(DIDEVTYPE_KEYBOARD)" ); - hr = g_dinput->EnumDevices( DI8DEVCLASS_KEYBOARD, EnumDevicesCallback, NULL, DIEDFL_ATTACHEDONLY ); + hr = g_dinput->EnumDevices( DI8DEVCLASS_KEYBOARD, EnumDevicesCallback, nullptr, DIEDFL_ATTACHEDONLY ); if( hr != DI_OK ) RageException::Throw( hr_ssprintf(hr, "InputHandler_DInput: IDirectInput::EnumDevices") ); LOG->Trace( "InputHandler_DInput: IDirectInput::EnumDevices(DIDEVTYPE_JOYSTICK)" ); - hr = g_dinput->EnumDevices( DI8DEVCLASS_GAMECTRL, EnumDevicesCallback, NULL, DIEDFL_ATTACHEDONLY ); + hr = g_dinput->EnumDevices( DI8DEVCLASS_GAMECTRL, EnumDevicesCallback, nullptr, DIEDFL_ATTACHEDONLY ); if( hr != DI_OK ) RageException::Throw( hr_ssprintf(hr, "InputHandler_DInput: IDirectInput::EnumDevices") ); // mouse LOG->Trace( "InputHandler_DInput: IDirectInput::EnumDevices(DIDEVTYPE_MOUSE)" ); - hr = g_dinput->EnumDevices( DI8DEVCLASS_POINTER, EnumDevicesCallback, NULL, DIEDFL_ATTACHEDONLY ); + hr = g_dinput->EnumDevices( DI8DEVCLASS_POINTER, EnumDevicesCallback, nullptr, DIEDFL_ATTACHEDONLY ); if( hr != DI_OK ) RageException::Throw( hr_ssprintf(hr, "InputHandler_DInput: IDirectInput::EnumDevices") ); @@ -339,7 +338,7 @@ InputHandler_DInput::~InputHandler_DInput() Devices.clear(); g_dinput->Release(); - g_dinput = NULL; + g_dinput = nullptr; } void InputHandler_DInput::WindowReset() @@ -936,7 +935,7 @@ void InputHandler_DInput::InputThreadMain() SetThreadPriorityBoost( GetCurrentThread(), FALSE ); vector BufferedDevices; - HANDLE Handle = CreateEvent( NULL, FALSE, FALSE, NULL ); + HANDLE Handle = CreateEvent( nullptr, FALSE, FALSE, nullptr ); for( unsigned i = 0; i < Devices.size(); ++i ) { if( !Devices[i].buffered ) @@ -987,7 +986,7 @@ void InputHandler_DInput::InputThreadMain() continue; Devices[i].Device->Unacquire(); - Devices[i].Device->SetEventNotification( NULL ); + Devices[i].Device->SetEventNotification(nullptr); } CloseHandle(Handle); @@ -1022,7 +1021,7 @@ static wchar_t ScancodeAndKeysToChar( DWORD scancode, unsigned char keys[256] ) unsigned short result[2]; // ToAscii writes a max of 2 chars ZERO( result ); - if( pToUnicodeEx != NULL ) + if( pToUnicodeEx != nullptr ) { int iNum = pToUnicodeEx( vk, scancode, keys, (LPWSTR)result, 2, 0, layout ); if( iNum == 1 ) @@ -1054,14 +1053,14 @@ wchar_t InputHandler_DInput::DeviceButtonToChar( DeviceButton button, bool bUseC return '\0'; } - FOREACH_CONST( DIDevice, Devices, d ) + for (DIDevice const &d : Devices) { - if( d->type != DIDevice::KEYBOARD ) + if( d.type != DIDevice::KEYBOARD ) continue; - FOREACH_CONST( input_t, d->Inputs, i ) + for (input_t const &i : d.Inputs) { - if( button != i->num ) + if( button != i.num ) continue; unsigned char keys[256]; @@ -1069,7 +1068,7 @@ wchar_t InputHandler_DInput::DeviceButtonToChar( DeviceButton button, bool bUseC if( bUseCurrentKeyModifiers ) GetKeyboardState(keys); // todo: handle Caps Lock -freem - wchar_t c = ScancodeAndKeysToChar( i->ofs, keys ); + wchar_t c = ScancodeAndKeysToChar( i.ofs, keys ); if( c ) return c; } diff --git a/src/arch/InputHandler/InputHandler_DirectInputHelper.cpp b/src/arch/InputHandler/InputHandler_DirectInputHelper.cpp index 04651420fd..c582dc7066 100644 --- a/src/arch/InputHandler/InputHandler_DirectInputHelper.cpp +++ b/src/arch/InputHandler/InputHandler_DirectInputHelper.cpp @@ -12,7 +12,7 @@ #pragma comment(lib, "dxguid.lib") #endif #endif -LPDIRECTINPUT8 g_dinput = NULL; +LPDIRECTINPUT8 g_dinput = nullptr; static int ConvertScancodeToKey( int scancode ); static BOOL CALLBACK DIJoystick_EnumDevObjectsProc(LPCDIDEVICEOBJECTINSTANCE dev, LPVOID data); @@ -24,7 +24,7 @@ DIDevice::DIDevice() dev = InputDevice_Invalid; buffered = true; memset(&JoystickInst, 0, sizeof(JoystickInst)); - Device = NULL; + Device = nullptr; } bool DIDevice::Open() @@ -37,7 +37,7 @@ bool DIDevice::Open() LPDIRECTINPUTDEVICE8 tmpdevice; // load joystick - HRESULT hr = g_dinput->CreateDevice( JoystickInst.guidInstance, &tmpdevice, NULL ); + HRESULT hr = g_dinput->CreateDevice( JoystickInst.guidInstance, &tmpdevice, nullptr ); if ( hr != DI_OK ) { LOG->Info( hr_ssprintf(hr, "OpenDevice: IDirectInput_CreateDevice") ); @@ -131,12 +131,12 @@ bool DIDevice::Open() void DIDevice::Close() { // Don't try to close a device that isn't open. - ASSERT( Device != NULL ); + ASSERT( Device != nullptr ); Device->Unacquire(); Device->Release(); - Device = NULL; + Device = nullptr; buttons = axes = hats = 0; Inputs.clear(); } diff --git a/src/arch/InputHandler/InputHandler_Linux_Event.cpp b/src/arch/InputHandler/InputHandler_Linux_Event.cpp index dad2ba8ae9..dfc44dedbc 100644 --- a/src/arch/InputHandler/InputHandler_Linux_Event.cpp +++ b/src/arch/InputHandler/InputHandler_Linux_Event.cpp @@ -275,7 +275,7 @@ InputHandler_Linux_Event::InputHandler_Linux_Event() , m_bDevicesChanged(false) , m_NextDevice(DEVICE_JOY10) { - if(LINUXINPUT == NULL) LINUXINPUT = new LinuxInputManager; + if(LINUXINPUT == nullptr) LINUXINPUT = new LinuxInputManager; LINUXINPUT->InitDriver(this); if( ! g_apEventDevices.empty() ) // LinuxInputManager found at least one valid device for us @@ -362,7 +362,7 @@ void InputHandler_Linux_Event::InputThread() break; struct timeval zero = {0,100000}; - if( select(iMaxFD+1, &fdset, NULL, NULL, &zero) <= 0 ) + if( select(iMaxFD+1, &fdset, nullptr, nullptr, &zero) <= 0 ) continue; RageTimer now; diff --git a/src/arch/InputHandler/InputHandler_Linux_Joystick.cpp b/src/arch/InputHandler/InputHandler_Linux_Joystick.cpp index e5e729eb16..d61c2082eb 100644 --- a/src/arch/InputHandler/InputHandler_Linux_Joystick.cpp +++ b/src/arch/InputHandler/InputHandler_Linux_Joystick.cpp @@ -31,7 +31,7 @@ InputHandler_Linux_Joystick::InputHandler_Linux_Joystick() m_iLastFd = 0; - if( LINUXINPUT == NULL ) LINUXINPUT = new LinuxInputManager; + if( LINUXINPUT == nullptr ) LINUXINPUT = new LinuxInputManager; LINUXINPUT->InitDriver(this); if( fds[0] != -1 ) // LinuxInputManager found at least one valid joystick for us @@ -126,7 +126,7 @@ void InputHandler_Linux_Joystick::InputThread() break; struct timeval zero = {0,100000}; - if( select(max_fd+1, &fdset, NULL, NULL, &zero) <= 0 ) + if( select(max_fd+1, &fdset, nullptr, nullptr, &zero) <= 0 ) continue; RageTimer now; diff --git a/src/arch/InputHandler/InputHandler_Linux_tty.cpp b/src/arch/InputHandler/InputHandler_Linux_tty.cpp index cbadef03ae..95995a0221 100644 --- a/src/arch/InputHandler/InputHandler_Linux_tty.cpp +++ b/src/arch/InputHandler/InputHandler_Linux_tty.cpp @@ -33,14 +33,14 @@ static int saved_kbd_mode; /* This is normally a singleton. Keep track of it, so we can access it * from our signal handler. */ -static InputHandler_Linux_tty *handler = NULL; +static InputHandler_Linux_tty *handler = nullptr; void InputHandler_Linux_tty::OnCrash(int signo) { /* Make sure we delete the input handler if we crash, so we don't leave * the terminal in raw mode. */ delete handler; - handler = NULL; + handler = nullptr; } @@ -161,7 +161,7 @@ InputHandler_Linux_tty::~InputHandler_Linux_tty() tcsetattr(fd, TCSAFLUSH, &saved_kbd_termios); close(fd); - handler = NULL; + handler = nullptr; } void InputHandler_Linux_tty::Update() @@ -173,7 +173,7 @@ void InputHandler_Linux_tty::Update() FD_SET(fd, &fdset); struct timeval zero = {0,0}; - if ( select(fd+1, &fdset, NULL, NULL, &zero) <= 0 ) + if ( select(fd+1, &fdset, nullptr, nullptr, &zero) <= 0 ) return; unsigned char keybuf[BUFSIZ]; diff --git a/src/arch/InputHandler/InputHandler_MacOSX_HID.cpp b/src/arch/InputHandler/InputHandler_MacOSX_HID.cpp index af048e7e06..442c1450d0 100644 --- a/src/arch/InputHandler/InputHandler_MacOSX_HID.cpp +++ b/src/arch/InputHandler/InputHandler_MacOSX_HID.cpp @@ -1,7 +1,6 @@ #include "global.h" #include "RageLog.h" #include "InputHandler_MacOSX_HID.h" -#include "Foreach.h" #include "PrefsManager.h" #include "InputFilter.h" #include "archutils/Darwin/DarwinThreadHelpers.h" @@ -30,7 +29,7 @@ void InputHandler_MacOSX_HID::QueueCallback( void *target, int result, void *ref while( (result = CALL(queue, getNextEvent, &event, zeroTime, 0)) == kIOReturnSuccess ) { - if( event.longValueSize != 0 && event.longValue != NULL ) + if( event.longValueSize != 0 && event.longValue != nullptr ) { free( event.longValue ); continue; @@ -38,8 +37,8 @@ void InputHandler_MacOSX_HID::QueueCallback( void *target, int result, void *ref //LOG->Trace( "Got event with cookie %p, value %d", event.elementCookie, int(event.value) ); dev->GetButtonPresses( vPresses, event.elementCookie, event.value, now ); } - FOREACH_CONST( DeviceInput, vPresses, i ) - INPUTFILTER->ButtonPressed( *i ); + for (DeviceInput &i : vPresses) + INPUTFILTER->ButtonPressed( i ); } static void RunLoopStarted( CFRunLoopObserverRef o, CFRunLoopActivity a, void *sem ) @@ -66,7 +65,7 @@ int InputHandler_MacOSX_HID::Run( void *data ) { /* The function copies the information out of the structure, so the memory * pointed to by context does not need to persist beyond the function call. */ - CFRunLoopObserverContext context = { 0, &This->m_Sem, NULL, NULL, NULL }; + CFRunLoopObserverContext context = { 0, &This->m_Sem, nullptr, nullptr, nullptr }; CFRunLoopObserverRef o = CFRunLoopObserverCreate( kCFAllocatorDefault, kCFRunLoopEntry, false, 0, RunLoopStarted, &context); CFRunLoopAddObserver( This->m_LoopRef, o, kCFRunLoopDefaultMode ); @@ -83,7 +82,7 @@ int InputHandler_MacOSX_HID::Run( void *data ) void *info = This->m_LoopRef; void (*perform)(void *) = (void (*)(void *))CFRunLoopStop; // { version, info, retain, release, copyDescription, equal, hash, schedule, cancel, perform } - CFRunLoopSourceContext context = { 0, info, NULL, NULL, NULL, NULL, NULL, NULL, NULL, perform }; + CFRunLoopSourceContext context = { 0, info, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, perform }; // Pass 1 so that it is called after all inputs have been handled (they will have order = 0) This->m_SourceRef = CFRunLoopSourceCreate( kCFAllocatorDefault, 1, &context ); @@ -120,8 +119,8 @@ void InputHandler_MacOSX_HID::StartDevices() int n = 0; ASSERT( m_LoopRef ); - FOREACH( HIDDevice *, m_vDevices, i ) - (*i)->StartQueue( m_LoopRef, InputHandler_MacOSX_HID::QueueCallback, this, n++ ); + for (HIDDevice *i : m_vDevices) + i->StartQueue( m_LoopRef, InputHandler_MacOSX_HID::QueueCallback, this, n++ ); CFRunLoopSourceRef runLoopSource = IONotificationPortGetRunLoopSource( m_NotifyPort ); @@ -130,8 +129,8 @@ void InputHandler_MacOSX_HID::StartDevices() InputHandler_MacOSX_HID::~InputHandler_MacOSX_HID() { - FOREACH( HIDDevice *, m_vDevices, i ) - delete *i; + for (HIDDevice *i : m_vDevices) + delete i; if( PREFSMAN->m_bThreadedInput ) { CFRunLoopSourceSignal( m_SourceRef ); @@ -142,8 +141,8 @@ InputHandler_MacOSX_HID::~InputHandler_MacOSX_HID() LOG->Trace( "Input handler thread shut down." ); } - FOREACH( io_iterator_t, m_vIters, i ) - IOObjectRelease( *i ); + for (io_iterator_t &i : m_vIters) + IOObjectRelease( i ); IONotificationPortDestroy( m_NotifyPort ); } @@ -152,7 +151,7 @@ static CFDictionaryRef GetMatchingDictionary( int usagePage, int usage ) // Build the matching dictionary. CFMutableDictionaryRef dict; - if( (dict = IOServiceMatching(kIOHIDDeviceKey)) == NULL ) + if( (dict = IOServiceMatching(kIOHIDDeviceKey)) == nullptr ) FAIL_M( "Couldn't create a matching dictionary." ); // Refine the search by only looking for joysticks CFNumberRef usagePageRef = CFInt( usagePage ); @@ -181,7 +180,7 @@ static HIDDevice *MakeDevice( InputDevice id ) return new JoystickDevice; if( IsPump(id) ) return new PumpDevice; - return NULL; + return nullptr; } void InputHandler_MacOSX_HID::AddDevices( int usagePage, int usage, InputDevice &id ) @@ -277,8 +276,8 @@ InputHandler_MacOSX_HID::InputHandler_MacOSX_HID() : m_Sem( "Input thread starte void InputHandler_MacOSX_HID::GetDevicesAndDescriptions( vector& vDevices ) { - FOREACH_CONST( HIDDevice *, m_vDevices, i ) - (*i)->GetDevicesAndDescriptions( vDevices ); + for (HIDDevice *i : m_vDevices) + i->GetDevicesAndDescriptions( vDevices ); } RString InputHandler_MacOSX_HID::GetDeviceSpecificInputString( const DeviceInput &di ) @@ -380,7 +379,7 @@ static wchar_t KeyCodeToChar(CGKeyCode keyCode, unsigned int modifierFlags) { TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource(); CFDataRef uchr = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData); - const UCKeyboardLayout *keyboardLayout = uchr ? (const UCKeyboardLayout*)CFDataGetBytePtr(uchr) : NULL; + const UCKeyboardLayout *keyboardLayout = uchr ? (const UCKeyboardLayout*)CFDataGetBytePtr(uchr) : nullptr; if( keyboardLayout ) { @@ -450,7 +449,7 @@ wchar_t InputHandler_MacOSX_HID::DeviceButtonToChar( DeviceButton button, bool b UInt8 iMacVirtualKey; if( KeyboardDevice::DeviceButtonToMacVirtualKey( button, iMacVirtualKey ) ) { - CGEventRef event = CGEventCreate(NULL); + CGEventRef event = CGEventCreate(nullptr); CGEventFlags mods = CGEventGetFlags(event); CFRelease(event); UInt32 nModifiers = bUseCurrentKeyModifiers ? (UInt32)mods : 0; diff --git a/src/arch/InputHandler/InputHandler_SextetStream.cpp b/src/arch/InputHandler/InputHandler_SextetStream.cpp index 0516bfefd9..e0cde24bdd 100644 --- a/src/arch/InputHandler/InputHandler_SextetStream.cpp +++ b/src/arch/InputHandler/InputHandler_SextetStream.cpp @@ -96,7 +96,7 @@ class InputHandler_SextetStream::Impl // Construct and return the LineReader that makes sense for this // object. getLineReader() calls this; if the returned object claims - // it is valid, it is returned. Otherwise, it is destroyed and NULL + // it is valid, it is returned. Otherwise, it is destroyed and nullptr // is returned. virtual LineReader * getUnvalidatedLineReader() = 0; @@ -115,10 +115,10 @@ class InputHandler_SextetStream::Impl LineReader * getLineReader() { LineReader * linereader = getUnvalidatedLineReader(); - if(linereader != NULL) { + if(linereader != nullptr) { if(!linereader->IsValid()) { delete linereader; - linereader = NULL; + linereader = nullptr; } } return linereader; @@ -230,7 +230,7 @@ class InputHandler_SextetStream::Impl LOG->Trace("Input thread started; getting line reader"); linereader = getLineReader(); - if(linereader == NULL) { + if(linereader == nullptr) { LOG->Warn("Could not open line reader for SextetStream input"); } else { @@ -259,19 +259,19 @@ class InputHandler_SextetStream::Impl void InputHandler_SextetStream::GetDevicesAndDescriptions(vector& vDevicesOut) { - if(_impl != NULL) { + if(_impl != nullptr) { _impl->GetDevicesAndDescriptions(vDevicesOut); } } InputHandler_SextetStream::InputHandler_SextetStream() { - _impl = NULL; + _impl = nullptr; } InputHandler_SextetStream::~InputHandler_SextetStream() { - if(_impl != NULL) { + if(_impl != nullptr) { delete _impl; } } @@ -312,27 +312,27 @@ namespace filename.c_str()); file = std::fopen(filename.c_str(), "rb"); - if(file == NULL) { + if(file == nullptr) { LOG->Warn("Error opening file '%s' for input (cstdio): %s", filename.c_str(), std::strerror(errno)); } else { LOG->Info("File opened"); // Disable buffering on the file - std::setbuf(file, NULL); + std::setbuf(file, nullptr); } } ~StdCFileLineReader() { - if(file != NULL) { + if(file != nullptr) { std::fclose(file); } } virtual bool IsValid() { - return file != NULL; + return file != nullptr; } virtual bool ReadLine(RString& line) @@ -342,8 +342,8 @@ namespace line = ""; - if(file != NULL) { - while(fgets(buffer, BUFFER_SIZE, file) != NULL) { + if(file != nullptr) { + while(fgets(buffer, BUFFER_SIZE, file) != nullptr) { afterFirst = true; line += buffer; len = line.length(); diff --git a/src/arch/InputHandler/InputHandler_Win32_MIDI.cpp b/src/arch/InputHandler/InputHandler_Win32_MIDI.cpp index 1cb056a812..f2ee13fb82 100644 --- a/src/arch/InputHandler/InputHandler_Win32_MIDI.cpp +++ b/src/arch/InputHandler/InputHandler_Win32_MIDI.cpp @@ -24,7 +24,7 @@ InputHandler_Win32_MIDI::InputHandler_Win32_MIDI() { int device_id = 0; - g_device = NULL; + g_device = nullptr; if( device_id >= (int) midiInGetNumDevs() ) { diff --git a/src/arch/InputHandler/InputHandler_Win32_Pump.cpp b/src/arch/InputHandler/InputHandler_Win32_Pump.cpp index b8fed6a93c..e2ab6a4249 100644 --- a/src/arch/InputHandler/InputHandler_Win32_Pump.cpp +++ b/src/arch/InputHandler/InputHandler_Win32_Pump.cpp @@ -29,7 +29,7 @@ InputHandler_Win32_Pump::InputHandler_Win32_Pump() const int pump_usb_pid = pump_usb_pids[p]; for( int i = 0; i < NUM_PUMPS; ++i ) { - if( m_pDevice[i].Open(pump_usb_vid, pump_usb_pid, sizeof(long), i, NULL) ) + if( m_pDevice[i].Open(pump_usb_vid, pump_usb_pid, sizeof(long), i, nullptr) ) { iNumFound++; LOG->Info( "Found Pump pad %i", iNumFound ); diff --git a/src/arch/InputHandler/InputHandler_X11.cpp b/src/arch/InputHandler/InputHandler_X11.cpp index f59d84a05d..917c019364 100644 --- a/src/arch/InputHandler/InputHandler_X11.cpp +++ b/src/arch/InputHandler/InputHandler_X11.cpp @@ -135,7 +135,7 @@ static DeviceButton XSymToDeviceButton( int key ) InputHandler_X11::InputHandler_X11() { - if( Dpy == NULL || Win == None ) + if( Dpy == nullptr || Win == None ) return; XWindowAttributes winAttrib; @@ -151,7 +151,7 @@ InputHandler_X11::InputHandler_X11() InputHandler_X11::~InputHandler_X11() { - if( Dpy == NULL || Win == None ) + if( Dpy == nullptr || Win == None ) return; // TODO: Determine if we even need to set this back (or is the window // destroyed just after this?) @@ -166,7 +166,7 @@ InputHandler_X11::~InputHandler_X11() void InputHandler_X11::Update() { - if( Dpy == NULL || Win == None ) + if( Dpy == nullptr || Win == None ) { InputHandler::UpdateTimer(); return; diff --git a/src/arch/InputHandler/LinuxInputManager.cpp b/src/arch/InputHandler/LinuxInputManager.cpp index 395d5e3c3f..7162a5475d 100644 --- a/src/arch/InputHandler/LinuxInputManager.cpp +++ b/src/arch/InputHandler/LinuxInputManager.cpp @@ -5,7 +5,6 @@ #include "RageInput.h" // g_sInputDrivers #include "RageLog.h" -#include "Foreach.h" #include // std::string::npos @@ -19,11 +18,11 @@ RString getDevice(RString inputDir, RString type) { RString result = ""; DIR* dir = opendir( inputDir.c_str() ); - if(dir == NULL) + if(dir == nullptr) { LOG->Warn("LinuxInputManager: Couldn't open %s: %s.", inputDir.c_str(), strerror(errno) ); return ""; } struct dirent* d; - while( ( d = readdir(dir) ) != NULL) + while( ( d = readdir(dir) ) != nullptr) if( strncmp( type.c_str(), d->d_name, type.size() ) == 0) { result = RString("/dev/input/") + d->d_name; @@ -42,12 +41,12 @@ LinuxInputManager::LinuxInputManager() if( g_sInputDrivers.Get() == "" ) { m_bEventEnabled = true; m_bJoystickEnabled = true; } - m_EventDriver = NULL; - m_JoystickDriver = NULL; + m_EventDriver = nullptr; + m_JoystickDriver = nullptr; // XXX: Can I use RageFile for this? DIR* sysClassInput = opendir("/sys/class/input"); - if( sysClassInput == NULL ) + if( sysClassInput == nullptr) { // XXX: Probably should throw a Dialog. But Linux doesn't have a DialogDriver yet so eh. LOG->Warn("Couldn't open /sys/class/input: %s. Joysticks will not work!", strerror(errno) ); @@ -55,7 +54,7 @@ LinuxInputManager::LinuxInputManager() } struct dirent* d; - while( ( d = readdir(sysClassInput) ) != NULL) + while( ( d = readdir(sysClassInput) ) != nullptr) { if( strncmp( "input", d->d_name, 5) != 0) continue; @@ -78,15 +77,15 @@ void LinuxInputManager::InitDriver(InputHandler_Linux_Event* driver) { m_EventDriver = driver; - FOREACH(RString, m_vsPendingEventDevices, dev) + for (RString &dev : m_vsPendingEventDevices) { - RString devFile = getDevice(*dev, "event"); + RString devFile = getDevice(dev, "event"); ASSERT( devFile != "" ); - if( ! driver->TryDevice(devFile) && m_bJoystickEnabled && getDevice(*dev, "js") != "" ) - m_vsPendingJoystickDevices.push_back(*dev); + if( ! driver->TryDevice(devFile) && m_bJoystickEnabled && getDevice(dev, "js") != "" ) + m_vsPendingJoystickDevices.push_back(dev); } - if( m_JoystickDriver != NULL ) InitDriver(m_JoystickDriver); + if( m_JoystickDriver != nullptr ) InitDriver(m_JoystickDriver); m_vsPendingEventDevices.clear(); } @@ -95,9 +94,9 @@ void LinuxInputManager::InitDriver(InputHandler_Linux_Joystick* driver) { m_JoystickDriver = driver; - FOREACH(RString, m_vsPendingJoystickDevices, dev) + for (RString &dev : m_vsPendingJoystickDevices) { - RString devFile = getDevice(*dev, "js"); + RString devFile = getDevice(dev, "js"); ASSERT( devFile != "" ); driver->TryDevice(devFile); @@ -106,7 +105,7 @@ void LinuxInputManager::InitDriver(InputHandler_Linux_Joystick* driver) m_vsPendingJoystickDevices.clear(); } -LinuxInputManager* LINUXINPUT = NULL; // global and accessible anywhere in our program +LinuxInputManager* LINUXINPUT = nullptr; // global and accessible anywhere in our program /* * (c) 2013 Ben "root" Anderson @@ -131,4 +130,4 @@ LinuxInputManager* LINUXINPUT = NULL; // global and accessible anywhere in our p * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. - */ \ No newline at end of file + */ diff --git a/src/arch/Lights/LightsDriver.cpp b/src/arch/Lights/LightsDriver.cpp index 09272a7a9c..5f7887b7aa 100644 --- a/src/arch/Lights/LightsDriver.cpp +++ b/src/arch/Lights/LightsDriver.cpp @@ -1,7 +1,7 @@ #include "global.h" #include "LightsDriver.h" #include "RageLog.h" -#include "Foreach.h" + #include "arch/arch_default.h" DriverList LightsDriver::m_pDriverList; @@ -13,19 +13,19 @@ void LightsDriver::Create( const RString &sDrivers, vector &Add vector asDriversToTry; split( sDrivers, ",", asDriversToTry, true ); - FOREACH_CONST( RString, asDriversToTry, Driver ) + for (RString const &Driver : asDriversToTry) { - RageDriver *pRet = m_pDriverList.Create( *Driver ); - if( pRet == NULL ) + RageDriver *pRet = m_pDriverList.Create( Driver ); + if( pRet == nullptr ) { - LOG->Trace( "Unknown lights driver: %s", Driver->c_str() ); + LOG->Trace( "Unknown lights driver: %s", Driver.c_str() ); continue; } LightsDriver *pDriver = dynamic_cast( pRet ); - ASSERT( pDriver != NULL ); + ASSERT( pDriver != nullptr ); - LOG->Info( "Lights driver: %s", Driver->c_str() ); + LOG->Info( "Lights driver: %s", Driver.c_str() ); Add.push_back( pDriver ); } } diff --git a/src/arch/Lights/LightsDriver_Linux_PIUIO_Leds.cpp b/src/arch/Lights/LightsDriver_Linux_PIUIO_Leds.cpp index 083e96777f..6fac181a50 100644 --- a/src/arch/Lights/LightsDriver_Linux_PIUIO_Leds.cpp +++ b/src/arch/Lights/LightsDriver_Linux_PIUIO_Leds.cpp @@ -30,14 +30,14 @@ namespace { const char *dance_leds[NUM_GameController][NUM_GameButton] = { { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "/sys/class/leds/piuio::output20/brightness", "/sys/class/leds/piuio::output21/brightness", "/sys/class/leds/piuio::output18/brightness", "/sys/class/leds/piuio::output19/brightness", }, { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "/sys/class/leds/piuio::output4/brightness", "/sys/class/leds/piuio::output5/brightness", "/sys/class/leds/piuio::output2/brightness", @@ -47,7 +47,7 @@ namespace { const char *pump_leds[NUM_GameController][NUM_GameButton] = { { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "/sys/class/leds/piuio::output2/brightness", "/sys/class/leds/piuio::output3/brightness", "/sys/class/leds/piuio::output4/brightness", @@ -55,7 +55,7 @@ namespace { "/sys/class/leds/piuio::output6/brightness", }, { - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, "/sys/class/leds/piuio::output18/brightness", "/sys/class/leds/piuio::output19/brightness", "/sys/class/leds/piuio::output20/brightness", @@ -66,10 +66,10 @@ namespace { bool SetLight(const char *filename, bool on) { - if (filename == NULL) + if (filename == nullptr) return true; FILE *f = fopen(filename, "w"); - if (f == NULL) + if (f == nullptr) { return false; } diff --git a/src/arch/Lights/LightsDriver_PacDrive.cpp b/src/arch/Lights/LightsDriver_PacDrive.cpp index daeb5c0499..4fac6e6913 100644 --- a/src/arch/Lights/LightsDriver_PacDrive.cpp +++ b/src/arch/Lights/LightsDriver_PacDrive.cpp @@ -8,24 +8,24 @@ REGISTER_LIGHTS_DRIVER_CLASS(PacDrive); -HINSTANCE PachDLL = NULL; +HINSTANCE PachDLL = nullptr; bool PacDriveConnected = false; typedef int (WINAPI PacInitialize)(void); -PacInitialize* m_pacinit = NULL; +PacInitialize* m_pacinit = nullptr; typedef void (WINAPI PacShutdown)(void); -PacShutdown* m_pacdone = NULL; +PacShutdown* m_pacdone = nullptr; typedef bool (WINAPI PacSetLEDStates)(int, short int); -PacSetLEDStates* m_pacset = NULL; +PacSetLEDStates* m_pacset = nullptr; LightsDriver_PacDrive::LightsDriver_PacDrive() { // init io.dll PachDLL = LoadLibrary("pacdrive32.dll"); - if(PachDLL == NULL) + if(PachDLL == nullptr) { - MessageBox(NULL, "Could not LoadLibrary( pacdrive32.dll ).", "ERROR", MB_OK ); + MessageBox(nullptr, "Could not LoadLibrary( pacdrive32.dll ).", "ERROR", MB_OK ); return; } @@ -39,7 +39,7 @@ LightsDriver_PacDrive::LightsDriver_PacDrive() if( NumPacDrives == 0 ) { PacDriveConnected = false; // set not connected - MessageBox(NULL, "Could not find connected PacDrive.", "ERROR", MB_OK); + MessageBox(nullptr, "Could not find connected PacDrive.", "ERROR", MB_OK); return; } else diff --git a/src/arch/Lights/LightsDriver_SextetStream.cpp b/src/arch/Lights/LightsDriver_SextetStream.cpp index 862590d156..26d1e5e787 100644 --- a/src/arch/Lights/LightsDriver_SextetStream.cpp +++ b/src/arch/Lights/LightsDriver_SextetStream.cpp @@ -167,7 +167,7 @@ namespace } virtual ~Impl() { - if(out != NULL) + if(out != nullptr) { out->Flush(); out->Close(); @@ -184,7 +184,7 @@ namespace // Only write if the message has changed since the last write. if(memcmp(buffer, lastOutput, FULL_SEXTET_COUNT) != 0) { - if(out != NULL) + if(out != nullptr) { out->Write(buffer, FULL_SEXTET_COUNT); out->Flush(); @@ -205,12 +205,12 @@ namespace LightsDriver_SextetStream::LightsDriver_SextetStream() { - _impl = NULL; + _impl = nullptr; } LightsDriver_SextetStream::~LightsDriver_SextetStream() { - if(IMPL != NULL) + if(IMPL != nullptr) { delete IMPL; } @@ -218,7 +218,7 @@ LightsDriver_SextetStream::~LightsDriver_SextetStream() void LightsDriver_SextetStream::Set(const LightsState *ls) { - if(IMPL != NULL) + if(IMPL != nullptr) { IMPL->Set(ls); } @@ -244,7 +244,7 @@ inline RageFile * openOutputStream(const RString& filename) { LOG->Warn("Error opening file '%s' for output: %s", filename.c_str(), file->GetError().c_str()); SAFE_DELETE(file); - file = NULL; + file = nullptr; } return file; diff --git a/src/arch/Lights/LightsDriver_Win32Minimaid.cpp b/src/arch/Lights/LightsDriver_Win32Minimaid.cpp index d8a2e9ff7e..e71a28bec5 100644 --- a/src/arch/Lights/LightsDriver_Win32Minimaid.cpp +++ b/src/arch/Lights/LightsDriver_Win32Minimaid.cpp @@ -10,7 +10,7 @@ REGISTER_LIGHTS_DRIVER_CLASS( Win32Minimaid ); -HINSTANCE hMMMAGICDLL = NULL; +HINSTANCE hMMMAGICDLL = nullptr; int minimaid_filter(unsigned int, struct _EXCEPTION_POINTERS *) { @@ -41,7 +41,7 @@ void setup_driver() } __except (minimaid_filter(GetExceptionCode(), GetExceptionInformation())) { - MessageBox(NULL, "Could not connect to the Mimimaid device. Freeing the library now.", "ERROR", MB_OK); + MessageBox(nullptr, "Could not connect to the Mimimaid device. Freeing the library now.", "ERROR", MB_OK); FreeLibrary(hMMMAGICDLL); } @@ -51,9 +51,9 @@ LightsDriver_Win32Minimaid::LightsDriver_Win32Minimaid() { _mmmagic_loaded=false; hMMMAGICDLL = LoadLibraryW(L"mmmagic.dll"); - if(hMMMAGICDLL == NULL) + if(hMMMAGICDLL == nullptr) { - MessageBox(NULL, "Could not LoadLibrary( mmmagic.dll ).", "ERROR", MB_OK ); + MessageBox(nullptr, "Could not LoadLibrary( mmmagic.dll ).", "ERROR", MB_OK ); return; } setup_driver(); diff --git a/src/arch/Lights/LightsDriver_Win32Parallel.cpp b/src/arch/Lights/LightsDriver_Win32Parallel.cpp index 93e52b15d4..8b2082c712 100644 --- a/src/arch/Lights/LightsDriver_Win32Parallel.cpp +++ b/src/arch/Lights/LightsDriver_Win32Parallel.cpp @@ -5,12 +5,12 @@ REGISTER_LIGHTS_DRIVER_CLASS(Win32Parallel); -HINSTANCE hDLL = NULL; +HINSTANCE hDLL = nullptr; typedef void (WINAPI PORTOUT)(short int Port, char Data); -PORTOUT* PortOut = NULL; +PORTOUT* PortOut = nullptr; typedef short int (WINAPI ISDRIVERINSTALLED)(); -ISDRIVERINSTALLED* IsDriverInstalled = NULL; +ISDRIVERINSTALLED* IsDriverInstalled = nullptr; const int LIGHTS_PER_PARALLEL_PORT = 8; // xxx: don't hardcode the port addresses. -aj @@ -44,9 +44,9 @@ LightsDriver_Win32Parallel::LightsDriver_Win32Parallel() { // init io.dll hDLL = LoadLibrary("parallel_lights_io.dll"); - if(hDLL == NULL) + if(hDLL == nullptr) { - MessageBox(NULL, "Could not LoadLibrary( parallel_lights_io.dll ).", "ERROR", MB_OK ); + MessageBox(nullptr, "Could not LoadLibrary( parallel_lights_io.dll ).", "ERROR", MB_OK ); return; } diff --git a/src/arch/LoadingWindow/LoadingWindow.cpp b/src/arch/LoadingWindow/LoadingWindow.cpp index 1c75ec774d..6265d27657 100644 --- a/src/arch/LoadingWindow/LoadingWindow.cpp +++ b/src/arch/LoadingWindow/LoadingWindow.cpp @@ -1,82 +1,82 @@ -#include "global.h" -#include "LoadingWindow.h" -#include "PrefsManager.h" -#include "RageLog.h" -#include "arch/arch_default.h" - -LoadingWindow *LoadingWindow::Create() -{ - if( !PREFSMAN->m_bShowLoadingWindow ) - return new LoadingWindow_Null; -#if defined(UNIX) && !defined(HAVE_GTK) - return new LoadingWindow_Null; -#endif - // Don't load NULL by default. - const RString drivers = "win32,macosx,gtk"; - vector DriversToTry; - split( drivers, ",", DriversToTry, true ); - - ASSERT( DriversToTry.size() != 0 ); - - RString Driver; - LoadingWindow *ret = NULL; - - for( unsigned i = 0; ret == NULL && i < DriversToTry.size(); ++i ) - { - Driver = DriversToTry[i]; - -#ifdef USE_LOADING_WINDOW_MACOSX - if( !DriversToTry[i].CompareNoCase("MacOSX") ) ret = new LoadingWindow_MacOSX; -#endif -#ifdef USE_LOADING_WINDOW_GTK - if( !DriversToTry[i].CompareNoCase("Gtk") ) ret = new LoadingWindow_Gtk; -#endif -#ifdef USE_LOADING_WINDOW_WIN32 - if( !DriversToTry[i].CompareNoCase("Win32") ) ret = new LoadingWindow_Win32; -#endif - if( !DriversToTry[i].CompareNoCase("Null") ) ret = new LoadingWindow_Null; - - if( ret == NULL ) - continue; - - RString sError = ret->Init(); - if( sError != "" ) - { - LOG->Info( "Couldn't load driver %s: %s", DriversToTry[i].c_str(), sError.c_str() ); - SAFE_DELETE( ret ); - } - } - - if( ret ) { - LOG->Info( "Loading window: %s", Driver.c_str() ); - - ret->SetIndeterminate(true); - } - - return ret; -} - -/* - * (c) 2002-2005 Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "LoadingWindow.h" +#include "PrefsManager.h" +#include "RageLog.h" +#include "arch/arch_default.h" + +LoadingWindow *LoadingWindow::Create() +{ + if( !PREFSMAN->m_bShowLoadingWindow ) + return new LoadingWindow_Null; +#if defined(UNIX) && !defined(HAVE_GTK) + return new LoadingWindow_Null; +#endif + // Don't load nullptr by default. + const RString drivers = "win32,macosx,gtk"; + vector DriversToTry; + split( drivers, ",", DriversToTry, true ); + + ASSERT( DriversToTry.size() != 0 ); + + RString Driver; + LoadingWindow *ret = nullptr; + + for( unsigned i = 0; ret == nullptr && i < DriversToTry.size(); ++i ) + { + Driver = DriversToTry[i]; + +#ifdef USE_LOADING_WINDOW_MACOSX + if( !DriversToTry[i].CompareNoCase("MacOSX") ) ret = new LoadingWindow_MacOSX; +#endif +#ifdef USE_LOADING_WINDOW_GTK + if( !DriversToTry[i].CompareNoCase("Gtk") ) ret = new LoadingWindow_Gtk; +#endif +#ifdef USE_LOADING_WINDOW_WIN32 + if( !DriversToTry[i].CompareNoCase("Win32") ) ret = new LoadingWindow_Win32; +#endif + if( !DriversToTry[i].CompareNoCase("Null") ) ret = new LoadingWindow_Null; + + if( ret == nullptr ) + continue; + + RString sError = ret->Init(); + if( sError != "" ) + { + LOG->Info( "Couldn't load driver %s: %s", DriversToTry[i].c_str(), sError.c_str() ); + SAFE_DELETE( ret ); + } + } + + if( ret ) { + LOG->Info( "Loading window: %s", Driver.c_str() ); + + ret->SetIndeterminate(true); + } + + return ret; +} + +/* + * (c) 2002-2005 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/arch/LoadingWindow/LoadingWindow_Gtk.cpp b/src/arch/LoadingWindow/LoadingWindow_Gtk.cpp index 1931ef007d..4fb976fc98 100644 --- a/src/arch/LoadingWindow/LoadingWindow_Gtk.cpp +++ b/src/arch/LoadingWindow/LoadingWindow_Gtk.cpp @@ -1,137 +1,137 @@ -#include "global.h" -#include "RageLog.h" -#include "RageFileManager.h" -#include "RageUtil.h" -#include "LoadingWindow_Gtk.h" -#include "LoadingWindow_GtkModule.h" - -#include - -static void *Handle = NULL; -static INIT Module_Init; -static SHUTDOWN Module_Shutdown; -static SETTEXT Module_SetText; -static SETICON Module_SetIcon; -static SETSPLASH Module_SetSplash; -static SETPROGRESS Module_SetProgress; -static SETINDETERMINATE Module_SetIndeterminate; - -LoadingWindow_Gtk::LoadingWindow_Gtk() -{ -} - -static RString ModuleError( const RString s ) -{ - return ssprintf( "Couldn't load symbol Module_%s", s.c_str() ); -} - -RString LoadingWindow_Gtk::Init() -{ - ASSERT( Handle == NULL ); - - Handle = dlopen( RageFileManagerUtil::sDirOfExecutable + "/" + "GtkModule.so", RTLD_NOW ); - if( Handle == NULL ) - return ssprintf( "dlopen(): %s", dlerror() ); - - Module_Init = (INIT) dlsym(Handle, "Init"); - if( !Module_Init ) - return ModuleError("Init"); - - Module_Shutdown = (SHUTDOWN) dlsym(Handle, "Shutdown"); - if( !Module_Shutdown ) - return ModuleError("Shutdown"); - - Module_SetText = (SETTEXT) dlsym(Handle, "SetText"); - if( !Module_SetText ) - return ModuleError("SetText"); - - Module_SetIcon = (SETICON) dlsym(Handle, "SetIcon"); - if( !Module_SetIcon ) - return ModuleError("SetIcon"); - - Module_SetSplash = (SETSPLASH) dlsym(Handle, "SetSplash"); - if( !Module_SetSplash ) - return ModuleError("SetSplash"); - - Module_SetProgress = (SETPROGRESS) dlsym(Handle, "SetProgress"); - if( !Module_SetProgress ) - return ModuleError("SetProgress"); - - Module_SetIndeterminate = (SETINDETERMINATE) dlsym(Handle, "SetIndeterminate"); - if( !Module_SetIndeterminate ) - return ModuleError("SetIndeterminate"); - - const char *ret = Module_Init( &g_argc, &g_argv ); - if( ret != NULL ) - return ret; - return ""; -} - -LoadingWindow_Gtk::~LoadingWindow_Gtk() -{ - if( Module_Shutdown != NULL ) - Module_Shutdown(); - Module_Shutdown = NULL; - - if( Handle ) - dlclose( Handle ); - Handle = NULL; -} - -void LoadingWindow_Gtk::SetText( RString s ) -{ - Module_SetText( s ); -} - -void LoadingWindow_Gtk::SetIcon( const RageSurface *pIcon ) -{ - Module_SetIcon( pIcon ); -} - -void LoadingWindow_Gtk::SetSplash( const RageSurface *pSplash ) -{ - Module_SetSplash( pSplash ); -} - -void LoadingWindow_Gtk::SetProgress( const int progress ) -{ - LoadingWindow::SetProgress( progress ); - Module_SetProgress( m_progress, m_totalWork ); -} - -void LoadingWindow_Gtk::SetTotalWork( const int totalWork ) -{ - LoadingWindow::SetTotalWork( totalWork ); - Module_SetProgress( m_progress, m_totalWork ); -} - -void LoadingWindow_Gtk::SetIndeterminate( bool indeterminate ) -{ - LoadingWindow::SetIndeterminate( indeterminate ); - Module_SetIndeterminate( m_indeterminate ); -} - -/* - * (c) 2003-2004 Glenn Maynard, Sean Burke - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "RageLog.h" +#include "RageFileManager.h" +#include "RageUtil.h" +#include "LoadingWindow_Gtk.h" +#include "LoadingWindow_GtkModule.h" + +#include + +static void *Handle = nullptr; +static INIT Module_Init; +static SHUTDOWN Module_Shutdown; +static SETTEXT Module_SetText; +static SETICON Module_SetIcon; +static SETSPLASH Module_SetSplash; +static SETPROGRESS Module_SetProgress; +static SETINDETERMINATE Module_SetIndeterminate; + +LoadingWindow_Gtk::LoadingWindow_Gtk() +{ +} + +static RString ModuleError( const RString s ) +{ + return ssprintf( "Couldn't load symbol Module_%s", s.c_str() ); +} + +RString LoadingWindow_Gtk::Init() +{ + ASSERT( Handle == nullptr ); + + Handle = dlopen( RageFileManagerUtil::sDirOfExecutable + "/" + "GtkModule.so", RTLD_NOW ); + if( Handle == nullptr ) + return ssprintf( "dlopen(): %s", dlerror() ); + + Module_Init = (INIT) dlsym(Handle, "Init"); + if( !Module_Init ) + return ModuleError("Init"); + + Module_Shutdown = (SHUTDOWN) dlsym(Handle, "Shutdown"); + if( !Module_Shutdown ) + return ModuleError("Shutdown"); + + Module_SetText = (SETTEXT) dlsym(Handle, "SetText"); + if( !Module_SetText ) + return ModuleError("SetText"); + + Module_SetIcon = (SETICON) dlsym(Handle, "SetIcon"); + if( !Module_SetIcon ) + return ModuleError("SetIcon"); + + Module_SetSplash = (SETSPLASH) dlsym(Handle, "SetSplash"); + if( !Module_SetSplash ) + return ModuleError("SetSplash"); + + Module_SetProgress = (SETPROGRESS) dlsym(Handle, "SetProgress"); + if( !Module_SetProgress ) + return ModuleError("SetProgress"); + + Module_SetIndeterminate = (SETINDETERMINATE) dlsym(Handle, "SetIndeterminate"); + if( !Module_SetIndeterminate ) + return ModuleError("SetIndeterminate"); + + const char *ret = Module_Init( &g_argc, &g_argv ); + if( ret != nullptr ) + return ret; + return ""; +} + +LoadingWindow_Gtk::~LoadingWindow_Gtk() +{ + if( Module_Shutdown != nullptr ) + Module_Shutdown(); + Module_Shutdown = nullptr; + + if( Handle ) + dlclose( Handle ); + Handle = nullptr; +} + +void LoadingWindow_Gtk::SetText( RString s ) +{ + Module_SetText( s ); +} + +void LoadingWindow_Gtk::SetIcon( const RageSurface *pIcon ) +{ + Module_SetIcon( pIcon ); +} + +void LoadingWindow_Gtk::SetSplash( const RageSurface *pSplash ) +{ + Module_SetSplash( pSplash ); +} + +void LoadingWindow_Gtk::SetProgress( const int progress ) +{ + LoadingWindow::SetProgress( progress ); + Module_SetProgress( m_progress, m_totalWork ); +} + +void LoadingWindow_Gtk::SetTotalWork( const int totalWork ) +{ + LoadingWindow::SetTotalWork( totalWork ); + Module_SetProgress( m_progress, m_totalWork ); +} + +void LoadingWindow_Gtk::SetIndeterminate( bool indeterminate ) +{ + LoadingWindow::SetIndeterminate( indeterminate ); + Module_SetIndeterminate( m_indeterminate ); +} + +/* + * (c) 2003-2004 Glenn Maynard, Sean Burke + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/arch/LoadingWindow/LoadingWindow_GtkModule.cpp b/src/arch/LoadingWindow/LoadingWindow_GtkModule.cpp index ff4da99132..a46091ce8c 100644 --- a/src/arch/LoadingWindow/LoadingWindow_GtkModule.cpp +++ b/src/arch/LoadingWindow/LoadingWindow_GtkModule.cpp @@ -1,151 +1,151 @@ -#include "global.h" -#include "LoadingWindow_GtkModule.h" -#include "RageUtil.h" -#include "RageSurface.h" -#include "RageSurfaceUtils.h" -#include "RageSurface_Load.h" - -#include - -static GtkWidget *label; -static GtkWidget *window; -static GtkWidget *splash; -static GtkWidget *progressBar; - -extern "C" const char *Init( int *argc, char ***argv ) -{ - // Need to use external library to load this image. Native loader seems broken :/ - const gchar *splash_image_path = "Data/splash.png"; - GtkWidget *vbox; - - gtk_disable_setlocale(); - if( !gtk_init_check(argc,argv) ) - return "Couldn't initialize gtk (cannot open display)"; - - window = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_position( GTK_WINDOW(window), GTK_WIN_POS_CENTER ); - gtk_widget_set_size_request(window,468,-1); - gtk_window_set_deletable( GTK_WINDOW(window), FALSE ); - gtk_window_set_resizable(GTK_WINDOW(window),FALSE); - gtk_window_set_role( GTK_WINDOW(window), "sm-startup" ); - //gtk_window_set_icon( GTK_WINDOW(window), ); - gtk_widget_realize(window); - - splash = gtk_image_new_from_file(splash_image_path); - - label = gtk_label_new(NULL); - gtk_label_set_justify(GTK_LABEL(label),GTK_JUSTIFY_CENTER); - gtk_label_set_ellipsize(GTK_LABEL(label),PANGO_ELLIPSIZE_END); - gtk_label_set_line_wrap(GTK_LABEL(label),FALSE); - - progressBar = gtk_progress_bar_new(); - gtk_progress_bar_set_fraction( GTK_PROGRESS_BAR(progressBar), 0.0 ); - - vbox = gtk_vbox_new(FALSE,0); - gtk_container_add(GTK_CONTAINER(window),vbox); - gtk_box_pack_start(GTK_BOX(vbox),splash,FALSE,FALSE,0); - gtk_box_pack_end(GTK_BOX(vbox),progressBar,FALSE,FALSE,0); - gtk_box_pack_end(GTK_BOX(vbox),label,TRUE,TRUE,0); - - gtk_widget_show_all(window); - gtk_main_iteration_do(FALSE); - return NULL; -} - -extern "C" void Shutdown() -{ - gtk_widget_hide(window); - g_signal_emit_by_name (G_OBJECT (window), "destroy"); - while( gtk_events_pending() ) - gtk_main_iteration_do(FALSE); -} - -extern "C" void SetText( const char *s ) -{ - gtk_label_set_text(GTK_LABEL(label), s); - gtk_widget_show(label); - gtk_main_iteration_do(FALSE); -} - -void DeletePixels( guchar *pixels, gpointer data ) -{ - delete[] (uint8_t *)pixels; -} - -GdkPixbuf *MakePixbuf( const RageSurface *pSrc ) -{ - RageSurface *pSurface = CreateSurface( pSrc->w, pSrc->h, 32, - 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 ); - RageSurfaceUtils::Blit( pSrc, pSurface , -1, -1 ); - - GdkPixbuf *pBuf = gdk_pixbuf_new_from_data( pSurface->pixels, GDK_COLORSPACE_RGB, - true, 8, pSurface->w, pSurface->h , pSurface->pitch, DeletePixels, NULL); - - if( pBuf != NULL ) - pSurface->pixels_owned = false; - - delete pSurface; - return pBuf; -} - -extern "C" void SetIcon( const RageSurface *pSrcImg ) -{ - GdkPixbuf *pBuf = MakePixbuf( pSrcImg ); - if( pBuf != NULL ) - { - gtk_window_set_icon( GTK_WINDOW(window), pBuf ); - g_object_unref(pBuf); - } - gtk_main_iteration_do(FALSE); -} - -extern "C" void SetSplash( const RageSurface *pSplash ) -{ - GdkPixbuf *pBuf = MakePixbuf( pSplash ); - if( pBuf != NULL ) - { - gtk_image_set_from_pixbuf(GTK_IMAGE(splash), pBuf); - g_object_unref(pBuf); - } - gtk_main_iteration_do(FALSE); -} - -extern "C" void SetProgress( int progress, int totalWork ) -{ - gdouble fraction = ( totalWork > 0 ? progress / (gdouble)totalWork : 0 ); - if( fraction > 1.0 ) fraction = 1.0; - if( fraction < 0.0 ) fraction = 0.0; - gtk_progress_bar_set_fraction( GTK_PROGRESS_BAR(progressBar), fraction ); - gtk_main_iteration_do(FALSE); -} - -extern "C" void SetIndeterminate( bool indeterminate ) -{ - gtk_progress_bar_pulse(GTK_PROGRESS_BAR(progressBar)); - gtk_main_iteration_do(FALSE); -} - -/* - * (c) 2003-2004 Glenn Maynard, Sean Burke - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "LoadingWindow_GtkModule.h" +#include "RageUtil.h" +#include "RageSurface.h" +#include "RageSurfaceUtils.h" +#include "RageSurface_Load.h" + +#include + +static GtkWidget *label; +static GtkWidget *window; +static GtkWidget *splash; +static GtkWidget *progressBar; + +extern "C" const char *Init( int *argc, char ***argv ) +{ + // Need to use external library to load this image. Native loader seems broken :/ + const gchar *splash_image_path = "Data/splash.png"; + GtkWidget *vbox; + + gtk_disable_setlocale(); + if( !gtk_init_check(argc,argv) ) + return "Couldn't initialize gtk (cannot open display)"; + + window = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_set_position( GTK_WINDOW(window), GTK_WIN_POS_CENTER ); + gtk_widget_set_size_request(window,468,-1); + gtk_window_set_deletable( GTK_WINDOW(window), FALSE ); + gtk_window_set_resizable(GTK_WINDOW(window),FALSE); + gtk_window_set_role( GTK_WINDOW(window), "sm-startup" ); + //gtk_window_set_icon( GTK_WINDOW(window), ); + gtk_widget_realize(window); + + splash = gtk_image_new_from_file(splash_image_path); + + label = gtk_label_new(nullptr); + gtk_label_set_justify(GTK_LABEL(label),GTK_JUSTIFY_CENTER); + gtk_label_set_ellipsize(GTK_LABEL(label),PANGO_ELLIPSIZE_END); + gtk_label_set_line_wrap(GTK_LABEL(label),FALSE); + + progressBar = gtk_progress_bar_new(); + gtk_progress_bar_set_fraction( GTK_PROGRESS_BAR(progressBar), 0.0 ); + + vbox = gtk_vbox_new(FALSE,0); + gtk_container_add(GTK_CONTAINER(window),vbox); + gtk_box_pack_start(GTK_BOX(vbox),splash,FALSE,FALSE,0); + gtk_box_pack_end(GTK_BOX(vbox),progressBar,FALSE,FALSE,0); + gtk_box_pack_end(GTK_BOX(vbox),label,TRUE,TRUE,0); + + gtk_widget_show_all(window); + gtk_main_iteration_do(FALSE); + return nullptr; +} + +extern "C" void Shutdown() +{ + gtk_widget_hide(window); + g_signal_emit_by_name (G_OBJECT (window), "destroy"); + while( gtk_events_pending() ) + gtk_main_iteration_do(FALSE); +} + +extern "C" void SetText( const char *s ) +{ + gtk_label_set_text(GTK_LABEL(label), s); + gtk_widget_show(label); + gtk_main_iteration_do(FALSE); +} + +void DeletePixels( guchar *pixels, gpointer data ) +{ + delete[] (uint8_t *)pixels; +} + +GdkPixbuf *MakePixbuf( const RageSurface *pSrc ) +{ + RageSurface *pSurface = CreateSurface( pSrc->w, pSrc->h, 32, + 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 ); + RageSurfaceUtils::Blit( pSrc, pSurface , -1, -1 ); + + GdkPixbuf *pBuf = gdk_pixbuf_new_from_data( pSurface->pixels, GDK_COLORSPACE_RGB, + true, 8, pSurface->w, pSurface->h , pSurface->pitch, DeletePixels, nullptr); + + if( pBuf != nullptr ) + pSurface->pixels_owned = false; + + delete pSurface; + return pBuf; +} + +extern "C" void SetIcon( const RageSurface *pSrcImg ) +{ + GdkPixbuf *pBuf = MakePixbuf( pSrcImg ); + if( pBuf != nullptr ) + { + gtk_window_set_icon( GTK_WINDOW(window), pBuf ); + g_object_unref(pBuf); + } + gtk_main_iteration_do(FALSE); +} + +extern "C" void SetSplash( const RageSurface *pSplash ) +{ + GdkPixbuf *pBuf = MakePixbuf( pSplash ); + if( pBuf != nullptr ) + { + gtk_image_set_from_pixbuf(GTK_IMAGE(splash), pBuf); + g_object_unref(pBuf); + } + gtk_main_iteration_do(FALSE); +} + +extern "C" void SetProgress( int progress, int totalWork ) +{ + gdouble fraction = ( totalWork > 0 ? progress / (gdouble)totalWork : 0 ); + if( fraction > 1.0 ) fraction = 1.0; + if( fraction < 0.0 ) fraction = 0.0; + gtk_progress_bar_set_fraction( GTK_PROGRESS_BAR(progressBar), fraction ); + gtk_main_iteration_do(FALSE); +} + +extern "C" void SetIndeterminate( bool indeterminate ) +{ + gtk_progress_bar_pulse(GTK_PROGRESS_BAR(progressBar)); + gtk_main_iteration_do(FALSE); +} + +/* + * (c) 2003-2004 Glenn Maynard, Sean Burke + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/arch/LoadingWindow/LoadingWindow_Win32.cpp b/src/arch/LoadingWindow/LoadingWindow_Win32.cpp index 1e7a44783d..76a739f61a 100644 --- a/src/arch/LoadingWindow/LoadingWindow_Win32.cpp +++ b/src/arch/LoadingWindow/LoadingWindow_Win32.cpp @@ -17,7 +17,7 @@ #include "LocalizedString.h" #include "RageSurfaceUtils_Zoom.h" -static HBITMAP g_hBitmap = NULL; +static HBITMAP g_hBitmap = nullptr; /* Load a RageSurface into a GDI surface. */ static HBITMAP LoadWin32Surface( const RageSurface *pSplash, HWND hWnd ) @@ -39,11 +39,11 @@ static HBITMAP LoadWin32Surface( const RageSurface *pSplash, HWND hWnd ) RageSurfaceUtils::Zoom( s, iWidth, iHeight ); } - HDC hScreen = GetDC(NULL); - ASSERT_M( hScreen != NULL, werr_ssprintf(GetLastError(), "hScreen") ); + HDC hScreen = GetDC(nullptr); + ASSERT_M( hScreen != nullptr, werr_ssprintf(GetLastError(), "hScreen") ); HBITMAP bitmap = CreateCompatibleBitmap( hScreen, s->w, s->h ); - ASSERT_M( bitmap != NULL, werr_ssprintf(GetLastError(), "CreateCompatibleBitmap") ); + ASSERT_M( bitmap != nullptr, werr_ssprintf(GetLastError(), "CreateCompatibleBitmap") ); HDC BitmapDC = CreateCompatibleDC( hScreen ); SelectObject( BitmapDC, bitmap ); @@ -60,10 +60,10 @@ static HBITMAP LoadWin32Surface( const RageSurface *pSplash, HWND hWnd ) } } - SelectObject( BitmapDC, NULL ); + SelectObject( BitmapDC, nullptr ); DeleteObject( BitmapDC ); - ReleaseDC( NULL, hScreen ); + ReleaseDC( nullptr, hScreen ); delete s; return bitmap; @@ -73,8 +73,8 @@ static HBITMAP LoadWin32Surface( RString sFile, HWND hWnd ) { RString error; RageSurface *pSurface = RageSurfaceUtils::LoadFile( sFile, error ); - if( pSurface == NULL ) - return NULL; + if( pSurface == nullptr ) + return nullptr; HBITMAP ret = LoadWin32Surface( pSurface, hWnd ); delete pSurface; @@ -92,7 +92,7 @@ BOOL CALLBACK LoadingWindow_Win32::WndProc( HWND hWnd, UINT msg, WPARAM wParam, if( !vs.empty() ) g_hBitmap = LoadWin32Surface( vs[0], hWnd ); } - if( g_hBitmap == NULL ) + if( g_hBitmap == nullptr ) g_hBitmap = LoadWin32Surface( "Data/splash.bmp", hWnd ); SendMessage( GetDlgItem(hWnd,IDC_SPLASH), @@ -104,7 +104,7 @@ BOOL CALLBACK LoadingWindow_Win32::WndProc( HWND hWnd, UINT msg, WPARAM wParam, case WM_DESTROY: DeleteObject( g_hBitmap ); - g_hBitmap = NULL; + g_hBitmap = nullptr; break; } @@ -113,25 +113,25 @@ BOOL CALLBACK LoadingWindow_Win32::WndProc( HWND hWnd, UINT msg, WPARAM wParam, void LoadingWindow_Win32::SetIcon( const RageSurface *pIcon ) { - if( m_hIcon != NULL ) + if( m_hIcon != nullptr ) DestroyIcon( m_hIcon ); m_hIcon = IconFromSurface( pIcon ); - if( m_hIcon != NULL ) + if( m_hIcon != nullptr ) // XXX: GCL_HICON isn't available on x86-64 Windows SetClassLong( hwnd, GCL_HICON, (LONG) m_hIcon ); } void LoadingWindow_Win32::SetSplash( const RageSurface *pSplash ) { - if( g_hBitmap != NULL ) + if( g_hBitmap != nullptr ) { DeleteObject( g_hBitmap ); - g_hBitmap = NULL; + g_hBitmap = nullptr; } g_hBitmap = LoadWin32Surface( pSplash, hwnd ); - if( g_hBitmap != NULL ) + if( g_hBitmap != nullptr ) { SendDlgItemMessage( hwnd, IDC_SPLASH, @@ -144,9 +144,9 @@ void LoadingWindow_Win32::SetSplash( const RageSurface *pSplash ) LoadingWindow_Win32::LoadingWindow_Win32() { - m_hIcon = NULL; - hwnd = CreateDialog( handle.Get(), MAKEINTRESOURCE(IDD_LOADING_DIALOG), NULL, WndProc ); - ASSERT( hwnd != NULL ); + m_hIcon = nullptr; + hwnd = CreateDialog( handle.Get(), MAKEINTRESOURCE(IDD_LOADING_DIALOG), nullptr, WndProc ); + ASSERT( hwnd != nullptr ); for( unsigned i = 0; i < 3; ++i ) text[i] = "ABC"; /* always set on first call */ SetText( "" ); @@ -157,7 +157,7 @@ LoadingWindow_Win32::~LoadingWindow_Win32() { if( hwnd ) DestroyWindow( hwnd ); - if( m_hIcon != NULL ) + if( m_hIcon != nullptr ) DestroyIcon( m_hIcon ); } diff --git a/src/arch/LowLevelWindow/LowLevelWindow.h b/src/arch/LowLevelWindow/LowLevelWindow.h index af6f04f72a..3f21ca63b5 100644 --- a/src/arch/LowLevelWindow/LowLevelWindow.h +++ b/src/arch/LowLevelWindow/LowLevelWindow.h @@ -34,7 +34,7 @@ public: virtual const ActualVideoModeParams GetActualVideoModeParams() const = 0; virtual bool SupportsRenderToTexture() const { return false; } - virtual RenderTarget *CreateRenderTarget() { return NULL; } + virtual RenderTarget *CreateRenderTarget() { return nullptr; } virtual bool SupportsFullscreenBorderlessWindow() const { return false; }; diff --git a/src/arch/LowLevelWindow/LowLevelWindow_MacOSX.mm b/src/arch/LowLevelWindow/LowLevelWindow_MacOSX.mm index ffba7bd8ec..fc203b61f8 100644 --- a/src/arch/LowLevelWindow/LowLevelWindow_MacOSX.mm +++ b/src/arch/LowLevelWindow/LowLevelWindow_MacOSX.mm @@ -255,7 +255,7 @@ void RenderTarget_MacOSX::Create( const RenderTargetParam ¶m, int &iTextureW glTexImage2D( GL_TEXTURE_2D, 0, param.bWithAlpha? GL_RGBA8:GL_RGB8, iTextureWidth, iTextureHeight, 0, param.bWithAlpha? GL_RGBA:GL_RGB, - GL_UNSIGNED_BYTE, NULL ); + GL_UNSIGNED_BYTE, nil); GLenum error = glGetError(); ASSERT_M(error == GL_NO_ERROR, RageDisplay_Legacy_Helpers::GLToString(error)); @@ -293,7 +293,7 @@ void RenderTarget_MacOSX::FinishRenderingTo() } -LowLevelWindow_MacOSX::LowLevelWindow_MacOSX() : m_Context(nil), m_BGContext(nil), m_CurrentDisplayMode(NULL), m_DisplayID(0) +LowLevelWindow_MacOSX::LowLevelWindow_MacOSX() : m_Context(nil), m_BGContext(nil), m_CurrentDisplayMode(nil), m_DisplayID(0) { POOL; m_WindowDelegate = [[SMWindowDelegate alloc] init]; @@ -323,12 +323,12 @@ void *LowLevelWindow_MacOSX::GetProcAddress( RString s ) // Both functions mentioned in there are deprecated in 10.4. const RString& symbolName( '_' + s ); const uint32_t count = _dyld_image_count(); - NSSymbol symbol = NULL; + NSSymbol symbol = nil; const uint32_t options = NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR; for( uint32_t i = 0; i < count && !symbol; ++i ) symbol = NSLookupSymbolInImage( _dyld_get_image_header(i), symbolName, options ); - return symbol ? NSAddressOfSymbol( symbol ) : NULL; + return symbol ? NSAddressOfSymbol( symbol ) : nil; } RString LowLevelWindow_MacOSX::TryVideoMode( const VideoModeParams& p, bool& newDeviceOut ) @@ -462,13 +462,13 @@ void LowLevelWindow_MacOSX::ShutDownFullScreen() ASSERT( err == kCGErrorSuccess ); SetActualParamsFromMode( m_CurrentDisplayMode ); // We don't own this so we cannot release it. - m_CurrentDisplayMode = NULL; + m_CurrentDisplayMode = nil; m_CurrentParams.windowed = true; } int LowLevelWindow_MacOSX::ChangeDisplayMode( const VideoModeParams& p ) { - CFDictionaryRef mode = NULL; + CFDictionaryRef mode = nil; CFDictionaryRef newMode; CGDisplayErr err; @@ -483,10 +483,10 @@ int LowLevelWindow_MacOSX::ChangeDisplayMode( const VideoModeParams& p ) } if( p.rate == REFRESH_DEFAULT ) - newMode = CGDisplayBestModeForParameters( kCGDirectMainDisplay, p.bpp, p.width, p.height, NULL ); + newMode = CGDisplayBestModeForParameters( kCGDirectMainDisplay, p.bpp, p.width, p.height, nil); else newMode = CGDisplayBestModeForParametersAndRefreshRate( kCGDirectMainDisplay, p.bpp, - p.width, p.height, p.rate, NULL ); + p.width, p.height, p.rate, nil); err = CGDisplaySwitchToMode( kCGDirectMainDisplay, newMode ); diff --git a/src/arch/LowLevelWindow/LowLevelWindow_Win32.cpp b/src/arch/LowLevelWindow/LowLevelWindow_Win32.cpp index e07cad765f..25ace08fa5 100644 --- a/src/arch/LowLevelWindow/LowLevelWindow_Win32.cpp +++ b/src/arch/LowLevelWindow/LowLevelWindow_Win32.cpp @@ -14,29 +14,23 @@ #include static PIXELFORMATDESCRIPTOR g_CurrentPixelFormat; -static HGLRC g_HGLRC = NULL; -static HGLRC g_HGLRC_Background = NULL; -static HMODULE g_HGL_Module = NULL; +static HGLRC g_HGLRC = nullptr; +static HGLRC g_HGLRC_Background = nullptr; +static HMODULE g_HGL_Module = nullptr; static void DestroyGraphicsWindowAndOpenGLContext() { - if( g_HGLRC != NULL ) + if( g_HGLRC != nullptr ) { - wglMakeCurrent( NULL, NULL ); + wglMakeCurrent( nullptr, nullptr ); wglDeleteContext( g_HGLRC ); - g_HGLRC = NULL; + g_HGLRC = nullptr; } - if( g_HGLRC_Background != NULL ) + if( g_HGLRC_Background != nullptr ) { wglDeleteContext( g_HGLRC_Background ); - g_HGLRC_Background = NULL; - } - - if( g_HGL_Module != NULL ) - { - FreeLibrary(g_HGL_Module); - g_HGL_Module = NULL; + g_HGLRC_Background = nullptr; } ZERO( g_CurrentPixelFormat ); @@ -47,25 +41,25 @@ static void DestroyGraphicsWindowAndOpenGLContext() void *LowLevelWindow_Win32::GetProcAddress( RString s ) { void *pRet = (void*) wglGetProcAddress( s ); - if( pRet != NULL ) + if( pRet != nullptr ) return pRet; - if (g_HGL_Module != NULL) + if (g_HGL_Module != nullptr) { pRet = (void *) ::GetProcAddress( g_HGL_Module, s ); - if (pRet != NULL) + if (pRet != nullptr) return pRet; } - return (void*) ::GetProcAddress( GetModuleHandle(NULL), s ); + return (void*) ::GetProcAddress( GetModuleHandle(nullptr), s ); } LowLevelWindow_Win32::LowLevelWindow_Win32() { - ASSERT( g_HGLRC == NULL ); - ASSERT( g_HGLRC_Background == NULL ); - ASSERT( g_HGL_Module == NULL ); + ASSERT( g_HGLRC == nullptr ); + ASSERT( g_HGLRC_Background == nullptr ); + ASSERT( g_HGL_Module == nullptr ); GraphicsWindow::Initialize( false ); } @@ -83,8 +77,8 @@ void LowLevelWindow_Win32::GetDisplaySpecs( DisplaySpecs &out ) const int ChooseWindowPixelFormat( const VideoModeParams &p, PIXELFORMATDESCRIPTOR *pixfmt ) { - ASSERT( GraphicsWindow::GetHwnd() != NULL ); - ASSERT( GraphicsWindow::GetHDC() != NULL ); + ASSERT( GraphicsWindow::GetHwnd() != nullptr ); + ASSERT( GraphicsWindow::GetHDC() != nullptr ); ZERO( *pixfmt ); pixfmt->nSize = sizeof(PIXELFORMATDESCRIPTOR); @@ -144,7 +138,7 @@ RString LowLevelWindow_Win32::TryVideoMode( const VideoModeParams &p, bool &bNew bool bCanSetPixelFormat = true; /* Do we have an old window? */ - if( GraphicsWindow::GetHwnd() == NULL ) + if( GraphicsWindow::GetHwnd() == nullptr ) { /* No. Always create and show the window before changing the video mode. * Otherwise, some other window may have focus, and changing the video mode will @@ -157,7 +151,7 @@ RString LowLevelWindow_Win32::TryVideoMode( const VideoModeParams &p, bool &bNew bCanSetPixelFormat = false; } - ASSERT( GraphicsWindow::GetHwnd() != NULL ); + ASSERT( GraphicsWindow::GetHwnd() != nullptr ); /* Set the display mode: switch to a fullscreen mode or revert to windowed mode. */ LOG->Trace("SetScreenMode ..."); @@ -199,13 +193,13 @@ RString LowLevelWindow_Win32::TryVideoMode( const VideoModeParams &p, bool &bNew * We have to create the new window first. */ LOG->Trace( "Mode requires new pixel format, and we've already set one; resetting OpenGL context" ); - if( g_HGLRC != NULL ) + if( g_HGLRC != nullptr ) { - wglMakeCurrent( NULL, NULL ); + wglMakeCurrent( nullptr, nullptr ); wglDeleteContext( g_HGLRC ); - g_HGLRC = NULL; + g_HGLRC = nullptr; wglDeleteContext( g_HGLRC_Background ); - g_HGLRC_Background = NULL; + g_HGLRC_Background = nullptr; } bNewDeviceOut = true; @@ -231,19 +225,19 @@ RString LowLevelWindow_Win32::TryVideoMode( const VideoModeParams &p, bool &bNew DumpPixelFormat( g_CurrentPixelFormat ); } - if( g_HGLRC == NULL ) + if( g_HGLRC == nullptr ) { g_HGL_Module = LoadLibraryA("opengl32.dll"); g_HGLRC = wglCreateContext( GraphicsWindow::GetHDC() ); - if ( g_HGLRC == NULL ) + if ( g_HGLRC == nullptr ) { DestroyGraphicsWindowAndOpenGLContext(); return hr_ssprintf( GetLastError(), "wglCreateContext" ); } g_HGLRC_Background = wglCreateContext( GraphicsWindow::GetHDC() ); - if( g_HGLRC_Background == NULL ) + if( g_HGLRC_Background == nullptr ) { DestroyGraphicsWindowAndOpenGLContext(); return hr_ssprintf( GetLastError(), "wglCreateContext" ); @@ -253,7 +247,7 @@ RString LowLevelWindow_Win32::TryVideoMode( const VideoModeParams &p, bool &bNew { LOG->Warn( werr_ssprintf(GetLastError(), "wglShareLists failed") ); wglDeleteContext( g_HGLRC_Background ); - g_HGLRC_Background = NULL; + g_HGLRC_Background = nullptr; } if( !wglMakeCurrent( GraphicsWindow::GetHDC(), g_HGLRC ) ) @@ -267,7 +261,7 @@ RString LowLevelWindow_Win32::TryVideoMode( const VideoModeParams &p, bool &bNew bool LowLevelWindow_Win32::SupportsThreadedRendering() { - return g_HGLRC_Background != NULL; + return g_HGLRC_Background != nullptr; } void LowLevelWindow_Win32::BeginConcurrentRendering() @@ -281,7 +275,7 @@ void LowLevelWindow_Win32::BeginConcurrentRendering() void LowLevelWindow_Win32::EndConcurrentRendering() { - wglMakeCurrent( NULL, NULL ); + wglMakeCurrent( nullptr, nullptr ); } static LocalizedString OPENGL_NOT_AVAILABLE( "LowLevelWindow_Win32", "OpenGL hardware acceleration is not available." ); @@ -343,8 +337,8 @@ RenderTarget_Win32::RenderTarget_Win32(LowLevelWindow_Win32 *pWind) { m_pWind = pWind; m_texHandle = 0; - m_hOldDeviceContext = NULL; - m_hOldRenderContext = NULL; + m_hOldDeviceContext = nullptr; + m_hOldRenderContext = nullptr; } RenderTarget_Win32::~RenderTarget_Win32() @@ -377,7 +371,7 @@ void RenderTarget_Win32::Create(const RenderTargetParam ¶m, int &iTextureWid internalformat = param.bWithAlpha? GL_RGBA8:GL_RGB8; glTexImage2D(GL_TEXTURE_2D, 0, internalformat, iTextureWidth, - iTextureHeight, 0, type, GL_UNSIGNED_BYTE, NULL); + iTextureHeight, 0, type, GL_UNSIGNED_BYTE, nullptr); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); diff --git a/src/arch/LowLevelWindow/LowLevelWindow_X11.cpp b/src/arch/LowLevelWindow/LowLevelWindow_X11.cpp index 85bf24391a..6ccfa1c363 100644 --- a/src/arch/LowLevelWindow/LowLevelWindow_X11.cpp +++ b/src/arch/LowLevelWindow/LowLevelWindow_X11.cpp @@ -31,8 +31,8 @@ using namespace X11Helper; // Display ID for treating the entire X screen as the display const std::string ID_XSCREEN = "XSCREEN_RANDR"; -static GLXContext g_pContext = NULL; -static GLXContext g_pBackgroundContext = NULL; +static GLXContext g_pContext = nullptr; +static GLXContext g_pBackgroundContext = nullptr; static Window g_AltWindow = None; static bool g_bChangedScreenSize = false; static SizeID g_iOldSize = None; @@ -98,12 +98,12 @@ LowLevelWindow_X11::~LowLevelWindow_X11() if( g_pContext ) { glXDestroyContext( Dpy, g_pContext ); - g_pContext = NULL; + g_pContext = nullptr; } if( g_pBackgroundContext ) { glXDestroyContext( Dpy, g_pBackgroundContext ); - g_pBackgroundContext = NULL; + g_pBackgroundContext = nullptr; } XDestroyWindow( Dpy, Win ); Win = None; @@ -138,7 +138,7 @@ void LowLevelWindow_X11::RestoreOutputConfig() { void *LowLevelWindow_X11::GetProcAddress( RString s ) { // XXX: We should check whether glXGetProcAddress or - // glXGetProcAddressARB is available/not NULL, and go by that, + // glXGetProcAddressARB is available/not nullptr, and go by that, // instead of assuming like this. return (void*) glXGetProcAddressARB( (const GLubyte*) s.c_str() ); } @@ -156,9 +156,9 @@ RString LowLevelWindow_X11::TryVideoMode( const VideoModeParams &p, bool &bNewDe int windowHeight = p.height; bool renderOffscreen = false; - if( g_pContext == NULL || p.bpp != CurrentParams.bpp || m_bWasWindowed != p.windowed ) + if( g_pContext == nullptr || p.bpp != CurrentParams.bpp || m_bWasWindowed != p.windowed ) { - bool bFirstRun = g_pContext == NULL; + bool bFirstRun = g_pContext == nullptr; // Different depth, or we didn't make a window before. New context. bNewDeviceOut = true; @@ -186,7 +186,7 @@ RString LowLevelWindow_X11::TryVideoMode( const VideoModeParams &p, bool &bNewDe visAttribs[i++] = None; XVisualInfo *xvi = glXChooseVisual( Dpy, DefaultScreen(Dpy), visAttribs ); - if( xvi == NULL ) + if( xvi == nullptr ) return "No visual available for that depth."; // I get strange behavior if I add override redirect after creating the window. @@ -205,7 +205,7 @@ RString LowLevelWindow_X11::TryVideoMode( const VideoModeParams &p, bool &bNewDe glXDestroyContext( Dpy, g_pContext ); if( g_pBackgroundContext ) glXDestroyContext( Dpy, g_pBackgroundContext ); - g_pContext = glXCreateContext( Dpy, xvi, NULL, True ); + g_pContext = glXCreateContext( Dpy, xvi, nullptr, True ); g_pBackgroundContext = glXCreateContext( Dpy, xvi, g_pContext, True ); glXMakeCurrent( Dpy, Win, g_pContext ); @@ -307,7 +307,7 @@ RString LowLevelWindow_X11::TryVideoMode( const VideoModeParams &p, bool &bNewDe LOG->Info("LowLevelWindow_X11: Using XRandR"); XRRScreenResources *scrRes = XRRGetScreenResources(Dpy, Win); - ASSERT(scrRes != NULL); + ASSERT(scrRes != nullptr); ASSERT(scrRes->ncrtc > 0); ASSERT(scrRes->noutput > 0); ASSERT(scrRes->nmode > 0); @@ -353,7 +353,7 @@ RString LowLevelWindow_X11::TryVideoMode( const VideoModeParams &p, bool &bNewDe // if the target output is not currently being driven by a crtc, // find an unused crtc that can be connected to it XRROutputInfo *tgtOutInfo = XRRGetOutputInfo( Dpy, scrRes, targetOut ); - if (tgtOutInfo == NULL) + if (tgtOutInfo == nullptr) { XRRFreeScreenResources(scrRes); return "Failed to find XRROutput"; @@ -748,7 +748,7 @@ void LowLevelWindow_X11::GetDisplaySpecs(DisplaySpecs &out) const { bool LowLevelWindow_X11::SupportsThreadedRendering() { - return g_pBackgroundContext != NULL; + return g_pBackgroundContext != nullptr; } class RenderTarget_X11: public RenderTarget @@ -780,9 +780,9 @@ RenderTarget_X11::RenderTarget_X11( LowLevelWindow_X11 *pWind ) { m_pWind = pWind; m_iPbuffer = 0; - m_pPbufferContext = NULL; + m_pPbufferContext = nullptr; m_iTexHandle = 0; - m_pOldContext = NULL; + m_pOldContext = nullptr; m_pOldDrawable = 0; } @@ -860,7 +860,7 @@ void RenderTarget_X11::Create( const RenderTargetParam ¶m, int &iTextureWidt iTextureHeightOut = iTextureHeight; glTexImage2D( GL_TEXTURE_2D, 0, param.bWithAlpha? GL_RGBA8:GL_RGB8, - iTextureWidth, iTextureHeight, 0, param.bWithAlpha? GL_RGBA:GL_RGB, GL_UNSIGNED_BYTE, NULL ); + iTextureWidth, iTextureHeight, 0, param.bWithAlpha? GL_RGBA:GL_RGB, GL_UNSIGNED_BYTE, nullptr ); GLenum error = glGetError(); ASSERT_M( error == GL_NO_ERROR, GLToString(error) ); @@ -897,7 +897,7 @@ void RenderTarget_X11::FinishRenderingTo() glBindTexture( GL_TEXTURE_2D, 0 ); glXMakeCurrent( Dpy, m_pOldDrawable, m_pOldContext ); - m_pOldContext = NULL; + m_pOldContext = nullptr; m_pOldDrawable = 0; } @@ -906,7 +906,7 @@ bool LowLevelWindow_X11::SupportsRenderToTexture() const { // Server must support pbuffers: const int iScreen = DefaultScreen( Dpy ); - float fVersion = strtof( glXQueryServerString(Dpy, iScreen, GLX_VERSION), NULL ); + float fVersion = strtof( glXQueryServerString(Dpy, iScreen, GLX_VERSION), nullptr ); if( fVersion < 1.3f ) return false; @@ -969,7 +969,7 @@ void LowLevelWindow_X11::BeginConcurrentRendering() void LowLevelWindow_X11::EndConcurrentRendering() { - bool b = glXMakeCurrent( Dpy, None, NULL ); + bool b = glXMakeCurrent( Dpy, None, nullptr ); ASSERT(b); } diff --git a/src/arch/MemoryCard/MemoryCardDriver.cpp b/src/arch/MemoryCard/MemoryCardDriver.cpp index 0b3f51351b..1b0b87e45c 100644 --- a/src/arch/MemoryCard/MemoryCardDriver.cpp +++ b/src/arch/MemoryCard/MemoryCardDriver.cpp @@ -2,7 +2,7 @@ #include "MemoryCardDriver.h" #include "RageFileManager.h" #include "RageLog.h" -#include "Foreach.h" + #include "ProfileManager.h" static const RString TEMP_MOUNT_POINT = "/@mctemptimeout/"; @@ -68,11 +68,11 @@ bool MemoryCardDriver::DoOneUpdate( bool bMount, vector& vStor GetUSBStorageDevices( vStorageDevicesOut ); // log connects - FOREACH( UsbStorageDevice, vStorageDevicesOut, newd ) + for (UsbStorageDevice &newd : vStorageDevicesOut) { - vector::iterator iter = find( vOld.begin(), vOld.end(), *newd ); + vector::iterator iter = find( vOld.begin(), vOld.end(), newd ); if( iter == vOld.end() ) // didn't find - LOG->Trace( "New device connected: %s", newd->sDevice.c_str() ); + LOG->Trace( "New device connected: %s", newd.sDevice.c_str() ); } /* When we first see a device, regardless of bMount, just return it as CHECKING, @@ -141,7 +141,7 @@ bool MemoryCardDriver::DoOneUpdate( bool bMount, vector& vStor #include "arch/arch_default.h" MemoryCardDriver *MemoryCardDriver::Create() { - MemoryCardDriver *ret = NULL; + MemoryCardDriver *ret = nullptr; switch( g_MemoryCardDriver ) { diff --git a/src/arch/MemoryCard/MemoryCardDriverThreaded_Folder.cpp b/src/arch/MemoryCard/MemoryCardDriverThreaded_Folder.cpp index b491647ba0..98d10d3f79 100644 --- a/src/arch/MemoryCard/MemoryCardDriverThreaded_Folder.cpp +++ b/src/arch/MemoryCard/MemoryCardDriverThreaded_Folder.cpp @@ -2,7 +2,6 @@ #include "MemoryCardDriverThreaded_Folder.h" #include "RageLog.h" #include "RageUtil.h" -#include "Foreach.h" #include "PlayerNumber.h" #include "MemoryCardManager.h" diff --git a/src/arch/MemoryCard/MemoryCardDriverThreaded_Linux.cpp b/src/arch/MemoryCard/MemoryCardDriverThreaded_Linux.cpp index e6ea69fa85..08c1ea5a02 100644 --- a/src/arch/MemoryCard/MemoryCardDriverThreaded_Linux.cpp +++ b/src/arch/MemoryCard/MemoryCardDriverThreaded_Linux.cpp @@ -83,7 +83,7 @@ static void GetFileList( const RString &sPath, vector &out ) out.clear(); DIR *dp = opendir( sPath ); - if( dp == NULL ) + if( dp == nullptr ) return; // false; // XXX warn while( const struct dirent *ent = readdir(dp) ) @@ -317,7 +317,7 @@ void MemoryCardDriverThreaded_Linux::GetUSBStorageDevices( vectorsOsMountDir.c_str(), RandomInt(100000)), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, NULL ); + nullptr, CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE, nullptr ); if( hFile == INVALID_HANDLE_VALUE ) { @@ -193,7 +193,7 @@ void MemoryCardDriverThreaded_Windows::Unmount( UsbStorageDevice* pDevice ) /* Try to flush the device before returning. This requires administrator priviliges. */ HANDLE hDevice = CreateFile( pDevice->sDevice, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); + nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr ); if( hDevice == INVALID_HANDLE_VALUE ) { diff --git a/src/arch/MovieTexture/MovieTexture.cpp b/src/arch/MovieTexture/MovieTexture.cpp index 8c9190117f..1f54e3928e 100644 --- a/src/arch/MovieTexture/MovieTexture.cpp +++ b/src/arch/MovieTexture/MovieTexture.cpp @@ -6,7 +6,7 @@ #include "PrefsManager.h" #include "RageFile.h" #include "LocalizedString.h" -#include "Foreach.h" + #include "arch/arch_default.h" void ForceToAscii( RString &str ) @@ -92,34 +92,35 @@ RageMovieTexture *RageMovieTexture::Create( RageTextureID ID ) if( DriversToTry.empty() ) RageException::Throw( "%s", MOVIE_DRIVERS_EMPTY.GetValue().c_str() ); - RageMovieTexture *ret = NULL; + RageMovieTexture *ret = nullptr; - FOREACH_CONST( RString, DriversToTry, Driver ) + for (RString const &Driver : DriversToTry) { - LOG->Trace( "Initializing driver: %s", Driver->c_str() ); - RageDriver *pDriverBase = RageMovieTextureDriver::m_pDriverList.Create( *Driver ); + char const * driverString = Driver.c_str(); + LOG->Trace( "Initializing driver: %s", driverString ); + RageDriver *pDriverBase = RageMovieTextureDriver::m_pDriverList.Create( Driver ); - if( pDriverBase == NULL ) + if( pDriverBase == nullptr ) { - LOG->Trace( "Unknown movie driver name: %s", Driver->c_str() ); + LOG->Trace( "Unknown movie driver name: %s", driverString ); continue; } RageMovieTextureDriver *pDriver = dynamic_cast( pDriverBase ); - ASSERT( pDriver != NULL ); + ASSERT( pDriver != nullptr ); RString sError; ret = pDriver->Create( ID, sError ); delete pDriver; - if( ret == NULL ) + if( ret == nullptr ) { - LOG->Trace( "Couldn't load driver %s: %s", Driver->c_str(), sError.c_str() ); + LOG->Trace( "Couldn't load driver %s: %s", driverString, sError.c_str() ); SAFE_DELETE( ret ); continue; } LOG->Trace( "Created movie texture \"%s\" with driver \"%s\"", - ID.filename.c_str(), Driver->c_str() ); + ID.filename.c_str(), driverString ); break; } if ( !ret ) diff --git a/src/arch/MovieTexture/MovieTexture_DShow.cpp b/src/arch/MovieTexture/MovieTexture_DShow.cpp index cac1360c7d..3a7accfc4f 100644 --- a/src/arch/MovieTexture/MovieTexture_DShow.cpp +++ b/src/arch/MovieTexture/MovieTexture_DShow.cpp @@ -1,580 +1,580 @@ -#include "global.h" - -#if defined(_MSC_VER) -/* XXX register thread */ -#pragma comment(lib, "winmm.lib") - -// Link with the DirectShow base class libraries -#if defined(DEBUG) - #pragma comment(lib, "baseclasses/debug/strmbasd.lib") -#else - #pragma comment(lib, "baseclasses/release/strmbase.lib") -#endif -#endif - -#include "MovieTexture_DShowHelper.h" -#include "MovieTexture_DShow.h" - -/* for TEXTUREMAN->GetTextureColorDepth() */ -#include "RageTextureManager.h" -#include "RageUtil.h" -#include "RageLog.h" -#include "RageException.h" -#include "RageSurface.h" -#include "arch/Dialog/Dialog.h" -#include "archutils/Win32/DirectXHelpers.h" - -#include /* for GetVideoCodecDebugInfo */ -#if defined(_MSC_VER) -#pragma comment(lib, "vfw32.lib") -#endif - -RageMovieTexture *RageMovieTextureDriver_DShow::Create( RageTextureID ID, RString &sError ) -{ - MovieTexture_DShow *pRet = new MovieTexture_DShow( ID ); - sError = pRet->Init(); - if( !sError.empty() ) - SAFE_DELETE( pRet ); - return pRet; -} - -REGISTER_MOVIE_TEXTURE_CLASS( DShow ); - -static RString FourCCToString( int fcc ) -{ - char c[4]; - c[0] = char((fcc >> 0) & 0xFF); - c[1] = char((fcc >> 8) & 0xFF); - c[2] = char((fcc >> 16) & 0xFF); - c[3] = char((fcc >> 24) & 0xFF); - - RString s; - for( int i = 0; i < 4; ++i ) - s += clamp( c[i], '\x20', '\x7e' ); - - return s; -} - -static void CheckCodecVersion( RString codec, RString desc ) -{ - if( !codec.CompareNoCase("DIVX") ) - { - /* "DivX 5.0.5 Codec" */ - Regex GetDivXVersion; - - int major, minor, rev; - if( sscanf( desc, "DivX %i.%i.%i", &major, &minor, &rev ) != 3 && - sscanf( desc, "DivX Pro %i.%i.%i", &major, &minor, &rev ) != 3 ) - { - LOG->Warn( "Couldn't parse DivX version \"%s\"", desc.c_str() ); - return; - } - - /* 5.0.0 through 5.0.4 are old and cause crashes. Warn. */ - if( major == 5 && minor == 0 && rev < 5 ) - { - Dialog::OK( - ssprintf("The version of DivX installed, %i.%i.%i, is out of date and may\n" - "cause instability. Please upgrade to DivX 5.0.5 or newer, available at:\n" - "\n" - "http://www.divx.com/", major, minor, rev), - desc ); - return; - } - } -} - - -static void GetVideoCodecDebugInfo() -{ - ICINFO info = { sizeof(ICINFO) }; - LOG->Info( "Video codecs:" ); - CHECKPOINT; - int i; - for( i=0; ICInfo(ICTYPE_VIDEO, i, &info); ++i ) - { - CHECKPOINT; - if( FourCCToString(info.fccHandler) == "ASV1" ) - { - /* Broken. */ - LOG->Info("%i: %s: skipped", i, FourCCToString(info.fccHandler).c_str()); - continue; - } - - LOG->Trace( "Scanning codec %s", FourCCToString(info.fccHandler).c_str() ); - CHECKPOINT; - HIC hic = ICOpen( info.fccType, info.fccHandler, ICMODE_DECOMPRESS ); - if( !hic ) - { - LOG->Info("Couldn't open video codec %s", - FourCCToString(info.fccHandler).c_str()); - continue; - } - - CHECKPOINT; - if( ICGetInfo(hic, &info, sizeof(ICINFO)) ) - { - CheckCodecVersion( FourCCToString(info.fccHandler), WStringToRString(info.szDescription) ); - CHECKPOINT; - - LOG->Info( " %s: %ls (%ls)", - FourCCToString(info.fccHandler).c_str(), info.szName, info.szDescription ); - } - else - LOG->Info( "ICGetInfo(%s) failed", FourCCToString(info.fccHandler).c_str() ); - - CHECKPOINT; - ICClose(hic); - } - - if( i == 0 ) - LOG->Info( " None found" ); -} - - -MovieTexture_DShow::MovieTexture_DShow( RageTextureID ID ) : - RageMovieTexture( ID ), - buffer_lock( "buffer_lock", 1 ), - buffer_finished( "buffer_finished", 0 ) -{ - LOG->Trace( "MovieTexture_DShow::MovieTexture_DShow()" ); - - static bool bFirst = true; - if( bFirst ) - { - bFirst = false; - GetVideoCodecDebugInfo(); - } - - m_bLoop = true; - m_bPlaying = false; - - m_uTexHandle = 0; - buffer = NULL; -} - -RString MovieTexture_DShow::Init() -{ - RString sError = Create(); - if( sError != "" ) - return sError; - - CreateFrameRects(); - - // flip all frame rects because movies are upside down - for( unsigned i=0; iTrace( "MovieTexture_DShow::~MovieTexture_DShow" ); - LOG->Flush(); - - SkipUpdates(); - - /* Shut down the graph. We can't call Stop() here, since that will - * call SkipUpdates again, which will deadlock if we call it twice - * in a row. */ - if( m_pGB ) - { - LOG->Trace( "MovieTexture_DShow: shutdown" ); - LOG->Flush(); - CComPtr pMC; - m_pGB.QueryInterface(&pMC); - - HRESULT hr; - if( FAILED( hr = pMC->Stop() ) ) - RageException::Throw( hr_ssprintf(hr, "Could not stop the DirectShow graph.") ); - -// Stop(); - m_pGB.Release(); - } - LOG->Trace( "MovieTexture_DShow: shutdown ok" ); - LOG->Flush(); - if( m_uTexHandle ) - DISPLAY->DeleteTexture( m_uTexHandle ); -} - -void MovieTexture_DShow::Reload() -{ - // do nothing -} - -/* If there's a frame waiting in the buffer, then the decoding thread put it there - * and is waiting for us to do something with it. */ -void MovieTexture_DShow::CheckFrame() -{ - if(buffer == NULL) - return; - - CHECKPOINT; - - /* Just in case we were invalidated: */ - CreateTexture(); - - // DirectShow feeds us in BGR8 - RageSurface *pFromDShow = CreateSurfaceFrom( - m_iSourceWidth, m_iSourceHeight, - 24, - 0xFF0000, - 0x00FF00, - 0x0000FF, - 0x000000, - (uint8_t *) buffer, m_iSourceWidth*3 ); - - /* - * Optimization notes: - * - * With D3D, this surface can be anything; it'll convert it on the fly. If - * it happens to exactly match the texture, it'll copy a little faster. - * - * With OpenGL, it's best that this be a real, supported texture format, though - * it doesn't need to be that of the actual texture. If it isn't, it'll have - * to do a very slow conversion. Both RGB8 and BGR8 are both (usually) valid - * formats. - */ - CHECKPOINT; - DISPLAY->UpdateTexture( - m_uTexHandle, - pFromDShow, - 0, 0, - m_iImageWidth, m_iImageHeight ); - CHECKPOINT; - - delete pFromDShow; - - buffer = NULL; - - CHECKPOINT; - - /* Start the decoding thread again. */ - buffer_finished.Post(); - - CHECKPOINT; -} - -void MovieTexture_DShow::Update(float fDeltaTime) -{ - CHECKPOINT; - - // restart the movie if we reach the end - if( m_bLoop ) - { - // Check for completion events - CComPtr pME; - m_pGB.QueryInterface(&pME); - - long lEventCode, lParam1, lParam2; - pME->GetEvent( &lEventCode, &lParam1, &lParam2, 0 ); - if( lEventCode == EC_COMPLETE ) - SetPosition(0); - } - - CHECKPOINT; - - CheckFrame(); -} - -RString PrintCodecError( HRESULT hr, RString s ) -{ - /* Actually, we might need XviD; we might want to look - * at the file and try to figure out if it's something - * common: DIV3, DIV4, DIV5, XVID, or maybe even MPEG2. */ - RString err = hr_ssprintf(hr, "%s", s.c_str()); - return - ssprintf( - "There was an error initializing a movie: %s.\n" - "Could not locate the DivX video codec.\n" - "DivX is required to movie textures and must\n" - "be installed before running the application.\n\n" - "Please visit http://www.divx.com to download the latest version.", - err.c_str() ); -} - -RString MovieTexture_DShow::GetActiveFilterList() -{ - RString ret; - - IEnumFilters *pEnum = NULL; - HRESULT hr = m_pGB->EnumFilters(&pEnum); - if (FAILED(hr)) - return hr_ssprintf(hr, "EnumFilters"); - - IBaseFilter *pF = NULL; - while( S_OK == pEnum->Next(1, &pF, 0) ) - { - FILTER_INFO FilterInfo; - pF->QueryFilterInfo( &FilterInfo ); - - if( ret != "" ) - ret += ", "; - ret += WStringToRString(FilterInfo.achName); - - if( FilterInfo.pGraph ) - FilterInfo.pGraph->Release(); - pF->Release(); - } - pEnum->Release(); - return ret; -} - -RString MovieTexture_DShow::Create() -{ - RageTextureID actualID = GetID(); - - HRESULT hr; - - actualID.iAlphaBits = 0; - - if( FAILED( hr=CoInitialize(NULL) ) ) - RageException::Throw( hr_ssprintf(hr, "Could not CoInitialize") ); - - // Create the filter graph - if( FAILED( hr=m_pGB.CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC) ) ) - RageException::Throw( hr_ssprintf(hr, "Could not create CLSID_FilterGraph!") ); - - // Create the Texture Renderer object - CTextureRenderer *pCTR = new CTextureRenderer; - - /* Get a pointer to the IBaseFilter on the TextureRenderer, and add it to the - * graph. When m_pGB is released, it will free pFTR. */ - CComPtr pFTR = pCTR; - if( FAILED( hr = m_pGB->AddFilter(pFTR, L"TEXTURERENDERER" ) ) ) - RageException::Throw( hr_ssprintf(hr, "Could not add renderer filter to graph!") ); - - // Add the source filter - CComPtr pFSrc; // Source Filter - wstring wFileName = RStringToWstring(actualID.filename); - - // if this fails, it's probably because the user doesn't have DivX installed - /* No, it also happens if the movie can't be opened for some reason; for example, - * if another program has it open and locked. Missing codecs probably won't - * show up until Connect(). */ - if( FAILED( hr = m_pGB->AddSourceFilter( wFileName.c_str(), wFileName.c_str(), &pFSrc ) ) ) - return PrintCodecError( hr, "Could not create source filter to graph!" ); - - // Find the source's output and the renderer's input - CComPtr pFTRPinIn; // Texture Renderer Input Pin - if( FAILED( hr = pFTR->FindPin( L"In", &pFTRPinIn ) ) ) - return hr_ssprintf(hr, "Could not find input pin" ); - - CComPtr pFSrcPinOut; // Source Filter Output Pin - if( FAILED( hr = pFSrc->FindPin( L"Output", &pFSrcPinOut ) ) ) - return hr_ssprintf( hr, "Could not find output pin" ); - - // Connect these two filters - if( FAILED( hr = m_pGB->Connect( pFSrcPinOut, pFTRPinIn ) ) ) - return PrintCodecError( hr, "Could not connect pins" ); - - LOG->Trace( "Filters: %s", GetActiveFilterList().c_str() ); - - // Pass us to our TextureRenderer. - pCTR->SetRenderTarget(this); - - /* Cap the max texture size to the hardware max. */ - actualID.iMaxSize = min( actualID.iMaxSize, DISPLAY->GetMaxTextureSize() ); - - // The graph is built, now get the set the output video width and height. - // The source and image width will always be the same since we can't scale the video - m_iSourceWidth = pCTR->GetVidWidth(); - m_iSourceHeight = pCTR->GetVidHeight(); - - /* image size cannot exceed max size */ - m_iImageWidth = min( m_iSourceWidth, actualID.iMaxSize ); - m_iImageHeight = min( m_iSourceHeight, actualID.iMaxSize ); - - /* Texture dimensions need to be a power of two; jump to the next. */ - m_iTextureWidth = power_of_two(m_iImageWidth); - m_iTextureHeight = power_of_two(m_iImageHeight); - - /* We've set up the movie, so we know the dimensions we need. Set - * up the texture. */ - CreateTexture(); - - /* Pausing the graph will cause only one frame to be rendered. Do that, then - * wait for the frame to be rendered, to guarantee that the texture is set - * when this function returns. */ - Pause(); - - CHECKPOINT; - pCTR->m_OneFrameDecoded.Wait(); - CHECKPOINT; - CheckFrame(); - CHECKPOINT; - - // Start the graph running - Play(); - - return RString(); -} - - -void MovieTexture_DShow::NewData(const char *data) -{ - ASSERT(data); - - /* Try to lock. */ - if( buffer_lock.TryWait() ) - { - /* The main thread is doing something uncommon, such as pausing. - * Drop this frame. */ - return; - } - - buffer = data; - - buffer_finished.Wait(); - - ASSERT( buffer == NULL ); - - buffer_lock.Post(); -} - - -void MovieTexture_DShow::CreateTexture() -{ - if( m_uTexHandle ) - return; - - RagePixelFormat pixfmt; - int depth = TEXTUREMAN->GetPrefs().m_iMovieColorDepth; - switch( depth ) - { - default: - FAIL_M(ssprintf("Unsupported movie color depth: %i", depth)); - case 16: - if( DISPLAY->SupportsTextureFormat(RagePixelFormat_RGB5) ) - pixfmt = RagePixelFormat_RGB5; - else - pixfmt = RagePixelFormat_RGBA4; // everything supports RGBA4 - break; - case 32: - if( DISPLAY->SupportsTextureFormat(RagePixelFormat_RGB8) ) - pixfmt = RagePixelFormat_RGB8; - else if( DISPLAY->SupportsTextureFormat(RagePixelFormat_RGBA8) ) - pixfmt = RagePixelFormat_RGBA8; - else if( DISPLAY->SupportsTextureFormat(RagePixelFormat_RGB5) ) - pixfmt = RagePixelFormat_RGB5; - else - pixfmt = RagePixelFormat_RGBA4; // everything supports RGBA4 - break; - } - - - const RageDisplay::RagePixelFormatDesc *pfd = DISPLAY->GetPixelFormatDesc(pixfmt); - RageSurface *img = CreateSurface( m_iTextureWidth, m_iTextureHeight, - pfd->bpp, pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3] ); - - m_uTexHandle = DISPLAY->CreateTexture( pixfmt, img, false ); - - delete img; -} - - -void MovieTexture_DShow::Play() -{ - SkipUpdates(); - - LOG->Trace("MovieTexture_DShow::Play()"); - CComPtr pMC; - m_pGB.QueryInterface(&pMC); - - // Start the graph running; - HRESULT hr; - if( FAILED(hr = pMC->Run()) ) - RageException::Throw( hr_ssprintf(hr, "Could not run the DirectShow graph.") ); - - m_bPlaying = true; - - StopSkippingUpdates(); -} - -void MovieTexture_DShow::Pause() -{ - SkipUpdates(); - - CComPtr pMC; - m_pGB.QueryInterface(&pMC); - - HRESULT hr; - /* Use Pause(), so we'll get a still frame in CTextureRenderer::OnReceiveFirstSample. */ - if( FAILED(hr = pMC->Pause()) ) - RageException::Throw( hr_ssprintf(hr, "Could not pause the DirectShow graph.") ); - - StopSkippingUpdates(); -} - - -void MovieTexture_DShow::SetPosition( float fSeconds ) -{ - SkipUpdates(); - - CComPtr pMP; - m_pGB.QueryInterface(&pMP); - pMP->put_CurrentPosition(0); - - StopSkippingUpdates(); -} - -void MovieTexture_DShow::SetPlaybackRate( float fRate ) -{ - if( fRate == 0 ) - { - this->Pause(); - return; - } - - SkipUpdates(); - - CComPtr pMP; - m_pGB.QueryInterface(&pMP); - HRESULT hr = pMP->put_Rate(fRate); // fails on many codecs - - StopSkippingUpdates(); - - if( FAILED(hr) ) - { - this->Pause(); - return; - } -} - -/* - * (c) 2001-2004 Chris Danford, Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" + +#if defined(_MSC_VER) +/* XXX register thread */ +#pragma comment(lib, "winmm.lib") + +// Link with the DirectShow base class libraries +#if defined(DEBUG) + #pragma comment(lib, "baseclasses/debug/strmbasd.lib") +#else + #pragma comment(lib, "baseclasses/release/strmbase.lib") +#endif +#endif + +#include "MovieTexture_DShowHelper.h" +#include "MovieTexture_DShow.h" + +/* for TEXTUREMAN->GetTextureColorDepth() */ +#include "RageTextureManager.h" +#include "RageUtil.h" +#include "RageLog.h" +#include "RageException.h" +#include "RageSurface.h" +#include "arch/Dialog/Dialog.h" +#include "archutils/Win32/DirectXHelpers.h" + +#include /* for GetVideoCodecDebugInfo */ +#if defined(_MSC_VER) +#pragma comment(lib, "vfw32.lib") +#endif + +RageMovieTexture *RageMovieTextureDriver_DShow::Create( RageTextureID ID, RString &sError ) +{ + MovieTexture_DShow *pRet = new MovieTexture_DShow( ID ); + sError = pRet->Init(); + if( !sError.empty() ) + SAFE_DELETE( pRet ); + return pRet; +} + +REGISTER_MOVIE_TEXTURE_CLASS( DShow ); + +static RString FourCCToString( int fcc ) +{ + char c[4]; + c[0] = char((fcc >> 0) & 0xFF); + c[1] = char((fcc >> 8) & 0xFF); + c[2] = char((fcc >> 16) & 0xFF); + c[3] = char((fcc >> 24) & 0xFF); + + RString s; + for( int i = 0; i < 4; ++i ) + s += clamp( c[i], '\x20', '\x7e' ); + + return s; +} + +static void CheckCodecVersion( RString codec, RString desc ) +{ + if( !codec.CompareNoCase("DIVX") ) + { + /* "DivX 5.0.5 Codec" */ + Regex GetDivXVersion; + + int major, minor, rev; + if( sscanf( desc, "DivX %i.%i.%i", &major, &minor, &rev ) != 3 && + sscanf( desc, "DivX Pro %i.%i.%i", &major, &minor, &rev ) != 3 ) + { + LOG->Warn( "Couldn't parse DivX version \"%s\"", desc.c_str() ); + return; + } + + /* 5.0.0 through 5.0.4 are old and cause crashes. Warn. */ + if( major == 5 && minor == 0 && rev < 5 ) + { + Dialog::OK( + ssprintf("The version of DivX installed, %i.%i.%i, is out of date and may\n" + "cause instability. Please upgrade to DivX 5.0.5 or newer, available at:\n" + "\n" + "http://www.divx.com/", major, minor, rev), + desc ); + return; + } + } +} + + +static void GetVideoCodecDebugInfo() +{ + ICINFO info = { sizeof(ICINFO) }; + LOG->Info( "Video codecs:" ); + CHECKPOINT; + int i; + for( i=0; ICInfo(ICTYPE_VIDEO, i, &info); ++i ) + { + CHECKPOINT; + if( FourCCToString(info.fccHandler) == "ASV1" ) + { + /* Broken. */ + LOG->Info("%i: %s: skipped", i, FourCCToString(info.fccHandler).c_str()); + continue; + } + + LOG->Trace( "Scanning codec %s", FourCCToString(info.fccHandler).c_str() ); + CHECKPOINT; + HIC hic = ICOpen( info.fccType, info.fccHandler, ICMODE_DECOMPRESS ); + if( !hic ) + { + LOG->Info("Couldn't open video codec %s", + FourCCToString(info.fccHandler).c_str()); + continue; + } + + CHECKPOINT; + if( ICGetInfo(hic, &info, sizeof(ICINFO)) ) + { + CheckCodecVersion( FourCCToString(info.fccHandler), WStringToRString(info.szDescription) ); + CHECKPOINT; + + LOG->Info( " %s: %ls (%ls)", + FourCCToString(info.fccHandler).c_str(), info.szName, info.szDescription ); + } + else + LOG->Info( "ICGetInfo(%s) failed", FourCCToString(info.fccHandler).c_str() ); + + CHECKPOINT; + ICClose(hic); + } + + if( i == 0 ) + LOG->Info( " None found" ); +} + + +MovieTexture_DShow::MovieTexture_DShow( RageTextureID ID ) : + RageMovieTexture( ID ), + buffer_lock( "buffer_lock", 1 ), + buffer_finished( "buffer_finished", 0 ) +{ + LOG->Trace( "MovieTexture_DShow::MovieTexture_DShow()" ); + + static bool bFirst = true; + if( bFirst ) + { + bFirst = false; + GetVideoCodecDebugInfo(); + } + + m_bLoop = true; + m_bPlaying = false; + + m_uTexHandle = 0; + buffer = nullptr; +} + +RString MovieTexture_DShow::Init() +{ + RString sError = Create(); + if( sError != "" ) + return sError; + + CreateFrameRects(); + + // flip all frame rects because movies are upside down + for( unsigned i=0; iTrace( "MovieTexture_DShow::~MovieTexture_DShow" ); + LOG->Flush(); + + SkipUpdates(); + + /* Shut down the graph. We can't call Stop() here, since that will + * call SkipUpdates again, which will deadlock if we call it twice + * in a row. */ + if( m_pGB ) + { + LOG->Trace( "MovieTexture_DShow: shutdown" ); + LOG->Flush(); + CComPtr pMC; + m_pGB.QueryInterface(&pMC); + + HRESULT hr; + if( FAILED( hr = pMC->Stop() ) ) + RageException::Throw( hr_ssprintf(hr, "Could not stop the DirectShow graph.") ); + +// Stop(); + m_pGB.Release(); + } + LOG->Trace( "MovieTexture_DShow: shutdown ok" ); + LOG->Flush(); + if( m_uTexHandle ) + DISPLAY->DeleteTexture( m_uTexHandle ); +} + +void MovieTexture_DShow::Reload() +{ + // do nothing +} + +/* If there's a frame waiting in the buffer, then the decoding thread put it there + * and is waiting for us to do something with it. */ +void MovieTexture_DShow::CheckFrame() +{ + if(buffer == nullptr) + return; + + CHECKPOINT; + + /* Just in case we were invalidated: */ + CreateTexture(); + + // DirectShow feeds us in BGR8 + RageSurface *pFromDShow = CreateSurfaceFrom( + m_iSourceWidth, m_iSourceHeight, + 24, + 0xFF0000, + 0x00FF00, + 0x0000FF, + 0x000000, + (uint8_t *) buffer, m_iSourceWidth*3 ); + + /* + * Optimization notes: + * + * With D3D, this surface can be anything; it'll convert it on the fly. If + * it happens to exactly match the texture, it'll copy a little faster. + * + * With OpenGL, it's best that this be a real, supported texture format, though + * it doesn't need to be that of the actual texture. If it isn't, it'll have + * to do a very slow conversion. Both RGB8 and BGR8 are both (usually) valid + * formats. + */ + CHECKPOINT; + DISPLAY->UpdateTexture( + m_uTexHandle, + pFromDShow, + 0, 0, + m_iImageWidth, m_iImageHeight ); + CHECKPOINT; + + delete pFromDShow; + + buffer = nullptr; + + CHECKPOINT; + + /* Start the decoding thread again. */ + buffer_finished.Post(); + + CHECKPOINT; +} + +void MovieTexture_DShow::Update(float fDeltaTime) +{ + CHECKPOINT; + + // restart the movie if we reach the end + if( m_bLoop ) + { + // Check for completion events + CComPtr pME; + m_pGB.QueryInterface(&pME); + + long lEventCode, lParam1, lParam2; + pME->GetEvent( &lEventCode, &lParam1, &lParam2, 0 ); + if( lEventCode == EC_COMPLETE ) + SetPosition(0); + } + + CHECKPOINT; + + CheckFrame(); +} + +RString PrintCodecError( HRESULT hr, RString s ) +{ + /* Actually, we might need XviD; we might want to look + * at the file and try to figure out if it's something + * common: DIV3, DIV4, DIV5, XVID, or maybe even MPEG2. */ + RString err = hr_ssprintf(hr, "%s", s.c_str()); + return + ssprintf( + "There was an error initializing a movie: %s.\n" + "Could not locate the DivX video codec.\n" + "DivX is required to movie textures and must\n" + "be installed before running the application.\n\n" + "Please visit http://www.divx.com to download the latest version.", + err.c_str() ); +} + +RString MovieTexture_DShow::GetActiveFilterList() +{ + RString ret; + + IEnumFilters *pEnum = nullptr; + HRESULT hr = m_pGB->EnumFilters(&pEnum); + if (FAILED(hr)) + return hr_ssprintf(hr, "EnumFilters"); + + IBaseFilter *pF = nullptr; + while( S_OK == pEnum->Next(1, &pF, 0) ) + { + FILTER_INFO FilterInfo; + pF->QueryFilterInfo( &FilterInfo ); + + if( ret != "" ) + ret += ", "; + ret += WStringToRString(FilterInfo.achName); + + if( FilterInfo.pGraph ) + FilterInfo.pGraph->Release(); + pF->Release(); + } + pEnum->Release(); + return ret; +} + +RString MovieTexture_DShow::Create() +{ + RageTextureID actualID = GetID(); + + HRESULT hr; + + actualID.iAlphaBits = 0; + + if( FAILED( hr=CoInitialize(nullptr) ) ) + RageException::Throw( hr_ssprintf(hr, "Could not CoInitialize") ); + + // Create the filter graph + if( FAILED( hr=m_pGB.CoCreateInstance(CLSID_FilterGraph, nullptr, CLSCTX_INPROC) ) ) + RageException::Throw( hr_ssprintf(hr, "Could not create CLSID_FilterGraph!") ); + + // Create the Texture Renderer object + CTextureRenderer *pCTR = new CTextureRenderer; + + /* Get a pointer to the IBaseFilter on the TextureRenderer, and add it to the + * graph. When m_pGB is released, it will free pFTR. */ + CComPtr pFTR = pCTR; + if( FAILED( hr = m_pGB->AddFilter(pFTR, L"TEXTURERENDERER" ) ) ) + RageException::Throw( hr_ssprintf(hr, "Could not add renderer filter to graph!") ); + + // Add the source filter + CComPtr pFSrc; // Source Filter + wstring wFileName = RStringToWstring(actualID.filename); + + // if this fails, it's probably because the user doesn't have DivX installed + /* No, it also happens if the movie can't be opened for some reason; for example, + * if another program has it open and locked. Missing codecs probably won't + * show up until Connect(). */ + if( FAILED( hr = m_pGB->AddSourceFilter( wFileName.c_str(), wFileName.c_str(), &pFSrc ) ) ) + return PrintCodecError( hr, "Could not create source filter to graph!" ); + + // Find the source's output and the renderer's input + CComPtr pFTRPinIn; // Texture Renderer Input Pin + if( FAILED( hr = pFTR->FindPin( L"In", &pFTRPinIn ) ) ) + return hr_ssprintf(hr, "Could not find input pin" ); + + CComPtr pFSrcPinOut; // Source Filter Output Pin + if( FAILED( hr = pFSrc->FindPin( L"Output", &pFSrcPinOut ) ) ) + return hr_ssprintf( hr, "Could not find output pin" ); + + // Connect these two filters + if( FAILED( hr = m_pGB->Connect( pFSrcPinOut, pFTRPinIn ) ) ) + return PrintCodecError( hr, "Could not connect pins" ); + + LOG->Trace( "Filters: %s", GetActiveFilterList().c_str() ); + + // Pass us to our TextureRenderer. + pCTR->SetRenderTarget(this); + + /* Cap the max texture size to the hardware max. */ + actualID.iMaxSize = min( actualID.iMaxSize, DISPLAY->GetMaxTextureSize() ); + + // The graph is built, now get the set the output video width and height. + // The source and image width will always be the same since we can't scale the video + m_iSourceWidth = pCTR->GetVidWidth(); + m_iSourceHeight = pCTR->GetVidHeight(); + + /* image size cannot exceed max size */ + m_iImageWidth = min( m_iSourceWidth, actualID.iMaxSize ); + m_iImageHeight = min( m_iSourceHeight, actualID.iMaxSize ); + + /* Texture dimensions need to be a power of two; jump to the next. */ + m_iTextureWidth = power_of_two(m_iImageWidth); + m_iTextureHeight = power_of_two(m_iImageHeight); + + /* We've set up the movie, so we know the dimensions we need. Set + * up the texture. */ + CreateTexture(); + + /* Pausing the graph will cause only one frame to be rendered. Do that, then + * wait for the frame to be rendered, to guarantee that the texture is set + * when this function returns. */ + Pause(); + + CHECKPOINT; + pCTR->m_OneFrameDecoded.Wait(); + CHECKPOINT; + CheckFrame(); + CHECKPOINT; + + // Start the graph running + Play(); + + return RString(); +} + + +void MovieTexture_DShow::NewData(const char *data) +{ + ASSERT(data); + + /* Try to lock. */ + if( buffer_lock.TryWait() ) + { + /* The main thread is doing something uncommon, such as pausing. + * Drop this frame. */ + return; + } + + buffer = data; + + buffer_finished.Wait(); + + ASSERT( buffer == nullptr ); + + buffer_lock.Post(); +} + + +void MovieTexture_DShow::CreateTexture() +{ + if( m_uTexHandle ) + return; + + RagePixelFormat pixfmt; + int depth = TEXTUREMAN->GetPrefs().m_iMovieColorDepth; + switch( depth ) + { + default: + FAIL_M(ssprintf("Unsupported movie color depth: %i", depth)); + case 16: + if( DISPLAY->SupportsTextureFormat(RagePixelFormat_RGB5) ) + pixfmt = RagePixelFormat_RGB5; + else + pixfmt = RagePixelFormat_RGBA4; // everything supports RGBA4 + break; + case 32: + if( DISPLAY->SupportsTextureFormat(RagePixelFormat_RGB8) ) + pixfmt = RagePixelFormat_RGB8; + else if( DISPLAY->SupportsTextureFormat(RagePixelFormat_RGBA8) ) + pixfmt = RagePixelFormat_RGBA8; + else if( DISPLAY->SupportsTextureFormat(RagePixelFormat_RGB5) ) + pixfmt = RagePixelFormat_RGB5; + else + pixfmt = RagePixelFormat_RGBA4; // everything supports RGBA4 + break; + } + + + const RageDisplay::RagePixelFormatDesc *pfd = DISPLAY->GetPixelFormatDesc(pixfmt); + RageSurface *img = CreateSurface( m_iTextureWidth, m_iTextureHeight, + pfd->bpp, pfd->masks[0], pfd->masks[1], pfd->masks[2], pfd->masks[3] ); + + m_uTexHandle = DISPLAY->CreateTexture( pixfmt, img, false ); + + delete img; +} + + +void MovieTexture_DShow::Play() +{ + SkipUpdates(); + + LOG->Trace("MovieTexture_DShow::Play()"); + CComPtr pMC; + m_pGB.QueryInterface(&pMC); + + // Start the graph running; + HRESULT hr; + if( FAILED(hr = pMC->Run()) ) + RageException::Throw( hr_ssprintf(hr, "Could not run the DirectShow graph.") ); + + m_bPlaying = true; + + StopSkippingUpdates(); +} + +void MovieTexture_DShow::Pause() +{ + SkipUpdates(); + + CComPtr pMC; + m_pGB.QueryInterface(&pMC); + + HRESULT hr; + /* Use Pause(), so we'll get a still frame in CTextureRenderer::OnReceiveFirstSample. */ + if( FAILED(hr = pMC->Pause()) ) + RageException::Throw( hr_ssprintf(hr, "Could not pause the DirectShow graph.") ); + + StopSkippingUpdates(); +} + + +void MovieTexture_DShow::SetPosition( float fSeconds ) +{ + SkipUpdates(); + + CComPtr pMP; + m_pGB.QueryInterface(&pMP); + pMP->put_CurrentPosition(0); + + StopSkippingUpdates(); +} + +void MovieTexture_DShow::SetPlaybackRate( float fRate ) +{ + if( fRate == 0 ) + { + this->Pause(); + return; + } + + SkipUpdates(); + + CComPtr pMP; + m_pGB.QueryInterface(&pMP); + HRESULT hr = pMP->put_Rate(fRate); // fails on many codecs + + StopSkippingUpdates(); + + if( FAILED(hr) ) + { + this->Pause(); + return; + } +} + +/* + * (c) 2001-2004 Chris Danford, Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/arch/MovieTexture/MovieTexture_DShowHelper.cpp b/src/arch/MovieTexture/MovieTexture_DShowHelper.cpp index 11905a2c47..47f61f4a2e 100644 --- a/src/arch/MovieTexture/MovieTexture_DShowHelper.cpp +++ b/src/arch/MovieTexture/MovieTexture_DShowHelper.cpp @@ -13,13 +13,13 @@ struct __declspec(uuid("{71771540-2017-11cf-ae26-0020afd79767}")) CLSID_TextureR static HRESULT CBV_ret; CTextureRenderer::CTextureRenderer(): CBaseVideoRenderer(__uuidof(CLSID_TextureRenderer), - NAME("Texture Renderer"), NULL, &CBV_ret), + NAME("Texture Renderer"), nullptr, &CBV_ret), m_OneFrameDecoded( "m_OneFrameDecoded", 0 ) { if( FAILED(CBV_ret) ) RageException::Throw( hr_ssprintf(CBV_ret, "Could not create texture renderer object!") ); - m_pTexture = NULL; + m_pTexture = nullptr; } CTextureRenderer::~CTextureRenderer() @@ -69,9 +69,9 @@ void CTextureRenderer::SetRenderTarget( MovieTexture_DShow* pTexture ) // DoRenderSample: A sample has been delivered. Copy it. HRESULT CTextureRenderer::DoRenderSample( IMediaSample * pSample ) { - if( m_pTexture == NULL ) + if( m_pTexture == nullptr ) { - LOG->Warn( "DoRenderSample called while m_pTexture was NULL!" ); + LOG->Warn( "DoRenderSample called while m_pTexture was nullptr!" ); return S_OK; } diff --git a/src/arch/MovieTexture/MovieTexture_FFMpeg.cpp b/src/arch/MovieTexture/MovieTexture_FFMpeg.cpp index 8aec20d37f..812236bb78 100644 --- a/src/arch/MovieTexture/MovieTexture_FFMpeg.cpp +++ b/src/arch/MovieTexture/MovieTexture_FFMpeg.cpp @@ -109,8 +109,8 @@ MovieDecoder_FFMpeg::MovieDecoder_FFMpeg() { FixLilEndian(); - m_fctx = NULL; - m_pStream = NULL; + m_fctx = nullptr; + m_pStream = nullptr; m_iCurrentPacketOffset = -1; m_Frame = avcodec::av_frame_alloc(); @@ -127,21 +127,21 @@ MovieDecoder_FFMpeg::~MovieDecoder_FFMpeg() if (m_swsctx) { avcodec::sws_freeContext(m_swsctx); - m_swsctx = NULL; + m_swsctx = nullptr; } - if (m_avioContext != NULL ) + if (m_avioContext != nullptr ) { RageFile *file = (RageFile *)m_avioContext->opaque; file->Close(); delete file; avcodec::av_free(m_avioContext); } - if ( m_buffer != NULL ) + if ( m_buffer != nullptr ) { avcodec::av_free(m_buffer); } #if LIBAVCODEC_VERSION_MAJOR >= 58 - if ( m_pStreamCodec != NULL) + if ( m_pStreamCodec != nullptr) { avcodec::avcodec_free_context(&m_pStreamCodec); } @@ -156,9 +156,9 @@ void MovieDecoder_FFMpeg::Init() m_iFrameNumber = -1; /* decode one frame and you're on the 0th */ m_fTimestampOffset = 0; m_fLastFrame = 0; - m_swsctx = NULL; - m_avioContext = NULL; - m_buffer = NULL; + m_swsctx = nullptr; + m_avioContext = nullptr; + m_buffer = nullptr; if( m_iCurrentPacketOffset != -1 ) { @@ -277,7 +277,7 @@ int MovieDecoder_FFMpeg::DecodePacket( float fTargetTime ) int len; /* Hack: we need to send size = 0 to flush frames at the end, but we have * to give it a buffer to read from since it tries to read anyway. */ - m_Packet.data = m_Packet.size ? m_Packet.data : NULL; + m_Packet.data = m_Packet.size ? m_Packet.data : nullptr; #if LIBAVCODEC_VERSION_MAJOR < 58 len = avcodec::avcodec_decode_video2( m_pStreamCodec, @@ -360,13 +360,13 @@ void MovieDecoder_FFMpeg::GetFrame( RageSurface *pSurface ) * XXX 2: The problem of doing this in Open() is that m_AVTexfmt is not * already initialized with its correct value. */ - if( m_swsctx == NULL ) + if( m_swsctx == nullptr ) { m_swsctx = avcodec::sws_getCachedContext( m_swsctx, GetWidth(), GetHeight(), m_pStreamCodec->pix_fmt, GetWidth(), GetHeight(), m_AVTexfmt, - sws_flags, NULL, NULL, NULL ); - if( m_swsctx == NULL ) + sws_flags, nullptr, nullptr, nullptr ); + if( m_swsctx == nullptr ) { LOG->Warn("Cannot initialize sws conversion context for (%d,%d) %d->%d", GetWidth(), GetHeight(), m_pStreamCodec->pix_fmt, m_AVTexfmt); return; @@ -449,24 +449,24 @@ RString MovieDecoder_FFMpeg::Open( RString sFile ) } m_buffer = (unsigned char *)avcodec::av_malloc(STEPMANIA_FFMPEG_BUFFER_SIZE); - m_avioContext = avcodec::avio_alloc_context(m_buffer, STEPMANIA_FFMPEG_BUFFER_SIZE, 0, f, AVIORageFile_ReadPacket, NULL, AVIORageFile_Seek); + m_avioContext = avcodec::avio_alloc_context(m_buffer, STEPMANIA_FFMPEG_BUFFER_SIZE, 0, f, AVIORageFile_ReadPacket, nullptr, AVIORageFile_Seek); m_fctx->pb = m_avioContext; - int ret = avcodec::avformat_open_input( &m_fctx, sFile.c_str(), NULL, NULL ); + int ret = avcodec::avformat_open_input( &m_fctx, sFile.c_str(), nullptr, nullptr ); if( ret < 0 ) return RString( averr_ssprintf(ret, "AVCodec: Couldn't open \"%s\"", sFile.c_str()) ); - ret = avcodec::avformat_find_stream_info( m_fctx, NULL ); + ret = avcodec::avformat_find_stream_info( m_fctx, nullptr ); if( ret < 0 ) return RString( averr_ssprintf(ret, "AVCodec (%s): Couldn't find codec parameters", sFile.c_str()) ); - int stream_idx = avcodec::av_find_best_stream( m_fctx, avcodec::AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0 ); + int stream_idx = avcodec::av_find_best_stream( m_fctx, avcodec::AVMEDIA_TYPE_VIDEO, -1, -1, nullptr, 0 ); if ( stream_idx < 0 || static_cast(stream_idx) >= m_fctx->nb_streams || - m_fctx->streams[stream_idx] == NULL ) + m_fctx->streams[stream_idx] == nullptr ) return "Couldn't find any video streams"; m_pStream = m_fctx->streams[stream_idx]; #if LIBAVCODEC_VERSION_MAJOR >= 58 - m_pStreamCodec = avcodec::avcodec_alloc_context3(NULL); + m_pStreamCodec = avcodec::avcodec_alloc_context3(nullptr); if (avcodec::avcodec_parameters_to_context(m_pStreamCodec, m_pStream->codecpar) < 0) return ssprintf("Could not get context from parameters"); #else @@ -490,12 +490,12 @@ RString MovieDecoder_FFMpeg::OpenCodec() { Init(); - ASSERT( m_pStream != NULL ); + ASSERT( m_pStream != nullptr ); if( m_pStreamCodec->codec ) avcodec::avcodec_close( m_pStreamCodec ); avcodec::AVCodec *pCodec = avcodec::avcodec_find_decoder( m_pStreamCodec->codec_id ); - if( pCodec == NULL ) + if( pCodec == nullptr ) return ssprintf( "Couldn't find decoder %i", m_pStreamCodec->codec_id ); m_pStreamCodec->workaround_bugs = 1; @@ -509,10 +509,10 @@ RString MovieDecoder_FFMpeg::OpenCodec() LOG->Trace("Opening codec %s", pCodec->name ); - int ret = avcodec::avcodec_open2( m_pStreamCodec, pCodec, NULL ); + int ret = avcodec::avcodec_open2( m_pStreamCodec, pCodec, nullptr ); if( ret < 0 ) return RString( averr_ssprintf(ret, "Couldn't open codec \"%s\"", pCodec->name) ); - ASSERT( m_pStreamCodec->codec != NULL ); + ASSERT( m_pStreamCodec->codec != nullptr ); return RString(); } @@ -522,13 +522,13 @@ void MovieDecoder_FFMpeg::Close() if( m_pStream && m_pStreamCodec->codec ) { avcodec::avcodec_close( m_pStreamCodec ); - m_pStream = NULL; + m_pStream = nullptr; } if( m_fctx ) { avcodec::avformat_close_input( &m_fctx ); - m_fctx = NULL; + m_fctx = nullptr; } Init(); diff --git a/src/arch/MovieTexture/MovieTexture_Generic.cpp b/src/arch/MovieTexture/MovieTexture_Generic.cpp index ccf96fddea..a23fd43bfd 100644 --- a/src/arch/MovieTexture/MovieTexture_Generic.cpp +++ b/src/arch/MovieTexture/MovieTexture_Generic.cpp @@ -25,11 +25,11 @@ MovieTexture_Generic::MovieTexture_Generic( RageTextureID ID, MovieDecoder *pDec m_pDecoder = pDecoder; m_uTexHandle = 0; - m_pRenderTarget = NULL; - m_pTextureIntermediate = NULL; + m_pRenderTarget = nullptr; + m_pTextureIntermediate = nullptr; m_bLoop = true; - m_pSurface = NULL; - m_pTextureLock = NULL; + m_pSurface = nullptr; + m_pTextureLock = nullptr; m_ImageWaiting = FRAME_NONE; m_fRate = 1; m_bWantRewind = false; @@ -88,10 +88,10 @@ MovieTexture_Generic::~MovieTexture_Generic() void MovieTexture_Generic::DestroyTexture() { delete m_pSurface; - m_pSurface = NULL; + m_pSurface = nullptr; delete m_pTextureLock; - m_pTextureLock = NULL; + m_pTextureLock = nullptr; if( m_uTexHandle ) { @@ -100,9 +100,9 @@ void MovieTexture_Generic::DestroyTexture() } delete m_pRenderTarget; - m_pRenderTarget = NULL; + m_pRenderTarget = nullptr; delete m_pTextureIntermediate; - m_pTextureIntermediate = NULL; + m_pTextureIntermediate = nullptr; } class RageMovieTexture_Generic_Intermediate : public RageTexture @@ -162,7 +162,7 @@ private: m_SurfaceFormat.Mask[0], m_SurfaceFormat.Mask[1], m_SurfaceFormat.Mask[2], - m_SurfaceFormat.Mask[3], NULL, 1 ); + m_SurfaceFormat.Mask[3], nullptr, 1 ); m_uTexHandle = DISPLAY->CreateTexture( m_PixFmt, pSurface, false ); delete pSurface; @@ -176,16 +176,16 @@ private: void MovieTexture_Generic::Invalidate() { m_uTexHandle = 0; - if( m_pTextureIntermediate != NULL ) + if( m_pTextureIntermediate != nullptr ) m_pTextureIntermediate->Invalidate(); } void MovieTexture_Generic::CreateTexture() { - if( m_uTexHandle || m_pRenderTarget != NULL ) + if( m_uTexHandle || m_pRenderTarget != nullptr ) return; - CHECKPOINT_M("About to create a generic texture."); + CHECKPOINT; m_iSourceWidth = m_pDecoder->GetWidth(); m_iSourceHeight = m_pDecoder->GetHeight(); @@ -207,18 +207,18 @@ void MovieTexture_Generic::CreateTexture() m_iTextureWidth = power_of_two( m_iImageWidth ); m_iTextureHeight = power_of_two( m_iImageHeight ); MovieDecoderPixelFormatYCbCr fmt = PixelFormatYCbCr_Invalid; - if( m_pSurface == NULL ) + if( m_pSurface == nullptr ) { - ASSERT( m_pTextureLock == NULL ); + ASSERT( m_pTextureLock == nullptr ); if( g_bMovieTextureDirectUpdates ) m_pTextureLock = DISPLAY->CreateTextureLock(); m_pSurface = m_pDecoder->CreateCompatibleSurface( m_iImageWidth, m_iImageHeight, TEXTUREMAN->GetPrefs().m_iMovieColorDepth == 32, fmt ); - if( m_pTextureLock != NULL ) + if( m_pTextureLock != nullptr ) { delete [] m_pSurface->pixels; - m_pSurface->pixels = NULL; + m_pSurface->pixels = nullptr; } } @@ -447,22 +447,22 @@ void MovieTexture_Generic::UpdateFrame() /* Just in case we were invalidated: */ CreateTexture(); - if( m_pTextureLock != NULL ) + if( m_pTextureLock != nullptr ) { - int iHandle = m_pTextureIntermediate != NULL? m_pTextureIntermediate->GetTexHandle(): this->GetTexHandle(); + int iHandle = m_pTextureIntermediate != nullptr? m_pTextureIntermediate->GetTexHandle(): this->GetTexHandle(); m_pTextureLock->Lock( iHandle, m_pSurface ); } m_pDecoder->GetFrame( m_pSurface ); - if( m_pTextureLock != NULL ) + if( m_pTextureLock != nullptr ) m_pTextureLock->Unlock( m_pSurface, true ); - if( m_pRenderTarget != NULL ) + if( m_pRenderTarget != nullptr ) { CHECKPOINT_M( "About to upload the texture."); /* If we have no m_pTextureLock, we still have to upload the texture. */ - if( m_pTextureLock == NULL ) + if( m_pTextureLock == nullptr ) { DISPLAY->UpdateTexture( m_pTextureIntermediate->GetTexHandle(), @@ -476,7 +476,7 @@ void MovieTexture_Generic::UpdateFrame() } else { - if( m_pTextureLock == NULL ) + if( m_pTextureLock == nullptr ) { DISPLAY->UpdateTexture( m_uTexHandle, @@ -520,7 +520,7 @@ void MovieTexture_Generic::SetPosition( float fSeconds ) unsigned MovieTexture_Generic::GetTexHandle() const { - if( m_pRenderTarget != NULL ) + if( m_pRenderTarget != nullptr ) return m_pRenderTarget->GetTexHandle(); return m_uTexHandle; diff --git a/src/arch/RageDriver.cpp b/src/arch/RageDriver.cpp index 5301b1ec85..d996e23553 100644 --- a/src/arch/RageDriver.cpp +++ b/src/arch/RageDriver.cpp @@ -3,7 +3,7 @@ void DriverList::Add( const istring &sName, CreateRageDriverFn pfn ) { - if( m_pRegistrees == NULL ) + if( m_pRegistrees == nullptr ) m_pRegistrees = new map; ASSERT( m_pRegistrees->find(sName) == m_pRegistrees->end() ); @@ -12,12 +12,12 @@ void DriverList::Add( const istring &sName, CreateRageDriverFn pfn ) RageDriver *DriverList::Create( const RString &sDriverName ) { - if( m_pRegistrees == NULL ) - return NULL; + if( m_pRegistrees == nullptr ) + return nullptr; map::const_iterator iter = m_pRegistrees->find( istring(sDriverName) ); if( iter == m_pRegistrees->end() ) - return NULL; + return nullptr; return (iter->second)(); } diff --git a/src/arch/Sound/ALSA9Dynamic.cpp b/src/arch/Sound/ALSA9Dynamic.cpp index d8b4780db7..12b83a6452 100644 --- a/src/arch/Sound/ALSA9Dynamic.cpp +++ b/src/arch/Sound/ALSA9Dynamic.cpp @@ -6,13 +6,13 @@ #define ALSA_PCM_NEW_SW_PARAMS_API #include -static void *Handle = NULL; +static void *Handle = nullptr; #include "RageUtil.h" #include "ALSA9Dynamic.h" -/* foo_f dfoo = NULL */ -#define FUNC(ret, name, proto) name##_f d##name = NULL +/* foo_f dfoo = nullptr */ +#define FUNC(ret, name, proto) name##_f d##name = nullptr #include "ALSA9Functions.h" #undef FUNC @@ -31,10 +31,10 @@ RString LoadALSA() if( !IsADirectory("/rootfs/proc/asound/") ) return "/proc/asound/ does not exist"; - ASSERT( Handle == NULL ); + ASSERT( Handle == nullptr ); Handle = dlopen( lib, RTLD_NOW ); - if( Handle == NULL ) + if( Handle == nullptr ) return ssprintf("dlopen(%s): %s", lib.c_str(), dlerror()); RString error; @@ -62,8 +62,8 @@ void UnloadALSA() { if( Handle ) dlclose( Handle ); - Handle = NULL; -#define FUNC(ret, name, proto) d##name = NULL; + Handle = nullptr; +#define FUNC(ret, name, proto) d##name = nullptr; #include "ALSA9Functions.h" #undef FUNC } diff --git a/src/arch/Sound/ALSA9Helpers.cpp b/src/arch/Sound/ALSA9Helpers.cpp index caf02920a7..4199e81427 100644 --- a/src/arch/Sound/ALSA9Helpers.cpp +++ b/src/arch/Sound/ALSA9Helpers.cpp @@ -1,462 +1,462 @@ -#include "global.h" -#include "RageLog.h" -#include "RageUtil.h" -#include "ALSA9Helpers.h" -#include "ALSA9Dynamic.h" -#include "PrefsManager.h" - -/* int err; must be defined before using this macro */ -#define ALSA_CHECK(x) \ - if ( err < 0 ) { LOG->Info("ALSA: %s: %s", x, dsnd_strerror(err)); return false; } -#define ALSA_ASSERT(x) \ - if (err < 0) { LOG->Warn("ALSA: %s: %s", x, dsnd_strerror(err)); } - -bool Alsa9Buf::SetHWParams() -{ - int err; - - if( dsnd_pcm_state(pcm) == SND_PCM_STATE_PREPARED ) - dsnd_pcm_drop( pcm ); - - if( dsnd_pcm_state(pcm) != SND_PCM_STATE_OPEN ) - { - /* Reset the stream to SND_PCM_STATE_OPEN. */ - err = dsnd_pcm_hw_free( pcm ); - ALSA_ASSERT("dsnd_pcm_hw_free"); - } -// ASSERT_M( dsnd_pcm_state(pcm) == SND_PCM_STATE_OPEN, ssprintf("(%s)", dsnd_pcm_state_name(dsnd_pcm_state(pcm))) ); - - /* allocate the hardware parameters structure */ - snd_pcm_hw_params_t *hwparams; - dsnd_pcm_hw_params_alloca( &hwparams ); - - err = dsnd_pcm_hw_params_any(pcm, hwparams); - ALSA_CHECK("dsnd_pcm_hw_params_any"); - - /* Set to interleaved mmap mode. */ - err = dsnd_pcm_hw_params_set_access(pcm, hwparams, SND_PCM_ACCESS_MMAP_INTERLEAVED); - ALSA_CHECK("dsnd_pcm_hw_params_set_access"); - - /* Set the PCM format: signed 16bit, native endian. */ - err = dsnd_pcm_hw_params_set_format(pcm, hwparams, SND_PCM_FORMAT_S16); - ALSA_CHECK("dsnd_pcm_hw_params_set_format"); - - /* Set the number of channels. */ - err = dsnd_pcm_hw_params_set_channels(pcm, hwparams, 2); - ALSA_CHECK("dsnd_pcm_hw_params_set_channels"); - - /* Set the sample rate. */ - err = dsnd_pcm_hw_params_set_rate_near(pcm, hwparams, &samplerate, 0); - ALSA_CHECK("dsnd_pcm_hw_params_set_rate_near"); - - /* Set the buffersize to the writeahead, and then copy back the actual value - * we got. */ - writeahead = preferred_writeahead; - err = dsnd_pcm_hw_params_set_buffer_size_near( pcm, hwparams, &writeahead ); - ALSA_CHECK("dsnd_pcm_hw_params_set_buffer_size_near"); - - /* The period size is roughly equivalent to what we call the chunksize. */ - int dir = 0; - chunksize = preferred_chunksize; - err = dsnd_pcm_hw_params_set_period_size_near( pcm, hwparams, &chunksize, &dir ); - ALSA_CHECK("dsnd_pcm_hw_params_set_period_size_near"); - -// LOG->Info("asked for %i period, got %i", chunksize, period_size); - - /* write the hardware parameters to the device */ - err = dsnd_pcm_hw_params( pcm, hwparams ); - ALSA_CHECK("dsnd_pcm_hw_params"); - - return true; -} - -bool Alsa9Buf::SetSWParams() -{ - snd_pcm_sw_params_t *swparams; - dsnd_pcm_sw_params_alloca( &swparams ); - dsnd_pcm_sw_params_current( pcm, swparams ); - - int err = dsnd_pcm_sw_params_set_xfer_align( pcm, swparams, 1 ); - ALSA_ASSERT("dsnd_pcm_sw_params_set_xfer_align"); - - /* chunksize has been set to the period size. Set avail_min to the period - * size, too, so poll() wakes up once per chunk. */ - err = dsnd_pcm_sw_params_set_avail_min( pcm, swparams, chunksize ); - ALSA_ASSERT("dsnd_pcm_sw_params_set_avail_min"); - - /* If this fails, we might have bound dsnd_pcm_sw_params_set_avail_min to - * the old SW API. */ -// ASSERT( err <= 0 ); - - /* Disable SND_PCM_STATE_XRUN. */ - snd_pcm_uframes_t boundary = 0; - err = dsnd_pcm_sw_params_get_boundary( swparams, &boundary ); - ALSA_ASSERT("dsnd_pcm_sw_params_get_boundary"); - - err = dsnd_pcm_sw_params_set_stop_threshold( pcm, swparams, boundary ); - ALSA_ASSERT("dsnd_pcm_sw_params_set_stop_threshold"); - - err = dsnd_pcm_sw_params(pcm, swparams); - ALSA_ASSERT("dsnd_pcm_sw_params"); - - err = dsnd_pcm_prepare(pcm); - ALSA_ASSERT("dsnd_pcm_prepare"); - - return true; -} - -void Alsa9Buf::ErrorHandler(const char *file, int line, const char *function, int err, const char *fmt, ...) -{ - va_list va; - va_start( va, fmt ); - RString str = vssprintf(fmt, va); - va_end( va ); - - if( err ) - str += ssprintf( " (%s)", dsnd_strerror(err) ); - - /* Annoying: these happen both normally (eg. "out of memory" when allocating too many PCM - * slots) and abnormally, and there's no way to tell which is which. I don't want to - * pollute the warning output. */ - LOG->Trace( "ALSA error: %s:%i %s: %s", file, line, function, str.c_str() ); -} - -void Alsa9Buf::InitializeErrorHandler() -{ - dsnd_lib_error_set_handler( ErrorHandler ); -} - -static RString DeviceName() -{ - if( !PREFSMAN->m_iSoundDevice.Get().empty() ) - return PREFSMAN->m_iSoundDevice; - return "default"; -} - -void Alsa9Buf::GetSoundCardDebugInfo() -{ - static bool done = false; - if( done ) - return; - done = true; - - if( DoesFileExist("/rootfs/proc/asound/version") ) - { - RString sVersion; - GetFileContents( "/rootfs/proc/asound/version", sVersion, true ); - LOG->Info( "ALSA: %s", sVersion.c_str() ); - } - - InitializeErrorHandler(); - - int card = -1; - while( dsnd_card_next( &card ) >= 0 && card >= 0 ) - { - const RString id = ssprintf( "hw:%d", card ); - snd_ctl_t *handle; - int err; - err = dsnd_ctl_open( &handle, id, 0 ); - if ( err < 0 ) - { - LOG->Info( "Couldn't open card #%i (\"%s\") to probe: %s", card, id.c_str(), dsnd_strerror(err) ); - continue; - } - - snd_ctl_card_info_t *info; - dsnd_ctl_card_info_alloca(&info); - err = dsnd_ctl_card_info( handle, info ); - if ( err < 0 ) - { - LOG->Info( "Couldn't get card info for card #%i (\"%s\"): %s", card, id.c_str(), dsnd_strerror(err) ); - dsnd_ctl_close( handle ); - continue; - } - - int dev = -1; - while ( dsnd_ctl_pcm_next_device( handle, &dev ) >= 0 && dev >= 0 ) - { - snd_pcm_info_t *pcminfo; - dsnd_pcm_info_alloca(&pcminfo); - dsnd_pcm_info_set_device(pcminfo, dev); - dsnd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK); - - err = dsnd_ctl_pcm_info(handle, pcminfo); - if ( err < 0 ) - { - if (err != -ENOENT) - LOG->Info("dsnd_ctl_pcm_info(%i) (%s) failed: %s", card, id.c_str(), dsnd_strerror(err)); - continue; - } - - LOG->Info( "ALSA Driver: %i: %s [%s], device %i: %s [%s], %i/%i subdevices avail", - card, dsnd_ctl_card_info_get_name(info), dsnd_ctl_card_info_get_id(info), dev, - dsnd_pcm_info_get_id(pcminfo), dsnd_pcm_info_get_name(pcminfo), - dsnd_pcm_info_get_subdevices_avail(pcminfo), - dsnd_pcm_info_get_subdevices_count(pcminfo) ); - - } - dsnd_ctl_close(handle); - } - - if( card == 0 ) - LOG->Info( "No ALSA sound cards were found."); - - if( !PREFSMAN->m_iSoundDevice.Get().empty() ) - LOG->Info( "ALSA device overridden to \"%s\"", PREFSMAN->m_iSoundDevice.Get().c_str() ); -} - -Alsa9Buf::Alsa9Buf() -{ - samplerate = 44100; - samplebits = 16; - last_cursor_pos = 0; - preferred_writeahead = 8192; - preferred_chunksize = 1024; - pcm = NULL; -} - -RString Alsa9Buf::Init( int channels_, - int iWriteahead, - int iChunkSize, - int iSampleRate ) -{ - channels = channels_; - preferred_writeahead = iWriteahead; - preferred_chunksize = iChunkSize; - if( iSampleRate == 0 ) - samplerate = 44100; - else - samplerate = iSampleRate; - - GetSoundCardDebugInfo(); - - InitializeErrorHandler(); - - /* Open the device. */ - int err; - err = dsnd_pcm_open( &pcm, DeviceName(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK ); - if( err < 0 ) - return ssprintf( "dsnd_pcm_open(%s): %s", DeviceName().c_str(), dsnd_strerror(err) ); - - if( !SetHWParams() ) - { - CHECKPOINT; - return "SetHWParams failed"; - } - - SetSWParams(); - - LOG->Info( "ALSA: Mixing at %ihz", samplerate ); - - if( preferred_writeahead != writeahead ) - LOG->Info( "ALSA: writeahead adjusted from %u to %u", (unsigned) preferred_writeahead, (unsigned) writeahead ); - if( preferred_chunksize != chunksize ) - LOG->Info( "ALSA: chunksize adjusted from %u to %u", (unsigned) preferred_chunksize, (unsigned) chunksize ); - - return ""; -} - -Alsa9Buf::~Alsa9Buf() -{ - if( pcm != NULL ) - dsnd_pcm_close( pcm ); -} - - -/* Don't fill the buffer any more than than "writeahead" frames. Prefer to - * write "chunksize" frames at a time. (These numbers are hints; if the - * hardware parameters require it, they can be ignored.) */ -int Alsa9Buf::GetNumFramesToFill() -{ - /* Make sure we can write ahead at least two chunks. Otherwise, we'll only - * fill one chunk ahead, and underrun. */ - int ActualWriteahead = max( writeahead, chunksize*2 ); - - snd_pcm_sframes_t avail_frames = dsnd_pcm_avail_update(pcm); - - int total_frames = writeahead; - if( avail_frames > total_frames ) - { - /* underrun */ - const int size = avail_frames-total_frames; - LOG->Trace("underrun (%i frames)", size); - int large_skip_threshold = 2 * samplerate; - - /* For small underruns, ignore them. We'll return the maximum writeahead and ALSA will - * just discard the data. GetPosition will return consistent values during this time, - * so arrows will continue to scroll smoothly until the music catches up. */ - if( size >= large_skip_threshold ) - { - /* It's a large skip. Catch up. If we fall too far behind, the sound thread will - * be decoding as fast as it can, which will steal too many cycles from the rendering - * thread. */ - dsnd_pcm_forward( pcm, size ); - } - } - - if( avail_frames < 0 ) - avail_frames = dsnd_pcm_avail_update(pcm); - - if( avail_frames < 0 ) - { - LOG->Trace( "RageSoundDriver_ALSA9::GetData: dsnd_pcm_avail_update: %s", dsnd_strerror(avail_frames) ); - return 0; - } - - /* Number of frames that have data: */ - const snd_pcm_sframes_t filled_frames = max( 0l, total_frames - avail_frames ); - - /* Number of frames that don't have data, that are within the writeahead: */ - snd_pcm_sframes_t unfilled_frames = clamp( ActualWriteahead - filled_frames, 0l, (snd_pcm_sframes_t)ActualWriteahead ); - -// LOG->Trace( "total_fr: %i; avail_fr: %i; filled_fr: %i; ActualWr %i; chunksize %i; unfilled_frames %i ", -// total_frames, avail_frames, filled_frames, ActualWriteahead, chunksize, unfilled_frames ); - - /* If we have less than a chunk empty, don't fill at all. Otherwise, we'll - * spend a lot of CPU filling in partial chunks, instead of waiting for some - * sound to play and then filling a whole chunk at once. */ - if( unfilled_frames < (int) chunksize ) - return 0; - - return chunksize; -} - -bool Alsa9Buf::WaitUntilFramesCanBeFilled( int timeout_ms ) -{ - int err = dsnd_pcm_wait( pcm, timeout_ms ); - /* EINTR is normal; don't warn. */ - if( err == -EINTR ) - return false; - ALSA_ASSERT("snd_pcm_wait"); - - return err == 1; -} - -void Alsa9Buf::Write( const int16_t *buffer, int frames ) -{ - /* We should be able to write it all. If we don't, treat it as an error. */ - int wrote; - do - { - wrote = dsnd_pcm_mmap_writei( pcm, (const char *) buffer, frames ); - } - while( wrote == -EAGAIN ); - - if( wrote < 0 ) - { - LOG->Trace( "RageSoundDriver_ALSA9::GetData: dsnd_pcm_mmap_writei: %s (%i)", dsnd_strerror(wrote), wrote ); - return; - } - - last_cursor_pos += wrote; - if( wrote < frames ) - LOG->Trace("Couldn't write whole buffer? (%i < %i)", wrote, frames ); -} - - - -/* - * When the play buffer underruns, subsequent writes to the buffer - * return -EPIPE. When this happens, call Recover() to restart playback. - */ -bool Alsa9Buf::Recover( int r ) -{ - if( r == -EPIPE ) - { - LOG->Trace("RageSound_ALSA9::Recover (prepare)"); - int err = dsnd_pcm_prepare(pcm); - ALSA_ASSERT("dsnd_pcm_prepare (Recover)"); - return true; - } - - if( r == -ESTRPIPE ) - { - LOG->Trace("RageSound_ALSA9::Recover (resume)"); - int err; - while ((err = dsnd_pcm_resume(pcm)) == -EAGAIN) - usleep(10000); // 10ms - - ALSA_ASSERT("dsnd_pcm_resume (Recover)"); - return true; - } - - return false; -} - -int64_t Alsa9Buf::GetPosition() const -{ - if( dsnd_pcm_state(pcm) == SND_PCM_STATE_PREPARED ) - return last_cursor_pos; - - dsnd_pcm_hwsync( pcm ); - - /* delay is returned in frames */ - snd_pcm_sframes_t delay; - int err = dsnd_pcm_delay( pcm, &delay ); - ALSA_ASSERT("dsnd_pcm_delay"); - - return last_cursor_pos - delay; -} - -void Alsa9Buf::Play() -{ - /* NOP. It'll start playing when it gets some data. */ -} - -void Alsa9Buf::Stop() -{ - dsnd_pcm_drop( pcm ); - dsnd_pcm_prepare( pcm ); - last_cursor_pos = 0; -} - -RString Alsa9Buf::GetHardwareID( RString name ) -{ - InitializeErrorHandler(); - - if( name.empty() ) - name = DeviceName(); - - snd_ctl_t *handle; - int err; - err = dsnd_ctl_open( &handle, name, 0 ); - if ( err < 0 ) - { - LOG->Info( "Couldn't open card \"%s\" to get ID: %s", name.c_str(), dsnd_strerror(err) ); - return "???"; - } - - snd_ctl_card_info_t *info; - dsnd_ctl_card_info_alloca(&info); - err = dsnd_ctl_card_info( handle, info ); - RString ret = dsnd_ctl_card_info_get_id( info ); - dsnd_ctl_close(handle); - - return ret; -} - - -/* - * (c) 2002-2004 Glenn Maynard, Aaron VonderHaar - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "RageLog.h" +#include "RageUtil.h" +#include "ALSA9Helpers.h" +#include "ALSA9Dynamic.h" +#include "PrefsManager.h" + +/* int err; must be defined before using this macro */ +#define ALSA_CHECK(x) \ + if ( err < 0 ) { LOG->Info("ALSA: %s: %s", x, dsnd_strerror(err)); return false; } +#define ALSA_ASSERT(x) \ + if (err < 0) { LOG->Warn("ALSA: %s: %s", x, dsnd_strerror(err)); } + +bool Alsa9Buf::SetHWParams() +{ + int err; + + if( dsnd_pcm_state(pcm) == SND_PCM_STATE_PREPARED ) + dsnd_pcm_drop( pcm ); + + if( dsnd_pcm_state(pcm) != SND_PCM_STATE_OPEN ) + { + /* Reset the stream to SND_PCM_STATE_OPEN. */ + err = dsnd_pcm_hw_free( pcm ); + ALSA_ASSERT("dsnd_pcm_hw_free"); + } +// ASSERT_M( dsnd_pcm_state(pcm) == SND_PCM_STATE_OPEN, ssprintf("(%s)", dsnd_pcm_state_name(dsnd_pcm_state(pcm))) ); + + /* allocate the hardware parameters structure */ + snd_pcm_hw_params_t *hwparams; + dsnd_pcm_hw_params_alloca( &hwparams ); + + err = dsnd_pcm_hw_params_any(pcm, hwparams); + ALSA_CHECK("dsnd_pcm_hw_params_any"); + + /* Set to interleaved mmap mode. */ + err = dsnd_pcm_hw_params_set_access(pcm, hwparams, SND_PCM_ACCESS_MMAP_INTERLEAVED); + ALSA_CHECK("dsnd_pcm_hw_params_set_access"); + + /* Set the PCM format: signed 16bit, native endian. */ + err = dsnd_pcm_hw_params_set_format(pcm, hwparams, SND_PCM_FORMAT_S16); + ALSA_CHECK("dsnd_pcm_hw_params_set_format"); + + /* Set the number of channels. */ + err = dsnd_pcm_hw_params_set_channels(pcm, hwparams, 2); + ALSA_CHECK("dsnd_pcm_hw_params_set_channels"); + + /* Set the sample rate. */ + err = dsnd_pcm_hw_params_set_rate_near(pcm, hwparams, &samplerate, 0); + ALSA_CHECK("dsnd_pcm_hw_params_set_rate_near"); + + /* Set the buffersize to the writeahead, and then copy back the actual value + * we got. */ + writeahead = preferred_writeahead; + err = dsnd_pcm_hw_params_set_buffer_size_near( pcm, hwparams, &writeahead ); + ALSA_CHECK("dsnd_pcm_hw_params_set_buffer_size_near"); + + /* The period size is roughly equivalent to what we call the chunksize. */ + int dir = 0; + chunksize = preferred_chunksize; + err = dsnd_pcm_hw_params_set_period_size_near( pcm, hwparams, &chunksize, &dir ); + ALSA_CHECK("dsnd_pcm_hw_params_set_period_size_near"); + +// LOG->Info("asked for %i period, got %i", chunksize, period_size); + + /* write the hardware parameters to the device */ + err = dsnd_pcm_hw_params( pcm, hwparams ); + ALSA_CHECK("dsnd_pcm_hw_params"); + + return true; +} + +bool Alsa9Buf::SetSWParams() +{ + snd_pcm_sw_params_t *swparams; + dsnd_pcm_sw_params_alloca( &swparams ); + dsnd_pcm_sw_params_current( pcm, swparams ); + + int err = dsnd_pcm_sw_params_set_xfer_align( pcm, swparams, 1 ); + ALSA_ASSERT("dsnd_pcm_sw_params_set_xfer_align"); + + /* chunksize has been set to the period size. Set avail_min to the period + * size, too, so poll() wakes up once per chunk. */ + err = dsnd_pcm_sw_params_set_avail_min( pcm, swparams, chunksize ); + ALSA_ASSERT("dsnd_pcm_sw_params_set_avail_min"); + + /* If this fails, we might have bound dsnd_pcm_sw_params_set_avail_min to + * the old SW API. */ +// ASSERT( err <= 0 ); + + /* Disable SND_PCM_STATE_XRUN. */ + snd_pcm_uframes_t boundary = 0; + err = dsnd_pcm_sw_params_get_boundary( swparams, &boundary ); + ALSA_ASSERT("dsnd_pcm_sw_params_get_boundary"); + + err = dsnd_pcm_sw_params_set_stop_threshold( pcm, swparams, boundary ); + ALSA_ASSERT("dsnd_pcm_sw_params_set_stop_threshold"); + + err = dsnd_pcm_sw_params(pcm, swparams); + ALSA_ASSERT("dsnd_pcm_sw_params"); + + err = dsnd_pcm_prepare(pcm); + ALSA_ASSERT("dsnd_pcm_prepare"); + + return true; +} + +void Alsa9Buf::ErrorHandler(const char *file, int line, const char *function, int err, const char *fmt, ...) +{ + va_list va; + va_start( va, fmt ); + RString str = vssprintf(fmt, va); + va_end( va ); + + if( err ) + str += ssprintf( " (%s)", dsnd_strerror(err) ); + + /* Annoying: these happen both normally (eg. "out of memory" when allocating too many PCM + * slots) and abnormally, and there's no way to tell which is which. I don't want to + * pollute the warning output. */ + LOG->Trace( "ALSA error: %s:%i %s: %s", file, line, function, str.c_str() ); +} + +void Alsa9Buf::InitializeErrorHandler() +{ + dsnd_lib_error_set_handler( ErrorHandler ); +} + +static RString DeviceName() +{ + if( !PREFSMAN->m_iSoundDevice.Get().empty() ) + return PREFSMAN->m_iSoundDevice; + return "default"; +} + +void Alsa9Buf::GetSoundCardDebugInfo() +{ + static bool done = false; + if( done ) + return; + done = true; + + if( DoesFileExist("/rootfs/proc/asound/version") ) + { + RString sVersion; + GetFileContents( "/rootfs/proc/asound/version", sVersion, true ); + LOG->Info( "ALSA: %s", sVersion.c_str() ); + } + + InitializeErrorHandler(); + + int card = -1; + while( dsnd_card_next( &card ) >= 0 && card >= 0 ) + { + const RString id = ssprintf( "hw:%d", card ); + snd_ctl_t *handle; + int err; + err = dsnd_ctl_open( &handle, id, 0 ); + if ( err < 0 ) + { + LOG->Info( "Couldn't open card #%i (\"%s\") to probe: %s", card, id.c_str(), dsnd_strerror(err) ); + continue; + } + + snd_ctl_card_info_t *info; + dsnd_ctl_card_info_alloca(&info); + err = dsnd_ctl_card_info( handle, info ); + if ( err < 0 ) + { + LOG->Info( "Couldn't get card info for card #%i (\"%s\"): %s", card, id.c_str(), dsnd_strerror(err) ); + dsnd_ctl_close( handle ); + continue; + } + + int dev = -1; + while ( dsnd_ctl_pcm_next_device( handle, &dev ) >= 0 && dev >= 0 ) + { + snd_pcm_info_t *pcminfo; + dsnd_pcm_info_alloca(&pcminfo); + dsnd_pcm_info_set_device(pcminfo, dev); + dsnd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK); + + err = dsnd_ctl_pcm_info(handle, pcminfo); + if ( err < 0 ) + { + if (err != -ENOENT) + LOG->Info("dsnd_ctl_pcm_info(%i) (%s) failed: %s", card, id.c_str(), dsnd_strerror(err)); + continue; + } + + LOG->Info( "ALSA Driver: %i: %s [%s], device %i: %s [%s], %i/%i subdevices avail", + card, dsnd_ctl_card_info_get_name(info), dsnd_ctl_card_info_get_id(info), dev, + dsnd_pcm_info_get_id(pcminfo), dsnd_pcm_info_get_name(pcminfo), + dsnd_pcm_info_get_subdevices_avail(pcminfo), + dsnd_pcm_info_get_subdevices_count(pcminfo) ); + + } + dsnd_ctl_close(handle); + } + + if( card == 0 ) + LOG->Info( "No ALSA sound cards were found."); + + if( !PREFSMAN->m_iSoundDevice.Get().empty() ) + LOG->Info( "ALSA device overridden to \"%s\"", PREFSMAN->m_iSoundDevice.Get().c_str() ); +} + +Alsa9Buf::Alsa9Buf() +{ + samplerate = 44100; + samplebits = 16; + last_cursor_pos = 0; + preferred_writeahead = 8192; + preferred_chunksize = 1024; + pcm = nullptr; +} + +RString Alsa9Buf::Init( int channels_, + int iWriteahead, + int iChunkSize, + int iSampleRate ) +{ + channels = channels_; + preferred_writeahead = iWriteahead; + preferred_chunksize = iChunkSize; + if( iSampleRate == 0 ) + samplerate = 44100; + else + samplerate = iSampleRate; + + GetSoundCardDebugInfo(); + + InitializeErrorHandler(); + + /* Open the device. */ + int err; + err = dsnd_pcm_open( &pcm, DeviceName(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK ); + if( err < 0 ) + return ssprintf( "dsnd_pcm_open(%s): %s", DeviceName().c_str(), dsnd_strerror(err) ); + + if( !SetHWParams() ) + { + CHECKPOINT; + return "SetHWParams failed"; + } + + SetSWParams(); + + LOG->Info( "ALSA: Mixing at %ihz", samplerate ); + + if( preferred_writeahead != writeahead ) + LOG->Info( "ALSA: writeahead adjusted from %u to %u", (unsigned) preferred_writeahead, (unsigned) writeahead ); + if( preferred_chunksize != chunksize ) + LOG->Info( "ALSA: chunksize adjusted from %u to %u", (unsigned) preferred_chunksize, (unsigned) chunksize ); + + return ""; +} + +Alsa9Buf::~Alsa9Buf() +{ + if( pcm != nullptr ) + dsnd_pcm_close( pcm ); +} + + +/* Don't fill the buffer any more than than "writeahead" frames. Prefer to + * write "chunksize" frames at a time. (These numbers are hints; if the + * hardware parameters require it, they can be ignored.) */ +int Alsa9Buf::GetNumFramesToFill() +{ + /* Make sure we can write ahead at least two chunks. Otherwise, we'll only + * fill one chunk ahead, and underrun. */ + int ActualWriteahead = max( writeahead, chunksize*2 ); + + snd_pcm_sframes_t avail_frames = dsnd_pcm_avail_update(pcm); + + int total_frames = writeahead; + if( avail_frames > total_frames ) + { + /* underrun */ + const int size = avail_frames-total_frames; + LOG->Trace("underrun (%i frames)", size); + int large_skip_threshold = 2 * samplerate; + + /* For small underruns, ignore them. We'll return the maximum writeahead and ALSA will + * just discard the data. GetPosition will return consistent values during this time, + * so arrows will continue to scroll smoothly until the music catches up. */ + if( size >= large_skip_threshold ) + { + /* It's a large skip. Catch up. If we fall too far behind, the sound thread will + * be decoding as fast as it can, which will steal too many cycles from the rendering + * thread. */ + dsnd_pcm_forward( pcm, size ); + } + } + + if( avail_frames < 0 ) + avail_frames = dsnd_pcm_avail_update(pcm); + + if( avail_frames < 0 ) + { + LOG->Trace( "RageSoundDriver_ALSA9::GetData: dsnd_pcm_avail_update: %s", dsnd_strerror(avail_frames) ); + return 0; + } + + /* Number of frames that have data: */ + const snd_pcm_sframes_t filled_frames = max( 0l, total_frames - avail_frames ); + + /* Number of frames that don't have data, that are within the writeahead: */ + snd_pcm_sframes_t unfilled_frames = clamp( ActualWriteahead - filled_frames, 0l, (snd_pcm_sframes_t)ActualWriteahead ); + +// LOG->Trace( "total_fr: %i; avail_fr: %i; filled_fr: %i; ActualWr %i; chunksize %i; unfilled_frames %i ", +// total_frames, avail_frames, filled_frames, ActualWriteahead, chunksize, unfilled_frames ); + + /* If we have less than a chunk empty, don't fill at all. Otherwise, we'll + * spend a lot of CPU filling in partial chunks, instead of waiting for some + * sound to play and then filling a whole chunk at once. */ + if( unfilled_frames < (int) chunksize ) + return 0; + + return chunksize; +} + +bool Alsa9Buf::WaitUntilFramesCanBeFilled( int timeout_ms ) +{ + int err = dsnd_pcm_wait( pcm, timeout_ms ); + /* EINTR is normal; don't warn. */ + if( err == -EINTR ) + return false; + ALSA_ASSERT("snd_pcm_wait"); + + return err == 1; +} + +void Alsa9Buf::Write( const int16_t *buffer, int frames ) +{ + /* We should be able to write it all. If we don't, treat it as an error. */ + int wrote; + do + { + wrote = dsnd_pcm_mmap_writei( pcm, (const char *) buffer, frames ); + } + while( wrote == -EAGAIN ); + + if( wrote < 0 ) + { + LOG->Trace( "RageSoundDriver_ALSA9::GetData: dsnd_pcm_mmap_writei: %s (%i)", dsnd_strerror(wrote), wrote ); + return; + } + + last_cursor_pos += wrote; + if( wrote < frames ) + LOG->Trace("Couldn't write whole buffer? (%i < %i)", wrote, frames ); +} + + + +/* + * When the play buffer underruns, subsequent writes to the buffer + * return -EPIPE. When this happens, call Recover() to restart playback. + */ +bool Alsa9Buf::Recover( int r ) +{ + if( r == -EPIPE ) + { + LOG->Trace("RageSound_ALSA9::Recover (prepare)"); + int err = dsnd_pcm_prepare(pcm); + ALSA_ASSERT("dsnd_pcm_prepare (Recover)"); + return true; + } + + if( r == -ESTRPIPE ) + { + LOG->Trace("RageSound_ALSA9::Recover (resume)"); + int err; + while ((err = dsnd_pcm_resume(pcm)) == -EAGAIN) + usleep(10000); // 10ms + + ALSA_ASSERT("dsnd_pcm_resume (Recover)"); + return true; + } + + return false; +} + +int64_t Alsa9Buf::GetPosition() const +{ + if( dsnd_pcm_state(pcm) == SND_PCM_STATE_PREPARED ) + return last_cursor_pos; + + dsnd_pcm_hwsync( pcm ); + + /* delay is returned in frames */ + snd_pcm_sframes_t delay; + int err = dsnd_pcm_delay( pcm, &delay ); + ALSA_ASSERT("dsnd_pcm_delay"); + + return last_cursor_pos - delay; +} + +void Alsa9Buf::Play() +{ + /* NOP. It'll start playing when it gets some data. */ +} + +void Alsa9Buf::Stop() +{ + dsnd_pcm_drop( pcm ); + dsnd_pcm_prepare( pcm ); + last_cursor_pos = 0; +} + +RString Alsa9Buf::GetHardwareID( RString name ) +{ + InitializeErrorHandler(); + + if( name.empty() ) + name = DeviceName(); + + snd_ctl_t *handle; + int err; + err = dsnd_ctl_open( &handle, name, 0 ); + if ( err < 0 ) + { + LOG->Info( "Couldn't open card \"%s\" to get ID: %s", name.c_str(), dsnd_strerror(err) ); + return "???"; + } + + snd_ctl_card_info_t *info; + dsnd_ctl_card_info_alloca(&info); + err = dsnd_ctl_card_info( handle, info ); + RString ret = dsnd_ctl_card_info_get_id( info ); + dsnd_ctl_close(handle); + + return ret; +} + + +/* + * (c) 2002-2004 Glenn Maynard, Aaron VonderHaar + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/arch/Sound/DSoundHelpers.cpp b/src/arch/Sound/DSoundHelpers.cpp index 74a27ec41a..22be7b291c 100644 --- a/src/arch/Sound/DSoundHelpers.cpp +++ b/src/arch/Sound/DSoundHelpers.cpp @@ -43,10 +43,10 @@ void DSound::SetPrimaryBufferMode() format.dwSize = sizeof(format); format.dwFlags = DSBCAPS_PRIMARYBUFFER; format.dwBufferBytes = 0; - format.lpwfxFormat = NULL; + format.lpwfxFormat = nullptr; IDirectSoundBuffer *pBuffer; - HRESULT hr = this->GetDS()->CreateSoundBuffer( &format, &pBuffer, NULL ); + HRESULT hr = this->GetDS()->CreateSoundBuffer( &format, &pBuffer, nullptr ); if( FAILED(hr) ) { LOG->Warn(hr_ssprintf(hr, "Couldn't create primary buffer")); @@ -98,15 +98,15 @@ void DSound::SetPrimaryBufferMode() DSound::DSound() { HRESULT hr; - if( FAILED( hr = CoInitialize(NULL) ) ) + if( FAILED( hr = CoInitialize(nullptr) ) ) RageException::Throw( hr_ssprintf(hr, "CoInitialize") ); - m_pDS = NULL; + m_pDS = nullptr; } RString DSound::Init() { HRESULT hr; - if( FAILED( hr = DirectSoundCreate(NULL, &m_pDS, NULL) ) ) + if( FAILED( hr = DirectSoundCreate(nullptr, &m_pDS, nullptr) ) ) return hr_ssprintf( hr, "DirectSoundCreate" ); static bool bShownInfo = false; @@ -139,7 +139,7 @@ RString DSound::Init() DSound::~DSound() { - if( m_pDS != NULL ) + if( m_pDS != nullptr ) m_pDS->Release(); CoUninitialize(); } @@ -163,8 +163,8 @@ bool DSound::IsEmulated() const DSoundBuf::DSoundBuf() { - m_pBuffer = NULL; - m_pTempBuffer = NULL; + m_pBuffer = nullptr; + m_pTempBuffer = nullptr; } RString DSoundBuf::Init( DSound &ds, DSoundBuf::hw hardware, @@ -236,7 +236,7 @@ RString DSoundBuf::Init( DSound &ds, DSoundBuf::hw hardware, format.lpwfxFormat = &waveformat; - HRESULT hr = ds.GetDS()->CreateSoundBuffer( &format, &m_pBuffer, NULL ); + HRESULT hr = ds.GetDS()->CreateSoundBuffer( &format, &m_pBuffer, nullptr ); if( FAILED(hr) ) return hr_ssprintf( hr, "CreateSoundBuffer failed (%i hz)", m_iSampleBits ); @@ -318,7 +318,7 @@ static bool contained( int iStart, int iEnd, int iPos ) DSoundBuf::~DSoundBuf() { - if( m_pBuffer != NULL ) + if( m_pBuffer != nullptr ) m_pBuffer->Release(); delete [] m_pTempBuffer; } diff --git a/src/arch/Sound/RageSoundDriver.cpp b/src/arch/Sound/RageSoundDriver.cpp index aa13582851..8507345e14 100644 --- a/src/arch/Sound/RageSoundDriver.cpp +++ b/src/arch/Sound/RageSoundDriver.cpp @@ -3,7 +3,7 @@ #include "RageSoundManager.h" #include "RageLog.h" #include "RageUtil.h" -#include "Foreach.h" + #include "arch/arch_default.h" DriverList RageSoundDriver::m_pDriverList; @@ -44,28 +44,29 @@ RageSoundDriver *RageSoundDriver::Create( const RString& drivers ) } } - FOREACH_CONST( RString, drivers_to_try, Driver ) + for (RString const &Driver : drivers_to_try) { - RageDriver *pDriver = m_pDriverList.Create( *Driver ); - if( pDriver == NULL ) + RageDriver *pDriver = m_pDriverList.Create( Driver ); + char const *driverString = Driver.c_str(); + if( pDriver == nullptr ) { - LOG->Trace( "Unknown sound driver: %s", Driver->c_str() ); + LOG->Trace( "Unknown sound driver: %s", driverString ); continue; } RageSoundDriver *pRet = dynamic_cast( pDriver ); - ASSERT( pRet != NULL ); + ASSERT( pRet != nullptr ); const RString sError = pRet->Init(); if( sError.empty() ) { - LOG->Info( "Sound driver: %s", Driver->c_str() ); + LOG->Info( "Sound driver: %s", driverString ); return pRet; } - LOG->Info( "Couldn't load driver %s: %s", Driver->c_str(), sError.c_str() ); + LOG->Info( "Couldn't load driver %s: %s", driverString, sError.c_str() ); SAFE_DELETE( pRet ); } - return NULL; + return nullptr; } RString RageSoundDriver::GetDefaultSoundDriverList() diff --git a/src/arch/Sound/RageSoundDriver_ALSA9_Software.cpp b/src/arch/Sound/RageSoundDriver_ALSA9_Software.cpp index b53df0c358..aedf9f75ef 100644 --- a/src/arch/Sound/RageSoundDriver_ALSA9_Software.cpp +++ b/src/arch/Sound/RageSoundDriver_ALSA9_Software.cpp @@ -53,12 +53,12 @@ bool RageSoundDriver_ALSA9_Software::GetData() if( frames_to_fill <= 0 ) return false; - static int16_t *buf = NULL; + static int16_t *buf = nullptr; static int bufsize = 0; if( buf && bufsize < frames_to_fill ) { delete[] buf; - buf = NULL; + buf = nullptr; } if( !buf ) { @@ -89,7 +89,7 @@ void RageSoundDriver_ALSA9_Software::SetupDecodingThread() RageSoundDriver_ALSA9_Software::RageSoundDriver_ALSA9_Software() { - m_pPCM = NULL; + m_pPCM = nullptr; m_bShutdown = false; } diff --git a/src/arch/Sound/RageSoundDriver_AU.cpp b/src/arch/Sound/RageSoundDriver_AU.cpp index 18fc0ca905..006f935a17 100644 --- a/src/arch/Sound/RageSoundDriver_AU.cpp +++ b/src/arch/Sound/RageSoundDriver_AU.cpp @@ -40,8 +40,8 @@ static inline RString FourCCToString( uint32_t num ) return s; } -RageSoundDriver_AU::RageSoundDriver_AU() : m_OutputUnit(NULL), m_iSampleRate(0), m_bDone(false), m_bStarted(false), - m_pIOThread(NULL), m_pNotificationThread(NULL), m_Semaphore("Sound") +RageSoundDriver_AU::RageSoundDriver_AU() : m_OutputUnit(nullptr), m_iSampleRate(0), m_bDone(false), m_bStarted(false), + m_pIOThread(nullptr), m_pNotificationThread(nullptr), m_Semaphore("Sound") { } @@ -80,7 +80,7 @@ static void SetSampleRate( AudioUnit au, Float64 desiredRate ) kAudioObjectPropertyElementWildcard }; - if( (error = AudioObjectGetPropertyData(OutputDevice, &AvailableRatesAddr, 0, NULL, &size, NULL)) ) + if( (error = AudioObjectGetPropertyData(OutputDevice, &AvailableRatesAddr, 0, nullptr, &size, nullptr)) ) { LOG->Warn( WERROR("Couldn't get available nominal sample rates info", error) ); return; @@ -113,7 +113,7 @@ static void SetSampleRate( AudioUnit au, Float64 desiredRate ) if( bestRate == 0.0 ) return; - if( (error = AudioObjectSetPropertyData(OutputDevice, &RateAddr, 0, NULL, sizeof(Float64), &bestRate)) ) + if( (error = AudioObjectSetPropertyData(OutputDevice, &RateAddr, 0, nullptr, sizeof(Float64), &bestRate)) ) { LOG->Warn( WERROR("Couldn't set the device's sample rate", error) ); } @@ -131,12 +131,12 @@ RString RageSoundDriver_AU::Init() Component comp = FindNextComponent( NULL, &desc ); - if( comp == NULL ) + if( comp == nullptr ) return "Failed to find the default output unit."; OSStatus error = OpenAComponent( comp, &m_OutputUnit ); - if( error != noErr || m_OutputUnit == NULL ) + if( error != noErr || m_OutputUnit == nullptr ) return ERROR( "Could not open the default output unit", error ); // Set up a callback function to generate output to the output unit @@ -255,7 +255,7 @@ float RageSoundDriver_AU::GetPlayLatency() const }; size = sizeof( Float64 ); - if( (error = AudioObjectGetPropertyData(OutputDevice, &RateAddr, 0, NULL, &size, &sampleRate)) ) + if( (error = AudioObjectGetPropertyData(OutputDevice, &RateAddr, 0, nullptr, &size, &sampleRate)) ) { LOG->Warn( WERROR("Couldn't get the device sample rate", error) ); return 0.0f; @@ -268,7 +268,7 @@ float RageSoundDriver_AU::GetPlayLatency() const }; size = sizeof( UInt32 ); - if( (error = AudioObjectGetPropertyData(OutputDevice, &BufferAddr, 0, NULL, &size, &bufferSize)) ) + if( (error = AudioObjectGetPropertyData(OutputDevice, &BufferAddr, 0, nullptr, &size, &bufferSize)) ) { LOG->Warn( WERROR("Couldn't determine buffer size", error) ); bufferSize = 0; @@ -283,7 +283,7 @@ float RageSoundDriver_AU::GetPlayLatency() const }; size = sizeof( UInt32 ); - if( (error = AudioObjectGetPropertyData(OutputDevice, &LatencyAddr, 0, NULL, &size, &frames)) ) + if( (error = AudioObjectGetPropertyData(OutputDevice, &LatencyAddr, 0, nullptr, &size, &frames)) ) { LOG->Warn( WERROR( "Couldn't get device latency", error) ); frames = 0; @@ -297,7 +297,7 @@ float RageSoundDriver_AU::GetPlayLatency() const bufferSize += frames; size = sizeof( UInt32 ); - if( (error = AudioObjectGetPropertyData(OutputDevice, &SafetyAddr, 0, NULL, &size, &frames)) ) + if( (error = AudioObjectGetPropertyData(OutputDevice, &SafetyAddr, 0, nullptr, &size, &frames)) ) { LOG->Warn( WERROR("Couldn't get device safety offset", error) ); frames = 0; @@ -312,7 +312,7 @@ float RageSoundDriver_AU::GetPlayLatency() const kAudioObjectPropertyElementWildcard }; - if( (error = AudioObjectGetPropertyData(OutputDevice, &StreamsAddr, 0, NULL, &size, NULL)) ) + if( (error = AudioObjectGetPropertyData(OutputDevice, &StreamsAddr, 0, nullptr, &size, nullptr)) ) { LOG->Warn( WERROR("Device has no streams", error) ); break; @@ -325,7 +325,7 @@ float RageSoundDriver_AU::GetPlayLatency() const } AudioStreamID *streams = new AudioStreamID[num]; - if( (error = AudioObjectGetPropertyData(OutputDevice, &StreamsAddr, 0, NULL, &size, streams)) ) + if( (error = AudioObjectGetPropertyData(OutputDevice, &StreamsAddr, 0, nullptr, &size, streams)) ) { LOG->Warn( WERROR("Cannot get device's streams", error) ); delete[] streams; @@ -338,7 +338,7 @@ float RageSoundDriver_AU::GetPlayLatency() const kAudioObjectPropertyElementWildcard }; - if( (error = AudioObjectGetPropertyData(streams[0], &LatencyAddr, 0, NULL, &size, &frames)) ) + if( (error = AudioObjectGetPropertyData(streams[0], &LatencyAddr, 0, nullptr, &size, &frames)) ) { LOG->Warn( WERROR("Stream does not report latency", error) ); frames = 0; @@ -360,7 +360,7 @@ OSStatus RageSoundDriver_AU::Render( void *inRefCon, { RageSoundDriver_AU *This = (RageSoundDriver_AU *)inRefCon; - if( unlikely(This->m_pIOThread == NULL) ) + if( unlikely(This->m_pIOThread == nullptr) ) This->m_pIOThread = new RageThreadRegister( "HAL I/O thread" ); AudioBuffer &buf = ioData->mBuffers[0]; diff --git a/src/arch/Sound/RageSoundDriver_DSound_Software.cpp b/src/arch/Sound/RageSoundDriver_DSound_Software.cpp index 1366f45fec..ffdc822b8d 100644 --- a/src/arch/Sound/RageSoundDriver_DSound_Software.cpp +++ b/src/arch/Sound/RageSoundDriver_DSound_Software.cpp @@ -1,169 +1,169 @@ -#include "global.h" -#include "RageSoundDriver_DSound_Software.h" -#include "DSoundHelpers.h" - -#include "RageLog.h" -#include "RageUtil.h" -#include "RageSoundManager.h" -#include "PrefsManager.h" -#include "archutils/Win32/ErrorStrings.h" - -REGISTER_SOUND_DRIVER_CLASS2( DirectSound-sw, DSound_Software ); - -static const int channels = 2; -static const int bytes_per_frame = channels*2; /* 16-bit */ -static const int safe_writeahead = 1024*4; /* in frames */ -static int g_iMaxWriteahead; - -/* We'll fill the buffer in chunks this big. */ -static const int num_chunks = 8; -static int chunksize() { return g_iMaxWriteahead / num_chunks; } - -void RageSoundDriver_DSound_Software::MixerThread() -{ - if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL) ) - if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL) ) - LOG->Warn(werr_ssprintf(GetLastError(), "Failed to set sound thread priority")); - - /* Fill a buffer before we start playing, so we don't play whatever junk is - * in the buffer. */ - char *locked_buf; - unsigned len; - while( m_pPCM->get_output_buf(&locked_buf, &len, chunksize()) ) - { - memset( locked_buf, 0, len ); - m_pPCM->release_output_buf(locked_buf, len); - } - - /* Start playing. */ - m_pPCM->Play(); - - while( !m_bShutdownMixerThread ) - { - char *pLockedBuf; - unsigned iLen; - const int64_t iPlayPos = m_pPCM->GetOutputPosition(); /* must be called before get_output_buf */ - - if( !m_pPCM->get_output_buf(&pLockedBuf, &iLen, chunksize()) ) - { - Sleep( chunksize()*1000 / m_iSampleRate ); - continue; - } - - this->Mix( (int16_t *) pLockedBuf, iLen/bytes_per_frame, iPlayPos, m_pPCM->GetPosition() ); - - m_pPCM->release_output_buf( pLockedBuf, iLen ); - } - - /* I'm not sure why, but if we don't stop the stream now, then the thread will take - * 90ms (our buffer size) longer to close. */ - m_pPCM->Stop(); -} - -int64_t RageSoundDriver_DSound_Software::GetPosition() const -{ - return m_pPCM->GetPosition(); -} - -int RageSoundDriver_DSound_Software::MixerThread_start(void *p) -{ - ((RageSoundDriver_DSound_Software *) p)->MixerThread(); - return 0; -} - -RageSoundDriver_DSound_Software::RageSoundDriver_DSound_Software() -{ - m_bShutdownMixerThread = false; - m_pPCM = NULL; -} - -RString RageSoundDriver_DSound_Software::Init() -{ - RString sError = ds.Init(); - if( sError != "" ) - return sError; - - /* If we're emulated, we're better off with the WaveOut driver; DS - * emulation tends to be desynced. */ - if( ds.IsEmulated() ) - return "Driver unusable (emulated device)"; - - g_iMaxWriteahead = safe_writeahead; - if( PREFSMAN->m_iSoundWriteAhead ) - g_iMaxWriteahead = PREFSMAN->m_iSoundWriteAhead; - - /* Create a DirectSound stream, but don't force it into hardware. */ - m_pPCM = new DSoundBuf; - m_iSampleRate = PREFSMAN->m_iSoundPreferredSampleRate; - if( m_iSampleRate == 0 ) - m_iSampleRate = 44100; - sError = m_pPCM->Init( ds, DSoundBuf::HW_DONT_CARE, channels, m_iSampleRate, 16, g_iMaxWriteahead ); - if( sError != "" ) - return sError; - - LOG->Info( "Software mixing at %i hz", m_iSampleRate ); - - StartDecodeThread(); - - m_MixingThread.SetName("Mixer thread"); - m_MixingThread.Create( MixerThread_start, this ); - - return RString(); -} - -RageSoundDriver_DSound_Software::~RageSoundDriver_DSound_Software() -{ - /* Signal the mixing thread to quit. */ - if( m_MixingThread.IsCreated() ) - { - m_bShutdownMixerThread = true; - LOG->Trace("Shutting down mixer thread ..."); - LOG->Flush(); - m_MixingThread.Wait(); - LOG->Trace("Mixer thread shut down."); - LOG->Flush(); - } - - delete m_pPCM; -} - -void RageSoundDriver_DSound_Software::SetupDecodingThread() -{ - if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL) ) - LOG->Warn( werr_ssprintf(GetLastError(), "Failed to set decoding thread priority") ); -} - -float RageSoundDriver_DSound_Software::GetPlayLatency() const -{ - return (1.0f / m_iSampleRate) * g_iMaxWriteahead; -} - -int RageSoundDriver_DSound_Software::GetSampleRate() const -{ - return m_iSampleRate; -} - -/* - * (c) 2002-2004 Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "RageSoundDriver_DSound_Software.h" +#include "DSoundHelpers.h" + +#include "RageLog.h" +#include "RageUtil.h" +#include "RageSoundManager.h" +#include "PrefsManager.h" +#include "archutils/Win32/ErrorStrings.h" + +REGISTER_SOUND_DRIVER_CLASS2( DirectSound-sw, DSound_Software ); + +static const int channels = 2; +static const int bytes_per_frame = channels*2; /* 16-bit */ +static const int safe_writeahead = 1024*4; /* in frames */ +static int g_iMaxWriteahead; + +/* We'll fill the buffer in chunks this big. */ +static const int num_chunks = 8; +static int chunksize() { return g_iMaxWriteahead / num_chunks; } + +void RageSoundDriver_DSound_Software::MixerThread() +{ + if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL) ) + if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL) ) + LOG->Warn(werr_ssprintf(GetLastError(), "Failed to set sound thread priority")); + + /* Fill a buffer before we start playing, so we don't play whatever junk is + * in the buffer. */ + char *locked_buf; + unsigned len; + while( m_pPCM->get_output_buf(&locked_buf, &len, chunksize()) ) + { + memset( locked_buf, 0, len ); + m_pPCM->release_output_buf(locked_buf, len); + } + + /* Start playing. */ + m_pPCM->Play(); + + while( !m_bShutdownMixerThread ) + { + char *pLockedBuf; + unsigned iLen; + const int64_t iPlayPos = m_pPCM->GetOutputPosition(); /* must be called before get_output_buf */ + + if( !m_pPCM->get_output_buf(&pLockedBuf, &iLen, chunksize()) ) + { + Sleep( chunksize()*1000 / m_iSampleRate ); + continue; + } + + this->Mix( (int16_t *) pLockedBuf, iLen/bytes_per_frame, iPlayPos, m_pPCM->GetPosition() ); + + m_pPCM->release_output_buf( pLockedBuf, iLen ); + } + + /* I'm not sure why, but if we don't stop the stream now, then the thread will take + * 90ms (our buffer size) longer to close. */ + m_pPCM->Stop(); +} + +int64_t RageSoundDriver_DSound_Software::GetPosition() const +{ + return m_pPCM->GetPosition(); +} + +int RageSoundDriver_DSound_Software::MixerThread_start(void *p) +{ + ((RageSoundDriver_DSound_Software *) p)->MixerThread(); + return 0; +} + +RageSoundDriver_DSound_Software::RageSoundDriver_DSound_Software() +{ + m_bShutdownMixerThread = false; + m_pPCM = nullptr; +} + +RString RageSoundDriver_DSound_Software::Init() +{ + RString sError = ds.Init(); + if( sError != "" ) + return sError; + + /* If we're emulated, we're better off with the WaveOut driver; DS + * emulation tends to be desynced. */ + if( ds.IsEmulated() ) + return "Driver unusable (emulated device)"; + + g_iMaxWriteahead = safe_writeahead; + if( PREFSMAN->m_iSoundWriteAhead ) + g_iMaxWriteahead = PREFSMAN->m_iSoundWriteAhead; + + /* Create a DirectSound stream, but don't force it into hardware. */ + m_pPCM = new DSoundBuf; + m_iSampleRate = PREFSMAN->m_iSoundPreferredSampleRate; + if( m_iSampleRate == 0 ) + m_iSampleRate = 44100; + sError = m_pPCM->Init( ds, DSoundBuf::HW_DONT_CARE, channels, m_iSampleRate, 16, g_iMaxWriteahead ); + if( sError != "" ) + return sError; + + LOG->Info( "Software mixing at %i hz", m_iSampleRate ); + + StartDecodeThread(); + + m_MixingThread.SetName("Mixer thread"); + m_MixingThread.Create( MixerThread_start, this ); + + return RString(); +} + +RageSoundDriver_DSound_Software::~RageSoundDriver_DSound_Software() +{ + /* Signal the mixing thread to quit. */ + if( m_MixingThread.IsCreated() ) + { + m_bShutdownMixerThread = true; + LOG->Trace("Shutting down mixer thread ..."); + LOG->Flush(); + m_MixingThread.Wait(); + LOG->Trace("Mixer thread shut down."); + LOG->Flush(); + } + + delete m_pPCM; +} + +void RageSoundDriver_DSound_Software::SetupDecodingThread() +{ + if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL) ) + LOG->Warn( werr_ssprintf(GetLastError(), "Failed to set decoding thread priority") ); +} + +float RageSoundDriver_DSound_Software::GetPlayLatency() const +{ + return (1.0f / m_iSampleRate) * g_iMaxWriteahead; +} + +int RageSoundDriver_DSound_Software::GetSampleRate() const +{ + return m_iSampleRate; +} + +/* + * (c) 2002-2004 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/arch/Sound/RageSoundDriver_Generic_Software.cpp b/src/arch/Sound/RageSoundDriver_Generic_Software.cpp index 34df51752e..4604b1df80 100644 --- a/src/arch/Sound/RageSoundDriver_Generic_Software.cpp +++ b/src/arch/Sound/RageSoundDriver_Generic_Software.cpp @@ -18,7 +18,7 @@ static int underruns = 0, logged_underruns = 0; RageSoundDriver::Sound::Sound() { - m_pSound = NULL; + m_pSound = nullptr; m_State = AVAILABLE; m_bPaused = false; } @@ -257,7 +257,7 @@ void RageSoundDriver::Update() while( m_Sounds[i].m_PosMapQueue.read( &p, 1 ) ) { RageSoundBase *pSound = m_Sounds[i].m_pSound; - if( pSound != NULL ) + if( pSound != nullptr ) pSound->CommitPlayingPosition( p.iStreamFrame, p.iHardwareFrame, p.iFrames ); } } @@ -280,7 +280,7 @@ void RageSoundDriver::Update() // LOG->Trace("finishing sound %i", i); m_Sounds[i].m_pSound->SoundIsFinishedPlaying(); - m_Sounds[i].m_pSound = NULL; + m_Sounds[i].m_pSound = nullptr; /* This sound is done. Set it to HALTING, since the mixer thread might * be accessing it; it'll change it back to STOPPED once it's ready to @@ -389,7 +389,7 @@ void RageSoundDriver::StopMixing( RageSoundBase *pSound ) /* Invalidate the m_pSound pointer to guarantee we don't make any further references to * it. Once this call returns, the sound may no longer exist. */ - m_Sounds[i].m_pSound = NULL; + m_Sounds[i].m_pSound = nullptr; // LOG->Trace("end StopMixing"); m_Mutex.Unlock(); @@ -439,7 +439,7 @@ void RageSoundDriver::SetDecodeBufferSize( int iFrames ) void RageSoundDriver::low_sample_count_workaround() { - if (soundDriverMaxSamples != 0) GetHardwareFrame(NULL); + if (soundDriverMaxSamples != 0) GetHardwareFrame(nullptr); } RageSoundDriver::RageSoundDriver(): @@ -531,9 +531,9 @@ int64_t RageSoundDriver::ClampHardwareFrame( int64_t iHardwareFrame ) const return m_iVMaxHardwareFrame; } -int64_t RageSoundDriver::GetHardwareFrame( RageTimer *pTimestamp=NULL ) const +int64_t RageSoundDriver::GetHardwareFrame( RageTimer *pTimestamp=nullptr ) const { - if( pTimestamp == NULL ) + if( pTimestamp == nullptr ) return ClampHardwareFrame( GetPosition() ); /* diff --git a/src/arch/Sound/RageSoundDriver_JACK.cpp b/src/arch/Sound/RageSoundDriver_JACK.cpp index 0b18cf4757..f0b291173e 100644 --- a/src/arch/Sound/RageSoundDriver_JACK.cpp +++ b/src/arch/Sound/RageSoundDriver_JACK.cpp @@ -11,15 +11,15 @@ REGISTER_SOUND_DRIVER_CLASS( JACK ); RageSoundDriver_JACK::RageSoundDriver_JACK() : RageSoundDriver() { - client = NULL; - port_l = NULL; - port_r = NULL; + client = nullptr; + port_l = nullptr; + port_r = nullptr; } RageSoundDriver_JACK::~RageSoundDriver_JACK() { - // If Init failed, it cleaned up already and set client to NULL - if (client == NULL) + // If Init failed, it cleaned up already and set client to nullptr + if (client == nullptr) return; // Clean up and shut down client @@ -36,7 +36,7 @@ RString RageSoundDriver_JACK::Init() // Open JACK client and call it "StepMania" or whatever client = jack_client_open(PRODUCT_FAMILY, JackNoStartServer, &status); - if (client == NULL) + if (client == nullptr) return "Couldn't connect to JACK server"; sample_rate = jack_get_sample_rate(client); @@ -64,7 +64,7 @@ RString RageSoundDriver_JACK::Init() // Create output ports port_l = jack_port_register(client, "out_l", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); - if (port_l == NULL) + if (port_l == nullptr) { error = "Couldn't create JACK port out_l"; goto out_close; @@ -72,7 +72,7 @@ RString RageSoundDriver_JACK::Init() port_r = jack_port_register(client, "out_r", JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); - if (port_r == NULL) + if (port_r == nullptr) { error = "Couldn't create JACK port out_r"; goto out_unreg_l; @@ -104,7 +104,7 @@ out_unreg_l: jack_port_unregister(client, port_l); out_close: jack_client_close(client); - client = NULL; + client = nullptr; return error; } @@ -113,23 +113,23 @@ RString RageSoundDriver_JACK::ConnectPorts() vector portNames; split(PREFSMAN->m_iSoundDevice.Get(), ",", portNames, true); - const char *port_out_l = NULL, *port_out_r = NULL; - const char **ports = NULL; + const char *port_out_l = nullptr, *port_out_r = nullptr; + const char **ports = nullptr; if( portNames.size() == 0 ) { // The user has NOT specified any ports to connect to. Search // for all physical sinks and use the first two. - ports = jack_get_ports( client, NULL, NULL, JackPortIsInput | JackPortIsPhysical ); - if( ports == NULL ) + ports = jack_get_ports( client, nullptr, nullptr, JackPortIsInput | JackPortIsPhysical ); + if( ports == nullptr ) return "Couldn't get JACK ports"; - if( ports[0] == NULL ) + if( ports[0] == nullptr ) { jack_free( ports ); return "No physical sinks!"; } port_out_l = ports[0]; - if( ports[1] == NULL ) + if( ports[1] == nullptr ) // Only one physical sink. We're going mono! port_out_r = ports[0]; else @@ -151,9 +151,9 @@ RString RageSoundDriver_JACK::ConnectPorts() if( ! ( jack_port_flags( out ) & JackPortIsInput ) ) continue; - if( out != NULL ) + if( out != nullptr ) { - if( port_out_l == NULL ) + if( port_out_l == nullptr ) port_out_l = jack_port_name( out ); else { @@ -162,10 +162,10 @@ RString RageSoundDriver_JACK::ConnectPorts() } } } - if( port_out_l == NULL ) + if( port_out_l == nullptr ) return "All specified sinks are invalid."; - if( port_out_r == NULL ) + if( port_out_r == nullptr ) // Only found one valid sink. Going mono! port_out_r = port_out_l; } @@ -177,7 +177,7 @@ RString RageSoundDriver_JACK::ConnectPorts() else if( jack_connect( client, jack_port_name(port_r), port_out_r ) != 0 ) ret = "Couldn't connect right JACK port"; - if( ports != NULL ) + if( ports != nullptr ) jack_free( ports ); return ret; diff --git a/src/arch/Sound/RageSoundDriver_OSS.cpp b/src/arch/Sound/RageSoundDriver_OSS.cpp index b91b767309..6828de3e94 100644 --- a/src/arch/Sound/RageSoundDriver_OSS.cpp +++ b/src/arch/Sound/RageSoundDriver_OSS.cpp @@ -58,7 +58,7 @@ void RageSoundDriver_OSS::MixerThread() usleep( 10000 ); struct timeval tv = { 0, 10000 }; - select(fd+1, NULL, &f, NULL, &tv); + select(fd+1, nullptr, &f, nullptr, &tv); } } @@ -81,7 +81,7 @@ bool RageSoundDriver_OSS::GetData() const int chunksize = ab.fragsize; - static int16_t *buf = NULL; + static int16_t *buf = nullptr; if(!buf) buf = new int16_t[chunksize / sizeof(int16_t)]; diff --git a/src/arch/Sound/RageSoundDriver_PulseAudio.cpp b/src/arch/Sound/RageSoundDriver_PulseAudio.cpp index 54bfc8474f..96937df930 100644 --- a/src/arch/Sound/RageSoundDriver_PulseAudio.cpp +++ b/src/arch/Sound/RageSoundDriver_PulseAudio.cpp @@ -16,9 +16,9 @@ REGISTER_SOUND_DRIVER_CLASS2( Pulse, PulseAudio ); /* Constructor */ RageSoundDriver_PulseAudio::RageSoundDriver_PulseAudio() : RageSoundDriver(), -m_LastPosition(0), m_SampleRate(0), m_Error(NULL), +m_LastPosition(0), m_SampleRate(0), m_Error(nullptr), m_Sem("Pulseaudio Synchronization Semaphore"), -m_PulseMainLoop(NULL), m_PulseCtx(NULL), m_PulseStream(NULL) +m_PulseMainLoop(nullptr), m_PulseCtx(nullptr), m_PulseStream(nullptr) { m_SampleRate = PREFSMAN->m_iSoundPreferredSampleRate; if( m_SampleRate == 0 ) @@ -32,7 +32,7 @@ RageSoundDriver_PulseAudio::~RageSoundDriver_PulseAudio() pa_threaded_mainloop_stop(m_PulseMainLoop); pa_threaded_mainloop_free(m_PulseMainLoop); - if(m_Error != NULL) + if(m_Error != nullptr) { free(m_Error); } @@ -45,7 +45,7 @@ RString RageSoundDriver_PulseAudio::Init() LOG->Trace("Pulse: pa_threaded_mainloop_new()..."); m_PulseMainLoop = pa_threaded_mainloop_new(); - if(m_PulseMainLoop == NULL) + if(m_PulseMainLoop == nullptr) { return "pa_threaded_mainloop_new() failed!"; } @@ -63,7 +63,7 @@ RString RageSoundDriver_PulseAudio::Init() "StepMania", plist); pa_proplist_free(plist); - if(m_PulseCtx == NULL) + if(m_PulseCtx == nullptr) { return "pa_context_new_with_proplist() failed!"; } @@ -72,7 +72,7 @@ RString RageSoundDriver_PulseAudio::Init() m_PulseCtx = pa_context_new( pa_threaded_mainloop_get_api(m_PulseMainLoop), "Stepmania"); - if(m_PulseCtx == NULL) + if(m_PulseCtx == nullptr) { return "pa_context_new() failed!"; } @@ -81,7 +81,7 @@ RString RageSoundDriver_PulseAudio::Init() pa_context_set_state_callback(m_PulseCtx, StaticCtxStateCb, this); LOG->Trace("Pulse: pa_context_connect()..."); - error = pa_context_connect(m_PulseCtx, NULL, (pa_context_flags_t)0, NULL); + error = pa_context_connect(m_PulseCtx, nullptr, (pa_context_flags_t)0, nullptr); if(error < 0) { @@ -101,10 +101,10 @@ RString RageSoundDriver_PulseAudio::Init() StartDecodeThread(); /* Wait for the pulseaudio stream to be ready before returning. - * An error may occur, if it appends, m_Error becomes non-NULL. */ + * An error may occur, if it appends, m_Error becomes non-nullptr. */ m_Sem.Wait(); - if(m_Error == NULL) + if(m_Error == nullptr) { return ""; } @@ -137,7 +137,7 @@ void RageSoundDriver_PulseAudio::m_InitStream(void) { if(asprintf(&m_Error, "invalid sample spec!") == -1) { - m_Error = NULL; + m_Error = nullptr; } m_Sem.Post(); return; @@ -151,11 +151,11 @@ void RageSoundDriver_PulseAudio::m_InitStream(void) /* create the stream */ LOG->Trace("Pulse: pa_stream_new()..."); m_PulseStream = pa_stream_new(m_PulseCtx, "Stepmania Audio", &ss, &map); - if(m_PulseStream == NULL) + if(m_PulseStream == nullptr) { if(asprintf(&m_Error, "pa_stream_new(): %s", pa_strerror(pa_context_errno(m_PulseCtx))) == -1) { - m_Error = NULL; + m_Error = nullptr; } m_Sem.Post(); return; @@ -224,14 +224,14 @@ void RageSoundDriver_PulseAudio::m_InitStream(void) /* connect the stream for playback */ LOG->Trace("Pulse: pa_stream_connect_playback()..."); - error = pa_stream_connect_playback(m_PulseStream, NULL, &attr, - PA_STREAM_AUTO_TIMING_UPDATE, NULL, NULL); + error = pa_stream_connect_playback(m_PulseStream, nullptr, &attr, + PA_STREAM_AUTO_TIMING_UPDATE, nullptr, nullptr); if(error < 0) { if(asprintf(&m_Error, "pa_stream_connect_playback(): %s", pa_strerror(pa_context_errno(m_PulseCtx))) == -1) { - m_Error = NULL; + m_Error = nullptr; } m_Sem.Post(); return; @@ -261,7 +261,7 @@ void RageSoundDriver_PulseAudio::CtxStateCb(pa_context *c) case PA_CONTEXT_FAILED: if(asprintf(&m_Error, "context connection failed: %s", pa_strerror(pa_context_errno(m_PulseCtx))) == -1) { - m_Error = NULL; + m_Error = nullptr; } m_Sem.Post(); return; @@ -316,7 +316,7 @@ void RageSoundDriver_PulseAudio::StreamWriteCb(pa_stream *s, size_t length) int64_t pos1 = m_LastPosition; int64_t pos2 = pos1 + nbframes/2; /* Mix() position in stereo frames */ this->Mix( buf, pos2-pos1, pos1, pos2); - if(pa_stream_write(m_PulseStream, buf, length, NULL, 0, PA_SEEK_RELATIVE) < 0) + if(pa_stream_write(m_PulseStream, buf, length, nullptr, 0, PA_SEEK_RELATIVE) < 0) { RageException::Throw("Pulse: pa_stream_write()"); } diff --git a/src/arch/Sound/RageSoundDriver_WDMKS.cpp b/src/arch/Sound/RageSoundDriver_WDMKS.cpp index 5e477a09b6..b84e4c1c84 100644 --- a/src/arch/Sound/RageSoundDriver_WDMKS.cpp +++ b/src/arch/Sound/RageSoundDriver_WDMKS.cpp @@ -1,1409 +1,1409 @@ -#include "global.h" -#include "RageSoundDriver_WDMKS.h" -#include "Foreach.h" -#include "RageLog.h" -#include "RageUtil.h" -#include "PrefsManager.h" -#include "archutils/Win32/ErrorStrings.h" - -#define _INC_MMREG -#define _NTRTL_ /* Turn off default definition of DEFINE_GUIDEX */ -#if !defined(DEFINE_WAVEFORMATEX_GUID) -#define DEFINE_WAVEFORMATEX_GUID(x) (USHORT)(x), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 -#endif - -#include -#include -#include -#include -#include -#include - -typedef KSDDKAPI DWORD WINAPI KSCREATEPIN(HANDLE, PKSPIN_CONNECT, ACCESS_MASK, PHANDLE); - -#ifndef KSAUDIO_SPEAKER_5POINT1_SURROUND -#define KSAUDIO_SPEAKER_5POINT1_SURROUND \ - (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT) -#endif - -#ifndef KSAUDIO_SPEAKER_7POINT1_SURROUND -#define KSAUDIO_SPEAKER_7POINT1_SURROUND \ - (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | \ - SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT) -#endif - -struct WinWdmFilter; - -struct WinWdmPin -{ - WinWdmPin( WinWdmFilter *pParentFilter, int iPinId ) - { - m_hHandle = NULL; - m_pParentFilter = pParentFilter; - m_iPinId = iPinId; - } - - ~WinWdmPin() - { - Close(); - } - - bool Instantiate( const WAVEFORMATEX *pFormat, RString &sError ); - void Close(); - - bool SetState( KSSTATE state, RString &sError ); - KSPIN_CONNECT *MakeFormat( const WAVEFORMATEX *pFormat ) const; - bool IsFormatSupported( const WAVEFORMATEX *pFormat ) const; - - HANDLE m_hHandle; - WinWdmFilter *m_pParentFilter; - int m_iPinId; - vector m_dataRangesItem; -}; - -enum DeviceSampleFormat -{ - DeviceSampleFormat_Float32, - DeviceSampleFormat_Int16, - DeviceSampleFormat_Int24, - DeviceSampleFormat_Int32, - NUM_DeviceSampleFormat, - DeviceSampleFormat_Invalid -}; - -static int GetBytesPerSample( DeviceSampleFormat sf ) -{ - switch( sf ) - { - case DeviceSampleFormat_Float32: return 4; - case DeviceSampleFormat_Int16: return 2; - case DeviceSampleFormat_Int24: return 3; - case DeviceSampleFormat_Int32: return 4; - DEFAULT_FAIL(sf); - } -} - -/* The Filter structure - * A filter has a number of pins and a "friendly name" */ -struct WinWdmFilter -{ - /* Filter management functions */ - static WinWdmFilter *Create( const RString &sFilterName, const RString &sFriendlyName, RString &sError ); - - WinWdmFilter() - { - m_hHandle = NULL; - m_iUsageCount = 0; - } - - ~WinWdmFilter() - { - for( size_t i = 0; i < m_apPins.size(); ++i ) - delete m_apPins[i]; - if( m_hHandle ) - CloseHandle( m_hHandle ); - } - - WinWdmPin *CreatePin( unsigned long iPinId, RString &sError ); - WinWdmPin *InstantiateRenderPin( - DeviceSampleFormat &PreferredOutputSampleFormat, - int &iPreferredOutputChannels, - int &iPreferredSampleRate, - RString &sError ); - WinWdmPin *InstantiateRenderPin( const WAVEFORMATEX *wfex, RString &sError ); - bool Use( RString &sError ); - void Release(); - - HANDLE m_hHandle; - vector m_apPins; - RString m_sFilterName; - RString m_sFriendlyName; - int m_iUsageCount; -}; - -static RString GUIDToString( const GUID *pGuid ) -{ - return ssprintf("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", - pGuid->Data1, pGuid->Data2, pGuid->Data3, - pGuid->Data4[0], pGuid->Data4[1], pGuid->Data4[2], pGuid->Data4[3], - pGuid->Data4[4], pGuid->Data4[5], pGuid->Data4[6], pGuid->Data4[7] ); -} - -static HMODULE DllKsUser = NULL; -static KSCREATEPIN *FunctionKsCreatePin = NULL; - -/* Low level pin/filter access functions */ -static bool WdmSyncIoctl( - HANDLE hHandle, unsigned long ioctlNumber, void *pIn, unsigned long iInSize, - void *pOut, unsigned long iOutSize, unsigned long *pBytesReturned, RString &sError ) -{ - unsigned long iDummyBytesReturned; - if( pBytesReturned == NULL ) - pBytesReturned = &iDummyBytesReturned; - - OVERLAPPED overlapped; - memset( &overlapped, 0, sizeof(overlapped) ); - overlapped.hEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); - if( !overlapped.hEvent ) - { - sError = werr_ssprintf( GetLastError(), "CreateEvent" ); - return false; - } - overlapped.hEvent = (HANDLE)((DWORD_PTR)overlapped.hEvent | 0x1); - - int boolResult = DeviceIoControl( hHandle, ioctlNumber, pIn, iInSize, pOut, iOutSize, pBytesReturned, &overlapped ); - if( !boolResult ) - { - unsigned long iError = GetLastError(); - if( iError == ERROR_IO_PENDING ) - { - iError = WaitForSingleObject( overlapped.hEvent, INFINITE ); - if( iError != WAIT_OBJECT_0 ) - { - ASSERT( iError == WAIT_FAILED ); - sError = werr_ssprintf( GetLastError(), "WaitForSingleObject" ); - CloseHandle( overlapped.hEvent ); - return false; - } - } - else if(( iError == ERROR_INSUFFICIENT_BUFFER || iError == ERROR_MORE_DATA ) && - ioctlNumber == IOCTL_KS_PROPERTY && iOutSize == 0 ) - { - boolResult = TRUE; - } - else - { - sError = werr_ssprintf( iError, "DeviceIoControl" ); - CloseHandle( overlapped.hEvent ); - return false; - } - } - if( !boolResult ) - *pBytesReturned = 0; - - CloseHandle( overlapped.hEvent ); - return true; -} - -static bool WdmGetPropertySimple( HANDLE hHandle, const GUID *pGuidPropertySet, unsigned long iProperty, - void *pValue, unsigned long iValueSize, void *pInstance, unsigned long iInstanceSize, RString &sError ) -{ - unsigned long iPropertySize = sizeof(KSPROPERTY) + iInstanceSize; - vector buf; - buf.resize( iPropertySize ); - KSPROPERTY *ksProperty = (KSPROPERTY*) &buf[0]; - - memset( ksProperty, 0, sizeof(*ksProperty) ); - ksProperty->Set = *pGuidPropertySet; - ksProperty->Id = iProperty; - ksProperty->Flags = KSPROPERTY_TYPE_GET; - - if( pInstance ) - memcpy( &ksProperty[1], pInstance, iInstanceSize ); - - return WdmSyncIoctl( hHandle, IOCTL_KS_PROPERTY, ksProperty, iPropertySize, pValue, iValueSize, NULL, sError ); -} - -static bool WdmSetPropertySimple( - HANDLE hHandle, const GUID *pGuidPropertySet, unsigned long iProperty, - void *pValue, unsigned long iValueSize, - void *instance, unsigned long iInstanceSize, RString &sError ) -{ - vector buf; - unsigned long iPropertySize = sizeof(KSPROPERTY) + iInstanceSize; - buf.resize( iPropertySize ); - KSPROPERTY *ksProperty = (KSPROPERTY *) &buf[0]; - - memset( ksProperty, 0, sizeof(*ksProperty) ); - ksProperty->Set = *pGuidPropertySet; - ksProperty->Id = iProperty; - ksProperty->Flags = KSPROPERTY_TYPE_SET; - - if( instance ) - memcpy( ((char*)ksProperty + sizeof(KSPROPERTY)), instance, iInstanceSize ); - - return WdmSyncIoctl( hHandle, IOCTL_KS_PROPERTY, ksProperty, iPropertySize, pValue, iValueSize, NULL, sError ); -} - -static bool WdmGetPinPropertySimple( HANDLE hHandle, unsigned long iPinId, const GUID *pGuidPropertySet, unsigned long iProperty, - void *pValue, unsigned long iInstanceSize, RString &sError ) -{ - KSP_PIN ksPProp; - ksPProp.Property.Set = *pGuidPropertySet; - ksPProp.Property.Id = iProperty; - ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; - ksPProp.PinId = iPinId; - ksPProp.Reserved = 0; - - return WdmSyncIoctl( hHandle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN), pValue, iInstanceSize, NULL, sError ); -} - -static bool WdmGetPinPropertyMulti( - HANDLE hHandle, - unsigned long iPinId, - const GUID *pGuidPropertySet, - unsigned long iProperty, - KSMULTIPLE_ITEM **ksMultipleItem, - RString &sError ) -{ - KSP_PIN ksPProp; - - ksPProp.Property.Set = *pGuidPropertySet; - ksPProp.Property.Id = iProperty; - ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; - ksPProp.PinId = iPinId; - ksPProp.Reserved = 0; - - unsigned long multipleItemSize = 0; - if( !WdmSyncIoctl(hHandle, IOCTL_KS_PROPERTY, &ksPProp.Property, sizeof(KSP_PIN), NULL, 0, &multipleItemSize, sError) ) - return false; - - *ksMultipleItem = (KSMULTIPLE_ITEM*) malloc( multipleItemSize ); - ASSERT( *ksMultipleItem != NULL ); - - if( !WdmSyncIoctl( hHandle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN), (void*)*ksMultipleItem, multipleItemSize, NULL, sError) ) - { - free( ksMultipleItem ); - return false; - } - - return true; -} - -/* - * Create a new pin object belonging to a filter - * The pin object holds all the configuration information about the pin - * before it is opened, and then the handle of the pin after is opened - */ -WinWdmPin *WinWdmFilter::CreatePin( unsigned long iPinId, RString &sError ) -{ - { - /* Get the COMMUNICATION property */ - KSPIN_COMMUNICATION communication; - if( !WdmGetPinPropertySimple(m_hHandle, iPinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_COMMUNICATION, - &communication, sizeof(KSPIN_COMMUNICATION), sError) ) - { - sError = "KSPROPERTY_PIN_COMMUNICATION: " + sError; - return NULL; - } - - if( communication != KSPIN_COMMUNICATION_SINK && communication != KSPIN_COMMUNICATION_BOTH ) - { - sError = "Not an audio output device"; - return NULL; - } - } - - /* Get dataflow information */ - { - KSPIN_DATAFLOW dataFlow; - if( !WdmGetPinPropertySimple(m_hHandle, iPinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_DATAFLOW, - &dataFlow, sizeof(KSPIN_DATAFLOW), sError) ) - { - sError = "KSPROPERTY_PIN_DATAFLOW: " + sError; - return NULL; - } - - if( dataFlow != KSPIN_DATAFLOW_IN ) - { - sError = "Not KSPIN_DATAFLOW_IN"; - return NULL; - } - } - - /* Get the INTERFACE property list */ - { - KSMULTIPLE_ITEM *pItem = NULL; - if( !WdmGetPinPropertyMulti(m_hHandle, iPinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_INTERFACES, &pItem, sError) ) - { - sError = "KSPROPERTY_PIN_INTERFACES: " + sError; - return NULL; - } - - KSIDENTIFIER *identifier = (KSIDENTIFIER *) &pItem[1]; - - /* Check that at least one interface is STANDARD_STREAMING */ - sError = "No standard streaming"; - for( unsigned i = 0; i < pItem->Count; i++ ) - { - if( !memcmp( &identifier[i].Set, &KSINTERFACESETID_Standard, sizeof(GUID) ) && - identifier[i].Id == KSINTERFACE_STANDARD_STREAMING ) - { - sError = ""; - break; - } - } - - free( pItem ); - - if( sError != "" ) - return NULL; - } - - /* Get the MEDIUM properties list */ - { - KSMULTIPLE_ITEM *pItem = NULL; - if( !WdmGetPinPropertyMulti( m_hHandle, iPinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_MEDIUMS, &pItem, sError) ) - { - sError = "KSPROPERTY_PIN_MEDIUMS: " + sError; - return NULL; - } - - const KSIDENTIFIER *identifier = (KSIDENTIFIER *) &pItem[1]; - - /* Check that at least one medium is STANDARD_DEVIO */ - sError = "No STANDARD_DEVIO"; - for( unsigned i = 0; i < pItem->Count; i++ ) - { - if( !memcmp( &identifier[i].Set, &KSMEDIUMSETID_Standard, sizeof(GUID) ) && - identifier[i].Id == KSMEDIUM_STANDARD_DEVIO ) - { - sError = ""; - break; - } - } - - free( pItem ); - - if( sError != "" ) - return NULL; - } - - /* Allocate the new PIN object */ - WinWdmPin *pPin = new WinWdmPin( this, iPinId ); - - /* Get DATARANGEs */ - KSMULTIPLE_ITEM *pDataRangesItem; - if( !WdmGetPinPropertyMulti(m_hHandle, iPinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_DATARANGES, &pDataRangesItem, sError) ) - { - sError = "KSPROPERTY_PIN_DATARANGES: " + sError; - goto error; - } - - KSDATARANGE *pDataRanges = (KSDATARANGE*) (pDataRangesItem + 1); - - /* Find audio DATARANGEs */ - { - KSDATARANGE *pDataRange = pDataRanges; - for( unsigned i = 0; i < pDataRangesItem->Count; i++, pDataRange = (KSDATARANGE*)( ((char*)pDataRange) + pDataRange->FormatSize) ) - { - if( memcmp(&pDataRange->MajorFormat, &KSDATAFORMAT_TYPE_AUDIO, sizeof(GUID)) && - memcmp(&pDataRange->MajorFormat, &KSDATAFORMAT_TYPE_WILDCARD, sizeof(GUID)) ) - continue; - - if( memcmp(&pDataRange->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID) ) && - memcmp(&pDataRange->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof(GUID) ) && - memcmp(&pDataRange->SubFormat, &KSDATAFORMAT_SUBTYPE_WILDCARD, sizeof(GUID) ) ) - continue; - - if( memcmp(&pDataRange->Specifier, &KSDATAFORMAT_SPECIFIER_WILDCARD, sizeof(GUID)) && - memcmp(&pDataRange->Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX, sizeof(GUID) )) - continue; - - const KSDATARANGE_AUDIO *pDataRangeAudio = (KSDATARANGE_AUDIO *) pDataRange; - pPin->m_dataRangesItem.push_back( *pDataRangeAudio ); - } - } - free( pDataRangesItem ); - pDataRangesItem = NULL; - - if( pPin->m_dataRangesItem.size() == 0 ) - { - sError = "Pin has no supported audio data ranges"; - goto error; - } - - /* Success */ - sError = ""; - CHECKPOINT_M( "Pin created successfully" ); - return pPin; - -error: - /* Error cleanup */ - delete pPin; - return NULL; -} - -/* If the pin handle is open, close it */ -void WinWdmPin::Close() -{ - if( m_hHandle == NULL ) - return; - RString sError; - SetState( KSSTATE_PAUSE, sError ); - SetState( KSSTATE_STOP, sError ); - CloseHandle( m_hHandle ); - m_hHandle = NULL; - m_pParentFilter->Release(); -} - -/* Set the state of this (instantiated) pin */ -bool WinWdmPin::SetState( KSSTATE state, RString &sError ) -{ - ASSERT( m_hHandle != NULL ); - return WdmSetPropertySimple( m_hHandle, &KSPROPSETID_Connection, KSPROPERTY_CONNECTION_STATE, - &state, sizeof(state), NULL, 0, sError ); -} - -bool WinWdmPin::Instantiate( const WAVEFORMATEX *pFormat, RString &sError ) -{ - if( !IsFormatSupported(pFormat) ) - { - sError = "format not supported"; - return false; - } - - - if( !m_pParentFilter->Use(sError) ) - return false; - - KSPIN_CONNECT *pPinConnect = MakeFormat( pFormat ); - DWORD iRet = FunctionKsCreatePin( m_pParentFilter->m_hHandle, pPinConnect, GENERIC_WRITE | GENERIC_READ, &m_hHandle ); - free( pPinConnect ); - if( iRet == ERROR_SUCCESS ) - return true; - - sError = werr_ssprintf( iRet, "FunctionKsCreatePin" ); - m_pParentFilter->Release(); - m_hHandle = NULL; - return false; -} - -KSPIN_CONNECT *WinWdmPin::MakeFormat( const WAVEFORMATEX *pFormat ) const -{ - ASSERT( pFormat != NULL ); - - unsigned long iWfexSize = sizeof(WAVEFORMATEX) + pFormat->cbSize; - unsigned long iDataFormatSize = sizeof(KSDATAFORMAT) + iWfexSize; - unsigned long iSize = sizeof(KSPIN_CONNECT) + iDataFormatSize; - - KSPIN_CONNECT *pPinConnect = (KSPIN_CONNECT *) malloc( iSize ); - ASSERT( pPinConnect != NULL ); - - memset( pPinConnect, 0, iSize ); - pPinConnect->PinId = m_iPinId; - pPinConnect->Interface.Set = KSINTERFACESETID_Standard; - pPinConnect->Interface.Id = KSINTERFACE_STANDARD_STREAMING; - pPinConnect->Interface.Flags = 0; - pPinConnect->Medium.Set = KSMEDIUMSETID_Standard; - pPinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE; - pPinConnect->Medium.Flags = 0; - pPinConnect->PinToHandle = NULL; - pPinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL; - pPinConnect->Priority.PrioritySubClass = 1; - - KSDATAFORMAT_WAVEFORMATEX *ksDataFormatWfx = (KSDATAFORMAT_WAVEFORMATEX *)(pPinConnect + 1); - ksDataFormatWfx->DataFormat.Flags = 0; - ksDataFormatWfx->DataFormat.Reserved = 0; - ksDataFormatWfx->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO; - ksDataFormatWfx->DataFormat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; - ksDataFormatWfx->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX; - ksDataFormatWfx->DataFormat.FormatSize = iDataFormatSize; - - memcpy( &ksDataFormatWfx->WaveFormatEx, pFormat, iWfexSize ); - ksDataFormatWfx->DataFormat.SampleSize = (unsigned short)(pFormat->nChannels * (pFormat->wBitsPerSample / 8)); - return pPinConnect; -} - -bool WinWdmPin::IsFormatSupported( const WAVEFORMATEX *pFormat ) const -{ - GUID guid = { DEFINE_WAVEFORMATEX_GUID(pFormat->wFormatTag) }; - - if( pFormat->wFormatTag == WAVE_FORMAT_EXTENSIBLE ) - guid = ((WAVEFORMATEXTENSIBLE*) pFormat)->SubFormat; - - for( size_t i = 0; i < m_dataRangesItem.size(); i++ ) - { - const KSDATARANGE_AUDIO *pDataRangeAudio = &m_dataRangesItem[i]; - /* This is an audio or wildcard datarange... */ - if( memcmp(&pDataRangeAudio->DataRange.SubFormat, &KSDATAFORMAT_SUBTYPE_WILDCARD, sizeof(GUID)) && - memcmp(&pDataRangeAudio->DataRange.SubFormat, &guid, sizeof(GUID)) ) - continue; - - if( pDataRangeAudio->MaximumChannels != (ULONG) -1 && pDataRangeAudio->MaximumChannels < pFormat->nChannels ) - continue; - if( pFormat->wBitsPerSample < pDataRangeAudio->MinimumBitsPerSample || pFormat->wBitsPerSample > pDataRangeAudio->MaximumBitsPerSample ) - continue; - if( pFormat->nSamplesPerSec < pDataRangeAudio->MinimumSampleFrequency || pFormat->nSamplesPerSec > pDataRangeAudio->MaximumSampleFrequency ) - continue; - - return true; - } - - return false; -} - -/* Create a new filter object. */ -WinWdmFilter *WinWdmFilter::Create( const RString &sFilterName, const RString &sFriendlyName, RString &sError ) -{ - /* Allocate the new filter object */ - WinWdmFilter *pFilter = new WinWdmFilter; - - pFilter->m_sFilterName = sFilterName; - pFilter->m_sFriendlyName = sFriendlyName; - - /* Open the filter handle */ - if( !pFilter->Use(sError) ) - goto error; - - /* Get pin count */ - int iNumPins; - if( !WdmGetPinPropertySimple(pFilter->m_hHandle, 0, &KSPROPSETID_Pin, KSPROPERTY_PIN_CTYPES, &iNumPins, sizeof(iNumPins), sError) ) - goto error; - - /* Create all the pins we can */ - for( int iPinId = 0; iPinId < iNumPins; iPinId++ ) - { - /* Create the pin with this Id */ - WinWdmPin *pNewPin = pFilter->CreatePin( iPinId, sError ); - if( pNewPin != NULL ) - pFilter->m_apPins.push_back( pNewPin ); - } - - if( pFilter->m_apPins.empty() ) - { - /* No valid pin was found on this filter so we destroy it */ - sError = "filter has no supported audio pins"; - goto error; - } - - pFilter->Release(); - - sError = ""; - return pFilter; - -error: - /* Error cleanup */ - delete pFilter; - return NULL; -} - -/* - * Reopen the filter handle if necessary so it can be used - */ -bool WinWdmFilter::Use( RString &sError ) -{ - if( m_hHandle == NULL ) - { - /* Open the filter */ - m_hHandle = CreateFile( m_sFilterName, GENERIC_READ | GENERIC_WRITE, 0, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL ); - - if( m_hHandle == NULL ) - { - sError = werr_ssprintf( GetLastError(), "CreateFile(%s)", m_sFilterName.c_str() ); - return false; - } - } - - ++m_iUsageCount; - return true; -} - -/* - * Release the filter handle if nobody is using it - */ -void WinWdmFilter::Release() -{ - ASSERT( m_iUsageCount > 0 ); - - --m_iUsageCount; - if( m_iUsageCount == 0 ) - { - if( m_hHandle != NULL ) - { - CloseHandle( m_hHandle ); - m_hHandle = NULL; - } - } -} - -/* - * Create a render (playback) Pin using the supplied format - */ -WinWdmPin *WinWdmFilter::InstantiateRenderPin( const WAVEFORMATEX *wfex, RString &sError ) -{ - for( size_t i = 0; i < m_apPins.size(); ++i ) - { - WinWdmPin *pPin = m_apPins[i]; - if( pPin->Instantiate(wfex, sError) ) - { - sError = ""; - return pPin; - } - } - - sError = "No pin supports format"; - return NULL; -} - -template -void MoveToBeginning( vector &v, const U &item ) -{ - vector::iterator it = find( v.begin(), v.end(), item ); - if( it == v.end() ) - return; - vector::iterator next = it; - ++next; - copy_backward( v.begin(), it, next ); - *v.begin() = item; -} - -static void FillWFEXT( WAVEFORMATEXTENSIBLE* pwfext, DeviceSampleFormat sampleFormat, int sampleRate, int channelCount) -{ - pwfext->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; - pwfext->Format.nChannels = channelCount; - pwfext->Format.nSamplesPerSec = sampleRate; - switch( channelCount ) - { - case 1: pwfext->dwChannelMask = KSAUDIO_SPEAKER_MONO; break; - case 2: pwfext->dwChannelMask = KSAUDIO_SPEAKER_STEREO; break; - case 4: pwfext->dwChannelMask = KSAUDIO_SPEAKER_QUAD; break; - case 6: pwfext->dwChannelMask = KSAUDIO_SPEAKER_5POINT1; break; // or KSAUDIO_SPEAKER_5POINT1_SURROUND - case 8: pwfext->dwChannelMask = KSAUDIO_SPEAKER_7POINT1_SURROUND; break; // or KSAUDIO_SPEAKER_7POINT1 - } - - switch(sampleFormat) - { - case DeviceSampleFormat_Float32: pwfext->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; break; - case DeviceSampleFormat_Int32: pwfext->SubFormat = KSDATAFORMAT_SUBTYPE_PCM; break; - case DeviceSampleFormat_Int24: pwfext->SubFormat = KSDATAFORMAT_SUBTYPE_PCM; break; - case DeviceSampleFormat_Int16: pwfext->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;break; - } - - pwfext->Format.nBlockAlign = GetBytesPerSample( sampleFormat ); - pwfext->Format.wBitsPerSample = pwfext->Format.nBlockAlign * 8; - pwfext->Format.nBlockAlign *= channelCount; - pwfext->Samples.wValidBitsPerSample = pwfext->Format.wBitsPerSample; - pwfext->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX); - pwfext->Format.nAvgBytesPerSec = pwfext->Format.nSamplesPerSec * pwfext->Format.nBlockAlign; -} - -WinWdmPin *WinWdmFilter::InstantiateRenderPin( - DeviceSampleFormat &PreferredOutputSampleFormat, - int &iPreferredOutputChannels, - int &iPreferredSampleRate, - RString &sError ) -{ - /* - * All Preferred settings are hints, and can be ignored if needed. - * - * Drivers can advertise DataRanges, and reject formats that fit it. This is documented - * for devices that don't support mono sound; it may happen for other cases. - * - * Supported channel configurations are 8 (7.1), 6 (5.1), 4, 2 (stereo) and 1 (mono). Prefer - * more channels, since some drivers won't send audio to rear speakers in stereo modes. Sort - * the preferred channel count first. - */ - vector aChannels; - aChannels.push_back( 8 ); - aChannels.push_back( 6 ); - aChannels.push_back( 4 ); - aChannels.push_back( 2 ); - aChannels.push_back( 1 ); - MoveToBeginning( aChannels, iPreferredOutputChannels ); - - /* Try all sample formats. Try PreferredOutputSampleFormat first. */ - vector SampleFormats; - SampleFormats.push_back( DeviceSampleFormat_Int16 ); - SampleFormats.push_back( DeviceSampleFormat_Int24 ); - SampleFormats.push_back( DeviceSampleFormat_Int32 ); - SampleFormats.push_back( DeviceSampleFormat_Float32 ); - MoveToBeginning( SampleFormats, PreferredOutputSampleFormat ); - - /* - * Some hardware may advertise support for 44.1khz, but actually use poor resampling. - * Try to use 48khz before 44.1khz, unless iPreferredSampleRate specifically asks - * for 44.1khz. - * - * Try all samplerates listed in the device's DATARANGES. Sort iSampleRate first, - * then 48k, then 44.1k, then higher sample rates first. - */ - vector aSampleRates; - { - for( size_t j = 0; j < m_apPins.size(); ++j ) - { - WinWdmPin *pPin = m_apPins[j]; - FOREACH_CONST( KSDATARANGE_AUDIO, pPin->m_dataRangesItem, range ) - { - aSampleRates.push_back( range->MinimumSampleFrequency ); - aSampleRates.push_back( range->MaximumSampleFrequency ); - } - } - - if( iPreferredSampleRate != 0 ) - aSampleRates.push_back( iPreferredSampleRate ); - aSampleRates.push_back( 48000 ); - aSampleRates.push_back( 44100 ); - - sort( aSampleRates.begin(), aSampleRates.end() ); - aSampleRates.erase( unique(aSampleRates.begin(), aSampleRates.end()), aSampleRates.end() ); - reverse( aSampleRates.begin(), aSampleRates.end() ); - - MoveToBeginning( aSampleRates, 44100 ); - MoveToBeginning( aSampleRates, 48000 ); - if( iPreferredSampleRate != 0 ) - MoveToBeginning( aSampleRates, iPreferredSampleRate ); - } - - /* Try WAVE_FORMAT_EXTENSIBLE, then WAVE_FORMAT_PCM. */ - vector aTryPCM; - aTryPCM.push_back( false ); - aTryPCM.push_back( true ); - - FOREACH( bool, aTryPCM, bTryPCM ) - { - FOREACH( int, aSampleRates, iSampleRate ) - { - FOREACH( int, aChannels, iChannels ) - { - FOREACH( DeviceSampleFormat, SampleFormats, fmt ) - { - PreferredOutputSampleFormat = *fmt; - iPreferredOutputChannels = *iChannels; - iPreferredSampleRate = *iSampleRate; - - WAVEFORMATEXTENSIBLE wfx; - FillWFEXT( &wfx, PreferredOutputSampleFormat, iPreferredSampleRate, iPreferredOutputChannels ); - if( *bTryPCM ) - { - /* Try WAVE_FORMAT_PCM instead of WAVE_FORMAT_EXTENSIBLE. */ - wfx.Format.wFormatTag = WAVE_FORMAT_PCM; - wfx.Format.cbSize = 0; - wfx.Samples.wValidBitsPerSample = 0; - wfx.dwChannelMask = 0; - wfx.SubFormat = GUID_NULL; - } - - LOG->Trace( "KS: trying format: %i channels: %i samplerate: %i format: %04x", - PreferredOutputSampleFormat, iPreferredOutputChannels, - iPreferredSampleRate, wfx.Format.wFormatTag ); - WinWdmPin *pPlaybackPin = InstantiateRenderPin( (WAVEFORMATEX *) &wfx, sError ); - - if( pPlaybackPin != NULL ) - { - LOG->Trace( "KS: success" ); - return pPlaybackPin; - } - } - } - } - } - - sError = "No compatible format found"; - return NULL; -} - -static bool GetDevicePath( HANDLE hHandle, SP_DEVICE_INTERFACE_DATA *pInterfaceData, RString &sPath ) -{ - unsigned char interfaceDetailsArray[sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + (MAX_PATH * sizeof(WCHAR))]; - const int sizeInterface = sizeof(interfaceDetailsArray); - SP_DEVICE_INTERFACE_DETAIL_DATA *devInterfaceDetails = (SP_DEVICE_INTERFACE_DETAIL_DATA*) interfaceDetailsArray; - devInterfaceDetails->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); - - SP_DEVINFO_DATA devInfoData; - devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); - devInfoData.Reserved = 0; - - if( !SetupDiGetDeviceInterfaceDetail(hHandle, pInterfaceData, devInterfaceDetails, sizeInterface, NULL, &devInfoData) ) - return false; - sPath = devInterfaceDetails->DevicePath; - return true; -} - -/* Build a list of available filters. */ -static bool BuildFilterList( vector &aFilters, RString &sError ) -{ - const GUID *pCategoryGuid = (GUID*) &KSCATEGORY_RENDER; - - /* Open a handle to search for devices (filters) */ - HDEVINFO hHandle = SetupDiGetClassDevs( pCategoryGuid, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE ); - if( hHandle == INVALID_HANDLE_VALUE ) - { - sError = werr_ssprintf( GetLastError(), "SetupDiGetClassDevs" ); - return false; - } - - CHECKPOINT_M( "Setup called" ); - - /* Create filter objects for each interface */ - for( int device = 0;;device++ ) - { - SP_DEVICE_INTERFACE_DATA interfaceData; - interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); - interfaceData.Reserved = 0; - if( !SetupDiEnumDeviceInterfaces(hHandle, NULL, pCategoryGuid, device, &interfaceData) ) - break; /* No more devices */ - if( !interfaceData.Flags || (interfaceData.Flags & SPINT_REMOVED) ) - continue; - - RString sDevicePath; - if( !GetDevicePath(hHandle, &interfaceData, sDevicePath) ) - continue; - - /* Try to get the friendly name for this interface */ - char szFriendlyName[MAX_PATH] = "(error)"; - DWORD sizeFriendlyName = sizeof(szFriendlyName); - HKEY hKey = SetupDiOpenDeviceInterfaceRegKey( hHandle, &interfaceData, 0, KEY_QUERY_VALUE ); - if( hKey != INVALID_HANDLE_VALUE ) - { - DWORD type; - if( RegQueryValueEx(hKey, "FriendlyName", 0, &type, (BYTE*) szFriendlyName, &sizeFriendlyName) != ERROR_SUCCESS ) - strcpy( szFriendlyName, "(error)" ); - RegCloseKey( hKey ); - } - - WinWdmFilter *pNewFilter = WinWdmFilter::Create( sDevicePath, szFriendlyName, sError ); - if( pNewFilter == NULL ) - { - LOG->Trace( "Filter \"%s\" not created: %s", szFriendlyName, sError.c_str() ); - continue; - } - - aFilters.push_back( pNewFilter ); - } - - if( hHandle != NULL ) - SetupDiDestroyDeviceInfoList( hHandle ); - - return true; -} - -static bool PaWinWdm_Initialize( RString &sError ) -{ - if( DllKsUser == NULL ) - { - DllKsUser = LoadLibrary( "ksuser.dll" ); - if( DllKsUser == NULL ) - { - sError = werr_ssprintf( GetLastError(), "LoadLibrary(ksuser.dll)" ); - return false; - } - } - - FunctionKsCreatePin = (KSCREATEPIN*) GetProcAddress( DllKsUser, "KsCreatePin" ); - if( FunctionKsCreatePin == NULL ) - { - sError = "no KsCreatePin in ksuser.dll"; - FreeLibrary( DllKsUser ); - DllKsUser = NULL; - return false; - } - - return true; -} - -#define MAX_CHUNKS 4 -struct WinWdmStream -{ - WinWdmStream() - { - memset( this, 0, sizeof(*this) ); - for( int i = 0; i < MAX_CHUNKS; ++i ) - m_Signal[i].hEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); - m_pPlaybackPin = NULL; - } - - ~WinWdmStream() - { - CloseHandle( m_Signal[0].hEvent ); - CloseHandle( m_Signal[1].hEvent ); - Close(); - } - - bool Open( WinWdmFilter *pFilter, - int iWriteAheadFrames, - DeviceSampleFormat PreferredOutputSampleFormat, - int iPreferredOutputChannels, - int iSampleRate, - RString &sError ); - void Close() - { - if( m_pPlaybackPin ) - m_pPlaybackPin->Close(); - m_pPlaybackPin = NULL; - for( int i = 0; i < 2; ++i ) - { - VirtualFree( m_Packets[i].Data, 0, MEM_RELEASE ); - m_Packets[i].Data = NULL; - } - } - - bool SubmitPacket( int iPacket, RString &sError ); - - WinWdmPin *m_pPlaybackPin; - KSSTREAM_HEADER m_Packets[MAX_CHUNKS]; - OVERLAPPED m_Signal[MAX_CHUNKS]; - - int m_iSampleRate; - int m_iWriteAheadChunks; - int m_iFramesPerChunk; - int m_iBytesPerOutputSample; - int m_iDeviceOutputChannels; - DeviceSampleFormat m_DeviceSampleFormat; -}; - -bool WinWdmStream::Open( WinWdmFilter *pFilter, - int iWriteAheadFrames, - DeviceSampleFormat PreferredOutputSampleFormat, - int iPreferredOutputChannels, - int iPreferredSampleRate, - RString &sError ) -{ - /* Instantiate the output pin. */ - m_pPlaybackPin = pFilter->InstantiateRenderPin( - PreferredOutputSampleFormat, - iPreferredOutputChannels, - iPreferredSampleRate, - sError ); - - if( m_pPlaybackPin == NULL ) - goto error; - - m_DeviceSampleFormat = PreferredOutputSampleFormat; - m_iDeviceOutputChannels = iPreferredOutputChannels; - m_iSampleRate = iPreferredSampleRate; - m_iBytesPerOutputSample = GetBytesPerSample( m_DeviceSampleFormat ); - - int iFrameSize = 1; - { - KSALLOCATOR_FRAMING ksaf; - KSALLOCATOR_FRAMING_EX ksafex; - if( WdmGetPropertySimple(m_pPlaybackPin->m_hHandle, &KSPROPSETID_Connection, KSPROPERTY_CONNECTION_ALLOCATORFRAMING, - &ksaf, sizeof(ksaf), NULL, 0, sError) ) - { - iFrameSize = ksaf.FrameSize; - } - else if( WdmGetPropertySimple(m_pPlaybackPin->m_hHandle, &KSPROPSETID_Connection, KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX, - &ksafex, sizeof(ksafex), NULL, 0, sError) ) - { - iFrameSize = ksafex.FramingItem[0].FramingRange.Range.MinFrameSize; - } - } - - iFrameSize /= m_iBytesPerOutputSample * m_iDeviceOutputChannels; - - m_iWriteAheadChunks = 2; - - /* If a writeahead was specified, use it. */ - m_iFramesPerChunk = iWriteAheadFrames / m_iWriteAheadChunks; - if( m_iFramesPerChunk == 0 ) - { - m_iFramesPerChunk = 512 / m_iWriteAheadChunks; - m_iFramesPerChunk = max( m_iFramesPerChunk, iFrameSize ); // iFrameSize may be 0 - } - - LOG->Info( "KS: chunk size: %i; allocator framing: %i (%ims)", m_iFramesPerChunk, iFrameSize, (iFrameSize * 1000) / m_iSampleRate ); - LOG->Info( "KS: %i hz", m_iSampleRate ); - - /* Set up chunks. */ - for( int i = 0; i < MAX_CHUNKS; ++i ) - { - // _aligned_malloc( size, 64 )? - KSSTREAM_HEADER *p = &m_Packets[i]; - - /* Avoid any FileAlignment problems by using VirtualAlloc, which is always page aligned. */ - p->Data = (char *) VirtualAlloc( NULL, m_iFramesPerChunk*m_iBytesPerOutputSample*m_iDeviceOutputChannels, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE ); - ASSERT( p->Data != NULL ); - p->FrameExtent = m_iFramesPerChunk*m_iBytesPerOutputSample*m_iDeviceOutputChannels; - p->DataUsed = m_iFramesPerChunk*m_iBytesPerOutputSample*m_iDeviceOutputChannels; - p->Size = sizeof(*p); - p->PresentationTime.Numerator = 1; - p->PresentationTime.Denominator = 1; - } - - return true; - -error: - Close(); - return false; -} - -bool WinWdmStream::SubmitPacket( int iPacket, RString &sError ) -{ - KSSTREAM_HEADER *p = &m_Packets[iPacket]; - int iRet = DeviceIoControl( m_pPlaybackPin->m_hHandle, IOCTL_KS_WRITE_STREAM, NULL, 0, - p, p->Size, NULL, &m_Signal[iPacket] ); - ASSERT_M( iRet == 0, "DeviceIoControl" ); - - DWORD iError = GetLastError(); - if( iError == ERROR_IO_PENDING ) - return true; - - sError = werr_ssprintf(iError, "DeviceIoControl"); - return false; -} - - -#include -namespace -{ - void MapChannels( const int16_t *pIn, int16_t *pOut, int iInChannels, int iOutChannels, int iFrames, const int *pChannelMap ) - { - for( int i = 0; i < iFrames; ++i ) - { - for( int j = 0; j < iOutChannels; ++j ) - { - if( pChannelMap[j] == -1 ) - pOut[j] = 0; - else if( pChannelMap[j] == -2 ) - { - int iSum = 0; - for( int k = 0; k < iInChannels; ++k ) - iSum += pIn[k]; - iSum /= iInChannels; - pOut[j] = iSum; - } - else - pOut[j] = pIn[ pChannelMap[j] ]; - } - pOut += iOutChannels; - pIn += iInChannels; - } - } - - void MapChannels( const int16_t *pIn, int16_t *pOut, int iInChannels, int iOutChannels, int iFrames ) - { - static const int i1ChannelMap[] = { -2 }; - static const int i4ChannelMap[] = { 0, 1, 0, 1 }; - static const int i5_1ChannelMap[] = { 0, 1, -1, -2, 0, 1 }; - static const int i7_1ChannelMap[] = { 0, 1, -1, -2, 0, 1, 0, 1 }; - const int *pChannelMap; - switch( iOutChannels ) - { - case 1: pChannelMap = i1ChannelMap; break; // KSAUDIO_SPEAKER_MONO - case 4: pChannelMap = i4ChannelMap; break; // KSAUDIO_SPEAKER_QUAD - case 6: pChannelMap = i5_1ChannelMap; break; // KSAUDIO_SPEAKER_5POINT1_SURROUND - case 8: pChannelMap = i7_1ChannelMap; break; // KSAUDIO_SPEAKER_7POINT1_SURROUND - default: FAIL_M( ssprintf("%i", iOutChannels) ); - } - MapChannels( pIn, pOut, iInChannels, iOutChannels, iFrames, pChannelMap ); - } - - void MapSampleFormatFromInt16( const int16_t *pIn, void *pOut, int iSamples, DeviceSampleFormat FromFormat ) - { - switch( FromFormat ) - { - case DeviceSampleFormat_Float32: // untested - { - float *pOutBuf = (float *) pOut; - for( int i = 0; i < iSamples; ++i ) - pOutBuf[i] = SCALE( pIn[i], -32768, +32767, -1.0f, +1.0f ); // [-32768, 32767] -> [-1,+1] - break; - } - case DeviceSampleFormat_Int24: - { - const unsigned char *pInBytes = (unsigned char *) pIn; - unsigned char *pOutBuf = (unsigned char *) pOut; - for( int i = 0; i < iSamples; ++i ) - { - *pOutBuf++ = 0; - *pOutBuf++ = *pInBytes++; - *pOutBuf++ = *pInBytes++; - } - break; - } - case DeviceSampleFormat_Int32: - { - int16_t *pOutBuf = (int16_t *) pOut; - for( int i = 0; i < iSamples; ++i ) - { - *pOutBuf++ = 0; - *pOutBuf++ = *pIn++; - } - break; - } - } - } -} - -void RageSoundDriver_WDMKS::Read( void *pData, int iFrames, int iLastCursorPos, int iCurrentFrame ) -{ - /* If we need conversion, read into a temporary buffer. Otherwise, read directly - * into the target buffer. */ - int iChannels = 2; - if( m_pStream->m_iDeviceOutputChannels == iChannels && - m_pStream->m_DeviceSampleFormat == DeviceSampleFormat_Int16 ) - { - int16_t *pBuf = (int16_t *) pData; - this->Mix( pBuf, iFrames, iLastCursorPos, iCurrentFrame ); - return; - } - - int16_t *pBuf = (int16_t *) alloca( iFrames * iChannels * sizeof(int16_t) ); - this->Mix( (int16_t *) pBuf, iFrames, iLastCursorPos, iCurrentFrame ); - - /* If the device has other than 2 channels, convert. */ - if( m_pStream->m_iDeviceOutputChannels != iChannels ) - { - int16_t *pTempBuf = (int16_t *) alloca( iFrames * m_pStream->m_iBytesPerOutputSample * m_pStream->m_iDeviceOutputChannels ); - MapChannels( (int16_t *) pBuf, pTempBuf, iChannels, m_pStream->m_iDeviceOutputChannels, iFrames ); - pBuf = pTempBuf; - } - - /* If the device format isn't int16_t, convert. */ - if( m_pStream->m_DeviceSampleFormat != DeviceSampleFormat_Int16 ) - { - int iSamples = iFrames * m_pStream->m_iDeviceOutputChannels; - void *pTempBuf = alloca( iSamples * m_pStream->m_iBytesPerOutputSample ); - MapSampleFormatFromInt16( (int16_t *) pBuf, pTempBuf, iSamples, m_pStream->m_DeviceSampleFormat ); - pBuf = (int16_t *) pTempBuf; - } - - memcpy( pData, pBuf, iFrames * m_pStream->m_iDeviceOutputChannels * m_pStream->m_iBytesPerOutputSample ); -} - -bool RageSoundDriver_WDMKS::Fill( int iPacket, RString &sError ) -{ - uint64_t iCurrentFrame = GetPosition(); -// if( iCurrentFrame == m_iLastCursorPos ) -// LOG->Trace( "underrun" ); - - Read( m_pStream->m_Packets[iPacket].Data, m_pStream->m_iFramesPerChunk, m_iLastCursorPos, iCurrentFrame ); - - /* Increment m_iLastCursorPos. */ - m_iLastCursorPos += m_pStream->m_iFramesPerChunk; - - /* Submit the buffer. */ - return m_pStream->SubmitPacket( iPacket, sError ); -} - -void RageSoundDriver_WDMKS::MixerThread() -{ - /* I don't trust this driver with THREAD_PRIORITY_TIME_CRITICAL just yet. */ - if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST) ) -// if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL) ) - LOG->Warn( werr_ssprintf(GetLastError(), "Failed to set sound thread priority") ); - - /* Enable priority boosting. */ - SetThreadPriorityBoost( GetCurrentThread(), FALSE ); - - ASSERT( m_pStream->m_pPlaybackPin != NULL ); - - /* Some drivers (stock USB audio in XP) misbehave if we go from KSSTATE_STOP to - * KSSTATE_RUN. Always transition through KSSTATE_PAUSE. */ - RString sError; - if( !m_pStream->m_pPlaybackPin->SetState(KSSTATE_PAUSE, sError) || - !m_pStream->m_pPlaybackPin->SetState(KSSTATE_RUN, sError) ) - FAIL_M( sError ); - - /* Submit initial buffers. */ - for( int i = 0; i < m_pStream->m_iWriteAheadChunks; ++i ) - Fill( i, sError ); - - int iNextBufferToSend = m_pStream->m_iWriteAheadChunks; - iNextBufferToSend %= MAX_CHUNKS; - - int iWaitFor = 0; - - while( !m_bShutdown ) - { - /* Wait for next output buffer to finish. */ - HANDLE aEventHandles[2] = { m_hSignal, m_pStream->m_Signal[iWaitFor].hEvent }; - unsigned long iWait = WaitForMultipleObjects( 2, aEventHandles, FALSE, 1000 ); - - if( iWait == WAIT_FAILED ) - { - LOG->Warn( werr_ssprintf(GetLastError(), "WaitForMultipleObjects") ); - break; - } - if( iWait == WAIT_TIMEOUT ) - continue; - - if( iWait == WAIT_OBJECT_0 ) - { - /* Abort event */ - ASSERT( m_bShutdown ); /* Should have been set */ - continue; - } - ++iWaitFor; - iWaitFor %= MAX_CHUNKS; - - if( !Fill(iNextBufferToSend, sError) ) - { - LOG->Warn( "Fill(): %s", sError.c_str() ); - break; - } - - ++iNextBufferToSend; - iNextBufferToSend %= MAX_CHUNKS; - } - - /* Finished, either normally or aborted */ - m_pStream->m_pPlaybackPin->SetState( KSSTATE_PAUSE, sError ); - m_pStream->m_pPlaybackPin->SetState( KSSTATE_STOP, sError ); -} - - -REGISTER_SOUND_DRIVER_CLASS( WDMKS ); - -int RageSoundDriver_WDMKS::MixerThread_start( void *p ) -{ - ((RageSoundDriver_WDMKS *) p)->MixerThread(); - return 0; -} - -void RageSoundDriver_WDMKS::SetupDecodingThread() -{ - if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL) ) - LOG->Warn( werr_ssprintf(GetLastError(), "Failed to set sound thread priority") ); -} - -int64_t RageSoundDriver_WDMKS::GetPosition() const -{ - KSAUDIO_POSITION pos; - - RString sError; - WdmGetPropertySimple( m_pStream->m_pPlaybackPin->m_hHandle, &KSPROPSETID_Audio, KSPROPERTY_AUDIO_POSITION, - &pos, sizeof(pos), NULL, 0, sError ); - ASSERT_M( sError == "", sError ); - - pos.PlayOffset /= m_pStream->m_iBytesPerOutputSample * m_pStream->m_iDeviceOutputChannels; - return pos.PlayOffset; -} - -RageSoundDriver_WDMKS::RageSoundDriver_WDMKS() -{ - m_pStream = NULL; - m_pFilter = NULL; - m_bShutdown = false; - m_iLastCursorPos = 0; - m_hSignal = CreateEvent( NULL, FALSE, FALSE, NULL ); /* abort event */ -} - -RString RageSoundDriver_WDMKS::Init() -{ - RString sError; - if( !PaWinWdm_Initialize(sError) ) - return sError; - - vector apFilters; - if( !BuildFilterList(apFilters, sError) ) - return "Error building filter list: " + sError; - if( apFilters.empty() ) - return "No supported audio devices found"; - - for( size_t i = 0; i < apFilters.size(); ++i ) - { - const WinWdmFilter *pFilter = apFilters[i]; - LOG->Trace( "Device #%i: %s", i, pFilter->m_sFriendlyName.c_str() ); - for( size_t j = 0; j < pFilter->m_apPins.size(); ++j ) - { - WinWdmPin *pPin = pFilter->m_apPins[j]; - LOG->Trace( " Pin %i", j ); - FOREACH_CONST( KSDATARANGE_AUDIO, pPin->m_dataRangesItem, range ) - { - RString sSubFormat; - if( !memcmp(&range->DataRange.SubFormat, &KSDATAFORMAT_SUBTYPE_WILDCARD, sizeof(GUID)) ) - sSubFormat = "WILDCARD"; - else if( !memcmp(&range->DataRange.SubFormat, &KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID)) ) - sSubFormat = "PCM"; - else if( !memcmp(&range->DataRange.SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof(GUID)) ) - sSubFormat = "FLOAT"; - - LOG->Trace( " Range: %i channels, sample %i-%i, %i-%ihz (%s)", - range->MaximumChannels, - range->MinimumBitsPerSample, - range->MaximumBitsPerSample, - range->MinimumSampleFrequency, - range->MaximumSampleFrequency, - sSubFormat.c_str() - ); - } - } - } - - m_pFilter = apFilters[0]; - for( size_t i=0; i < apFilters.size(); ++i ) - { - if( apFilters[i] != m_pFilter ) - delete apFilters[i]; - } - apFilters.clear(); - - m_pStream = new WinWdmStream; - if( !m_pStream->Open( m_pFilter, - PREFSMAN->m_iSoundWriteAhead, - DeviceSampleFormat_Int16, - 0, // don't care - PREFSMAN->m_iSoundPreferredSampleRate, - sError ) ) - { - return sError; - } - - SetDecodeBufferSize( 2048 ); - StartDecodeThread(); - - MixingThread.SetName( "Mixer thread" ); - MixingThread.Create( MixerThread_start, this ); - - return RString(); -} - -RageSoundDriver_WDMKS::~RageSoundDriver_WDMKS() -{ - /* Signal the mixing thread to quit. */ - if( MixingThread.IsCreated() ) - { - m_bShutdown = true; - SetEvent( m_hSignal ); /* Signal immediately */ - LOG->Trace( "Shutting down mixer thread ..." ); - MixingThread.Wait(); - LOG->Trace( "Mixer thread shut down." ); - - delete m_pStream; - } - - delete m_pFilter; - CloseHandle( m_hSignal ); -} - -int RageSoundDriver_WDMKS::GetSampleRate() const -{ - return m_pStream->m_iSampleRate; -} - -float RageSoundDriver_WDMKS::GetPlayLatency() const -{ - /* If we have a 1000-byte buffer, and we fill 500 bytes at a time, we - * almost always have between 500 and 1000 bytes filled; on average, 750. */ - return (m_pStream->m_iFramesPerChunk + m_pStream->m_iFramesPerChunk/2) * (1.0f / m_pStream->m_iSampleRate); -} - -/* - * Based on the PortAudio Windows WDM-KS interface. - * - * Copyright (c) 1999-2004 Andrew Baldwin, Ross Bencina, Phil Burk - * Copyright (c) 2002-2006 Glenn Maynard - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* - * The text above constitutes the entire PortAudio license; however, - * the PortAudio community also makes the following non-binding requests: - * - * Any person wishing to distribute modifications to the Software is - * requested to send the modifications to the original developer so that - * they can be incorporated into the canonical version. It is also - * requested that these non-binding requests be included along with the - * license above. - */ +#include "global.h" +#include "RageSoundDriver_WDMKS.h" + +#include "RageLog.h" +#include "RageUtil.h" +#include "PrefsManager.h" +#include "archutils/Win32/ErrorStrings.h" + +#define _INC_MMREG +#define _NTRTL_ /* Turn off default definition of DEFINE_GUIDEX */ +#if !defined(DEFINE_WAVEFORMATEX_GUID) +#define DEFINE_WAVEFORMATEX_GUID(x) (USHORT)(x), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 +#endif + +#include +#include +#include +#include +#include +#include + +typedef KSDDKAPI DWORD WINAPI KSCREATEPIN(HANDLE, PKSPIN_CONNECT, ACCESS_MASK, PHANDLE); + +#ifndef KSAUDIO_SPEAKER_5POINT1_SURROUND +#define KSAUDIO_SPEAKER_5POINT1_SURROUND \ + (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT) +#endif + +#ifndef KSAUDIO_SPEAKER_7POINT1_SURROUND +#define KSAUDIO_SPEAKER_7POINT1_SURROUND \ + (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | \ + SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | SPEAKER_SIDE_LEFT | SPEAKER_SIDE_RIGHT) +#endif + +struct WinWdmFilter; + +struct WinWdmPin +{ + WinWdmPin( WinWdmFilter *pParentFilter, int iPinId ) + { + m_hHandle = nullptr; + m_pParentFilter = pParentFilter; + m_iPinId = iPinId; + } + + ~WinWdmPin() + { + Close(); + } + + bool Instantiate( const WAVEFORMATEX *pFormat, RString &sError ); + void Close(); + + bool SetState( KSSTATE state, RString &sError ); + KSPIN_CONNECT *MakeFormat( const WAVEFORMATEX *pFormat ) const; + bool IsFormatSupported( const WAVEFORMATEX *pFormat ) const; + + HANDLE m_hHandle; + WinWdmFilter *m_pParentFilter; + int m_iPinId; + vector m_dataRangesItem; +}; + +enum DeviceSampleFormat +{ + DeviceSampleFormat_Float32, + DeviceSampleFormat_Int16, + DeviceSampleFormat_Int24, + DeviceSampleFormat_Int32, + NUM_DeviceSampleFormat, + DeviceSampleFormat_Invalid +}; + +static int GetBytesPerSample( DeviceSampleFormat sf ) +{ + switch( sf ) + { + case DeviceSampleFormat_Float32: return 4; + case DeviceSampleFormat_Int16: return 2; + case DeviceSampleFormat_Int24: return 3; + case DeviceSampleFormat_Int32: return 4; + DEFAULT_FAIL(sf); + } +} + +/* The Filter structure + * A filter has a number of pins and a "friendly name" */ +struct WinWdmFilter +{ + /* Filter management functions */ + static WinWdmFilter *Create( const RString &sFilterName, const RString &sFriendlyName, RString &sError ); + + WinWdmFilter() + { + m_hHandle = nullptr; + m_iUsageCount = 0; + } + + ~WinWdmFilter() + { + for( size_t i = 0; i < m_apPins.size(); ++i ) + delete m_apPins[i]; + if( m_hHandle ) + CloseHandle( m_hHandle ); + } + + WinWdmPin *CreatePin( unsigned long iPinId, RString &sError ); + WinWdmPin *InstantiateRenderPin( + DeviceSampleFormat &PreferredOutputSampleFormat, + int &iPreferredOutputChannels, + int &iPreferredSampleRate, + RString &sError ); + WinWdmPin *InstantiateRenderPin( const WAVEFORMATEX *wfex, RString &sError ); + bool Use( RString &sError ); + void Release(); + + HANDLE m_hHandle; + vector m_apPins; + RString m_sFilterName; + RString m_sFriendlyName; + int m_iUsageCount; +}; + +static RString GUIDToString( const GUID *pGuid ) +{ + return ssprintf("%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + pGuid->Data1, pGuid->Data2, pGuid->Data3, + pGuid->Data4[0], pGuid->Data4[1], pGuid->Data4[2], pGuid->Data4[3], + pGuid->Data4[4], pGuid->Data4[5], pGuid->Data4[6], pGuid->Data4[7] ); +} + +static HMODULE DllKsUser = nullptr; +static KSCREATEPIN *FunctionKsCreatePin = nullptr; + +/* Low level pin/filter access functions */ +static bool WdmSyncIoctl( + HANDLE hHandle, unsigned long ioctlNumber, void *pIn, unsigned long iInSize, + void *pOut, unsigned long iOutSize, unsigned long *pBytesReturned, RString &sError ) +{ + unsigned long iDummyBytesReturned; + if( pBytesReturned == nullptr ) + pBytesReturned = &iDummyBytesReturned; + + OVERLAPPED overlapped; + memset( &overlapped, 0, sizeof(overlapped) ); + overlapped.hEvent = CreateEvent( nullptr, FALSE, FALSE, nullptr ); + if( !overlapped.hEvent ) + { + sError = werr_ssprintf( GetLastError(), "CreateEvent" ); + return false; + } + overlapped.hEvent = (HANDLE)((DWORD_PTR)overlapped.hEvent | 0x1); + + int boolResult = DeviceIoControl( hHandle, ioctlNumber, pIn, iInSize, pOut, iOutSize, pBytesReturned, &overlapped ); + if( !boolResult ) + { + unsigned long iError = GetLastError(); + if( iError == ERROR_IO_PENDING ) + { + iError = WaitForSingleObject( overlapped.hEvent, INFINITE ); + if( iError != WAIT_OBJECT_0 ) + { + ASSERT( iError == WAIT_FAILED ); + sError = werr_ssprintf( GetLastError(), "WaitForSingleObject" ); + CloseHandle( overlapped.hEvent ); + return false; + } + } + else if(( iError == ERROR_INSUFFICIENT_BUFFER || iError == ERROR_MORE_DATA ) && + ioctlNumber == IOCTL_KS_PROPERTY && iOutSize == 0 ) + { + boolResult = TRUE; + } + else + { + sError = werr_ssprintf( iError, "DeviceIoControl" ); + CloseHandle( overlapped.hEvent ); + return false; + } + } + if( !boolResult ) + *pBytesReturned = 0; + + CloseHandle( overlapped.hEvent ); + return true; +} + +static bool WdmGetPropertySimple( HANDLE hHandle, const GUID *pGuidPropertySet, unsigned long iProperty, + void *pValue, unsigned long iValueSize, void *pInstance, unsigned long iInstanceSize, RString &sError ) +{ + unsigned long iPropertySize = sizeof(KSPROPERTY) + iInstanceSize; + vector buf; + buf.resize( iPropertySize ); + KSPROPERTY *ksProperty = (KSPROPERTY*) &buf[0]; + + memset( ksProperty, 0, sizeof(*ksProperty) ); + ksProperty->Set = *pGuidPropertySet; + ksProperty->Id = iProperty; + ksProperty->Flags = KSPROPERTY_TYPE_GET; + + if( pInstance ) + memcpy( &ksProperty[1], pInstance, iInstanceSize ); + + return WdmSyncIoctl( hHandle, IOCTL_KS_PROPERTY, ksProperty, iPropertySize, pValue, iValueSize, nullptr, sError ); +} + +static bool WdmSetPropertySimple( + HANDLE hHandle, const GUID *pGuidPropertySet, unsigned long iProperty, + void *pValue, unsigned long iValueSize, + void *instance, unsigned long iInstanceSize, RString &sError ) +{ + vector buf; + unsigned long iPropertySize = sizeof(KSPROPERTY) + iInstanceSize; + buf.resize( iPropertySize ); + KSPROPERTY *ksProperty = (KSPROPERTY *) &buf[0]; + + memset( ksProperty, 0, sizeof(*ksProperty) ); + ksProperty->Set = *pGuidPropertySet; + ksProperty->Id = iProperty; + ksProperty->Flags = KSPROPERTY_TYPE_SET; + + if( instance ) + memcpy( ((char*)ksProperty + sizeof(KSPROPERTY)), instance, iInstanceSize ); + + return WdmSyncIoctl( hHandle, IOCTL_KS_PROPERTY, ksProperty, iPropertySize, pValue, iValueSize, nullptr, sError ); +} + +static bool WdmGetPinPropertySimple( HANDLE hHandle, unsigned long iPinId, const GUID *pGuidPropertySet, unsigned long iProperty, + void *pValue, unsigned long iInstanceSize, RString &sError ) +{ + KSP_PIN ksPProp; + ksPProp.Property.Set = *pGuidPropertySet; + ksPProp.Property.Id = iProperty; + ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; + ksPProp.PinId = iPinId; + ksPProp.Reserved = 0; + + return WdmSyncIoctl( hHandle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN), pValue, iInstanceSize, nullptr, sError ); +} + +static bool WdmGetPinPropertyMulti( + HANDLE hHandle, + unsigned long iPinId, + const GUID *pGuidPropertySet, + unsigned long iProperty, + KSMULTIPLE_ITEM **ksMultipleItem, + RString &sError ) +{ + KSP_PIN ksPProp; + + ksPProp.Property.Set = *pGuidPropertySet; + ksPProp.Property.Id = iProperty; + ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; + ksPProp.PinId = iPinId; + ksPProp.Reserved = 0; + + unsigned long multipleItemSize = 0; + if( !WdmSyncIoctl(hHandle, IOCTL_KS_PROPERTY, &ksPProp.Property, sizeof(KSP_PIN), nullptr, 0, &multipleItemSize, sError) ) + return false; + + *ksMultipleItem = (KSMULTIPLE_ITEM*) malloc( multipleItemSize ); + ASSERT( *ksMultipleItem != nullptr ); + + if( !WdmSyncIoctl( hHandle, IOCTL_KS_PROPERTY, &ksPProp, sizeof(KSP_PIN), (void*)*ksMultipleItem, multipleItemSize, nullptr, sError) ) + { + free( ksMultipleItem ); + return false; + } + + return true; +} + +/* + * Create a new pin object belonging to a filter + * The pin object holds all the configuration information about the pin + * before it is opened, and then the handle of the pin after is opened + */ +WinWdmPin *WinWdmFilter::CreatePin( unsigned long iPinId, RString &sError ) +{ + { + /* Get the COMMUNICATION property */ + KSPIN_COMMUNICATION communication; + if( !WdmGetPinPropertySimple(m_hHandle, iPinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_COMMUNICATION, + &communication, sizeof(KSPIN_COMMUNICATION), sError) ) + { + sError = "KSPROPERTY_PIN_COMMUNICATION: " + sError; + return nullptr; + } + + if( communication != KSPIN_COMMUNICATION_SINK && communication != KSPIN_COMMUNICATION_BOTH ) + { + sError = "Not an audio output device"; + return nullptr; + } + } + + /* Get dataflow information */ + { + KSPIN_DATAFLOW dataFlow; + if( !WdmGetPinPropertySimple(m_hHandle, iPinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_DATAFLOW, + &dataFlow, sizeof(KSPIN_DATAFLOW), sError) ) + { + sError = "KSPROPERTY_PIN_DATAFLOW: " + sError; + return nullptr; + } + + if( dataFlow != KSPIN_DATAFLOW_IN ) + { + sError = "Not KSPIN_DATAFLOW_IN"; + return nullptr; + } + } + + /* Get the INTERFACE property list */ + { + KSMULTIPLE_ITEM *pItem = nullptr; + if( !WdmGetPinPropertyMulti(m_hHandle, iPinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_INTERFACES, &pItem, sError) ) + { + sError = "KSPROPERTY_PIN_INTERFACES: " + sError; + return nullptr; + } + + KSIDENTIFIER *identifier = (KSIDENTIFIER *) &pItem[1]; + + /* Check that at least one interface is STANDARD_STREAMING */ + sError = "No standard streaming"; + for( unsigned i = 0; i < pItem->Count; i++ ) + { + if( !memcmp( &identifier[i].Set, &KSINTERFACESETID_Standard, sizeof(GUID) ) && + identifier[i].Id == KSINTERFACE_STANDARD_STREAMING ) + { + sError = ""; + break; + } + } + + free( pItem ); + + if( sError != "" ) + return nullptr; + } + + /* Get the MEDIUM properties list */ + { + KSMULTIPLE_ITEM *pItem = nullptr; + if( !WdmGetPinPropertyMulti( m_hHandle, iPinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_MEDIUMS, &pItem, sError) ) + { + sError = "KSPROPERTY_PIN_MEDIUMS: " + sError; + return nullptr; + } + + const KSIDENTIFIER *identifier = (KSIDENTIFIER *) &pItem[1]; + + /* Check that at least one medium is STANDARD_DEVIO */ + sError = "No STANDARD_DEVIO"; + for( unsigned i = 0; i < pItem->Count; i++ ) + { + if( !memcmp( &identifier[i].Set, &KSMEDIUMSETID_Standard, sizeof(GUID) ) && + identifier[i].Id == KSMEDIUM_STANDARD_DEVIO ) + { + sError = ""; + break; + } + } + + free( pItem ); + + if( sError != "" ) + return nullptr; + } + + /* Allocate the new PIN object */ + WinWdmPin *pPin = new WinWdmPin( this, iPinId ); + + /* Get DATARANGEs */ + KSMULTIPLE_ITEM *pDataRangesItem; + if( !WdmGetPinPropertyMulti(m_hHandle, iPinId, &KSPROPSETID_Pin, KSPROPERTY_PIN_DATARANGES, &pDataRangesItem, sError) ) + { + sError = "KSPROPERTY_PIN_DATARANGES: " + sError; + goto error; + } + + KSDATARANGE *pDataRanges = (KSDATARANGE*) (pDataRangesItem + 1); + + /* Find audio DATARANGEs */ + { + KSDATARANGE *pDataRange = pDataRanges; + for( unsigned i = 0; i < pDataRangesItem->Count; i++, pDataRange = (KSDATARANGE*)( ((char*)pDataRange) + pDataRange->FormatSize) ) + { + if( memcmp(&pDataRange->MajorFormat, &KSDATAFORMAT_TYPE_AUDIO, sizeof(GUID)) && + memcmp(&pDataRange->MajorFormat, &KSDATAFORMAT_TYPE_WILDCARD, sizeof(GUID)) ) + continue; + + if( memcmp(&pDataRange->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID) ) && + memcmp(&pDataRange->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof(GUID) ) && + memcmp(&pDataRange->SubFormat, &KSDATAFORMAT_SUBTYPE_WILDCARD, sizeof(GUID) ) ) + continue; + + if( memcmp(&pDataRange->Specifier, &KSDATAFORMAT_SPECIFIER_WILDCARD, sizeof(GUID)) && + memcmp(&pDataRange->Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX, sizeof(GUID) )) + continue; + + const KSDATARANGE_AUDIO *pDataRangeAudio = (KSDATARANGE_AUDIO *) pDataRange; + pPin->m_dataRangesItem.push_back( *pDataRangeAudio ); + } + } + free( pDataRangesItem ); + pDataRangesItem = nullptr; + + if( pPin->m_dataRangesItem.size() == 0 ) + { + sError = "Pin has no supported audio data ranges"; + goto error; + } + + /* Success */ + sError = ""; + CHECKPOINT_M( "Pin created successfully" ); + return pPin; + +error: + /* Error cleanup */ + delete pPin; + return nullptr; +} + +/* If the pin handle is open, close it */ +void WinWdmPin::Close() +{ + if( m_hHandle == nullptr ) + return; + RString sError; + SetState( KSSTATE_PAUSE, sError ); + SetState( KSSTATE_STOP, sError ); + CloseHandle( m_hHandle ); + m_hHandle = nullptr; + m_pParentFilter->Release(); +} + +/* Set the state of this (instantiated) pin */ +bool WinWdmPin::SetState( KSSTATE state, RString &sError ) +{ + ASSERT( m_hHandle != nullptr ); + return WdmSetPropertySimple( m_hHandle, &KSPROPSETID_Connection, KSPROPERTY_CONNECTION_STATE, + &state, sizeof(state), nullptr, 0, sError ); +} + +bool WinWdmPin::Instantiate( const WAVEFORMATEX *pFormat, RString &sError ) +{ + if( !IsFormatSupported(pFormat) ) + { + sError = "format not supported"; + return false; + } + + + if( !m_pParentFilter->Use(sError) ) + return false; + + KSPIN_CONNECT *pPinConnect = MakeFormat( pFormat ); + DWORD iRet = FunctionKsCreatePin( m_pParentFilter->m_hHandle, pPinConnect, GENERIC_WRITE | GENERIC_READ, &m_hHandle ); + free( pPinConnect ); + if( iRet == ERROR_SUCCESS ) + return true; + + sError = werr_ssprintf( iRet, "FunctionKsCreatePin" ); + m_pParentFilter->Release(); + m_hHandle = nullptr; + return false; +} + +KSPIN_CONNECT *WinWdmPin::MakeFormat( const WAVEFORMATEX *pFormat ) const +{ + ASSERT( pFormat != nullptr ); + + unsigned long iWfexSize = sizeof(WAVEFORMATEX) + pFormat->cbSize; + unsigned long iDataFormatSize = sizeof(KSDATAFORMAT) + iWfexSize; + unsigned long iSize = sizeof(KSPIN_CONNECT) + iDataFormatSize; + + KSPIN_CONNECT *pPinConnect = (KSPIN_CONNECT *) malloc( iSize ); + ASSERT( pPinConnect != nullptr ); + + memset( pPinConnect, 0, iSize ); + pPinConnect->PinId = m_iPinId; + pPinConnect->Interface.Set = KSINTERFACESETID_Standard; + pPinConnect->Interface.Id = KSINTERFACE_STANDARD_STREAMING; + pPinConnect->Interface.Flags = 0; + pPinConnect->Medium.Set = KSMEDIUMSETID_Standard; + pPinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE; + pPinConnect->Medium.Flags = 0; + pPinConnect->PinToHandle = nullptr; + pPinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL; + pPinConnect->Priority.PrioritySubClass = 1; + + KSDATAFORMAT_WAVEFORMATEX *ksDataFormatWfx = (KSDATAFORMAT_WAVEFORMATEX *)(pPinConnect + 1); + ksDataFormatWfx->DataFormat.Flags = 0; + ksDataFormatWfx->DataFormat.Reserved = 0; + ksDataFormatWfx->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO; + ksDataFormatWfx->DataFormat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; + ksDataFormatWfx->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX; + ksDataFormatWfx->DataFormat.FormatSize = iDataFormatSize; + + memcpy( &ksDataFormatWfx->WaveFormatEx, pFormat, iWfexSize ); + ksDataFormatWfx->DataFormat.SampleSize = (unsigned short)(pFormat->nChannels * (pFormat->wBitsPerSample / 8)); + return pPinConnect; +} + +bool WinWdmPin::IsFormatSupported( const WAVEFORMATEX *pFormat ) const +{ + GUID guid = { DEFINE_WAVEFORMATEX_GUID(pFormat->wFormatTag) }; + + if( pFormat->wFormatTag == WAVE_FORMAT_EXTENSIBLE ) + guid = ((WAVEFORMATEXTENSIBLE*) pFormat)->SubFormat; + + for( size_t i = 0; i < m_dataRangesItem.size(); i++ ) + { + const KSDATARANGE_AUDIO *pDataRangeAudio = &m_dataRangesItem[i]; + /* This is an audio or wildcard datarange... */ + if( memcmp(&pDataRangeAudio->DataRange.SubFormat, &KSDATAFORMAT_SUBTYPE_WILDCARD, sizeof(GUID)) && + memcmp(&pDataRangeAudio->DataRange.SubFormat, &guid, sizeof(GUID)) ) + continue; + + if( pDataRangeAudio->MaximumChannels != (ULONG) -1 && pDataRangeAudio->MaximumChannels < pFormat->nChannels ) + continue; + if( pFormat->wBitsPerSample < pDataRangeAudio->MinimumBitsPerSample || pFormat->wBitsPerSample > pDataRangeAudio->MaximumBitsPerSample ) + continue; + if( pFormat->nSamplesPerSec < pDataRangeAudio->MinimumSampleFrequency || pFormat->nSamplesPerSec > pDataRangeAudio->MaximumSampleFrequency ) + continue; + + return true; + } + + return false; +} + +/* Create a new filter object. */ +WinWdmFilter *WinWdmFilter::Create( const RString &sFilterName, const RString &sFriendlyName, RString &sError ) +{ + /* Allocate the new filter object */ + WinWdmFilter *pFilter = new WinWdmFilter; + + pFilter->m_sFilterName = sFilterName; + pFilter->m_sFriendlyName = sFriendlyName; + + /* Open the filter handle */ + if( !pFilter->Use(sError) ) + goto error; + + /* Get pin count */ + int iNumPins; + if( !WdmGetPinPropertySimple(pFilter->m_hHandle, 0, &KSPROPSETID_Pin, KSPROPERTY_PIN_CTYPES, &iNumPins, sizeof(iNumPins), sError) ) + goto error; + + /* Create all the pins we can */ + for( int iPinId = 0; iPinId < iNumPins; iPinId++ ) + { + /* Create the pin with this Id */ + WinWdmPin *pNewPin = pFilter->CreatePin( iPinId, sError ); + if( pNewPin != nullptr ) + pFilter->m_apPins.push_back( pNewPin ); + } + + if( pFilter->m_apPins.empty() ) + { + /* No valid pin was found on this filter so we destroy it */ + sError = "filter has no supported audio pins"; + goto error; + } + + pFilter->Release(); + + sError = ""; + return pFilter; + +error: + /* Error cleanup */ + delete pFilter; + return nullptr; +} + +/* + * Reopen the filter handle if necessary so it can be used + */ +bool WinWdmFilter::Use( RString &sError ) +{ + if( m_hHandle == nullptr ) + { + /* Open the filter */ + m_hHandle = CreateFile( m_sFilterName, GENERIC_READ | GENERIC_WRITE, 0, + nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, nullptr ); + + if( m_hHandle == nullptr ) + { + sError = werr_ssprintf( GetLastError(), "CreateFile(%s)", m_sFilterName.c_str() ); + return false; + } + } + + ++m_iUsageCount; + return true; +} + +/* + * Release the filter handle if nobody is using it + */ +void WinWdmFilter::Release() +{ + ASSERT( m_iUsageCount > 0 ); + + --m_iUsageCount; + if( m_iUsageCount == 0 ) + { + if( m_hHandle != nullptr ) + { + CloseHandle( m_hHandle ); + m_hHandle = nullptr; + } + } +} + +/* + * Create a render (playback) Pin using the supplied format + */ +WinWdmPin *WinWdmFilter::InstantiateRenderPin( const WAVEFORMATEX *wfex, RString &sError ) +{ + for( size_t i = 0; i < m_apPins.size(); ++i ) + { + WinWdmPin *pPin = m_apPins[i]; + if( pPin->Instantiate(wfex, sError) ) + { + sError = ""; + return pPin; + } + } + + sError = "No pin supports format"; + return nullptr; +} + +template +void MoveToBeginning( vector &v, const U &item ) +{ + vector::iterator it = find( v.begin(), v.end(), item ); + if( it == v.end() ) + return; + vector::iterator next = it; + ++next; + copy_backward( v.begin(), it, next ); + *v.begin() = item; +} + +static void FillWFEXT( WAVEFORMATEXTENSIBLE* pwfext, DeviceSampleFormat sampleFormat, int sampleRate, int channelCount) +{ + pwfext->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; + pwfext->Format.nChannels = channelCount; + pwfext->Format.nSamplesPerSec = sampleRate; + switch( channelCount ) + { + case 1: pwfext->dwChannelMask = KSAUDIO_SPEAKER_MONO; break; + case 2: pwfext->dwChannelMask = KSAUDIO_SPEAKER_STEREO; break; + case 4: pwfext->dwChannelMask = KSAUDIO_SPEAKER_QUAD; break; + case 6: pwfext->dwChannelMask = KSAUDIO_SPEAKER_5POINT1; break; // or KSAUDIO_SPEAKER_5POINT1_SURROUND + case 8: pwfext->dwChannelMask = KSAUDIO_SPEAKER_7POINT1_SURROUND; break; // or KSAUDIO_SPEAKER_7POINT1 + } + + switch(sampleFormat) + { + case DeviceSampleFormat_Float32: pwfext->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; break; + case DeviceSampleFormat_Int32: pwfext->SubFormat = KSDATAFORMAT_SUBTYPE_PCM; break; + case DeviceSampleFormat_Int24: pwfext->SubFormat = KSDATAFORMAT_SUBTYPE_PCM; break; + case DeviceSampleFormat_Int16: pwfext->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;break; + } + + pwfext->Format.nBlockAlign = GetBytesPerSample( sampleFormat ); + pwfext->Format.wBitsPerSample = pwfext->Format.nBlockAlign * 8; + pwfext->Format.nBlockAlign *= channelCount; + pwfext->Samples.wValidBitsPerSample = pwfext->Format.wBitsPerSample; + pwfext->Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE)-sizeof(WAVEFORMATEX); + pwfext->Format.nAvgBytesPerSec = pwfext->Format.nSamplesPerSec * pwfext->Format.nBlockAlign; +} + +WinWdmPin *WinWdmFilter::InstantiateRenderPin( + DeviceSampleFormat &PreferredOutputSampleFormat, + int &iPreferredOutputChannels, + int &iPreferredSampleRate, + RString &sError ) +{ + /* + * All Preferred settings are hints, and can be ignored if needed. + * + * Drivers can advertise DataRanges, and reject formats that fit it. This is documented + * for devices that don't support mono sound; it may happen for other cases. + * + * Supported channel configurations are 8 (7.1), 6 (5.1), 4, 2 (stereo) and 1 (mono). Prefer + * more channels, since some drivers won't send audio to rear speakers in stereo modes. Sort + * the preferred channel count first. + */ + vector aChannels; + aChannels.push_back( 8 ); + aChannels.push_back( 6 ); + aChannels.push_back( 4 ); + aChannels.push_back( 2 ); + aChannels.push_back( 1 ); + MoveToBeginning( aChannels, iPreferredOutputChannels ); + + /* Try all sample formats. Try PreferredOutputSampleFormat first. */ + vector SampleFormats; + SampleFormats.push_back( DeviceSampleFormat_Int16 ); + SampleFormats.push_back( DeviceSampleFormat_Int24 ); + SampleFormats.push_back( DeviceSampleFormat_Int32 ); + SampleFormats.push_back( DeviceSampleFormat_Float32 ); + MoveToBeginning( SampleFormats, PreferredOutputSampleFormat ); + + /* + * Some hardware may advertise support for 44.1khz, but actually use poor resampling. + * Try to use 48khz before 44.1khz, unless iPreferredSampleRate specifically asks + * for 44.1khz. + * + * Try all samplerates listed in the device's DATARANGES. Sort iSampleRate first, + * then 48k, then 44.1k, then higher sample rates first. + */ + vector aSampleRates; + { + for (WinWdmPin *pPin : m_apPins) + { + for (KSDATARANGE_AUDIO const &range : pPin->m_dataRangesItem) + { + aSampleRates.push_back( range.MinimumSampleFrequency ); + aSampleRates.push_back( range.MaximumSampleFrequency ); + } + } + + if( iPreferredSampleRate != 0 ) + aSampleRates.push_back( iPreferredSampleRate ); + aSampleRates.push_back( 48000 ); + aSampleRates.push_back( 44100 ); + + sort( aSampleRates.begin(), aSampleRates.end() ); + aSampleRates.erase( unique(aSampleRates.begin(), aSampleRates.end()), aSampleRates.end() ); + reverse( aSampleRates.begin(), aSampleRates.end() ); + + MoveToBeginning( aSampleRates, 44100 ); + MoveToBeginning( aSampleRates, 48000 ); + if( iPreferredSampleRate != 0 ) + MoveToBeginning( aSampleRates, iPreferredSampleRate ); + } + + /* Try WAVE_FORMAT_EXTENSIBLE, then WAVE_FORMAT_PCM. */ + vector aTryPCM; + aTryPCM.push_back( false ); + aTryPCM.push_back( true ); + + for (auto bTryPCM = aTryPCM.begin(); bTryPCM != aTryPCM.end(); ++bTryPCM) + { + for (int const &iSampleRate : aSampleRates) + { + for (int const &iChannels : aChannels) + { + for (DeviceSampleFormat &fmt : SampleFormats) + { + PreferredOutputSampleFormat = fmt; + iPreferredOutputChannels = iChannels; + iPreferredSampleRate = iSampleRate; + + WAVEFORMATEXTENSIBLE wfx; + FillWFEXT( &wfx, PreferredOutputSampleFormat, iPreferredSampleRate, iPreferredOutputChannels ); + if( *bTryPCM ) + { + /* Try WAVE_FORMAT_PCM instead of WAVE_FORMAT_EXTENSIBLE. */ + wfx.Format.wFormatTag = WAVE_FORMAT_PCM; + wfx.Format.cbSize = 0; + wfx.Samples.wValidBitsPerSample = 0; + wfx.dwChannelMask = 0; + wfx.SubFormat = GUID_NULL; + } + + LOG->Trace( "KS: trying format: %i channels: %i samplerate: %i format: %04x", + PreferredOutputSampleFormat, iPreferredOutputChannels, + iPreferredSampleRate, wfx.Format.wFormatTag ); + WinWdmPin *pPlaybackPin = InstantiateRenderPin( (WAVEFORMATEX *) &wfx, sError ); + + if( pPlaybackPin != nullptr ) + { + LOG->Trace( "KS: success" ); + return pPlaybackPin; + } + } + } + } + } + + sError = "No compatible format found"; + return nullptr; +} + +static bool GetDevicePath( HANDLE hHandle, SP_DEVICE_INTERFACE_DATA *pInterfaceData, RString &sPath ) +{ + unsigned char interfaceDetailsArray[sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + (MAX_PATH * sizeof(WCHAR))]; + const int sizeInterface = sizeof(interfaceDetailsArray); + SP_DEVICE_INTERFACE_DETAIL_DATA *devInterfaceDetails = (SP_DEVICE_INTERFACE_DETAIL_DATA*) interfaceDetailsArray; + devInterfaceDetails->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA); + + SP_DEVINFO_DATA devInfoData; + devInfoData.cbSize = sizeof(SP_DEVINFO_DATA); + devInfoData.Reserved = 0; + + if( !SetupDiGetDeviceInterfaceDetail(hHandle, pInterfaceData, devInterfaceDetails, sizeInterface, nullptr, &devInfoData) ) + return false; + sPath = devInterfaceDetails->DevicePath; + return true; +} + +/* Build a list of available filters. */ +static bool BuildFilterList( vector &aFilters, RString &sError ) +{ + const GUID *pCategoryGuid = (GUID*) &KSCATEGORY_RENDER; + + /* Open a handle to search for devices (filters) */ + HDEVINFO hHandle = SetupDiGetClassDevs( pCategoryGuid, nullptr, nullptr, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE ); + if( hHandle == INVALID_HANDLE_VALUE ) + { + sError = werr_ssprintf( GetLastError(), "SetupDiGetClassDevs" ); + return false; + } + + CHECKPOINT_M( "Setup called" ); + + /* Create filter objects for each interface */ + for( int device = 0;;device++ ) + { + SP_DEVICE_INTERFACE_DATA interfaceData; + interfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); + interfaceData.Reserved = 0; + if( !SetupDiEnumDeviceInterfaces(hHandle, nullptr, pCategoryGuid, device, &interfaceData) ) + break; /* No more devices */ + if( !interfaceData.Flags || (interfaceData.Flags & SPINT_REMOVED) ) + continue; + + RString sDevicePath; + if( !GetDevicePath(hHandle, &interfaceData, sDevicePath) ) + continue; + + /* Try to get the friendly name for this interface */ + char szFriendlyName[MAX_PATH] = "(error)"; + DWORD sizeFriendlyName = sizeof(szFriendlyName); + HKEY hKey = SetupDiOpenDeviceInterfaceRegKey( hHandle, &interfaceData, 0, KEY_QUERY_VALUE ); + if( hKey != INVALID_HANDLE_VALUE ) + { + DWORD type; + if( RegQueryValueEx(hKey, "FriendlyName", 0, &type, (BYTE*) szFriendlyName, &sizeFriendlyName) != ERROR_SUCCESS ) + strcpy( szFriendlyName, "(error)" ); + RegCloseKey( hKey ); + } + + WinWdmFilter *pNewFilter = WinWdmFilter::Create( sDevicePath, szFriendlyName, sError ); + if( pNewFilter == nullptr ) + { + LOG->Trace( "Filter \"%s\" not created: %s", szFriendlyName, sError.c_str() ); + continue; + } + + aFilters.push_back( pNewFilter ); + } + + if( hHandle != nullptr ) + SetupDiDestroyDeviceInfoList( hHandle ); + + return true; +} + +static bool PaWinWdm_Initialize( RString &sError ) +{ + if( DllKsUser == nullptr ) + { + DllKsUser = LoadLibrary( "ksuser.dll" ); + if( DllKsUser == nullptr ) + { + sError = werr_ssprintf( GetLastError(), "LoadLibrary(ksuser.dll)" ); + return false; + } + } + + FunctionKsCreatePin = (KSCREATEPIN*) GetProcAddress( DllKsUser, "KsCreatePin" ); + if( FunctionKsCreatePin == nullptr ) + { + sError = "no KsCreatePin in ksuser.dll"; + FreeLibrary( DllKsUser ); + DllKsUser = nullptr; + return false; + } + + return true; +} + +#define MAX_CHUNKS 4 +struct WinWdmStream +{ + WinWdmStream() + { + memset( this, 0, sizeof(*this) ); + for( int i = 0; i < MAX_CHUNKS; ++i ) + m_Signal[i].hEvent = CreateEvent( nullptr, FALSE, FALSE, nullptr ); + m_pPlaybackPin = nullptr; + } + + ~WinWdmStream() + { + CloseHandle( m_Signal[0].hEvent ); + CloseHandle( m_Signal[1].hEvent ); + Close(); + } + + bool Open( WinWdmFilter *pFilter, + int iWriteAheadFrames, + DeviceSampleFormat PreferredOutputSampleFormat, + int iPreferredOutputChannels, + int iSampleRate, + RString &sError ); + void Close() + { + if( m_pPlaybackPin ) + m_pPlaybackPin->Close(); + m_pPlaybackPin = nullptr; + for( int i = 0; i < 2; ++i ) + { + VirtualFree( m_Packets[i].Data, 0, MEM_RELEASE ); + m_Packets[i].Data = nullptr; + } + } + + bool SubmitPacket( int iPacket, RString &sError ); + + WinWdmPin *m_pPlaybackPin; + KSSTREAM_HEADER m_Packets[MAX_CHUNKS]; + OVERLAPPED m_Signal[MAX_CHUNKS]; + + int m_iSampleRate; + int m_iWriteAheadChunks; + int m_iFramesPerChunk; + int m_iBytesPerOutputSample; + int m_iDeviceOutputChannels; + DeviceSampleFormat m_DeviceSampleFormat; +}; + +bool WinWdmStream::Open( WinWdmFilter *pFilter, + int iWriteAheadFrames, + DeviceSampleFormat PreferredOutputSampleFormat, + int iPreferredOutputChannels, + int iPreferredSampleRate, + RString &sError ) +{ + /* Instantiate the output pin. */ + m_pPlaybackPin = pFilter->InstantiateRenderPin( + PreferredOutputSampleFormat, + iPreferredOutputChannels, + iPreferredSampleRate, + sError ); + + if( m_pPlaybackPin == nullptr ) + goto error; + + m_DeviceSampleFormat = PreferredOutputSampleFormat; + m_iDeviceOutputChannels = iPreferredOutputChannels; + m_iSampleRate = iPreferredSampleRate; + m_iBytesPerOutputSample = GetBytesPerSample( m_DeviceSampleFormat ); + + int iFrameSize = 1; + { + KSALLOCATOR_FRAMING ksaf; + KSALLOCATOR_FRAMING_EX ksafex; + if( WdmGetPropertySimple(m_pPlaybackPin->m_hHandle, &KSPROPSETID_Connection, KSPROPERTY_CONNECTION_ALLOCATORFRAMING, + &ksaf, sizeof(ksaf), nullptr, 0, sError) ) + { + iFrameSize = ksaf.FrameSize; + } + else if( WdmGetPropertySimple(m_pPlaybackPin->m_hHandle, &KSPROPSETID_Connection, KSPROPERTY_CONNECTION_ALLOCATORFRAMING_EX, + &ksafex, sizeof(ksafex), nullptr, 0, sError) ) + { + iFrameSize = ksafex.FramingItem[0].FramingRange.Range.MinFrameSize; + } + } + + iFrameSize /= m_iBytesPerOutputSample * m_iDeviceOutputChannels; + + m_iWriteAheadChunks = 2; + + /* If a writeahead was specified, use it. */ + m_iFramesPerChunk = iWriteAheadFrames / m_iWriteAheadChunks; + if( m_iFramesPerChunk == 0 ) + { + m_iFramesPerChunk = 512 / m_iWriteAheadChunks; + m_iFramesPerChunk = max( m_iFramesPerChunk, iFrameSize ); // iFrameSize may be 0 + } + + LOG->Info( "KS: chunk size: %i; allocator framing: %i (%ims)", m_iFramesPerChunk, iFrameSize, (iFrameSize * 1000) / m_iSampleRate ); + LOG->Info( "KS: %i hz", m_iSampleRate ); + + /* Set up chunks. */ + for( int i = 0; i < MAX_CHUNKS; ++i ) + { + // _aligned_malloc( size, 64 )? + KSSTREAM_HEADER *p = &m_Packets[i]; + + /* Avoid any FileAlignment problems by using VirtualAlloc, which is always page aligned. */ + p->Data = (char *) VirtualAlloc( nullptr, m_iFramesPerChunk*m_iBytesPerOutputSample*m_iDeviceOutputChannels, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE ); + ASSERT( p->Data != nullptr ); + p->FrameExtent = m_iFramesPerChunk*m_iBytesPerOutputSample*m_iDeviceOutputChannels; + p->DataUsed = m_iFramesPerChunk*m_iBytesPerOutputSample*m_iDeviceOutputChannels; + p->Size = sizeof(*p); + p->PresentationTime.Numerator = 1; + p->PresentationTime.Denominator = 1; + } + + return true; + +error: + Close(); + return false; +} + +bool WinWdmStream::SubmitPacket( int iPacket, RString &sError ) +{ + KSSTREAM_HEADER *p = &m_Packets[iPacket]; + int iRet = DeviceIoControl( m_pPlaybackPin->m_hHandle, IOCTL_KS_WRITE_STREAM, nullptr, 0, + p, p->Size, nullptr, &m_Signal[iPacket] ); + ASSERT_M( iRet == 0, "DeviceIoControl" ); + + DWORD iError = GetLastError(); + if( iError == ERROR_IO_PENDING ) + return true; + + sError = werr_ssprintf(iError, "DeviceIoControl"); + return false; +} + + +#include +namespace +{ + void MapChannels( const int16_t *pIn, int16_t *pOut, int iInChannels, int iOutChannels, int iFrames, const int *pChannelMap ) + { + for( int i = 0; i < iFrames; ++i ) + { + for( int j = 0; j < iOutChannels; ++j ) + { + if( pChannelMap[j] == -1 ) + pOut[j] = 0; + else if( pChannelMap[j] == -2 ) + { + int iSum = 0; + for( int k = 0; k < iInChannels; ++k ) + iSum += pIn[k]; + iSum /= iInChannels; + pOut[j] = iSum; + } + else + pOut[j] = pIn[ pChannelMap[j] ]; + } + pOut += iOutChannels; + pIn += iInChannels; + } + } + + void MapChannels( const int16_t *pIn, int16_t *pOut, int iInChannels, int iOutChannels, int iFrames ) + { + static const int i1ChannelMap[] = { -2 }; + static const int i4ChannelMap[] = { 0, 1, 0, 1 }; + static const int i5_1ChannelMap[] = { 0, 1, -1, -2, 0, 1 }; + static const int i7_1ChannelMap[] = { 0, 1, -1, -2, 0, 1, 0, 1 }; + const int *pChannelMap; + switch( iOutChannels ) + { + case 1: pChannelMap = i1ChannelMap; break; // KSAUDIO_SPEAKER_MONO + case 4: pChannelMap = i4ChannelMap; break; // KSAUDIO_SPEAKER_QUAD + case 6: pChannelMap = i5_1ChannelMap; break; // KSAUDIO_SPEAKER_5POINT1_SURROUND + case 8: pChannelMap = i7_1ChannelMap; break; // KSAUDIO_SPEAKER_7POINT1_SURROUND + default: FAIL_M( ssprintf("%i", iOutChannels) ); + } + MapChannels( pIn, pOut, iInChannels, iOutChannels, iFrames, pChannelMap ); + } + + void MapSampleFormatFromInt16( const int16_t *pIn, void *pOut, int iSamples, DeviceSampleFormat FromFormat ) + { + switch( FromFormat ) + { + case DeviceSampleFormat_Float32: // untested + { + float *pOutBuf = (float *) pOut; + for( int i = 0; i < iSamples; ++i ) + pOutBuf[i] = SCALE( pIn[i], -32768, +32767, -1.0f, +1.0f ); // [-32768, 32767] -> [-1,+1] + break; + } + case DeviceSampleFormat_Int24: + { + const unsigned char *pInBytes = (unsigned char *) pIn; + unsigned char *pOutBuf = (unsigned char *) pOut; + for( int i = 0; i < iSamples; ++i ) + { + *pOutBuf++ = 0; + *pOutBuf++ = *pInBytes++; + *pOutBuf++ = *pInBytes++; + } + break; + } + case DeviceSampleFormat_Int32: + { + int16_t *pOutBuf = (int16_t *) pOut; + for( int i = 0; i < iSamples; ++i ) + { + *pOutBuf++ = 0; + *pOutBuf++ = *pIn++; + } + break; + } + } + } +} + +void RageSoundDriver_WDMKS::Read( void *pData, int iFrames, int iLastCursorPos, int iCurrentFrame ) +{ + /* If we need conversion, read into a temporary buffer. Otherwise, read directly + * into the target buffer. */ + int iChannels = 2; + if( m_pStream->m_iDeviceOutputChannels == iChannels && + m_pStream->m_DeviceSampleFormat == DeviceSampleFormat_Int16 ) + { + int16_t *pBuf = (int16_t *) pData; + this->Mix( pBuf, iFrames, iLastCursorPos, iCurrentFrame ); + return; + } + + int16_t *pBuf = (int16_t *) alloca( iFrames * iChannels * sizeof(int16_t) ); + this->Mix( (int16_t *) pBuf, iFrames, iLastCursorPos, iCurrentFrame ); + + /* If the device has other than 2 channels, convert. */ + if( m_pStream->m_iDeviceOutputChannels != iChannels ) + { + int16_t *pTempBuf = (int16_t *) alloca( iFrames * m_pStream->m_iBytesPerOutputSample * m_pStream->m_iDeviceOutputChannels ); + MapChannels( (int16_t *) pBuf, pTempBuf, iChannels, m_pStream->m_iDeviceOutputChannels, iFrames ); + pBuf = pTempBuf; + } + + /* If the device format isn't int16_t, convert. */ + if( m_pStream->m_DeviceSampleFormat != DeviceSampleFormat_Int16 ) + { + int iSamples = iFrames * m_pStream->m_iDeviceOutputChannels; + void *pTempBuf = alloca( iSamples * m_pStream->m_iBytesPerOutputSample ); + MapSampleFormatFromInt16( (int16_t *) pBuf, pTempBuf, iSamples, m_pStream->m_DeviceSampleFormat ); + pBuf = (int16_t *) pTempBuf; + } + + memcpy( pData, pBuf, iFrames * m_pStream->m_iDeviceOutputChannels * m_pStream->m_iBytesPerOutputSample ); +} + +bool RageSoundDriver_WDMKS::Fill( int iPacket, RString &sError ) +{ + uint64_t iCurrentFrame = GetPosition(); +// if( iCurrentFrame == m_iLastCursorPos ) +// LOG->Trace( "underrun" ); + + Read( m_pStream->m_Packets[iPacket].Data, m_pStream->m_iFramesPerChunk, m_iLastCursorPos, iCurrentFrame ); + + /* Increment m_iLastCursorPos. */ + m_iLastCursorPos += m_pStream->m_iFramesPerChunk; + + /* Submit the buffer. */ + return m_pStream->SubmitPacket( iPacket, sError ); +} + +void RageSoundDriver_WDMKS::MixerThread() +{ + /* I don't trust this driver with THREAD_PRIORITY_TIME_CRITICAL just yet. */ + if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST) ) +// if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL) ) + LOG->Warn( werr_ssprintf(GetLastError(), "Failed to set sound thread priority") ); + + /* Enable priority boosting. */ + SetThreadPriorityBoost( GetCurrentThread(), FALSE ); + + ASSERT( m_pStream->m_pPlaybackPin != nullptr ); + + /* Some drivers (stock USB audio in XP) misbehave if we go from KSSTATE_STOP to + * KSSTATE_RUN. Always transition through KSSTATE_PAUSE. */ + RString sError; + if( !m_pStream->m_pPlaybackPin->SetState(KSSTATE_PAUSE, sError) || + !m_pStream->m_pPlaybackPin->SetState(KSSTATE_RUN, sError) ) + FAIL_M( sError ); + + /* Submit initial buffers. */ + for( int i = 0; i < m_pStream->m_iWriteAheadChunks; ++i ) + Fill( i, sError ); + + int iNextBufferToSend = m_pStream->m_iWriteAheadChunks; + iNextBufferToSend %= MAX_CHUNKS; + + int iWaitFor = 0; + + while( !m_bShutdown ) + { + /* Wait for next output buffer to finish. */ + HANDLE aEventHandles[2] = { m_hSignal, m_pStream->m_Signal[iWaitFor].hEvent }; + unsigned long iWait = WaitForMultipleObjects( 2, aEventHandles, FALSE, 1000 ); + + if( iWait == WAIT_FAILED ) + { + LOG->Warn( werr_ssprintf(GetLastError(), "WaitForMultipleObjects") ); + break; + } + if( iWait == WAIT_TIMEOUT ) + continue; + + if( iWait == WAIT_OBJECT_0 ) + { + /* Abort event */ + ASSERT( m_bShutdown ); /* Should have been set */ + continue; + } + ++iWaitFor; + iWaitFor %= MAX_CHUNKS; + + if( !Fill(iNextBufferToSend, sError) ) + { + LOG->Warn( "Fill(): %s", sError.c_str() ); + break; + } + + ++iNextBufferToSend; + iNextBufferToSend %= MAX_CHUNKS; + } + + /* Finished, either normally or aborted */ + m_pStream->m_pPlaybackPin->SetState( KSSTATE_PAUSE, sError ); + m_pStream->m_pPlaybackPin->SetState( KSSTATE_STOP, sError ); +} + + +REGISTER_SOUND_DRIVER_CLASS( WDMKS ); + +int RageSoundDriver_WDMKS::MixerThread_start( void *p ) +{ + ((RageSoundDriver_WDMKS *) p)->MixerThread(); + return 0; +} + +void RageSoundDriver_WDMKS::SetupDecodingThread() +{ + if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL) ) + LOG->Warn( werr_ssprintf(GetLastError(), "Failed to set sound thread priority") ); +} + +int64_t RageSoundDriver_WDMKS::GetPosition() const +{ + KSAUDIO_POSITION pos; + + RString sError; + WdmGetPropertySimple( m_pStream->m_pPlaybackPin->m_hHandle, &KSPROPSETID_Audio, KSPROPERTY_AUDIO_POSITION, + &pos, sizeof(pos), nullptr, 0, sError ); + ASSERT_M( sError == "", sError ); + + pos.PlayOffset /= m_pStream->m_iBytesPerOutputSample * m_pStream->m_iDeviceOutputChannels; + return pos.PlayOffset; +} + +RageSoundDriver_WDMKS::RageSoundDriver_WDMKS() +{ + m_pStream = nullptr; + m_pFilter = nullptr; + m_bShutdown = false; + m_iLastCursorPos = 0; + m_hSignal = CreateEvent( nullptr, FALSE, FALSE, nullptr ); /* abort event */ +} + +RString RageSoundDriver_WDMKS::Init() +{ + RString sError; + if( !PaWinWdm_Initialize(sError) ) + return sError; + + vector apFilters; + if( !BuildFilterList(apFilters, sError) ) + return "Error building filter list: " + sError; + if( apFilters.empty() ) + return "No supported audio devices found"; + + for( size_t i = 0; i < apFilters.size(); ++i ) + { + const WinWdmFilter *pFilter = apFilters[i]; + LOG->Trace( "Device #%i: %s", i, pFilter->m_sFriendlyName.c_str() ); + int j = 0; + for (WinWdmPin *pPin : pFilter->m_apPins) + { + LOG->Trace( " Pin %i", j++ ); + for (KSDATARANGE_AUDIO const &range : pPin->m_dataRangesItem) + { + RString sSubFormat; + GUID const &rawSubFormat = range.DataRange.SubFormat; + if( !memcmp(&rawSubFormat, &KSDATAFORMAT_SUBTYPE_WILDCARD, sizeof(GUID)) ) + sSubFormat = "WILDCARD"; + else if( !memcmp(&rawSubFormat, &KSDATAFORMAT_SUBTYPE_PCM, sizeof(GUID)) ) + sSubFormat = "PCM"; + else if( !memcmp(&rawSubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, sizeof(GUID)) ) + sSubFormat = "FLOAT"; + + LOG->Trace( " Range: %i channels, sample %i-%i, %i-%ihz (%s)", + range.MaximumChannels, + range.MinimumBitsPerSample, + range.MaximumBitsPerSample, + range.MinimumSampleFrequency, + range.MaximumSampleFrequency, + sSubFormat.c_str() + ); + } + } + } + + m_pFilter = apFilters[0]; + for( size_t i=0; i < apFilters.size(); ++i ) + { + if( apFilters[i] != m_pFilter ) + delete apFilters[i]; + } + apFilters.clear(); + + m_pStream = new WinWdmStream; + if( !m_pStream->Open( m_pFilter, + PREFSMAN->m_iSoundWriteAhead, + DeviceSampleFormat_Int16, + 0, // don't care + PREFSMAN->m_iSoundPreferredSampleRate, + sError ) ) + { + return sError; + } + + SetDecodeBufferSize( 2048 ); + StartDecodeThread(); + + MixingThread.SetName( "Mixer thread" ); + MixingThread.Create( MixerThread_start, this ); + + return RString(); +} + +RageSoundDriver_WDMKS::~RageSoundDriver_WDMKS() +{ + /* Signal the mixing thread to quit. */ + if( MixingThread.IsCreated() ) + { + m_bShutdown = true; + SetEvent( m_hSignal ); /* Signal immediately */ + LOG->Trace( "Shutting down mixer thread ..." ); + MixingThread.Wait(); + LOG->Trace( "Mixer thread shut down." ); + + delete m_pStream; + } + + delete m_pFilter; + CloseHandle( m_hSignal ); +} + +int RageSoundDriver_WDMKS::GetSampleRate() const +{ + return m_pStream->m_iSampleRate; +} + +float RageSoundDriver_WDMKS::GetPlayLatency() const +{ + /* If we have a 1000-byte buffer, and we fill 500 bytes at a time, we + * almost always have between 500 and 1000 bytes filled; on average, 750. */ + return (m_pStream->m_iFramesPerChunk + m_pStream->m_iFramesPerChunk/2) * (1.0f / m_pStream->m_iSampleRate); +} + +/* + * Based on the PortAudio Windows WDM-KS interface. + * + * Copyright (c) 1999-2004 Andrew Baldwin, Ross Bencina, Phil Burk + * Copyright (c) 2002-2006 Glenn Maynard + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * The text above constitutes the entire PortAudio license; however, + * the PortAudio community also makes the following non-binding requests: + * + * Any person wishing to distribute modifications to the Software is + * requested to send the modifications to the original developer so that + * they can be incorporated into the canonical version. It is also + * requested that these non-binding requests be included along with the + * license above. + */ diff --git a/src/arch/Sound/RageSoundDriver_WaveOut.cpp b/src/arch/Sound/RageSoundDriver_WaveOut.cpp index 91ad896fd5..355bbdc3ad 100644 --- a/src/arch/Sound/RageSoundDriver_WaveOut.cpp +++ b/src/arch/Sound/RageSoundDriver_WaveOut.cpp @@ -1,211 +1,211 @@ -#include "global.h" -#include "RageSoundDriver_WaveOut.h" - -#if defined(_MSC_VER) -#pragma comment(lib, "winmm.lib") -#endif - -#include "RageTimer.h" -#include "RageLog.h" -#include "RageSound.h" -#include "RageUtil.h" -#include "RageSoundManager.h" -#include "PrefsManager.h" -#include "archutils/Win32/ErrorStrings.h" - -REGISTER_SOUND_DRIVER_CLASS( WaveOut ); - -const int channels = 2; -const int bytes_per_frame = channels*2; /* 16-bit */ -const int buffersize_frames = 1024*8; /* in frames */ -const int buffersize = buffersize_frames * bytes_per_frame; /* in bytes */ - -const int num_chunks = 8; -const int chunksize_frames = buffersize_frames / num_chunks; -const int chunksize = buffersize / num_chunks; /* in bytes */ - -static RString wo_ssprintf( MMRESULT err, const char *szFmt, ...) -{ - char szBuf[MAXERRORLENGTH]; - waveOutGetErrorText( err, szBuf, MAXERRORLENGTH ); - - va_list va; - va_start( va, szFmt ); - RString s = vssprintf( szFmt, va ); - va_end( va ); - - return s += ssprintf( "(%s)", szBuf ); -} - -int RageSoundDriver_WaveOut::MixerThread_start( void *p ) -{ - ((RageSoundDriver_WaveOut *) p)->MixerThread(); - return 0; -} - -void RageSoundDriver_WaveOut::MixerThread() -{ - if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL) ) - LOG->Warn( werr_ssprintf(GetLastError(), "Failed to set sound thread priority") ); - - while( !m_bShutdown ) - { - while( GetData() ) - ; - - WaitForSingleObject( m_hSoundEvent, 10 ); - } - - waveOutReset( m_hWaveOut ); -} - -bool RageSoundDriver_WaveOut::GetData() -{ - /* Look for a free buffer. */ - int b; - for( b = 0; b < num_chunks; ++b ) - if( m_aBuffers[b].dwFlags & WHDR_DONE ) - break; - if( b == num_chunks ) - return false; - - /* Call the callback. */ - this->Mix( (int16_t *) m_aBuffers[b].lpData, chunksize_frames, m_iLastCursorPos, GetPosition() ); - - MMRESULT ret = waveOutWrite( m_hWaveOut, &m_aBuffers[b], sizeof(m_aBuffers[b]) ); - if( ret != MMSYSERR_NOERROR ) - FAIL_M( wo_ssprintf(ret, "waveOutWrite failed") ); - - /* Increment m_iLastCursorPos. */ - m_iLastCursorPos += chunksize_frames; - - return true; -} - -void RageSoundDriver_WaveOut::SetupDecodingThread() -{ - if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL) ) - LOG->Warn( werr_ssprintf(GetLastError(), "Failed to set sound thread priority") ); -} - -int64_t RageSoundDriver_WaveOut::GetPosition() const -{ - MMTIME tm; - tm.wType = TIME_SAMPLES; - MMRESULT ret = waveOutGetPosition( m_hWaveOut, &tm, sizeof(tm) ); - if( ret != MMSYSERR_NOERROR ) - FAIL_M( wo_ssprintf(ret, "waveOutGetPosition failed") ); - - return tm.u.sample; -} - -RageSoundDriver_WaveOut::RageSoundDriver_WaveOut() -{ - m_bShutdown = false; - m_iLastCursorPos = 0; - - m_hSoundEvent = CreateEvent( NULL, false, true, NULL ); - - m_hWaveOut = NULL; -} - -RString RageSoundDriver_WaveOut::Init() -{ - m_iSampleRate = PREFSMAN->m_iSoundPreferredSampleRate; - if( m_iSampleRate == 0 ) - m_iSampleRate = 44100; - - WAVEFORMATEX fmt; - fmt.wFormatTag = WAVE_FORMAT_PCM; - fmt.nChannels = channels; - fmt.cbSize = 0; - fmt.nSamplesPerSec = m_iSampleRate; - fmt.wBitsPerSample = 16; - fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; - fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; - - MMRESULT ret = waveOutOpen( &m_hWaveOut, WAVE_MAPPER, &fmt, (DWORD_PTR) m_hSoundEvent, NULL, CALLBACK_EVENT ); - if( ret != MMSYSERR_NOERROR ) - return wo_ssprintf( ret, "waveOutOpen failed" ); - - ZERO( m_aBuffers ); - for(int b = 0; b < num_chunks; ++b) - { - m_aBuffers[b].dwBufferLength = chunksize; - m_aBuffers[b].lpData = new char[chunksize]; - ret = waveOutPrepareHeader( m_hWaveOut, &m_aBuffers[b], sizeof(m_aBuffers[b]) ); - if( ret != MMSYSERR_NOERROR ) - return wo_ssprintf( ret, "waveOutPrepareHeader failed" ); - m_aBuffers[b].dwFlags |= WHDR_DONE; - } - - LOG->Info( "WaveOut software mixing at %i hz", m_iSampleRate ); - - /* We have a very large writeahead; make sure we have a large enough decode - * buffer to recover cleanly from underruns. */ - SetDecodeBufferSize( buffersize_frames * 3/2 ); - StartDecodeThread(); - - MixingThread.SetName( "Mixer thread" ); - MixingThread.Create( MixerThread_start, this ); - - return RString(); -} - -RageSoundDriver_WaveOut::~RageSoundDriver_WaveOut() -{ - /* Signal the mixing thread to quit. */ - if( MixingThread.IsCreated() ) - { - m_bShutdown = true; - SetEvent( m_hSoundEvent ); - LOG->Trace( "Shutting down mixer thread ..." ); - MixingThread.Wait(); - LOG->Trace( "Mixer thread shut down." ); - } - - if( m_hWaveOut != NULL ) - { - for( int b = 0; b < num_chunks && m_aBuffers[b].lpData != NULL; ++b ) - { - waveOutUnprepareHeader( m_hWaveOut, &m_aBuffers[b], sizeof(m_aBuffers[b]) ); - delete [] m_aBuffers[b].lpData; - } - - waveOutClose( m_hWaveOut ); - } - - CloseHandle( m_hSoundEvent ); -} - -float RageSoundDriver_WaveOut::GetPlayLatency() const -{ - /* If we have a 1000-byte buffer, and we fill 100 bytes at a time, we - * almost always have between 900 and 1000 bytes filled; on average, 950. */ - return (buffersize_frames - chunksize_frames/2) * (1.0f / m_iSampleRate); -} - -/* - * (c) 2002-2004 Glenn Maynard - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ +#include "global.h" +#include "RageSoundDriver_WaveOut.h" + +#if defined(_MSC_VER) +#pragma comment(lib, "winmm.lib") +#endif + +#include "RageTimer.h" +#include "RageLog.h" +#include "RageSound.h" +#include "RageUtil.h" +#include "RageSoundManager.h" +#include "PrefsManager.h" +#include "archutils/Win32/ErrorStrings.h" + +REGISTER_SOUND_DRIVER_CLASS( WaveOut ); + +const int channels = 2; +const int bytes_per_frame = channels*2; /* 16-bit */ +const int buffersize_frames = 1024*8; /* in frames */ +const int buffersize = buffersize_frames * bytes_per_frame; /* in bytes */ + +const int num_chunks = 8; +const int chunksize_frames = buffersize_frames / num_chunks; +const int chunksize = buffersize / num_chunks; /* in bytes */ + +static RString wo_ssprintf( MMRESULT err, const char *szFmt, ...) +{ + char szBuf[MAXERRORLENGTH]; + waveOutGetErrorText( err, szBuf, MAXERRORLENGTH ); + + va_list va; + va_start( va, szFmt ); + RString s = vssprintf( szFmt, va ); + va_end( va ); + + return s += ssprintf( "(%s)", szBuf ); +} + +int RageSoundDriver_WaveOut::MixerThread_start( void *p ) +{ + ((RageSoundDriver_WaveOut *) p)->MixerThread(); + return 0; +} + +void RageSoundDriver_WaveOut::MixerThread() +{ + if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL) ) + LOG->Warn( werr_ssprintf(GetLastError(), "Failed to set sound thread priority") ); + + while( !m_bShutdown ) + { + while( GetData() ) + ; + + WaitForSingleObject( m_hSoundEvent, 10 ); + } + + waveOutReset( m_hWaveOut ); +} + +bool RageSoundDriver_WaveOut::GetData() +{ + /* Look for a free buffer. */ + int b; + for( b = 0; b < num_chunks; ++b ) + if( m_aBuffers[b].dwFlags & WHDR_DONE ) + break; + if( b == num_chunks ) + return false; + + /* Call the callback. */ + this->Mix( (int16_t *) m_aBuffers[b].lpData, chunksize_frames, m_iLastCursorPos, GetPosition() ); + + MMRESULT ret = waveOutWrite( m_hWaveOut, &m_aBuffers[b], sizeof(m_aBuffers[b]) ); + if( ret != MMSYSERR_NOERROR ) + FAIL_M( wo_ssprintf(ret, "waveOutWrite failed") ); + + /* Increment m_iLastCursorPos. */ + m_iLastCursorPos += chunksize_frames; + + return true; +} + +void RageSoundDriver_WaveOut::SetupDecodingThread() +{ + if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL) ) + LOG->Warn( werr_ssprintf(GetLastError(), "Failed to set sound thread priority") ); +} + +int64_t RageSoundDriver_WaveOut::GetPosition() const +{ + MMTIME tm; + tm.wType = TIME_SAMPLES; + MMRESULT ret = waveOutGetPosition( m_hWaveOut, &tm, sizeof(tm) ); + if( ret != MMSYSERR_NOERROR ) + FAIL_M( wo_ssprintf(ret, "waveOutGetPosition failed") ); + + return tm.u.sample; +} + +RageSoundDriver_WaveOut::RageSoundDriver_WaveOut() +{ + m_bShutdown = false; + m_iLastCursorPos = 0; + + m_hSoundEvent = CreateEvent( nullptr, false, true, nullptr ); + + m_hWaveOut = nullptr; +} + +RString RageSoundDriver_WaveOut::Init() +{ + m_iSampleRate = PREFSMAN->m_iSoundPreferredSampleRate; + if( m_iSampleRate == 0 ) + m_iSampleRate = 44100; + + WAVEFORMATEX fmt; + fmt.wFormatTag = WAVE_FORMAT_PCM; + fmt.nChannels = channels; + fmt.cbSize = 0; + fmt.nSamplesPerSec = m_iSampleRate; + fmt.wBitsPerSample = 16; + fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; + fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; + + MMRESULT ret = waveOutOpen( &m_hWaveOut, WAVE_MAPPER, &fmt, (DWORD_PTR) m_hSoundEvent, NULL, CALLBACK_EVENT ); + if( ret != MMSYSERR_NOERROR ) + return wo_ssprintf( ret, "waveOutOpen failed" ); + + ZERO( m_aBuffers ); + for(int b = 0; b < num_chunks; ++b) + { + m_aBuffers[b].dwBufferLength = chunksize; + m_aBuffers[b].lpData = new char[chunksize]; + ret = waveOutPrepareHeader( m_hWaveOut, &m_aBuffers[b], sizeof(m_aBuffers[b]) ); + if( ret != MMSYSERR_NOERROR ) + return wo_ssprintf( ret, "waveOutPrepareHeader failed" ); + m_aBuffers[b].dwFlags |= WHDR_DONE; + } + + LOG->Info( "WaveOut software mixing at %i hz", m_iSampleRate ); + + /* We have a very large writeahead; make sure we have a large enough decode + * buffer to recover cleanly from underruns. */ + SetDecodeBufferSize( buffersize_frames * 3/2 ); + StartDecodeThread(); + + MixingThread.SetName( "Mixer thread" ); + MixingThread.Create( MixerThread_start, this ); + + return RString(); +} + +RageSoundDriver_WaveOut::~RageSoundDriver_WaveOut() +{ + /* Signal the mixing thread to quit. */ + if( MixingThread.IsCreated() ) + { + m_bShutdown = true; + SetEvent( m_hSoundEvent ); + LOG->Trace( "Shutting down mixer thread ..." ); + MixingThread.Wait(); + LOG->Trace( "Mixer thread shut down." ); + } + + if( m_hWaveOut != nullptr ) + { + for( int b = 0; b < num_chunks && m_aBuffers[b].lpData != nullptr; ++b ) + { + waveOutUnprepareHeader( m_hWaveOut, &m_aBuffers[b], sizeof(m_aBuffers[b]) ); + delete [] m_aBuffers[b].lpData; + } + + waveOutClose( m_hWaveOut ); + } + + CloseHandle( m_hSoundEvent ); +} + +float RageSoundDriver_WaveOut::GetPlayLatency() const +{ + /* If we have a 1000-byte buffer, and we fill 100 bytes at a time, we + * almost always have between 900 and 1000 bytes filled; on average, 950. */ + return (buffersize_frames - chunksize_frames/2) * (1.0f / m_iSampleRate); +} + +/* + * (c) 2002-2004 Glenn Maynard + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/src/arch/Threads/Threads_Pthreads.cpp b/src/arch/Threads/Threads_Pthreads.cpp index 0689974e61..5d74f45e9a 100644 --- a/src/arch/Threads/Threads_Pthreads.cpp +++ b/src/arch/Threads/Threads_Pthreads.cpp @@ -85,7 +85,7 @@ ThreadImpl *MakeThread( int (*pFunc)(void *pData), void *pData, uint64_t *piThre thread->m_StartFinishedSem = new SemaImpl_Pthreads( 0 ); - int ret = pthread_create( &thread->thread, NULL, StartThread, thread ); + int ret = pthread_create( &thread->thread, nullptr, StartThread, thread ); ASSERT_M( ret == 0, ssprintf( "MakeThread: pthread_create: %s", strerror(errno)) ); // Don't return until StartThread sets m_piThreadID. @@ -131,7 +131,7 @@ ThreadImpl *MakeThread( int (*pFunc)(void *pData), void *pData, uint64_t *piThre MutexImpl_Pthreads::MutexImpl_Pthreads( RageMutex *pParent ): MutexImpl( pParent ) { - pthread_mutex_init( &mutex, NULL ); + pthread_mutex_init( &mutex, nullptr ); } MutexImpl_Pthreads::~MutexImpl_Pthreads() @@ -166,7 +166,7 @@ bool MutexImpl_Pthreads::Lock() /* Wait for ten seconds. If it takes longer than that, we're * probably deadlocked. */ timeval tv; - gettimeofday( &tv, NULL ); + gettimeofday( &tv, nullptr ); timespec ts; ts.tv_sec = tv.tv_sec + len; @@ -248,7 +248,7 @@ MutexImpl *MakeMutex( RageMutex *pParent ) namespace { typedef int (* CONDATTR_SET_CLOCK)( pthread_condattr_t *attr, clockid_t clock_id ); - CONDATTR_SET_CLOCK g_CondattrSetclock = NULL; + CONDATTR_SET_CLOCK g_CondattrSetclock = nullptr; bool bInitialized = false; #if defined(UNIX) @@ -263,17 +263,17 @@ namespace return; bInitialized = true; - void *pLib = NULL; + void *pLib = nullptr; do { { - pLib = dlopen( NULL, RTLD_LAZY ); - if( pLib == NULL ) + pLib = dlopen( nullptr, RTLD_LAZY ); + if( pLib == nullptr ) break; g_CondattrSetclock = (CONDATTR_SET_CLOCK) dlsym( pLib, "pthread_condattr_setclock" ); - if( g_CondattrSetclock == NULL ) + if( g_CondattrSetclock == nullptr ) break; } @@ -293,10 +293,10 @@ namespace return; } while(0); - g_CondattrSetclock = NULL; - if( pLib != NULL ) + g_CondattrSetclock = nullptr; + if( pLib != nullptr ) dlclose( pLib ); - pLib = NULL; + pLib = nullptr; } #elif defined(MACOSX) void InitMonotonic() { bInitialized = true; } @@ -323,7 +323,7 @@ EventImpl_Pthreads::EventImpl_Pthreads( MutexImpl_Pthreads *pParent ) pthread_condattr_t condattr; pthread_condattr_init( &condattr ); - if( g_CondattrSetclock != NULL ) + if( g_CondattrSetclock != nullptr ) g_CondattrSetclock( &condattr, GetClock() ); pthread_cond_init( &m_Cond, &condattr ); @@ -338,7 +338,7 @@ EventImpl_Pthreads::~EventImpl_Pthreads() #if defined(HAVE_PTHREAD_COND_TIMEDWAIT) bool EventImpl_Pthreads::Wait( RageTimer *pTimeout ) { - if( pTimeout == NULL ) + if( pTimeout == nullptr ) { pthread_cond_wait( &m_Cond, &m_pParent->mutex ); return true; @@ -348,7 +348,7 @@ bool EventImpl_Pthreads::Wait( RageTimer *pTimeout ) * (no condattr_setclock), pthread_cond_timedwait has an inherent race * condition: the system clock may change before we call it. */ timespec abstime; - if( g_CondattrSetclock != NULL || GetClock() == CLOCK_REALTIME ) + if( g_CondattrSetclock != nullptr || GetClock() == CLOCK_REALTIME ) { /* If we support condattr_setclock, we'll set the condition to use * the same clock as RageTimer and can use it directly. If the @@ -360,7 +360,7 @@ bool EventImpl_Pthreads::Wait( RageTimer *pTimeout ) { // The RageTimer clock is different than the wait clock; convert it. timeval tv; - gettimeofday( &tv, NULL ); + gettimeofday( &tv, nullptr ); RageTimer timeofday( tv.tv_sec, tv.tv_usec ); @@ -460,9 +460,9 @@ bool SemaImpl_Pthreads::TryWait() // Use conditions, to work around OS X "forgetting" to implement semaphores. SemaImpl_Pthreads::SemaImpl_Pthreads( int iInitialValue ) { - int ret = pthread_cond_init( &m_Cond, NULL ); + int ret = pthread_cond_init( &m_Cond, nullptr ); ASSERT_M( ret == 0, ssprintf( "SemaImpl_Pthreads: pthread_cond_init: %s", strerror(errno)) ); - ret = pthread_mutex_init( &m_Mutex, NULL ); + ret = pthread_mutex_init( &m_Mutex, nullptr ); ASSERT_M( ret == 0, ssprintf( "SemaImpl_Pthreads: pthread_mutex_init: %s", strerror(errno)) ); m_iValue = iInitialValue; @@ -489,7 +489,7 @@ bool SemaImpl_Pthreads::Wait() if( UseTimedlock() ) { timeval tv; - gettimeofday( &tv, NULL ); + gettimeofday( &tv, nullptr ); /* Wait for ten seconds. If it takes longer than that, we're probably deadlocked. */ timespec ts; diff --git a/src/arch/Threads/Threads_Win32.cpp b/src/arch/Threads/Threads_Win32.cpp index edc08af71b..e74bb5a74f 100644 --- a/src/arch/Threads/Threads_Win32.cpp +++ b/src/arch/Threads/Threads_Win32.cpp @@ -7,12 +7,12 @@ const int MAX_THREADS=128; -static MutexImpl_Win32 *g_pThreadIdMutex = NULL; +static MutexImpl_Win32 *g_pThreadIdMutex = nullptr; static void InitThreadIdMutex() { - if( g_pThreadIdMutex != NULL ) + if( g_pThreadIdMutex != nullptr ) return; - g_pThreadIdMutex = new MutexImpl_Win32(NULL); + g_pThreadIdMutex = new MutexImpl_Win32(nullptr); } static uint64_t g_ThreadIds[MAX_THREADS]; @@ -26,7 +26,7 @@ HANDLE Win32ThreadIdToHandle( uint64_t iID ) return g_ThreadHandles[i]; } - return NULL; + return nullptr; } void ThreadImpl_Win32::Halt( bool Kill ) @@ -55,7 +55,7 @@ int ThreadImpl_Win32::Wait() GetExitCodeThread( ThreadHandle, &ret ); CloseHandle( ThreadHandle ); - ThreadHandle = NULL; + ThreadHandle = nullptr; return ret; } @@ -100,7 +100,7 @@ static DWORD WINAPI StartThread( LPVOID pData ) { if( g_ThreadIds[i] == RageThread::GetCurrentThreadID() ) { - g_ThreadHandles[i] = NULL; + g_ThreadHandles[i] = nullptr; g_ThreadIds[i] = 0; break; } @@ -143,7 +143,7 @@ ThreadImpl *MakeThisThread() // LOG->Warn( werr_ssprintf( GetLastError(), "DuplicateHandle(%p, %p) failed", // CurProc, GetCurrentThread() ) ); - thread->ThreadHandle = NULL; + thread->ThreadHandle = nullptr; } thread->ThreadId = GetCurrentThreadId(); @@ -160,9 +160,9 @@ ThreadImpl *MakeThread( int (*pFunc)(void *pData), void *pData, uint64_t *piThre thread->m_pFunc = pFunc; thread->m_pData = pData; - thread->ThreadHandle = CreateThread( NULL, 0, &StartThread, thread, CREATE_SUSPENDED, &thread->ThreadId ); + thread->ThreadHandle = CreateThread( nullptr, 0, &StartThread, thread, CREATE_SUSPENDED, &thread->ThreadId ); *piThreadID = (uint64_t) thread->ThreadId; - ASSERT_M( thread->ThreadHandle != NULL, ssprintf("%s", werr_ssprintf(GetLastError(), "CreateThread").c_str() ) ); + ASSERT_M( thread->ThreadHandle != nullptr, ssprintf("%s", werr_ssprintf(GetLastError(), "CreateThread").c_str() ) ); int slot = GetOpenSlot( thread->ThreadId ); g_ThreadHandles[slot] = thread->ThreadHandle; @@ -177,8 +177,8 @@ ThreadImpl *MakeThread( int (*pFunc)(void *pData), void *pData, uint64_t *piThre MutexImpl_Win32::MutexImpl_Win32( RageMutex *pParent ): MutexImpl( pParent ) { - mutex = CreateMutex( NULL, false, NULL ); - ASSERT_M( mutex != NULL, werr_ssprintf(GetLastError(), "CreateMutex") ); + mutex = CreateMutex( nullptr, false, nullptr ); + ASSERT_M( mutex != nullptr, werr_ssprintf(GetLastError(), "CreateMutex") ); } MutexImpl_Win32::~MutexImpl_Win32() @@ -188,7 +188,7 @@ MutexImpl_Win32::~MutexImpl_Win32() static bool SimpleWaitForSingleObject( HANDLE h, DWORD ms ) { - ASSERT( h != NULL ); + ASSERT( h != nullptr ); DWORD ret = WaitForSingleObject( h, ms ); switch( ret ) @@ -266,9 +266,9 @@ EventImpl_Win32::EventImpl_Win32( MutexImpl_Win32 *pParent ) { m_pParent = pParent; m_iNumWaiting = 0; - m_WakeupSema = CreateSemaphore( NULL, 0, 0x7fffffff, NULL ); + m_WakeupSema = CreateSemaphore( nullptr, 0, 0x7fffffff, nullptr ); InitializeCriticalSection( &m_iNumWaitingLock ); - m_WaitersDone = CreateEvent( NULL, FALSE, FALSE, NULL ); + m_WaitersDone = CreateEvent( nullptr, FALSE, FALSE, nullptr ); } EventImpl_Win32::~EventImpl_Win32() @@ -356,7 +356,7 @@ bool EventImpl_Win32::Wait( RageTimer *pTimeout ) LeaveCriticalSection( &m_iNumWaitingLock ); unsigned iMilliseconds = INFINITE; - if( pTimeout != NULL ) + if( pTimeout != nullptr ) { float fSecondsInFuture = -pTimeout->Ago(); iMilliseconds = (unsigned) max( 0, int( fSecondsInFuture * 1000 ) ); @@ -435,7 +435,7 @@ EventImpl *MakeEvent( MutexImpl *pMutex ) SemaImpl_Win32::SemaImpl_Win32( int iInitialValue ) { - sem = CreateSemaphore( NULL, iInitialValue, 999999999, NULL ); + sem = CreateSemaphore( nullptr, iInitialValue, 999999999, nullptr ); m_iCounter = iInitialValue; } @@ -447,7 +447,7 @@ SemaImpl_Win32::~SemaImpl_Win32() void SemaImpl_Win32::Post() { ++m_iCounter; - ReleaseSemaphore( sem, 1, NULL ); + ReleaseSemaphore( sem, 1, nullptr ); } bool SemaImpl_Win32::Wait() diff --git a/src/archutils/Common/PthreadHelpers.cpp b/src/archutils/Common/PthreadHelpers.cpp index edfa3ecc8e..543f70c55a 100644 --- a/src/archutils/Common/PthreadHelpers.cpp +++ b/src/archutils/Common/PthreadHelpers.cpp @@ -100,7 +100,7 @@ static int waittid( int ThreadID, int *status, int options ) static int PtraceAttach( int ThreadID ) { int ret; - ret = ptrace( PTRACE_ATTACH, ThreadID, NULL, NULL ); + ret = ptrace( PTRACE_ATTACH, ThreadID, nullptr, nullptr ); if( ret == -1 ) { printf("ptrace failed: %s\n", strerror(errno) ); @@ -120,7 +120,7 @@ static int PtraceAttach( int ThreadID ) static int PtraceDetach( int ThreadID ) { - return ptrace( PTRACE_DETACH, ThreadID, NULL, NULL ); + return ptrace( PTRACE_DETACH, ThreadID, nullptr, nullptr ); } @@ -223,7 +223,7 @@ bool GetThreadBacktraceContext( uint64_t ThreadID, BacktraceContext *ctx ) #if defined(CPU_X86_64) || defined(CPU_X86) user_regs_struct regs; - if( ptrace( PTRACE_GETREGS, pid_t(ThreadID), NULL, ®s ) == -1 ) + if( ptrace( PTRACE_GETREGS, pid_t(ThreadID), nullptr, ®s ) == -1 ) return false; ctx->pid = pid_t(ThreadID); diff --git a/src/archutils/Darwin/Crash.cpp b/src/archutils/Darwin/Crash.cpp index 1ee8f26341..a8ba3a04bc 100644 --- a/src/archutils/Darwin/Crash.cpp +++ b/src/archutils/Darwin/Crash.cpp @@ -24,7 +24,7 @@ RString CrashHandler::GetLogsDirectory() } // XXX Can we use LocalizedString here instead? -#define LSTRING(b,x) CFBundleCopyLocalizedString( (b), CFSTR(x), NULL, CFSTR("Localizable") ) +#define LSTRING(b,x) CFBundleCopyLocalizedString( (b), CFSTR(x), nullptr, CFSTR("Localizable") ) void CrashHandler::InformUserOfCrash( const RString& sPath ) { @@ -41,12 +41,12 @@ void CrashHandler::InformUserOfCrash( const RString& sPath ) CFStringRef sFormat = LSTRING( bundle, PRODUCT_FAMILY " has crashed. " "Debugging information has been output to\n\n%s\n\n" "Please file a bug report at\n\n%s" ); - CFStringRef sBody = CFStringCreateWithFormat( kCFAllocatorDefault, NULL, sFormat, + CFStringRef sBody = CFStringCreateWithFormat( kCFAllocatorDefault, nullptr, sFormat, sPath.c_str(), REPORT_BUG_URL ); CFOptionFlags response = kCFUserNotificationCancelResponse; CFTimeInterval timeout = 0.0; // Should we ever time out? - CFUserNotificationDisplayAlert( timeout, kCFUserNotificationStopAlertLevel, NULL, NULL, NULL, + CFUserNotificationDisplayAlert( timeout, kCFUserNotificationStopAlertLevel, nullptr, nullptr, nullptr, sTitle, sBody, sDefault, sAlternate, sOther, &response ); switch( response ) @@ -86,7 +86,7 @@ bool CrashHandler::IsDebuggerPresent() // Call sysctl. size = sizeof( info ); - ret = sysctl( mib, sizeof(mib)/sizeof(*mib), &info, &size, NULL, 0 ); + ret = sysctl( mib, sizeof(mib)/sizeof(*mib), &info, &size, nullptr, 0 ); // We're being debugged if the P_TRACED flag is set. diff --git a/src/archutils/Darwin/HIDDevice.cpp b/src/archutils/Darwin/HIDDevice.cpp index 61f98a787e..a3629d86ca 100644 --- a/src/archutils/Darwin/HIDDevice.cpp +++ b/src/archutils/Darwin/HIDDevice.cpp @@ -2,7 +2,7 @@ #include "HIDDevice.h" #include "RageUtil.h" -HIDDevice::HIDDevice() : m_Interface( NULL ), m_Queue( NULL ), m_bRunning( false ) +HIDDevice::HIDDevice() : m_Interface(nullptr), m_Queue(nullptr), m_bRunning( false ) { } @@ -108,7 +108,7 @@ bool HIDDevice::Open( io_object_t device ) if( hresult != S_OK ) { LOG->Warn( "Couldn't get device interface from plugin interface." ); - m_Interface = NULL; + m_Interface = nullptr; return false; } @@ -117,7 +117,7 @@ bool HIDDevice::Open( io_object_t device ) { PrintIOErr( ret, "Failed to open the interface." ); CALL( m_Interface, Release ); - m_Interface = NULL; + m_Interface = nullptr; return false; } @@ -133,9 +133,9 @@ bool HIDDevice::Open( io_object_t device ) { PrintIOErr( ret, "Failed to create the queue." ); CALL( m_Queue, Release ); - m_Queue = NULL; + m_Queue = nullptr; CALL( m_Interface, Release ); - m_Interface = NULL; + m_Interface = nullptr; return false; } diff --git a/src/archutils/Darwin/HIDDevice.h b/src/archutils/Darwin/HIDDevice.h index d486109688..897c595602 100644 --- a/src/archutils/Darwin/HIDDevice.h +++ b/src/archutils/Darwin/HIDDevice.h @@ -101,7 +101,7 @@ protected: // Perform a synchronous set report on the HID interface. inline IOReturn SetReport( IOHIDReportType type, UInt32 reportID, void *buffer, UInt32 size, UInt32 timeoutMS ) { - return CALL( m_Interface, setReport, type, reportID, buffer, size, timeoutMS, NULL, NULL, NULL ); + return CALL( m_Interface, setReport, type, reportID, buffer, size, timeoutMS, nullptr, nullptr, nullptr ); } public: HIDDevice(); diff --git a/src/archutils/Darwin/JoystickDevice.cpp b/src/archutils/Darwin/JoystickDevice.cpp index 4e4c35cc51..0642b4a38c 100644 --- a/src/archutils/Darwin/JoystickDevice.cpp +++ b/src/archutils/Darwin/JoystickDevice.cpp @@ -1,7 +1,6 @@ #include "global.h" #include "JoystickDevice.h" #include "RageLog.h" -#include "Foreach.h" using __gnu_cxx::hash_map; @@ -128,9 +127,8 @@ void JoystickDevice::AddElement( int usagePage, int usage, IOHIDElementCookie co void JoystickDevice::Open() { // Add elements to the queue for each Joystick - FOREACH_CONST( Joystick, m_vSticks, i ) + for (Joystick const &js : m_vSticks) { - const Joystick& js = *i; #define ADD(x) if( js.x ) AddElementToQueue( js.x ) ADD( x_axis ); ADD( y_axis ); ADD( z_axis ); ADD( x_rot ); ADD( y_rot ); ADD( z_rot ); @@ -156,10 +154,8 @@ bool JoystickDevice::InitDevice( int vid, int pid ) void JoystickDevice::GetButtonPresses( vector& vPresses, IOHIDElementCookie cookie, int value, const RageTimer& now ) const { - FOREACH_CONST( Joystick, m_vSticks, i ) + for (Joystick const &js : m_vSticks) { - const Joystick& js = *i; - if( js.x_axis == cookie ) { float level = SCALE( value, js.x_min, js.x_max, -1.0f, 1.0f ); @@ -251,7 +247,7 @@ int JoystickDevice::AssignIDs( InputDevice startID ) { if( !IsJoystick(startID) ) return -1; - FOREACH( Joystick, m_vSticks, i ) + for (auto i = m_vSticks.begin(); i != m_vSticks.end(); ++i) { if( !IsJoystick(startID) ) { @@ -266,8 +262,8 @@ int JoystickDevice::AssignIDs( InputDevice startID ) void JoystickDevice::GetDevicesAndDescriptions( vector& vDevices ) const { - FOREACH_CONST( Joystick, m_vSticks, i ) - vDevices.push_back( InputDeviceInfo(i->id,GetDescription()) ); + for (auto &i : m_vSticks) + vDevices.push_back( InputDeviceInfo(i.id,GetDescription()) ); } /* diff --git a/src/archutils/Darwin/SMMain.mm b/src/archutils/Darwin/SMMain.mm index 95046db24f..9bb44b9b37 100644 --- a/src/archutils/Darwin/SMMain.mm +++ b/src/archutils/Darwin/SMMain.mm @@ -191,8 +191,8 @@ static void SetupMenus( void ) [item setKeyEquivalentModifierMask:NSAlternateKeyMask]; // opt-enter [windowMenu addItem:item]; - [[mainMenu addItemWithTitle:[appMenu title] action:NULL keyEquivalent:@""] setSubmenu:appMenu]; - [[mainMenu addItemWithTitle:[windowMenu title] action:NULL keyEquivalent:@""] setSubmenu:windowMenu]; + [[mainMenu addItemWithTitle:[appMenu title] action:nil keyEquivalent:@""] setSubmenu:appMenu]; + [[mainMenu addItemWithTitle:[windowMenu title] action:nil keyEquivalent:@""] setSubmenu:windowMenu]; [NSApp setMainMenu:mainMenu]; [NSApp setAppleMenu:appMenu]; // This isn't the apple menu, but it doesn't work without this. diff --git a/src/archutils/Darwin/VectorHelper.cpp b/src/archutils/Darwin/VectorHelper.cpp index 4e0e1819df..c70256b5a8 100644 --- a/src/archutils/Darwin/VectorHelper.cpp +++ b/src/archutils/Darwin/VectorHelper.cpp @@ -10,7 +10,7 @@ bool Vector::CheckForVector() int32_t result = 0; size_t size = 4; - return !sysctlbyname( "hw.vectorunit", &result, &size, NULL, 0 ) && result; + return !sysctlbyname( "hw.vectorunit", &result, &size, nullptr, 0 ) && result; } /* for( unsigned pos = 0; pos < size; ++pos ) diff --git a/src/archutils/Unix/Backtrace.cpp b/src/archutils/Unix/Backtrace.cpp index 603a7898a4..f55be5b130 100644 --- a/src/archutils/Unix/Backtrace.cpp +++ b/src/archutils/Unix/Backtrace.cpp @@ -103,7 +103,7 @@ static int get_readable_ranges( const void **starts, const void **ends, int size while( got < size-1 ) { char *p = (char *) memchr( file, '\n', file_used ); - if( p == NULL ) + if( p == nullptr ) break; *p++ = 0; @@ -114,13 +114,13 @@ static int get_readable_ranges( const void **starts, const void **ends, int size /* Search for the hyphen. */ char *hyphen = strchr( line, '-' ); - if( hyphen == NULL ) + if( hyphen == nullptr ) continue; /* Parse error. */ /* Search for the space. */ char *space = strchr( hyphen, ' ' ); - if( space == NULL ) + if( space == nullptr ) continue; /* Parse error. */ /* " rwxp". If space[1] isn't 'r', then the block isn't readable. */ @@ -132,10 +132,10 @@ static int get_readable_ranges( const void **starts, const void **ends, int size if( strlen(space) < 4 || space[3] != 'x' ) continue; - /* If, for some reason, either end is NULL, skip it; that's our terminator. */ + /* If, for some reason, either end is nullptr, skip it; that's our terminator. */ const void *start = (const void *) xtoi( line ); const void *end = (const void *) xtoi( hyphen+1 ); - if( start != NULL && end != NULL ) + if( start != nullptr && end != nullptr ) { *starts++ = start; *ends++ = end; @@ -153,8 +153,8 @@ static int get_readable_ranges( const void **starts, const void **ends, int size close(fd); - *starts++ = NULL; - *ends++ = NULL; + *starts++ = nullptr; + *ends++ = nullptr; return got; } @@ -173,7 +173,7 @@ static int find_address( const void *p, const void **starts, const void **ends ) return -1; } -static void *SavedStackPointer = NULL; +static void *SavedStackPointer = nullptr; void InitializeBacktrace() { @@ -380,7 +380,7 @@ static void do_backtrace( const void **buf, size_t size, const BacktraceContext frame = frame->link; } - buf[i] = NULL; + buf[i] = nullptr; } #if defined(CPU_X86) @@ -408,11 +408,11 @@ void GetBacktrace( const void **buf, size_t size, const BacktraceContext *ctx ) InitializeBacktrace(); BacktraceContext CurrentCtx; - if( ctx == NULL ) + if( ctx == nullptr ) { ctx = &CurrentCtx; - CurrentCtx.ip = NULL; + CurrentCtx.ip = nullptr; CurrentCtx.bp = __builtin_frame_address(0); CurrentCtx.sp = __builtin_frame_address(0); CurrentCtx.pid = GetCurrentThreadId(); @@ -543,16 +543,16 @@ void GetBacktrace( const void **buf, size_t size, const BacktraceContext *ctx ) if( g_StackPointer == 0 ) { buf[0] = BACKTRACE_METHOD_NOT_AVAILABLE; - buf[1] = NULL; + buf[1] = nullptr; return; } BacktraceContext CurrentCtx; - if( ctx == NULL ) + if( ctx == nullptr ) { ctx = &CurrentCtx; - CurrentCtx.ip = NULL; + CurrentCtx.ip = nullptr; CurrentCtx.bp = __builtin_frame_address(0); CurrentCtx.sp = __builtin_frame_address(0); } @@ -582,7 +582,7 @@ void GetBacktrace( const void **buf, size_t size, const BacktraceContext *ctx ) { /* There isn't much we can do if this is the case. The stack should be read/write * and since it isn't, give up. */ - buf[i] = NULL; + buf[i] = nullptr; return; } const Frame *frame = (Frame *)ctx->sp; @@ -640,7 +640,7 @@ void GetBacktrace( const void **buf, size_t size, const BacktraceContext *ctx ) frame = frame->link; } - buf[i] = NULL; + buf[i] = nullptr; } #undef PROT_RW #undef PROT_EXE @@ -664,14 +664,14 @@ void InitializeBacktrace() { } void GetBacktrace( const void **buf, size_t size, const BacktraceContext *ctx ) { BacktraceContext CurrentCtx; - if( ctx == NULL ) + if( ctx == nullptr ) { ctx = &CurrentCtx; /* __builtin_frame_address is broken on OS X; it sometimes returns bogus results. */ register void *r1 __asm__ ("r1"); CurrentCtx.FramePtr = (const Frame *) r1; - CurrentCtx.PC = NULL; + CurrentCtx.PC = nullptr; } const Frame *frame = ctx->FramePtr; @@ -688,7 +688,7 @@ void GetBacktrace( const void **buf, size_t size, const BacktraceContext *ctx ) frame = frame->stackPointer; } - buf[i] = NULL; + buf[i] = nullptr; } #elif defined(BACKTRACE_METHOD_PPC_LINUX) @@ -713,13 +713,13 @@ void GetBacktrace( const void **buf, size_t size, const BacktraceContext *ctx ) { BacktraceContext CurrentCtx; - if( ctx == NULL ) + if( ctx == nullptr ) { ctx = &CurrentCtx; register void *r1 __asm__("1"); CurrentCtx.FramePtr = (const Frame *)r1; - CurrentCtx.PC = NULL; + CurrentCtx.PC = nullptr; } const Frame *frame = (const Frame *)ctx->FramePtr; @@ -733,7 +733,7 @@ void GetBacktrace( const void **buf, size_t size, const BacktraceContext *ctx ) if( frame->linkReg ) buf[i++] = frame->linkReg; } - buf[i] = NULL; + buf[i] = nullptr; } #else @@ -744,7 +744,7 @@ void InitializeBacktrace() { } void GetBacktrace( const void **buf, size_t size, const BacktraceContext *ctx ) { buf[0] = BACKTRACE_METHOD_NOT_AVAILABLE; - buf[1] = NULL; + buf[1] = nullptr; } #endif diff --git a/src/archutils/Unix/Backtrace.h b/src/archutils/Unix/Backtrace.h index 24dd2d402b..a89a20834a 100644 --- a/src/archutils/Unix/Backtrace.h +++ b/src/archutils/Unix/Backtrace.h @@ -31,10 +31,10 @@ struct BacktraceContext void InitializeBacktrace(); /* Retrieve up to size-1 backtrace pointers in buf. The array will be - * null-terminated. If ctx is NULL, retrieve the current backtrace; otherwise + * null-terminated. If ctx is nullptr, retrieve the current backtrace; otherwise * retrieve a backtrace for the given context. (Not all backtracers may * support contexts.) */ -void GetBacktrace( const void **buf, size_t size, const BacktraceContext *ctx = NULL ); +void GetBacktrace( const void **buf, size_t size, const BacktraceContext *ctx = nullptr ); /* Set up a BacktraceContext to get a backtrace for a thread. ThreadID may * not be the current thread. True is returned on success, false on failure. */ diff --git a/src/archutils/Unix/BacktraceNames.cpp b/src/archutils/Unix/BacktraceNames.cpp index d7bb8833d5..0b99033a79 100644 --- a/src/archutils/Unix/BacktraceNames.cpp +++ b/src/archutils/Unix/BacktraceNames.cpp @@ -44,7 +44,7 @@ void BacktraceNames::Demangle() return; int status = 0; - char *name = abi::__cxa_demangle( Symbol, NULL, NULL, &status ); + char *name = abi::__cxa_demangle( Symbol, nullptr, nullptr, &status ); if( name ) { Symbol = name; @@ -121,7 +121,7 @@ void BacktraceNames::FromAddr( void * const p ) * between one function and the next, because the first lookup will succeed. */ Dl_info di; - if( !dladdr((void *) p, &di) || di.dli_sname == NULL ) + if( !dladdr((void *) p, &di) || di.dli_sname == nullptr ) { if( !dladdr( ((char *) p) - 8, &di) ) return; @@ -177,7 +177,7 @@ static int osx_find_image( const void *p ) for( unsigned i = 0; i < image_count; i++ ) { const struct mach_header *header = _dyld_get_image_header(i); - if( header == NULL ) + if( header == nullptr ) continue; /* The load commands directly follow the mach_header. */ @@ -219,7 +219,7 @@ static const char *osx_find_link_edit( const struct mach_header *header ) return (char *) ( scmd->vmaddr - scmd->fileoff ); } - return NULL; + return nullptr; } void BacktraceNames::FromAddr( void * const p ) @@ -235,7 +235,7 @@ void BacktraceNames::FromAddr( void * const p ) /* Find the link-edit pointer. */ const char *link_edit = osx_find_link_edit( _dyld_get_image_header(index) ); - if( link_edit == NULL ) + if( link_edit == nullptr ) return; link_edit += _dyld_get_image_vmaddr_slide( index ); @@ -244,8 +244,8 @@ void BacktraceNames::FromAddr( void * const p ) const struct load_command *cmd = (struct load_command *) &header[1]; unsigned long diff = 0xffffffff; - const char *dli_sname = NULL; - void *dli_saddr = NULL; + const char *dli_sname = nullptr; + void *dli_saddr = nullptr; for( unsigned long i = 0; i < header->ncmds; i++, cmd = next_load_command(cmd) ) { @@ -299,7 +299,7 @@ void BacktraceNames::FromAddr( void * const p ) Address = (intptr_t) p; char **foo = backtrace_symbols(&p, 1); - if( foo == NULL ) + if( foo == nullptr ) return; FromString( foo[0] ); free(foo); diff --git a/src/archutils/Unix/CrashHandler.cpp b/src/archutils/Unix/CrashHandler.cpp index e842430640..3d33c14b2b 100644 --- a/src/archutils/Unix/CrashHandler.cpp +++ b/src/archutils/Unix/CrashHandler.cpp @@ -34,7 +34,7 @@ static void safe_print( int fd, ... ) for(;;) { const char *p = va_arg( ap, const char * ); - if( p == NULL ) + if( p == nullptr ) { break; } @@ -88,13 +88,13 @@ static void NORETURN spawn_child_process( int from_parent ) strncpy( magic, CHILD_MAGIC_PARAMETER, sizeof(magic) ); /* Use execve; it's the lowest-level of the exec calls. The others may allocate. */ - char *argv[3] = { path, magic, NULL }; - char *envp[1] = { NULL }; + char *argv[3] = { path, magic, nullptr }; + char *envp[1] = { nullptr }; execve( path, argv, envp ); /* If we got here, the exec failed. We can't call strerror. */ - // safe_print(fileno(stderr), "Crash handler execl(", path, ") failed: ", strerror(errno), "\n", NULL); - safe_print( fileno(stderr), "Crash handler execl(", path, ") failed: ", itoa( errno ), "\n", NULL ); + // safe_print(fileno(stderr), "Crash handler execl(", path, ") failed: ", strerror(errno), "\n", nullptr); + safe_print( fileno(stderr), "Crash handler execl(", path, ") failed: ", itoa( errno ), "\n", nullptr ); _exit(1); } @@ -116,13 +116,13 @@ static bool parent_write( int to_child, const void *p, size_t size ) int ret = retried_write( to_child, p, size ); if( ret == -1 ) { - safe_print( fileno(stderr), "Unexpected write() result (", strerror(errno), ")\n", NULL ); + safe_print( fileno(stderr), "Unexpected write() result (", strerror(errno), ")\n", nullptr ); return false; } if( size_t(ret) != size ) { - safe_print( fileno(stderr), "Unexpected write() result (", itoa(ret), ")\n", NULL ); + safe_print( fileno(stderr), "Unexpected write() result (", itoa(ret), ")\n", nullptr ); return false; } @@ -154,7 +154,7 @@ static void parent_process( int to_child, const CrashData *crash ) /* 4. Write RecentLogs. */ int cnt = 0; const char *ps[1024]; - while( cnt < 1024 && (ps[cnt] = RageLog::GetRecentLog( cnt )) != NULL ) + while( cnt < 1024 && (ps[cnt] = RageLog::GetRecentLog( cnt )) != nullptr ) ++cnt; parent_write(to_child, &cnt, sizeof(cnt)); @@ -211,9 +211,9 @@ static void parent_process( int to_child, const CrashData *crash ) static void RunCrashHandler( const CrashData *crash ) { - if( g_pCrashHandlerArgv0 == NULL ) + if( g_pCrashHandlerArgv0 == nullptr ) { - safe_print( fileno(stderr), "Crash handler failed: CrashHandlerHandleArgs was not called\n", NULL ); + safe_print( fileno(stderr), "Crash handler failed: CrashHandlerHandleArgs was not called\n", nullptr ); _exit( 1 ); } @@ -221,9 +221,9 @@ static void RunCrashHandler( const CrashData *crash ) struct sigaction sa; memset( &sa, 0, sizeof(sa) ); sa.sa_handler = SIG_IGN; - if( sigaction( SIGPIPE, &sa, NULL ) != 0 ) + if( sigaction( SIGPIPE, &sa, nullptr ) != 0 ) { - safe_print( fileno(stderr), "sigaction() failed: %s", strerror(errno), NULL ); + safe_print( fileno(stderr), "sigaction() failed: %s", strerror(errno), nullptr ); /* non-fatal */ } @@ -237,22 +237,22 @@ static void RunCrashHandler( const CrashData *crash ) switch( crash->type ) { case CrashData::SIGNAL: - safe_print( fileno(stderr), "Fatal signal (", SignalName(crash->signal), ")", NULL ); + safe_print( fileno(stderr), "Fatal signal (", SignalName(crash->signal), ")", nullptr ); break; case CrashData::FORCE_CRASH: - safe_print( fileno(stderr), "Crash handler failed: \"", crash->reason, "\"", NULL ); + safe_print( fileno(stderr), "Crash handler failed: \"", crash->reason, "\"", nullptr ); break; default: - safe_print( fileno(stderr), "Unexpected RunCrashHandler call (", itoa(crash->type), ")", NULL ); + safe_print( fileno(stderr), "Unexpected RunCrashHandler call (", itoa(crash->type), ")", nullptr ); break; } if( active == 1 ) - safe_print( fileno(stderr), " while still in the crash handler\n", NULL); + safe_print( fileno(stderr), " while still in the crash handler\n", nullptr); else if( active == 2 ) - safe_print( fileno(stderr), " while in the crash handler child\n", NULL); + safe_print( fileno(stderr), " while in the crash handler child\n", nullptr); _exit( 1 ); } @@ -267,14 +267,14 @@ static void RunCrashHandler( const CrashData *crash ) int fds[2]; if( pipe(fds) != 0 ) { - safe_print( fileno(stderr), "Crash handler pipe() failed: ", strerror(errno), "\n", NULL ); + safe_print( fileno(stderr), "Crash handler pipe() failed: ", strerror(errno), "\n", nullptr ); exit( 1 ); } pid_t childpid = fork(); if( childpid == -1 ) { - safe_print( fileno(stderr), "Crash handler fork() failed: ", strerror(errno), "\n", NULL ); + safe_print( fileno(stderr), "Crash handler fork() failed: ", strerror(errno), "\n", nullptr ); _exit( 1 ); } @@ -305,7 +305,7 @@ static void RunCrashHandler( const CrashData *crash ) RageThread::ResumeAllThreads(); if( WIFSIGNALED(status) ) - safe_print( fileno(stderr), "Crash handler child exited with signal ", itoa(WTERMSIG(status)), "\n", NULL ); + safe_print( fileno(stderr), "Crash handler child exited with signal ", itoa(WTERMSIG(status)), "\n", nullptr ); } } @@ -340,7 +340,7 @@ void CrashHandler::ForceCrash( const char *reason ) strncpy( crash.reason, reason, sizeof(crash.reason) ); crash.reason[ sizeof(crash.reason)-1 ] = 0; - GetBacktrace( crash.BacktracePointers[0], BACKTRACE_MAX_SIZE, NULL ); + GetBacktrace( crash.BacktracePointers[0], BACKTRACE_MAX_SIZE, nullptr ); RunCrashHandler( &crash ); } @@ -352,7 +352,7 @@ void CrashHandler::ForceDeadlock( RString reason, uint64_t iID ) crash.type = CrashData::FORCE_CRASH; - GetBacktrace( crash.BacktracePointers[0], BACKTRACE_MAX_SIZE, NULL ); + GetBacktrace( crash.BacktracePointers[0], BACKTRACE_MAX_SIZE, nullptr ); if( iID == GetInvalidThreadId() ) { @@ -384,7 +384,7 @@ void CrashHandler::CrashSignalHandler( int signal, siginfo_t *si, const ucontext static volatile bool bInCrashSignalHandler = false; if( bInCrashSignalHandler ) { - safe_print( 2, "Fatal: crash from within the crash signal handler\n", NULL ); + safe_print( 2, "Fatal: crash from within the crash signal handler\n", nullptr ); _exit(1); } diff --git a/src/archutils/Unix/CrashHandlerChild.cpp b/src/archutils/Unix/CrashHandlerChild.cpp index 0648751087..0ed38bb30c 100644 --- a/src/archutils/Unix/CrashHandlerChild.cpp +++ b/src/archutils/Unix/CrashHandlerChild.cpp @@ -26,7 +26,7 @@ bool child_read( int fd, void *p, int size ); -const char *g_pCrashHandlerArgv0 = NULL; +const char *g_pCrashHandlerArgv0 = nullptr; static void output_stack_trace( FILE *out, const void **BacktracePointers ) @@ -153,7 +153,7 @@ static void child_process() FD_ZERO( &rs ); FD_SET( 3, &rs ); - int ret = select( 4, &rs, NULL, NULL, &timeout ); + int ret = select( 4, &rs, nullptr, nullptr, &timeout ); if( ret == 0 ) { @@ -194,7 +194,7 @@ static void child_process() sCrashInfoPath += "/crashinfo.txt"; FILE *CrashDump = fopen( sCrashInfoPath, "w+" ); - if(CrashDump == NULL) + if(CrashDump == nullptr) { fprintf( stderr, "Couldn't open " + sCrashInfoPath + ": %s\n", strerror(errno) ); exit(1); @@ -271,7 +271,7 @@ static void child_process() /* stdout may have been inadvertently closed by the crash in the parent; * write to /dev/tty instead. */ FILE *tty = fopen( "/dev/tty", "w" ); - if( tty == NULL ) + if( tty == nullptr ) tty = stderr; fputs( "\n" diff --git a/src/archutils/Unix/SignalHandler.cpp b/src/archutils/Unix/SignalHandler.cpp index adfc9891cb..e049cbb849 100644 --- a/src/archutils/Unix/SignalHandler.cpp +++ b/src/archutils/Unix/SignalHandler.cpp @@ -59,7 +59,7 @@ SaveSignals::SaveSignals() for( int i = 0; signals[i] != -1; ++i ) { struct sigaction sa; - sigaction( signals[i], NULL, &sa ); + sigaction( signals[i], nullptr, &sa ); old_handlers.push_back( sa ); } } @@ -68,7 +68,7 @@ SaveSignals::~SaveSignals() { /* Restore the old signal handlers. */ for( unsigned i = 0; i < old_handlers.size(); ++i ) - sigaction( signals[i], &old_handlers[i], NULL ); + sigaction( signals[i], &old_handlers[i], nullptr ); } static void SigHandler( int signal, siginfo_t *si, void *ucp ) @@ -88,7 +88,7 @@ static void SigHandler( int signal, siginfo_t *si, void *ucp ) struct sigaction old; sigaction( signal, &sa, &old ); raise( signal ); - sigaction( signal, &old, NULL ); + sigaction( signal, &old, nullptr ); } } @@ -117,13 +117,13 @@ static void *CreateStack( int size ) * * mmap entries always show up individually in /proc/#/maps. We could use posix_memalign as * a fallback, but we'd have to put a barrier page on both sides to guarantee that. */ - char *p = NULL; - p = (char *) mmap( NULL, size+PageSize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0 ); + char *p = nullptr; + p = (char *) mmap( nullptr, size+PageSize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0 ); if( p == (void *) -1 ) - return NULL; + return nullptr; // if( posix_memalign( (void**) &p, PageSize, RealSize ) != 0 ) - // return NULL; + // return nullptr; if( find_stack_direction() < 0 ) { @@ -143,7 +143,7 @@ static void *CreateStack( int size ) /* Hook up events to fatal signals, so we can clean up if we're killed. */ void SignalHandler::OnClose( handler h ) { - if( saved_sigs == NULL ) + if( saved_sigs == nullptr ) { saved_sigs = new SaveSignals; @@ -158,27 +158,27 @@ void SignalHandler::OnClose( handler h ) /* Allocate a separate signal stack. This makes the crash handler work * if we run out of stack space. */ const int AltStackSize = 1024*64; - void *p = NULL; + void *p = nullptr; if( bUseAltSigStack ) p = CreateStack( AltStackSize ); - if( p != NULL ) + if( p != nullptr ) { stack_t ss; ss.ss_sp = (char*)p; /* cast for Darwin */ ss.ss_size = AltStackSize; ss.ss_flags = 0; - if( sigaltstack( &ss, NULL ) == -1 ) + if( sigaltstack( &ss, nullptr ) == -1 ) { LOG->Info( "sigaltstack failed: %s", strerror(errno) ); - p = NULL; /* no SA_ONSTACK */ + p = nullptr; /* no SA_ONSTACK */ } } struct sigaction sa; sa.sa_flags = 0; - if( p != NULL ) + if( p != nullptr ) sa.sa_flags |= SA_ONSTACK; sa.sa_flags |= SA_NODEFER; sa.sa_flags |= SA_SIGINFO; @@ -187,11 +187,11 @@ void SignalHandler::OnClose( handler h ) /* Set up our signal handlers. */ sa.sa_sigaction = SigHandler; for( int i = 0; signals[i] != -1; ++i ) - sigaction( signals[i], &sa, NULL ); + sigaction( signals[i], &sa, nullptr ); /* Block SIGPIPE, so we get EPIPE. */ sa.sa_handler = SIG_IGN; - sigaction( SIGPIPE, &sa, NULL ); + sigaction( SIGPIPE, &sa, nullptr ); } handlers.push_back(h); } diff --git a/src/archutils/Unix/X11Helper.cpp b/src/archutils/Unix/X11Helper.cpp index c1a19d7bd1..16f8bbb81b 100644 --- a/src/archutils/Unix/X11Helper.cpp +++ b/src/archutils/Unix/X11Helper.cpp @@ -7,7 +7,7 @@ #include -Display *X11Helper::Dpy = NULL; +Display *X11Helper::Dpy = nullptr; Window X11Helper::Win = None; static int ErrorCallback( Display*, XErrorEvent* ); @@ -20,9 +20,9 @@ static bool dpms_state_at_startup= false; bool X11Helper::OpenXConnection() { - DEBUG_ASSERT( Dpy == NULL && Win == None ); + DEBUG_ASSERT( Dpy == nullptr && Win == None ); Dpy = XOpenDisplay(0); - if( Dpy == NULL ) + if( Dpy == nullptr ) return false; XSetIOErrorHandler( FatalCallback ); @@ -65,10 +65,10 @@ void X11Helper::CloseXConnection() } } // The window should have been shut down - DEBUG_ASSERT( Dpy != NULL ); + DEBUG_ASSERT( Dpy != nullptr ); DEBUG_ASSERT( Win == None ); XCloseDisplay( Dpy ); - Dpy = NULL; + Dpy = nullptr; } bool X11Helper::MakeWindow( Window &win, int screenNum, int depth, Visual *visual, int width, int height, bool overrideRedirect ) @@ -103,7 +103,7 @@ bool X11Helper::MakeWindow( Window &win, int screenNum, int depth, Visual *visua return false; XClassHint *hint = XAllocClassHint(); - if ( hint == NULL ) { + if ( hint == nullptr ) { LOG->Warn("Could not set class hint for X11 Window"); } else { hint->res_name = (char*)g_XWMName.Get().c_str(); diff --git a/src/archutils/Win32/AppInstance.cpp b/src/archutils/Win32/AppInstance.cpp index 97f126428c..8d02ffd51e 100644 --- a/src/archutils/Win32/AppInstance.cpp +++ b/src/archutils/Win32/AppInstance.cpp @@ -5,9 +5,9 @@ AppInstance::AppInstance() { // Little trick to get an HINSTANCE of ourself without having access to the hwnd. TCHAR szFullAppPath[MAX_PATH]; - GetModuleFileName(NULL, szFullAppPath, MAX_PATH); + GetModuleFileName(nullptr, szFullAppPath, MAX_PATH); h = LoadLibrary(szFullAppPath); - /* h will be NULL if this fails. Most operations that take an HINSTANCE + /* h will be nullptr if this fails. Most operations that take an HINSTANCE * will still work without one (but may be missing graphics); that's OK. */ } diff --git a/src/archutils/Win32/CommandLine.cpp b/src/archutils/Win32/CommandLine.cpp index 903534da79..7dcbe706d6 100644 --- a/src/archutils/Win32/CommandLine.cpp +++ b/src/archutils/Win32/CommandLine.cpp @@ -9,7 +9,7 @@ int GetWin32CmdLine( char** &argv ) { char *pCmdLine = GetCommandLine(); int argc = 0; - argv = NULL; + argv = nullptr; int i = 0; while( pCmdLine[i] ) diff --git a/src/archutils/Win32/Crash.cpp b/src/archutils/Win32/Crash.cpp index d9c9784882..bd241dcb6c 100644 --- a/src/archutils/Win32/Crash.cpp +++ b/src/archutils/Win32/Crash.cpp @@ -23,7 +23,7 @@ static void SpliceProgramPath(char *buf, int bufsiz, const char *fn) { char tbuf[MAX_PATH]; char *pszFile; - GetModuleFileName(NULL, tbuf, sizeof tbuf); + GetModuleFileName(nullptr, tbuf, sizeof tbuf); GetFullPathName(tbuf, bufsiz, buf, &pszFile); strcpy(pszFile, fn); } @@ -50,7 +50,7 @@ static const struct ExceptionLookup { { EXCEPTION_INVALID_HANDLE, "Invalid handle" }, { EXCEPTION_STACK_OVERFLOW, "Stack overflow" }, { 0xe06d7363, "Unhandled Microsoft C++ Exception", }, - { NULL }, + { nullptr }, }; static const char *LookupException( DWORD code ) @@ -59,7 +59,7 @@ static const char *LookupException( DWORD code ) if( exceptions[i].code == code ) return exceptions[i].name; - return NULL; + return nullptr; } static CrashInfo g_CrashInfo; @@ -68,13 +68,13 @@ static void GetReason( const EXCEPTION_RECORD *pRecord, CrashInfo *crash ) // fill out bomb reason const char *reason = LookupException( pRecord->ExceptionCode ); - if( reason == NULL ) + if( reason == nullptr ) wsprintf( crash->m_CrashReason, "unknown exception 0x%08lx", pRecord->ExceptionCode ); else strcpy( crash->m_CrashReason, reason ); } -static HWND g_hForegroundWnd = NULL; +static HWND g_hForegroundWnd = nullptr; void CrashHandler::SetForegroundWindow( HWND hWnd ) { g_hForegroundWnd = hWnd; @@ -85,7 +85,7 @@ void WriteToChild( HANDLE hPipe, const void *pData, size_t iSize ) while( iSize ) { DWORD iActual; - if( !WriteFile(hPipe, pData, iSize, &iActual, NULL) ) + if( !WriteFile(hPipe, pData, iSize, &iActual, nullptr) ) return; iSize -= iActual; } @@ -106,7 +106,7 @@ bool StartChild( HANDLE &hProcess, HANDLE &hToStdin, HANDLE &hFromStdout ) SECURITY_ATTRIBUTES sa; sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.bInheritHandle = true; - sa.lpSecurityDescriptor = NULL; + sa.lpSecurityDescriptor = nullptr; CreatePipe( &si.hStdInput, &hToStdin, &sa, 0 ); CreatePipe( &hFromStdout, &si.hStdOutput, &sa, 0 ); @@ -115,19 +115,19 @@ bool StartChild( HANDLE &hProcess, HANDLE &hToStdin, HANDLE &hFromStdout ) } char szBuf[256] = ""; - GetModuleFileName( NULL, szBuf, MAX_PATH ); + GetModuleFileName( nullptr, szBuf, MAX_PATH ); strcat( szBuf, " " ); strcat( szBuf, CHILD_MAGIC_PARAMETER ); PROCESS_INFORMATION pi; int iRet = CreateProcess( - NULL, // pointer to name of executable module + nullptr, // pointer to name of executable module szBuf, // pointer to command line string - NULL, // process security attributes - NULL, // thread security attributes + nullptr, // process security attributes + nullptr, // thread security attributes true, // handle inheritance flag 0, // creation flags - NULL, // pointer to new environment block + nullptr, // pointer to new environment block cwd, // pointer to current directory name &si, // pointer to STARTUPINFO &pi // pointer to PROCESS_INFORMATION @@ -156,19 +156,19 @@ static const char *CrashGetModuleBaseName(HMODULE hmod, char *pszBaseName) // XXX: It looks like nothing in here COULD throw an exception. Need to verify that. // __try { if( !GetModuleFileName(hmod, szPath1, sizeof(szPath1)) ) - return NULL; + return nullptr; char *pszFile; DWORD dw = GetFullPathName( szPath1, sizeof(szPath2), szPath2, &pszFile ); if( !dw || dw > sizeof(szPath2) ) - return NULL; + return nullptr; strcpy( pszBaseName, pszFile ); pszFile = pszBaseName; - char *period = NULL; + char *period = nullptr; while( *pszFile++ ) if( pszFile[-1]=='.' ) period = pszFile-1; @@ -176,7 +176,7 @@ static const char *CrashGetModuleBaseName(HMODULE hmod, char *pszBaseName) if( period ) *period = 0; // } __except(1) { -// return NULL; +// return nullptr; // } return pszBaseName; @@ -222,7 +222,7 @@ void RunChild() // 4. Write RecentLogs. int cnt = 0; const TCHAR *ps[1024]; - while( cnt < 1024 && (ps[cnt] = RageLog::GetRecentLog( cnt )) != NULL ) + while( cnt < 1024 && (ps[cnt] = RageLog::GetRecentLog( cnt )) != nullptr ) ++cnt; WriteToChild(hToStdin, &cnt, sizeof(cnt)); @@ -254,7 +254,7 @@ void RunChild() * since GetModuleFileNameEx might not be available. Run the requests here. */ HMODULE hMod; DWORD iActual; - if( !ReadFile( hFromStdout, &hMod, sizeof(hMod), &iActual, NULL) ) + if( !ReadFile( hFromStdout, &hMod, sizeof(hMod), &iActual, nullptr) ) break; TCHAR szName[MAX_PATH]; @@ -301,8 +301,8 @@ static long MainExceptionHandler( EXCEPTION_POINTERS *pExc ) /* If we get here, then we've been called recursively, which means we * crashed. If InHere is greater than 1, then we crashed after writing * the crash dump; say so. */ - SetUnhandledExceptionFilter(NULL); - MessageBox( NULL, + SetUnhandledExceptionFilter(nullptr); + MessageBox( nullptr, InHere == 1? "The error reporting interface has crashed.\n": "The error reporting interface has crashed. However, crashinfo.txt was" @@ -333,7 +333,7 @@ static long MainExceptionHandler( EXCEPTION_POINTERS *pExc ) /* Now things get more risky. If we're fullscreen, the window will obscure * the crash dialog. Try to hide the window. Things might blow up here; do * this after DoSave, so we always write a crash dump. */ - if( GetWindowThreadProcessId( g_hForegroundWnd, NULL ) == GetCurrentThreadId() ) + if( GetWindowThreadProcessId( g_hForegroundWnd, nullptr ) == GetCurrentThreadId() ) { /* The thread that crashed was the thread that created the main window. * Hide the window. This will also restore the video mode, if necessary. */ @@ -342,12 +342,12 @@ static long MainExceptionHandler( EXCEPTION_POINTERS *pExc ) /* A different thread crashed. Simply kill all other windows. We can't * safely call ShowWindow; the main thread might be deadlocked. */ RageThread::HaltAllThreads( true ); - ChangeDisplaySettings( NULL, 0 ); + ChangeDisplaySettings( nullptr, 0 ); } InHere = false; - SetUnhandledExceptionFilter( NULL ); + SetUnhandledExceptionFilter(nullptr); /* Forcibly terminate; if we keep going, we'll try to shut down threads and * do other things that may deadlock, which is confusing for users. */ @@ -362,7 +362,7 @@ long __stdcall CrashHandler::ExceptionHandler( EXCEPTION_POINTERS *pExc ) * Allocate a new stack, and run the exception handler in it, to increase * the chances of success. */ int iSize = 1024*32; - char *pStack = (char *) VirtualAlloc( NULL, iSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE ); + char *pStack = (char *) VirtualAlloc( nullptr, iSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE ); pStack += iSize; // FIXME: This will probably explode on x86-64 #if defined(_MSC_VER) @@ -456,7 +456,7 @@ static bool PointsToValidCall( unsigned long ptr ) memset( buf, 0, sizeof(buf) ); - while(len > 0 && !ReadProcessMemory(GetCurrentProcess(), (void *)(ptr-len), buf+7-len, len, NULL)) + while(len > 0 && !ReadProcessMemory(GetCurrentProcess(), (void *)(ptr-len), buf+7-len, len, nullptr)) --len; return IsValidCall(buf+7, len); @@ -473,7 +473,7 @@ void CrashHandler::do_backtrace( const void **buf, size_t size, * due to stack corruption, we might not be able to get any frames from the * stack. Pull it out of pContext->Eip, which is always valid, and then * discard the first stack frame if it's the same. */ - if( buf+1 != pLast && pContext->Eip != NULL ) + if( buf+1 != pLast && pContext->Eip != 0 ) { *buf = (void *) pContext->Eip; ++buf; @@ -485,7 +485,7 @@ void CrashHandler::do_backtrace( const void **buf, size_t size, LDT_ENTRY sel; if( !GetThreadSelectorEntry( hThread, pContext->SegFs, &sel ) ) { - *buf = NULL; + *buf = nullptr; return; } @@ -532,16 +532,15 @@ void CrashHandler::do_backtrace( const void **buf, size_t size, break; lpAddr += 4; - } while( ReadProcessMemory(hProcess, lpAddr-4, &data, 4, NULL)); + } while( ReadProcessMemory(hProcess, lpAddr-4, &data, 4, nullptr)); - *buf = NULL; + *buf = nullptr; } // Trigger the crash handler. This works even in the debugger. static void NORETURN debug_crash() { -// __try { -#if defined(__MSC_VER) + __try { __asm xor ebx,ebx __asm mov eax,dword ptr [ebx] // __asm mov dword ptr [ebx],eax diff --git a/src/archutils/Win32/CrashHandlerChild.cpp b/src/archutils/Win32/CrashHandlerChild.cpp index 57a4a35bf8..fe8d8f1bed 100644 --- a/src/archutils/Win32/CrashHandlerChild.cpp +++ b/src/archutils/Win32/CrashHandlerChild.cpp @@ -41,8 +41,8 @@ namespace VDDebugInfo { struct Context { - Context() { pRVAHeap=NULL; } - bool Loaded() const { return pRVAHeap != NULL; } + Context() { pRVAHeap=nullptr; } + bool Loaded() const { return pRVAHeap != nullptr; } RString sRawBlock; int nBuildNumber; @@ -59,7 +59,7 @@ namespace VDDebugInfo static void GetVDIPath( char *buf, int bufsiz ) { - GetModuleFileName( NULL, buf, bufsiz ); + GetModuleFileName( nullptr, buf, bufsiz ); buf[bufsiz-5] = 0; char *p = strrchr( buf, '.' ); if( p ) @@ -86,7 +86,7 @@ namespace VDDebugInfo const unsigned char *src = (const unsigned char *) pctx->sRawBlock.data(); - pctx->pRVAHeap = NULL; + pctx->pRVAHeap = nullptr; static const char *header = "symbolic debug information"; if( memcmp(src, header, strlen(header)) ) @@ -121,11 +121,11 @@ namespace VDDebugInfo return true; pctx->sRawBlock = RString(); - pctx->pRVAHeap = NULL; + pctx->pRVAHeap = nullptr; GetVDIPath( pctx->sFilename, ARRAYLEN(pctx->sFilename) ); pctx->sError = RString(); - HANDLE h = CreateFile( pctx->sFilename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); + HANDLE h = CreateFile( pctx->sFilename, GENERIC_READ, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, nullptr ); if( h == INVALID_HANDLE_VALUE ) { pctx->sError = werr_ssprintf( GetLastError(), "CreateFile failed" ); @@ -133,7 +133,7 @@ namespace VDDebugInfo } do { - DWORD dwFileSize = GetFileSize( h, NULL ); + DWORD dwFileSize = GetFileSize( h, nullptr ); if( dwFileSize == INVALID_FILE_SIZE ) break; @@ -141,7 +141,7 @@ namespace VDDebugInfo std::fill(buffer, buffer + dwFileSize + 1, '\0' ); DWORD dwActual; - int iRet = ReadFile(h, buffer, dwFileSize, &dwActual, NULL); + int iRet = ReadFile(h, buffer, dwFileSize, &dwActual, nullptr); CloseHandle(h); pctx->sRawBlock = buffer; delete[] buffer; @@ -268,7 +268,7 @@ namespace SymbolLookup { SymSetOptions( SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS ); - if( !SymInitialize(g_hParent, NULL, TRUE) ) + if( !SymInitialize(g_hParent, nullptr, TRUE) ) return false; bInitted = true; @@ -288,7 +288,7 @@ namespace SymbolLookup pSymbol->MaxNameLen = sizeof(buffer) - sizeof(SYMBOL_INFO) + 1; if( !SymFromAddr(g_hParent, ptr, &disp, pSymbol) ) - return NULL; + return nullptr; return pSymbol; } @@ -394,7 +394,7 @@ namespace RString SpliceProgramPath( RString fn ) { char szBuf[MAX_PATH]; - GetModuleFileName( NULL, szBuf, sizeof(szBuf) ); + GetModuleFileName( nullptr, szBuf, sizeof(szBuf) ); char szModName[MAX_PATH]; char *pszFile; @@ -491,7 +491,7 @@ static void DoSave( const RString &sReport ) SetFileAttributes( sName, FILE_ATTRIBUTE_NORMAL ); FILE *pFile = fopen( sName, "w+" ); - if( pFile == NULL ) + if( pFile == nullptr ) return; fprintf( pFile, "%s", sReport.c_str() ); @@ -659,7 +659,7 @@ CrashDialog::CrashDialog( const RString &sCrashReport, const CompleteCrashData & m_CrashData( CrashData ) { LoadLocalizedStrings(); - m_pPost = NULL; + m_pPost = nullptr; } CrashDialog::~CrashDialog() @@ -692,7 +692,7 @@ BOOL CrashDialog::HandleMessage( UINT msg, WPARAM wParam, LPARAM lParam ) { HDC hdc = (HDC)wParam; HWND hwndStatic = (HWND)lParam; - HBRUSH hbr = NULL; + HBRUSH hbr = nullptr; // TODO: Change any attributes of the DC here switch( GetDlgCtrlID(hwndStatic) ) @@ -713,7 +713,7 @@ BOOL CrashDialog::HandleMessage( UINT msg, WPARAM wParam, LPARAM lParam ) switch(LOWORD(wParam)) { case IDC_BUTTON_CLOSE: - if( m_pPost != NULL ) + if( m_pPost != nullptr ) { // Cancel reporting, and revert the dialog as if "report" had not been pressed. m_pPost->Cancel(); @@ -734,7 +734,7 @@ BOOL CrashDialog::HandleMessage( UINT msg, WPARAM wParam, LPARAM lParam ) { RString sLogPath; FILE *pFile = fopen( SpliceProgramPath("../Portable.ini"), "r" ); - if(pFile != NULL) + if(pFile != nullptr) { sLogPath = SpliceProgramPath("../Logs/log.txt"); fclose( pFile ); @@ -742,11 +742,11 @@ BOOL CrashDialog::HandleMessage( UINT msg, WPARAM wParam, LPARAM lParam ) else sLogPath = SpecialDirs::GetAppDataDir() + PRODUCT_ID +"/Logs/log.txt"; - ShellExecute( NULL, "open", sLogPath, "", "", SW_SHOWNORMAL ); + ShellExecute( nullptr, "open", sLogPath, "", "", SW_SHOWNORMAL ); } break; case IDC_CRASH_SAVE: - ShellExecute( NULL, "open", SpliceProgramPath("../crashinfo.txt"), "", "", SW_SHOWNORMAL ); + ShellExecute( nullptr, "open", SpliceProgramPath("../crashinfo.txt"), "", "", SW_SHOWNORMAL ); return TRUE; case IDC_BUTTON_RESTART: Win32RestartProgram(); @@ -781,13 +781,13 @@ BOOL CrashDialog::HandleMessage( UINT msg, WPARAM wParam, LPARAM lParam ) m_pPost->Start( CRASH_REPORT_HOST, CRASH_REPORT_PORT, CRASH_REPORT_PATH ); - SetTimer( hDlg, 0, 100, NULL ); + SetTimer( hDlg, 0, 100, nullptr ); break; } break; case WM_TIMER: { - if( m_pPost == NULL ) + if( m_pPost == nullptr ) break; float fProgress = m_pPost->GetProgress(); @@ -875,7 +875,7 @@ void ChildProcess() // Now that we've done that, the process is gone. Don't use g_hParent. CloseHandle( SymbolLookup::g_hParent ); - SymbolLookup::g_hParent = NULL; + SymbolLookup::g_hParent = nullptr; CrashDialog cd( sCrashReport, Data ); #if defined(AUTOMATED_CRASH_REPORTS) diff --git a/src/archutils/Win32/CrashHandlerInternal.h b/src/archutils/Win32/CrashHandlerInternal.h index 895d5aa043..905b7e7a93 100644 --- a/src/archutils/Win32/CrashHandlerInternal.h +++ b/src/archutils/Win32/CrashHandlerInternal.h @@ -18,7 +18,7 @@ struct CrashInfo m_CrashReason[0] = 0; memset( m_AlternateThreadBacktrace, 0, sizeof(m_AlternateThreadBacktrace) ); memset( m_AlternateThreadName, 0, sizeof(m_AlternateThreadName) ); - m_BacktracePointers[0] = NULL; + m_BacktracePointers[0] = nullptr; } }; diff --git a/src/archutils/Win32/CrashHandlerNetworking.cpp b/src/archutils/Win32/CrashHandlerNetworking.cpp index 8deb043638..0ef4cf445a 100644 --- a/src/archutils/Win32/CrashHandlerNetworking.cpp +++ b/src/archutils/Win32/CrashHandlerNetworking.cpp @@ -5,7 +5,7 @@ #include "RageThreads.h" #include "RageTimer.h" #include "RageUtil.h" -#include "Foreach.h" + #if defined(WINDOWS) #include @@ -158,7 +158,7 @@ NetworkStream *CreateNetworkStream() WSADATA WSAData; WORD iVersionRequested = MAKEWORD(2,0); if( WSAStartup(iVersionRequested, &WSAData) != 0 ) - return NULL; + return nullptr; } return new NetworkStream_Win32; @@ -170,11 +170,11 @@ NetworkStream_Win32::NetworkStream_Win32(): { m_iPort = -1; m_State = STATE_IDLE; - m_Socket = NULL; + m_Socket = nullptr; #if defined(WINDOWS) - m_hResolve = NULL; - m_hResolveHwnd = NULL; - m_hCompletionEvent = CreateEvent( NULL, true, false, NULL ); + m_hResolve = nullptr; + m_hResolveHwnd = nullptr; + m_hCompletionEvent = CreateEvent( nullptr, true, false, nullptr ); #endif } @@ -355,7 +355,7 @@ void NetworkStream_Win32::Open( const RString &sHost, int iPort, ConnectionType m_iPort = iPort; // Look up the hostname. - hostent *pHost = NULL; + hostent *pHost = nullptr; char pBuf[MAXGETHOSTSTRUCT]; { pHost = (hostent *) pBuf; @@ -374,8 +374,8 @@ void NetworkStream_Win32::Open( const RString &sHost, int iPort, ConnectionType mw.Run(); m_Mutex.Lock(); - m_hResolve = NULL; - m_hResolveHwnd = NULL; + m_hResolve = nullptr; + m_hResolveHwnd = nullptr; if( m_State == STATE_CANCELLED ) { m_Mutex.Unlock(); @@ -475,7 +475,7 @@ void NetworkStream_Win32::Cancel() m_State = STATE_CANCELLED; // If resolving, abort the resolve. - if( m_hResolve != NULL ) + if( m_hResolve != nullptr ) { /* When we cancel the request, no message at all will be sent to the window, * so we need to do it ourself to inform it that it was cancelled. Be sure @@ -588,18 +588,18 @@ void NetworkPostData::CreateMimeData( const map &mapNameToData, while(1) { sMimeBoundaryOut = ssprintf( "--%08i", rand() ); - FOREACHM_CONST( RString, RString, mapNameToData, d ) - if( d->second.find(sMimeBoundaryOut) != RString::npos ) + for (auto const &d : mapNameToData) + if( d.second.find(sMimeBoundaryOut) != RString::npos ) continue; break; } - FOREACHM_CONST( RString, RString, mapNameToData, d ) + for (auto const &d : mapNameToData) { sOut += "--" + sMimeBoundaryOut + "\r\n"; - sOut += ssprintf( "Content-Disposition: form-data; name=\"%s\"\r\n", d->first.c_str() ); + sOut += ssprintf( "Content-Disposition: form-data; name=\"%s\"\r\n", d.first.c_str() ); sOut += "\r\n"; - sOut += d->second; + sOut += d.second; sOut += "\r\n"; } if( sOut.size() ) diff --git a/src/archutils/Win32/DialogUtil.cpp b/src/archutils/Win32/DialogUtil.cpp index 8ad854b55f..686e7c34d7 100644 --- a/src/archutils/Win32/DialogUtil.cpp +++ b/src/archutils/Win32/DialogUtil.cpp @@ -1,108 +1,108 @@ -#include "global.h" -#include "DialogUtil.h" -#include "RageUtil.h" -#include "ThemeManager.h" -#include "archutils/Win32/ErrorStrings.h" - -// Create*Font copied from MFC's CFont - -// pLogFont->nHeight is interpreted as PointSize * 10 -static HFONT CreatePointFontIndirect(const LOGFONT* lpLogFont) -{ - HDC hDC = ::GetDC(NULL); - - // convert nPointSize to logical units based on pDC - LOGFONT logFont = *lpLogFont; - POINT pt; - pt.y = ::GetDeviceCaps(hDC, LOGPIXELSY) * logFont.lfHeight; - pt.y /= 720; // 72 points/inch * 10 decipoints/point - pt.x = 0; - ::DPtoLP(hDC, &pt, 1); - POINT ptOrg = { 0, 0 }; - ::DPtoLP(hDC, &ptOrg, 1); - logFont.lfHeight = -abs(pt.y - ptOrg.y); - - ReleaseDC(NULL, hDC); - - return ::CreateFontIndirect(&logFont); -} - -// nPointSize is actually scaled 10x -static HFONT CreatePointFont(int nPointSize, LPCTSTR lpszFaceName) -{ - ASSERT(lpszFaceName != NULL); - - LOGFONT logFont; - memset(&logFont, 0, sizeof(LOGFONT)); - logFont.lfCharSet = DEFAULT_CHARSET; - logFont.lfHeight = nPointSize; - lstrcpyn(logFont.lfFaceName, lpszFaceName, strlen(logFont.lfFaceName)); - - return ::CreatePointFontIndirect(&logFont); -} - -void DialogUtil::SetHeaderFont( HWND hdlg, int nID ) -{ - ASSERT( hdlg != NULL ); - - HWND hControl = ::GetDlgItem( hdlg, nID ); - ASSERT( hControl != NULL ); - - // TODO: Fix font leak - const int FONT_POINTS = 16; - HFONT hfont = CreatePointFont( FONT_POINTS*10, "Arial Black" ); - ::SendMessage( hControl, WM_SETFONT, (WPARAM)hfont, TRUE ); -} - -void DialogUtil::LocalizeDialogAndContents( HWND hdlg ) -{ - ASSERT( THEME != NULL ); - - const int LARGE_STRING = 256; - char szTemp[LARGE_STRING] = ""; - RString sGroup; - - { - ::GetWindowText( hdlg, szTemp, ARRAYLEN(szTemp) ); - RString s = szTemp; - sGroup = "Dialog-"+s; - s = THEME->GetString( sGroup, s ); - ::SetWindowText( hdlg, ConvertUTF8ToACP(s).c_str() ); - } - - for( HWND hwndChild = ::GetTopWindow(hdlg); hwndChild != NULL; hwndChild = ::GetNextWindow(hwndChild,GW_HWNDNEXT) ) - { - ::GetWindowText( hwndChild, szTemp, ARRAYLEN(szTemp) ); - RString s = szTemp; - if( s.empty() ) - continue; - s = THEME->GetString( sGroup, s ); - ::SetWindowText( hwndChild, ConvertUTF8ToACP(s).c_str() ); - } -} - -/* - * (c) 2002-2004 Chris Danford - * All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, and/or sell copies of the Software, and to permit persons to - * whom the Software is furnished to do so, provided that the above - * copyright notice(s) and this permission notice appear in all copies of - * the Software and that both the above copyright notice(s) and this - * permission notice appear in supporting documentation. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF - * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS - * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT - * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS - * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR - * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - +#include "global.h" +#include "DialogUtil.h" +#include "RageUtil.h" +#include "ThemeManager.h" +#include "archutils/Win32/ErrorStrings.h" + +// Create*Font copied from MFC's CFont + +// pLogFont->nHeight is interpreted as PointSize * 10 +static HFONT CreatePointFontIndirect(const LOGFONT* lpLogFont) +{ + HDC hDC = ::GetDC(nullptr); + + // convert nPointSize to logical units based on pDC + LOGFONT logFont = *lpLogFont; + POINT pt; + pt.y = ::GetDeviceCaps(hDC, LOGPIXELSY) * logFont.lfHeight; + pt.y /= 720; // 72 points/inch * 10 decipoints/point + pt.x = 0; + ::DPtoLP(hDC, &pt, 1); + POINT ptOrg = { 0, 0 }; + ::DPtoLP(hDC, &ptOrg, 1); + logFont.lfHeight = -abs(pt.y - ptOrg.y); + + ReleaseDC(nullptr, hDC); + + return ::CreateFontIndirect(&logFont); +} + +// nPointSize is actually scaled 10x +static HFONT CreatePointFont(int nPointSize, LPCTSTR lpszFaceName) +{ + ASSERT(lpszFaceName != nullptr); + + LOGFONT logFont; + memset(&logFont, 0, sizeof(LOGFONT)); + logFont.lfCharSet = DEFAULT_CHARSET; + logFont.lfHeight = nPointSize; + lstrcpyn(logFont.lfFaceName, lpszFaceName, strlen(logFont.lfFaceName)); + + return ::CreatePointFontIndirect(&logFont); +} + +void DialogUtil::SetHeaderFont( HWND hdlg, int nID ) +{ + ASSERT( hdlg != nullptr ); + + HWND hControl = ::GetDlgItem( hdlg, nID ); + ASSERT( hControl != nullptr ); + + // TODO: Fix font leak + const int FONT_POINTS = 16; + HFONT hfont = CreatePointFont( FONT_POINTS*10, "Arial Black" ); + ::SendMessage( hControl, WM_SETFONT, (WPARAM)hfont, TRUE ); +} + +void DialogUtil::LocalizeDialogAndContents( HWND hdlg ) +{ + ASSERT( THEME != nullptr ); + + const int LARGE_STRING = 256; + char szTemp[LARGE_STRING] = ""; + RString sGroup; + + { + ::GetWindowText( hdlg, szTemp, ARRAYLEN(szTemp) ); + RString s = szTemp; + sGroup = "Dialog-"+s; + s = THEME->GetString( sGroup, s ); + ::SetWindowText( hdlg, ConvertUTF8ToACP(s).c_str() ); + } + + for( HWND hwndChild = ::GetTopWindow(hdlg); hwndChild != nullptr; hwndChild = ::GetNextWindow(hwndChild,GW_HWNDNEXT) ) + { + ::GetWindowText( hwndChild, szTemp, ARRAYLEN(szTemp) ); + RString s = szTemp; + if( s.empty() ) + continue; + s = THEME->GetString( sGroup, s ); + ::SetWindowText( hwndChild, ConvertUTF8ToACP(s).c_str() ); + } +} + +/* + * (c) 2002-2004 Chris Danford + * All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, and/or sell copies of the Software, and to permit persons to + * whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF + * THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS + * INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT + * OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS + * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + diff --git a/src/archutils/Win32/ErrorStrings.cpp b/src/archutils/Win32/ErrorStrings.cpp index 5e6dccc06b..336c5a0324 100644 --- a/src/archutils/Win32/ErrorStrings.cpp +++ b/src/archutils/Win32/ErrorStrings.cpp @@ -8,7 +8,7 @@ RString werr_ssprintf( int err, const char *fmt, ... ) { char buf[1024] = ""; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, - 0, err, 0, buf, sizeof(buf), NULL); + 0, err, 0, buf, sizeof(buf), nullptr); // Why is FormatMessage returning text ending with \r\n? (who? -aj) // Perhaps it's because you're on Windows, where newlines are \r\n. -aj @@ -31,13 +31,13 @@ RString ConvertWstringToCodepage( wstring s, int iCodePage ) return RString(); int iBytes = WideCharToMultiByte( iCodePage, 0, s.data(), s.size(), - NULL, 0, NULL, FALSE ); + nullptr, 0, nullptr, FALSE ); ASSERT_M( iBytes > 0, werr_ssprintf( GetLastError(), "WideCharToMultiByte" ).c_str() ); char * buf = new char[iBytes + 1]; std::fill(buf, buf + iBytes + 1, '\0'); WideCharToMultiByte( CP_ACP, 0, s.data(), s.size(), - buf, iBytes, NULL, FALSE ); + buf, iBytes, nullptr, FALSE ); RString ret( buf ); delete[] buf; return ret; @@ -53,7 +53,7 @@ wstring ConvertCodepageToWString( RString s, int iCodePage ) if( s.empty() ) return wstring(); - int iBytes = MultiByteToWideChar( iCodePage, 0, s.data(), s.size(), NULL, 0 ); + int iBytes = MultiByteToWideChar( iCodePage, 0, s.data(), s.size(), nullptr, 0 ); ASSERT_M( iBytes > 0, werr_ssprintf( GetLastError(), "MultiByteToWideChar" ).c_str() ); wchar_t *pTemp = new wchar_t[iBytes]; diff --git a/src/archutils/Win32/GetFileInformation.cpp b/src/archutils/Win32/GetFileInformation.cpp index cf9d814023..99966f356d 100644 --- a/src/archutils/Win32/GetFileInformation.cpp +++ b/src/archutils/Win32/GetFileInformation.cpp @@ -22,7 +22,7 @@ bool GetFileVersion( RString sFile, RString &sOut ) RString VersionBuffer( iSize, ' ' ); // Also VC6: - if( !GetFileVersionInfo( const_cast(sFile.c_str()), NULL, iSize, const_cast(VersionBuffer.c_str()) ) ) + if( !GetFileVersionInfo( const_cast(sFile.c_str()), nullptr, iSize, const_cast(VersionBuffer.c_str()) ) ) break; WORD *iTrans; @@ -73,7 +73,7 @@ RString FindSystemFile( RString sFile ) "/system/", "/system/drivers/", "/", - NULL + nullptr }; for( int i = 0; szPaths[i]; ++i ) @@ -95,7 +95,7 @@ bool GetProcessFileName( uint32_t iProcessID, RString &sName ) * kernel32.lib functions. */ do { HANDLE hSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, iProcessID ); - if( hSnap == NULL ) + if( hSnap == nullptr ) { sName = werr_ssprintf( GetLastError(), "CreateToolhelp32Snapshot" ); break; @@ -118,9 +118,9 @@ bool GetProcessFileName( uint32_t iProcessID, RString &sName ) // This method only works in NT/2K/XP. do { - static HINSTANCE hPSApi = NULL; + static HINSTANCE hPSApi = nullptr; typedef DWORD (WINAPI* pfnGetProcessImageFileNameA)(HANDLE hProcess, LPSTR lpImageFileName, DWORD nSize); - static pfnGetProcessImageFileNameA pGetProcessImageFileName = NULL; + static pfnGetProcessImageFileNameA pGetProcessImageFileName = nullptr; static bool bTried = false; if( !bTried ) @@ -128,7 +128,7 @@ bool GetProcessFileName( uint32_t iProcessID, RString &sName ) bTried = true; hPSApi = LoadLibrary("psapi.dll"); - if( hPSApi == NULL ) + if( hPSApi == nullptr ) { sName = werr_ssprintf( GetLastError(), "LoadLibrary" ); break; @@ -136,7 +136,7 @@ bool GetProcessFileName( uint32_t iProcessID, RString &sName ) else { pGetProcessImageFileName = (pfnGetProcessImageFileNameA) GetProcAddress( hPSApi, "GetProcessImageFileNameA" ); - if( pGetProcessImageFileName == NULL ) + if( pGetProcessImageFileName == nullptr ) { sName = werr_ssprintf( GetLastError(), "GetProcAddress" ); break; @@ -144,10 +144,10 @@ bool GetProcessFileName( uint32_t iProcessID, RString &sName ) } } - if( pGetProcessImageFileName != NULL ) + if( pGetProcessImageFileName != nullptr ) { - HANDLE hProc = OpenProcess( PROCESS_VM_READ|PROCESS_QUERY_INFORMATION, NULL, iProcessID ); - if( hProc == NULL ) + HANDLE hProc = OpenProcess( PROCESS_VM_READ|PROCESS_QUERY_INFORMATION, nullptr, iProcessID ); + if( hProc == nullptr ) { sName = werr_ssprintf( GetLastError(), "OpenProcess" ); break; diff --git a/src/archutils/Win32/GotoURL.cpp b/src/archutils/Win32/GotoURL.cpp index f6cc247506..93092f0b12 100644 --- a/src/archutils/Win32/GotoURL.cpp +++ b/src/archutils/Win32/GotoURL.cpp @@ -25,7 +25,7 @@ static LONG GetRegKey( HKEY key, RString subkey, LPTSTR retdata ) bool GotoURL( RString sUrl ) { // First try ShellExecute() - int iRet = (int) ShellExecute( NULL, "open", sUrl, NULL, NULL, SW_SHOWDEFAULT ); + int iRet = (int) ShellExecute( nullptr, "open", sUrl, nullptr, nullptr, SW_SHOWDEFAULT ); // If it failed, get the .htm regkey and lookup the program if( iRet > 32 ) @@ -41,11 +41,11 @@ bool GotoURL( RString sUrl ) return false; char *szPos = strstr( key, "\"%1\"" ); - if( szPos == NULL ) + if( szPos == nullptr ) { // No quotes found. Check for %1 without quotes szPos = strstr( key, "%1" ); - if( szPos == NULL ) + if( szPos == nullptr ) szPos = key+lstrlen(key)-1; // No parameter. else *szPos = '\0'; // Remove the parameter diff --git a/src/archutils/Win32/GraphicsWindow.cpp b/src/archutils/Win32/GraphicsWindow.cpp index f142c9096c..41cbbc0f22 100644 --- a/src/archutils/Win32/GraphicsWindow.cpp +++ b/src/archutils/Win32/GraphicsWindow.cpp @@ -23,7 +23,7 @@ static HDC g_HDC; static VideoModeParams g_CurrentParams; static bool g_bResolutionChanged = false; static bool g_bHasFocus = true; -static HICON g_hIcon = NULL; +static HICON g_hIcon = nullptr; static bool m_bWideWindowClass; static bool g_bD3D = false; @@ -36,8 +36,8 @@ static UINT g_iQueryCancelAutoPlayMessage = 0; static RString GetNewWindow() { HWND h = GetForegroundWindow(); - if( h == NULL ) - return "(NULL)"; + if( h == nullptr ) + return "(nullptr)"; DWORD iProcessID; GetWindowThreadProcessId( h, &iProcessID ); @@ -92,7 +92,7 @@ static LRESULT CALLBACK GraphicsWindow_WndProc( HWND hWnd, UINT msg, WPARAM wPar } else if( !g_bHasFocus && bHadFocus ) { - ChangeDisplaySettings( NULL, 0 ); + ChangeDisplaySettings( nullptr, 0 ); } } @@ -111,7 +111,7 @@ static LRESULT CALLBACK GraphicsWindow_WndProc( HWND hWnd, UINT msg, WPARAM wPar case WM_SETCURSOR: if( !g_CurrentParams.windowed ) { - SetCursor( NULL ); + SetCursor(nullptr); return 1; } break; @@ -190,7 +190,7 @@ static void AdjustVideoModeParams( VideoModeParams &p ) DEVMODE dm; ZERO( dm ); dm.dmSize = sizeof(dm); - if( !EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm) ) + if( !EnumDisplaySettings(nullptr, ENUM_CURRENT_SETTINGS, &dm) ) { p.rate = 60; LOG->Warn( "%s", werr_ssprintf(GetLastError(), "EnumDisplaySettings failed").c_str() ); @@ -226,7 +226,7 @@ RString GraphicsWindow::SetScreenMode( const VideoModeParams &p ) if( p.windowed ) { // We're going windowed. If we were previously fullscreen, reset. - ChangeDisplaySettings( NULL, 0 ); + ChangeDisplaySettings( nullptr, 0 ); return RString(); } @@ -244,7 +244,7 @@ RString GraphicsWindow::SetScreenMode( const VideoModeParams &p ) DevMode.dmDisplayFrequency = p.rate; DevMode.dmFields |= DM_DISPLAYFREQUENCY; } - ChangeDisplaySettings( NULL, 0 ); + ChangeDisplaySettings( nullptr, 0 ); int ret = ChangeDisplaySettings( &DevMode, CDS_FULLSCREEN ); if( ret != DISP_CHANGE_SUCCESSFUL && (DevMode.dmFields & DM_DISPLAYFREQUENCY) ) @@ -278,20 +278,20 @@ void GraphicsWindow::CreateGraphicsWindow( const VideoModeParams &p, bool bForce // Adjust g_CurrentParams to reflect the actual display settings. AdjustVideoModeParams( g_CurrentParams ); - if( g_hWndMain == NULL || bForceRecreateWindow ) + if( g_hWndMain == nullptr || bForceRecreateWindow ) { int iWindowStyle = GetWindowStyle( p.windowed ); AppInstance inst; HWND hWnd = CreateWindow( g_sClassName, "app", iWindowStyle, - 0, 0, 0, 0, NULL, NULL, inst, NULL ); - if( hWnd == NULL ) + 0, 0, 0, 0, nullptr, nullptr, inst, nullptr ); + if( hWnd == nullptr ) RageException::Throw( "%s", werr_ssprintf( GetLastError(), "CreateWindow" ).c_str() ); /* If an old window exists, transfer focus to the new window before * deleting it, or some other window may temporarily get focus, which * can cause it to be resized. */ - if( g_hWndMain != NULL ) + if( g_hWndMain != nullptr ) { // While we change to the new window, don't do ChangeDisplaySettings in WM_ACTIVATE. g_bRecreatingVideoMode = true; @@ -319,14 +319,14 @@ void GraphicsWindow::CreateGraphicsWindow( const VideoModeParams &p, bool bForce } while(0); // Update the window icon. - if( g_hIcon != NULL ) + if( g_hIcon != nullptr ) { - SetClassLong( g_hWndMain, GCL_HICON, (LONG) LoadIcon(NULL,IDI_APPLICATION) ); + SetClassLong( g_hWndMain, GCL_HICON, (LONG) LoadIcon(nullptr,IDI_APPLICATION) ); DestroyIcon( g_hIcon ); - g_hIcon = NULL; + g_hIcon = nullptr; } g_hIcon = IconFromFile( p.sIconFile ); - if( g_hIcon != NULL ) + if( g_hIcon != nullptr ) SetClassLong( g_hWndMain, GCL_HICON, (LONG) g_hIcon ); /* The window style may change as a result of switching to or from fullscreen; @@ -364,9 +364,9 @@ void GraphicsWindow::CreateGraphicsWindow( const VideoModeParams &p, bool bForce * If we don't do this, then starting up in a D3D fullscreen window may * cause all other windows on the system to be resized. */ MSG msg; - while( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) ) + while( PeekMessage( &msg, nullptr, 0, 0, PM_NOREMOVE ) ) { - GetMessage( &msg, NULL, 0, 0 ); + GetMessage( &msg, nullptr, 0, 0 ); DispatchMessage( &msg ); } } @@ -374,36 +374,36 @@ void GraphicsWindow::CreateGraphicsWindow( const VideoModeParams &p, bool bForce /** @brief Shut down the window, but don't reset the video mode. */ void GraphicsWindow::DestroyGraphicsWindow() { - if( g_HDC != NULL ) + if( g_HDC != nullptr ) { ReleaseDC( g_hWndMain, g_HDC ); - g_HDC = NULL; + g_HDC = nullptr; } CHECKPOINT; - if( g_hWndMain != NULL ) + if( g_hWndMain != nullptr ) { DestroyWindow( g_hWndMain ); - g_hWndMain = NULL; + g_hWndMain = nullptr; CrashHandler::SetForegroundWindow( g_hWndMain ); } CHECKPOINT; - if( g_hIcon != NULL ) + if( g_hIcon != nullptr ) { DestroyIcon( g_hIcon ); - g_hIcon = NULL; + g_hIcon = nullptr; } CHECKPOINT; MSG msg; - while( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) ) + while( PeekMessage( &msg, nullptr, 0, 0, PM_NOREMOVE ) ) { CHECKPOINT; - GetMessage( &msg, NULL, 0, 0 ); + GetMessage( &msg, nullptr, 0, 0 ); CHECKPOINT; DispatchMessage( &msg ); } @@ -423,10 +423,10 @@ void GraphicsWindow::Initialize( bool bD3D ) } //if we have dwm, get function pointers to the dll functions - if( hInstanceDwmapi != NULL ) - { - PFN_DwmFlush = (HRESULT (WINAPI *)(VOID))GetProcAddress( hInstanceDwmapi, "DwmFlush" ); - PFN_DwmIsCompositionEnabled = (HRESULT (WINAPI *)(BOOL*))GetProcAddress( hInstanceDwmapi, "DwmIsCompositionEnabled" ); + if( hInstanceDwmapi != nullptr ) + { + PFN_DwmFlush = (HRESULT (WINAPI *)(VOID))GetProcAddress( hInstanceDwmapi, "DwmFlush" ); + PFN_DwmIsCompositionEnabled = (HRESULT (WINAPI *)(BOOL*))GetProcAddress( hInstanceDwmapi, "DwmIsCompositionEnabled" ); } AppInstance inst; @@ -440,10 +440,10 @@ void GraphicsWindow::Initialize( bool bD3D ) 0, /* cbClsExtra */ 0, /* cbWndExtra */ inst, /* hInstance */ - NULL, /* set icon later */ - LoadCursor( NULL, IDC_ARROW ), /* default cursor */ - NULL, /* hbrBackground */ - NULL, /* lpszMenuName */ + nullptr, /* set icon later */ + LoadCursor( nullptr, IDC_ARROW ), /* default cursor */ + nullptr, /* hbrBackground */ + nullptr, /* lpszMenuName */ wsClassName.c_str() /* lpszClassName */ }; @@ -458,10 +458,10 @@ void GraphicsWindow::Initialize( bool bD3D ) 0, /* cbClsExtra */ 0, /* cbWndExtra */ inst, /* hInstance */ - NULL, /* set icon later */ - LoadCursor( NULL, IDC_ARROW ), /* default cursor */ - NULL, /* hbrBackground */ - NULL, /* lpszMenuName */ + nullptr, /* set icon later */ + LoadCursor( nullptr, IDC_ARROW ), /* default cursor */ + nullptr, /* hbrBackground */ + nullptr, /* lpszMenuName */ g_sClassName /* lpszClassName */ }; @@ -481,7 +481,7 @@ void GraphicsWindow::Shutdown() * It'd be nice to not do this: Windows will do it when we quit, and if * we're shutting down OpenGL to try D3D, this will cause extra mode * switches. However, we need to do this before displaying dialogs. */ - ChangeDisplaySettings( NULL, 0 ); + ChangeDisplaySettings( nullptr, 0 ); AppInstance inst; UnregisterClass( g_sClassName, inst ); @@ -489,7 +489,7 @@ void GraphicsWindow::Shutdown() HDC GraphicsWindow::GetHDC() { - ASSERT( g_HDC != NULL ); + ASSERT( g_HDC != nullptr ); return g_HDC; } @@ -501,29 +501,29 @@ const VideoModeParams &GraphicsWindow::GetParams() void GraphicsWindow::Update() { MSG msg; - while( PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE ) ) + while( PeekMessage( &msg, nullptr, 0, 0, PM_NOREMOVE ) ) { - GetMessage( &msg, NULL, 0, 0 ); + GetMessage( &msg, nullptr, 0, 0 ); DispatchMessage( &msg ); } HOOKS->SetHasFocus( g_bHasFocus ); if (g_CurrentParams.vsync) - { - //if we can use DWM - if( hInstanceDwmapi != NULL ) - { - BOOL compositeEnabled = true; - PFN_DwmIsCompositionEnabled(&compositeEnabled); - if (compositeEnabled) - { + { + //if we can use DWM + if( hInstanceDwmapi != nullptr ) + { + BOOL compositeEnabled = true; + PFN_DwmIsCompositionEnabled(&compositeEnabled); + if (compositeEnabled) + { PFN_DwmFlush(); } } } - if( g_bResolutionChanged && DISPLAY != NULL ) + if( g_bResolutionChanged && DISPLAY != nullptr ) { //LOG->Warn( "Changing resolution" ); diff --git a/src/archutils/Win32/GraphicsWindow.h b/src/archutils/Win32/GraphicsWindow.h index 8a41cb2864..70a22b9992 100644 --- a/src/archutils/Win32/GraphicsWindow.h +++ b/src/archutils/Win32/GraphicsWindow.h @@ -37,7 +37,7 @@ namespace GraphicsWindow HWND GetHwnd(); //dwm functions for vista+ - static HINSTANCE hInstanceDwmapi = NULL; + static HINSTANCE hInstanceDwmapi = nullptr; static HRESULT(WINAPI* PFN_DwmIsCompositionEnabled)(BOOL*); static HRESULT (WINAPI* PFN_DwmFlush)(VOID); }; diff --git a/src/archutils/Win32/MessageWindow.cpp b/src/archutils/Win32/MessageWindow.cpp index 13b974a41b..82fa29aecf 100644 --- a/src/archutils/Win32/MessageWindow.cpp +++ b/src/archutils/Win32/MessageWindow.cpp @@ -14,10 +14,10 @@ MessageWindow::MessageWindow( const RString &sClassName ) 0, /* cbClsExtra */ 0, /* cbWndExtra */ inst, /* hInstance */ - NULL, /* set icon later */ - LoadCursor( NULL, IDC_ARROW ), /* default cursor */ - NULL, /* hbrBackground */ - NULL, /* lpszMenuName */ + nullptr, /* set icon later */ + LoadCursor( nullptr, IDC_ARROW ), /* default cursor */ + nullptr, /* hbrBackground */ + nullptr, /* lpszMenuName */ sClassName /* lpszClassName */ }; @@ -25,8 +25,8 @@ MessageWindow::MessageWindow( const RString &sClassName ) RageException::Throw( "%s", werr_ssprintf( GetLastError(), "RegisterClass" ).c_str() ); // XXX: on 2k/XP, use HWND_MESSAGE as parent - m_hWnd = CreateWindow( sClassName, sClassName, WS_DISABLED, 0, 0, 0, 0, NULL, NULL, inst, NULL ); - ASSERT( m_hWnd != NULL ); + m_hWnd = CreateWindow( sClassName, sClassName, WS_DISABLED, 0, 0, 0, 0, nullptr, nullptr, inst, nullptr ); + ASSERT( m_hWnd != nullptr ); SetProp( m_hWnd, "MessageWindow", this ); } @@ -60,7 +60,7 @@ void MessageWindow::StopRunning() LRESULT CALLBACK MessageWindow::WndProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) { MessageWindow *pThis = (MessageWindow *) GetProp( hWnd, "MessageWindow" ); - if( pThis != NULL && pThis->HandleMessage(msg, wParam, lParam) ) + if( pThis != nullptr && pThis->HandleMessage(msg, wParam, lParam) ) return 0; return DefWindowProc( hWnd, msg, wParam, lParam ); diff --git a/src/archutils/Win32/RegistryAccess.cpp b/src/archutils/Win32/RegistryAccess.cpp index bdaaa88018..1f6f6f8c25 100644 --- a/src/archutils/Win32/RegistryAccess.cpp +++ b/src/archutils/Win32/RegistryAccess.cpp @@ -36,14 +36,14 @@ static bool GetRegKeyType( const RString &sIn, RString &sOut, HKEY &key ) } /* Given a full key, eg. "HKEY_LOCAL_MACHINE\hardware\foo", open it and return it. - * On error, return NULL. */ + * On error, return nullptr. */ enum RegKeyMode { READ, WRITE }; static HKEY OpenRegKey( const RString &sKey, RegKeyMode mode, bool bWarnOnError = true ) { RString sSubkey; HKEY hType; if( !GetRegKeyType(sKey, sSubkey, hType) ) - return NULL; + return nullptr; HKEY hRetKey; LONG retval = RegOpenKeyEx( hType, sSubkey, 0, (mode==READ) ? KEY_READ:KEY_WRITE, &hRetKey ); @@ -51,7 +51,7 @@ static HKEY OpenRegKey( const RString &sKey, RegKeyMode mode, bool bWarnOnError { if( bWarnOnError ) LOG->Warn( werr_ssprintf(retval, "RegOpenKeyEx(%x,%s) error", hType, sSubkey.c_str()) ); - return NULL; + return nullptr; } return hRetKey; @@ -60,13 +60,13 @@ static HKEY OpenRegKey( const RString &sKey, RegKeyMode mode, bool bWarnOnError bool RegistryAccess::GetRegValue( const RString &sKey, const RString &sName, RString &sVal ) { HKEY hKey = OpenRegKey( sKey, READ ); - if( hKey == NULL ) + if( hKey == nullptr ) return false; char sBuffer[MAX_PATH]; DWORD iSize = sizeof(sBuffer); DWORD iType; - LONG iRet = RegQueryValueEx( hKey, sName, NULL, &iType, (LPBYTE)sBuffer, &iSize ); + LONG iRet = RegQueryValueEx( hKey, sName, nullptr, &iType, (LPBYTE)sBuffer, &iSize ); RegCloseKey( hKey ); if( iRet != ERROR_SUCCESS ) return false; @@ -86,13 +86,13 @@ bool RegistryAccess::GetRegValue( const RString &sKey, const RString &sName, RSt bool RegistryAccess::GetRegValue( const RString &sKey, const RString &sName, int &iVal, bool bWarnOnError ) { HKEY hKey = OpenRegKey( sKey, READ, bWarnOnError ); - if( hKey == NULL ) + if( hKey == nullptr ) return false; DWORD iValue; DWORD iSize = sizeof(iValue); DWORD iType; - LONG iRet = RegQueryValueEx( hKey, sName, NULL, &iType, (LPBYTE) &iValue, &iSize ); + LONG iRet = RegQueryValueEx( hKey, sName, nullptr, &iType, (LPBYTE) &iValue, &iSize ); RegCloseKey( hKey ); if( iRet != ERROR_SUCCESS ) return false; @@ -115,7 +115,7 @@ bool RegistryAccess::GetRegValue( const RString &sKey, const RString &sName, boo bool RegistryAccess::GetRegSubKeys( const RString &sKey, vector &lst, const RString ®ex, bool bReturnPathToo ) { HKEY hKey = OpenRegKey( sKey, READ ); - if( hKey == NULL ) + if( hKey == nullptr ) return false; Regex re(regex); @@ -126,7 +126,7 @@ bool RegistryAccess::GetRegSubKeys( const RString &sKey, vector &lst, c FILETIME ft; char szBuffer[MAX_PATH]; DWORD iSize = sizeof(szBuffer); - LONG iRet = RegEnumKeyEx( hKey, index, szBuffer, &iSize, NULL, NULL, NULL, &ft); + LONG iRet = RegEnumKeyEx( hKey, index, szBuffer, &iSize, nullptr, nullptr, nullptr, &ft); if( iRet == ERROR_NO_MORE_ITEMS ) break; @@ -155,7 +155,7 @@ bool RegistryAccess::GetRegSubKeys( const RString &sKey, vector &lst, c bool RegistryAccess::SetRegValue( const RString &sKey, const RString &sName, const RString &sVal ) { HKEY hKey = OpenRegKey( sKey, WRITE ); - if( hKey == NULL ) + if( hKey == nullptr ) return false; bool bSuccess = true; @@ -177,7 +177,7 @@ bool RegistryAccess::SetRegValue( const RString &sKey, const RString &sName, con bool RegistryAccess::SetRegValue( const RString &sKey, const RString &sName, bool bVal ) { HKEY hKey = OpenRegKey( sKey, WRITE ); - if( hKey == NULL ) + if( hKey == nullptr ) return false; bool bSuccess = true; @@ -196,7 +196,7 @@ bool RegistryAccess::CreateKey( const RString &sKey ) RString sSubkey; HKEY hType; if( !GetRegKeyType(sKey, sSubkey, hType) ) - return NULL; + return nullptr; HKEY hKey; DWORD dwDisposition = 0; @@ -204,10 +204,10 @@ bool RegistryAccess::CreateKey( const RString &sKey ) hType, sSubkey, 0, - NULL, + nullptr, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, - NULL, + nullptr, &hKey, &dwDisposition ) != ERROR_SUCCESS ) { diff --git a/src/archutils/Win32/RestartProgram.cpp b/src/archutils/Win32/RestartProgram.cpp index 5f9d96e40c..3c1c985317 100644 --- a/src/archutils/Win32/RestartProgram.cpp +++ b/src/archutils/Win32/RestartProgram.cpp @@ -5,21 +5,21 @@ void Win32RestartProgram() { TCHAR szFullAppPath[MAX_PATH]; - GetModuleFileName(NULL, szFullAppPath, MAX_PATH); + GetModuleFileName(nullptr, szFullAppPath, MAX_PATH); // Relaunch PROCESS_INFORMATION pi; STARTUPINFO si; ZeroMemory( &si, sizeof(si) ); CreateProcess( - NULL, // pointer to name of executable module + nullptr, // pointer to name of executable module szFullAppPath, // pointer to command line string - NULL, // process security attributes - NULL, // thread security attributes + nullptr, // process security attributes + nullptr, // thread security attributes false, // handle inheritance flag 0, // creation flags - NULL, // pointer to new environment block - NULL, // pointer to current directory name + nullptr, // pointer to new environment block + nullptr, // pointer to current directory name &si, // pointer to STARTUPINFO &pi // pointer to PROCESS_INFORMATION ); diff --git a/src/archutils/Win32/SpecialDirs.cpp b/src/archutils/Win32/SpecialDirs.cpp index 499dd78538..ee56f2163f 100644 --- a/src/archutils/Win32/SpecialDirs.cpp +++ b/src/archutils/Win32/SpecialDirs.cpp @@ -6,7 +6,7 @@ static RString GetSpecialFolderPath( int csidl ) { RString sDir; TCHAR szDir[MAX_PATH] = ""; - HRESULT hResult = SHGetFolderPath( NULL, csidl, NULL, SHGFP_TYPE_CURRENT, szDir ); + HRESULT hResult = SHGetFolderPath( nullptr, csidl, nullptr, SHGFP_TYPE_CURRENT, szDir ); ASSERT( hResult == S_OK ); sDir = szDir; sDir += "/"; diff --git a/src/archutils/Win32/USB.cpp b/src/archutils/Win32/USB.cpp index 612b0aace0..f233a446e2 100644 --- a/src/archutils/Win32/USB.cpp +++ b/src/archutils/Win32/USB.cpp @@ -20,27 +20,27 @@ static RString GetUSBDevicePath( int iNum ) GUID guid; HidD_GetHidGuid( &guid ); - HDEVINFO DeviceInfo = SetupDiGetClassDevs( &guid, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE) ); + HDEVINFO DeviceInfo = SetupDiGetClassDevs( &guid, nullptr, nullptr, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE) ); SP_DEVICE_INTERFACE_DATA DeviceInterface; DeviceInterface.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA); if( !SetupDiEnumDeviceInterfaces (DeviceInfo, - NULL, &guid, iNum, &DeviceInterface) ) + nullptr, &guid, iNum, &DeviceInterface) ) { SetupDiDestroyDeviceInfoList( DeviceInfo ); return RString(); } unsigned long iSize; - SetupDiGetDeviceInterfaceDetail( DeviceInfo, &DeviceInterface, NULL, 0, &iSize, 0 ); + SetupDiGetDeviceInterfaceDetail( DeviceInfo, &DeviceInterface, nullptr, 0, &iSize, 0 ); PSP_INTERFACE_DEVICE_DETAIL_DATA DeviceDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA) malloc( iSize ); DeviceDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA); RString sRet; if( SetupDiGetDeviceInterfaceDetail(DeviceInfo, &DeviceInterface, - DeviceDetail, iSize, &iSize, NULL) ) + DeviceDetail, iSize, &iSize, nullptr) ) sRet = DeviceDetail->DevicePath; free( DeviceDetail ); @@ -56,7 +56,7 @@ bool USBDevice::Open( int iVID, int iPID, int iBlockSize, int iNum, void (*pfnIn while( (path = GetUSBDevicePath(iIndex++)) != "" ) { HANDLE h = CreateFile( path, GENERIC_READ, - FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); + FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr ); if( h == INVALID_HANDLE_VALUE ) continue; @@ -115,7 +115,7 @@ WindowsFileIO::WindowsFileIO() { ZeroMemory( &m_Overlapped, sizeof(m_Overlapped) ); m_Handle = INVALID_HANDLE_VALUE; - m_pBuffer = NULL; + m_pBuffer = nullptr; } WindowsFileIO::~WindowsFileIO() @@ -138,7 +138,7 @@ bool WindowsFileIO::Open( RString path, int iBlockSize ) CloseHandle( m_Handle ); m_Handle = CreateFile( path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, - NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL ); + nullptr, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, nullptr ); if( m_Handle == INVALID_HANDLE_VALUE ) return false; diff --git a/src/archutils/Win32/VideoDriverInfo.cpp b/src/archutils/Win32/VideoDriverInfo.cpp index 58d38b7952..8a94dbee83 100644 --- a/src/archutils/Win32/VideoDriverInfo.cpp +++ b/src/archutils/Win32/VideoDriverInfo.cpp @@ -18,7 +18,7 @@ RString GetPrimaryVideoName() // VC6 don't have a stub to static link with, so link dynamically. EnumDisplayDevices = (pfnEnumDisplayDevices)GetProcAddress(hInstUser32,"EnumDisplayDevicesA"); - if( EnumDisplayDevices == NULL ) + if( EnumDisplayDevices == nullptr ) { FreeLibrary(hInstUser32); return RString(); @@ -30,7 +30,7 @@ RString GetPrimaryVideoName() DISPLAY_DEVICE dd; ZERO( dd ); dd.cb = sizeof(dd); - if( !EnumDisplayDevices(NULL, i, &dd, 0) ) + if( !EnumDisplayDevices(nullptr, i, &dd, 0) ) break; if( dd.StateFlags & DISPLAY_DEVICE_PRIMARY_DEVICE ) { diff --git a/src/archutils/Win32/WindowIcon.cpp b/src/archutils/Win32/WindowIcon.cpp index 416ed6978d..fcaff50846 100644 --- a/src/archutils/Win32/WindowIcon.cpp +++ b/src/archutils/Win32/WindowIcon.cpp @@ -77,13 +77,13 @@ HICON IconFromSurface( const RageSurface *pSrcImg ) HICON icon = CreateIconFromResourceEx( (BYTE *) pBitmap, iSize + iSizeImage, TRUE, 0x00030000, pImg->w, pImg->h, LR_DEFAULTCOLOR ); delete pImg; - pImg = NULL; + pImg = nullptr; free( pBitmap ); - if( icon == NULL ) + if( icon == nullptr ) { LOG->Trace( "%s", werr_ssprintf( GetLastError(), "CreateIconFromResourceEx" ).c_str() ); - return NULL; + return nullptr; } return icon; @@ -93,10 +93,10 @@ HICON IconFromFile( const RString &sIconFile ) { RString sError; RageSurface *pImg = RageSurfaceUtils::LoadFile( sIconFile, sError ); - if( pImg == NULL ) + if( pImg == nullptr ) { LOG->Warn( "Couldn't open icon \"%s\": %s", sIconFile.c_str(), sError.c_str() ); - return NULL; + return nullptr; } HICON icon = IconFromSurface( pImg ); diff --git a/src/archutils/Win32/WindowsDialogBox.cpp b/src/archutils/Win32/WindowsDialogBox.cpp index 547a851b02..40f6621769 100644 --- a/src/archutils/Win32/WindowsDialogBox.cpp +++ b/src/archutils/Win32/WindowsDialogBox.cpp @@ -3,16 +3,16 @@ WindowsDialogBox::WindowsDialogBox() { - m_hWnd = NULL; + m_hWnd = nullptr; } void WindowsDialogBox::Run( int iDialog ) { char szFullAppPath[MAX_PATH]; - GetModuleFileName( NULL, szFullAppPath, MAX_PATH ); + GetModuleFileName( nullptr, szFullAppPath, MAX_PATH ); HINSTANCE hHandle = LoadLibrary( szFullAppPath ); - DialogBoxParam( hHandle, MAKEINTRESOURCE(iDialog), NULL, DlgProc, (LPARAM) this ); + DialogBoxParam( hHandle, MAKEINTRESOURCE(iDialog), nullptr, DlgProc, (LPARAM) this ); } BOOL APIENTRY WindowsDialogBox::DlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam ) @@ -21,10 +21,10 @@ BOOL APIENTRY WindowsDialogBox::DlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPA SetProp( hDlg, "WindowsDialogBox", (HANDLE) lParam ); WindowsDialogBox *pThis = (WindowsDialogBox *) GetProp( hDlg, "WindowsDialogBox" ); - if( pThis == NULL ) + if( pThis == nullptr ) return FALSE; - if( pThis->m_hWnd == NULL ) + if( pThis->m_hWnd == nullptr ) pThis->m_hWnd = hDlg; return pThis->HandleMessage( msg, wParam, lParam ); diff --git a/src/archutils/Win32/mapconv.cpp b/src/archutils/Win32/mapconv.cpp index e24ab7ed7f..3a5e142592 100644 --- a/src/archutils/Win32/mapconv.cpp +++ b/src/archutils/Win32/mapconv.cpp @@ -36,7 +36,7 @@ char *strtack(char *s, const char *t, const char *s_max) { ++s, ++t; if (s == s_max) - return NULL; + return nullptr; return s+1; } diff --git a/src/ezsockets.cpp b/src/ezsockets.cpp index a90db503e9..a665febb51 100644 --- a/src/ezsockets.cpp +++ b/src/ezsockets.cpp @@ -269,7 +269,7 @@ bool EzSockets::connect(const std::string& host, unsigned short port) struct hostent* phe; phe = gethostbyname(host.c_str()); - if (phe == NULL) + if (phe == nullptr) { return false; } @@ -295,7 +295,7 @@ inline bool checkCanRead(int sock, timeval& timeout) FD_ZERO(&fds); FD_SET((unsigned)sock, &fds); - return select(sock+1, &fds, NULL, NULL, &timeout) > 0; + return select(sock+1, &fds, nullptr, nullptr, &timeout) > 0; } bool EzSockets::CanRead() @@ -320,7 +320,7 @@ bool EzSockets::IsError() FD_ZERO(data->scks); FD_SET((unsigned)data->sock, data->scks); - if (select(data->sock+1, NULL, NULL, data->scks, data->times) >=0 ) + if (select(data->sock+1, nullptr, nullptr, data->scks, data->times) >=0 ) return false; state = skERROR; @@ -333,7 +333,7 @@ inline bool checkCanWrite(int sock, timeval& timeout) FD_ZERO(&fds); FD_SET((unsigned)sock, &fds); - return select(sock+1, NULL, &fds, NULL, &timeout) > 0; + return select(sock+1, nullptr, &fds, nullptr, &timeout) > 0; } bool EzSockets::CanWrite() diff --git a/src/global.h b/src/global.h index a96690653e..2075ec9df1 100644 --- a/src/global.h +++ b/src/global.h @@ -66,7 +66,7 @@ namespace Checkpoints void SetCheckpoint( const char *file, int line, const char *message ); } /** @brief Set a checkpoint with no message. */ -#define CHECKPOINT (Checkpoints::SetCheckpoint(__FILE__, __LINE__, NULL)) +#define CHECKPOINT (Checkpoints::SetCheckpoint(__FILE__, __LINE__, nullptr)) /** @brief Set a checkpoint with a specified message. */ #define CHECKPOINT_M(m) (Checkpoints::SetCheckpoint(__FILE__, __LINE__, m)) diff --git a/src/smpackage-net2003.sln b/src/smpackage-net2003.sln deleted file mode 100644 index 5b6b502f62..0000000000 --- a/src/smpackage-net2003.sln +++ /dev/null @@ -1,55 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "smpackage", "smpackage-net2003.vcproj", "{6B369A92-8DDF-487C-A589-614987544197}" - ProjectSection(ProjectDependencies) = postProject - {F8FE2773-87CB-402F-8DC8-A80837C3E24C} = {F8FE2773-87CB-402F-8DC8-A80837C3E24C} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZipArchive", "smpackage\ZipArchive\ZipArchive-net2003.vcproj", "{F8FE2773-87CB-402F-8DC8-A80837C3E24C}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfiguration) = preSolution - Debug = Debug - Release = Release - Static Debug = Static Debug - Static Release = Static Release - Unicode Debug = Unicode Debug - Unicode Release = Unicode Release - Unicode Static Release = Unicode Static Release - EndGlobalSection - GlobalSection(ProjectConfiguration) = postSolution - {6B369A92-8DDF-487C-A589-614987544197}.Debug.ActiveCfg = Debug|Win32 - {6B369A92-8DDF-487C-A589-614987544197}.Debug.Build.0 = Debug|Win32 - {6B369A92-8DDF-487C-A589-614987544197}.Release.ActiveCfg = Release|Win32 - {6B369A92-8DDF-487C-A589-614987544197}.Release.Build.0 = Release|Win32 - {6B369A92-8DDF-487C-A589-614987544197}.Static Debug.ActiveCfg = Debug|Win32 - {6B369A92-8DDF-487C-A589-614987544197}.Static Debug.Build.0 = Debug|Win32 - {6B369A92-8DDF-487C-A589-614987544197}.Static Release.ActiveCfg = Release|Win32 - {6B369A92-8DDF-487C-A589-614987544197}.Static Release.Build.0 = Release|Win32 - {6B369A92-8DDF-487C-A589-614987544197}.Unicode Debug.ActiveCfg = Debug|Win32 - {6B369A92-8DDF-487C-A589-614987544197}.Unicode Debug.Build.0 = Debug|Win32 - {6B369A92-8DDF-487C-A589-614987544197}.Unicode Release.ActiveCfg = Release|Win32 - {6B369A92-8DDF-487C-A589-614987544197}.Unicode Release.Build.0 = Release|Win32 - {6B369A92-8DDF-487C-A589-614987544197}.Unicode Static Release.ActiveCfg = Release|Win32 - {6B369A92-8DDF-487C-A589-614987544197}.Unicode Static Release.Build.0 = Release|Win32 - {F8FE2773-87CB-402F-8DC8-A80837C3E24C}.Debug.ActiveCfg = Debug|Win32 - {F8FE2773-87CB-402F-8DC8-A80837C3E24C}.Debug.Build.0 = Debug|Win32 - {F8FE2773-87CB-402F-8DC8-A80837C3E24C}.Release.ActiveCfg = Release|Win32 - {F8FE2773-87CB-402F-8DC8-A80837C3E24C}.Release.Build.0 = Release|Win32 - {F8FE2773-87CB-402F-8DC8-A80837C3E24C}.Static Debug.ActiveCfg = Static Debug|Win32 - {F8FE2773-87CB-402F-8DC8-A80837C3E24C}.Static Debug.Build.0 = Static Debug|Win32 - {F8FE2773-87CB-402F-8DC8-A80837C3E24C}.Static Release.ActiveCfg = Static Release|Win32 - {F8FE2773-87CB-402F-8DC8-A80837C3E24C}.Static Release.Build.0 = Static Release|Win32 - {F8FE2773-87CB-402F-8DC8-A80837C3E24C}.Unicode Debug.ActiveCfg = Unicode Debug|Win32 - {F8FE2773-87CB-402F-8DC8-A80837C3E24C}.Unicode Debug.Build.0 = Unicode Debug|Win32 - {F8FE2773-87CB-402F-8DC8-A80837C3E24C}.Unicode Release.ActiveCfg = Unicode Release|Win32 - {F8FE2773-87CB-402F-8DC8-A80837C3E24C}.Unicode Release.Build.0 = Unicode Release|Win32 - {F8FE2773-87CB-402F-8DC8-A80837C3E24C}.Unicode Static Release.ActiveCfg = Unicode Static Release|Win32 - {F8FE2773-87CB-402F-8DC8-A80837C3E24C}.Unicode Static Release.Build.0 = Unicode Static Release|Win32 - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - EndGlobalSection - GlobalSection(ExtensibilityAddIns) = postSolution - EndGlobalSection -EndGlobal diff --git a/src/smpackage-net2003.vcproj b/src/smpackage-net2003.vcproj deleted file mode 100644 index 8bbe33e746..0000000000 --- a/src/smpackage-net2003.vcproj +++ /dev/null @@ -1,1072 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/smpackage/CreateLanguageDlg.cpp b/src/smpackage/CreateLanguageDlg.cpp index 6391934a2d..94f5e692b1 100644 --- a/src/smpackage/CreateLanguageDlg.cpp +++ b/src/smpackage/CreateLanguageDlg.cpp @@ -5,7 +5,6 @@ #include "stdafx.h" #include "smpackage.h" #include "CreateLanguageDlg.h" -#include "Foreach.h" #include "RageUtil.h" #include "SMPackageUtil.h" #include ".\createlanguagedlg.h" diff --git a/src/smpackage/LanguagesDlg.cpp b/src/smpackage/LanguagesDlg.cpp index d5165716ed..e0a3cd9491 100644 --- a/src/smpackage/LanguagesDlg.cpp +++ b/src/smpackage/LanguagesDlg.cpp @@ -4,7 +4,6 @@ #include "global.h" #include "stdafx.h" #include "smpackage.h" -#include "Foreach.h" #include "LanguagesDlg.h" #include "SpecialFiles.h" #include "RageUtil.h" @@ -53,7 +52,7 @@ BOOL LanguagesDlg::OnInitDialog() vector vs; GetDirListing( SpecialFiles::THEMES_DIR+"*", vs, true ); StripCvsAndSvn( vs ); - FOREACH_CONST( RString, vs, s ) + for (vector::const_iterator s = vs.begin(); s != vs.end(); ++s) m_listThemes.AddString( *s ); if( !vs.empty() ) m_listThemes.SetSel( 0 ); @@ -100,7 +99,7 @@ void LanguagesDlg::OnSelchangeListThemes() vector vs; GetDirListing( sLanguagesDir+"*.ini", vs, false ); - FOREACH_CONST( RString, vs, s ) + for (vector::const_iterator s = vs.begin(); s != vs.end(); ++s) { RString sIsoCode = GetFileNameWithoutExtension(*s); RString sLanguage = SMPackageUtil::GetLanguageDisplayString(sIsoCode); @@ -389,7 +388,7 @@ void LanguagesDlg::OnBnClickedButtonImport() int iNumModified = 0; int iNumUnchanged = 0; int iNumIgnored = 0; - FOREACH_CONST( CsvFile::StringVector, csv.m_vvs, line ) + for (vector::const_iterator line = csv.m_vvs.begin(); line != csv.m_vvs.end(); ++line) { int iLineIndex = line - csv.m_vvs.begin(); @@ -462,7 +461,7 @@ void GetAllMatches( const RString &sRegex, const RString &sString, vector &asList, RageFile &file ) { RString sLine; - FOREACH_CONST( RString, asList, s ) + for (vector::const_iterator s = asList.begin(); s != asList.end(); ++s) { if( sLine.size() + s->size() > 100 ) {