Simple loop to handle.
This commit is contained in:
+203
-204
@@ -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<RString> 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<RString> 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; i<asImagePaths.size(); i++ )
|
||||
{
|
||||
const RString sPath = asImagePaths[i];
|
||||
if( Basename(sPath).Left(1) == "_" )
|
||||
continue; // don't directly load files starting with an underscore
|
||||
BGAnimationLayer* pLayer = new BGAnimationLayer;
|
||||
pLayer->LoadFromAniLayerFile( 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 "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<RString> 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 != 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<RString> 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; i<asImagePaths.size(); i++ )
|
||||
{
|
||||
const RString sPath = asImagePaths[i];
|
||||
if( Basename(sPath).Left(1) == "_" )
|
||||
continue; // don't directly load files starting with an underscore
|
||||
BGAnimationLayer* pLayer = new BGAnimationLayer;
|
||||
pLayer->LoadFromAniLayerFile( 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.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user