diff --git a/stepmania/src/BGAnimation.cpp b/stepmania/src/BGAnimation.cpp index 3cde785952..331e935964 100644 --- a/stepmania/src/BGAnimation.cpp +++ b/stepmania/src/BGAnimation.cpp @@ -59,7 +59,7 @@ void AddLayersFromAniDir( CString sAniDir, vector &layersAddTo, bool Gen CString expr; if( ini.GetValue( "BGAnimation", "Condition", expr ) || ini.GetValue( "BGAnimation", "Cond", expr ) ) { - if( !Lua::RunExpression( expr ) ) + if( !Lua::RunExpressionB( expr ) ) return; } } @@ -77,7 +77,7 @@ void AddLayersFromAniDir( CString sAniDir, vector &layersAddTo, bool Gen CString expr; if( ini.GetValue(sLayer,"Condition",expr) ) { - if( !Lua::RunExpression( expr ) ) + if( !Lua::RunExpressionB( expr ) ) continue; } diff --git a/stepmania/src/LuaHelpers.cpp b/stepmania/src/LuaHelpers.cpp index c420fa3fee..eaeb9949de 100644 --- a/stepmania/src/LuaHelpers.cpp +++ b/stepmania/src/LuaHelpers.cpp @@ -3,6 +3,7 @@ #include "LuaFunctions.h" #include "RageUtil.h" #include "RageLog.h" +#include "ScreenDimensions.h" #include #include @@ -129,12 +130,15 @@ static int LuaPanic( lua_State *L ) longjmp( jbuf, 1 ); } -bool Lua::RunExpression( const CString &str ) +lua_State *L = NULL; + +void OpenLua() { -try { + ASSERT( L == NULL ); + if( setjmp(jbuf) ) RageException::Throw("%s", jbuf_error.c_str()); - lua_State *L = lua_open(); + L = lua_open(); ASSERT( L ); lua_atpanic( L, LuaPanic ); @@ -145,7 +149,43 @@ try { lua_settop(L, 0); // luaopen_* pushes stuff onto the stack that we don't need Lua::RegisterFunctions( L ); +} +void CloseLua() +{ + ASSERT( L ); + + lua_close( L ); + L = NULL; +} + +void Lua::UpdateGlobals() +{ + if( L == NULL ) + OpenLua(); + + ASSERT( L ); + + lua_pushnumber( L, SCREEN_WIDTH ); + lua_setglobal( L, "SCREEN_WIDTH" ); + lua_pushnumber( L, SCREEN_HEIGHT ); + lua_setglobal( L, "SCREEN_HEIGHT" ); + lua_pushnumber( L, SCREEN_LEFT ); + lua_setglobal( L, "SCREEN_LEFT" ); + lua_pushnumber( L, SCREEN_RIGHT ); + lua_setglobal( L, "SCREEN_RIGHT" ); + lua_pushnumber( L, SCREEN_TOP ); + lua_setglobal( L, "SCREEN_TOP" ); + lua_pushnumber( L, SCREEN_BOTTOM ); + lua_setglobal( L, "SCREEN_BOTTOM" ); + lua_pushnumber( L, CENTER_X ); + lua_setglobal( L, "SCREEN_CENTER_X" ); + lua_pushnumber( L, CENTER_Y ); + lua_setglobal( L, "SCREEN_CENTER_Y" ); +} + +void RunExpression( const CString &str ) +{ LoadFromString( L, "return " + str ); ASSERT_M( lua_gettop(L) == 1, ssprintf("%i", lua_gettop(L)) ); @@ -163,16 +203,40 @@ try { * as a boolean, convert it before returning. */ if( lua_isfunction( L, -1 ) ) throw CString( "result is a function; did you forget \"()\"?" ); - - bool result = !!lua_toboolean( L, -1 ); - lua_pop( L, -1 ); - - lua_close( L ); - - return result; -} catch( const CString &err ) { - RageException::Throw( "Error running \"%s\": %s", str.c_str(), err.c_str() ); } + +bool Lua::RunExpressionB( const CString &str ) +{ + try { + if( L == NULL ) + OpenLua(); + + RunExpression( str ); + + bool result = !!lua_toboolean( L, -1 ); + lua_pop( L, -1 ); + + return result; + } catch( const CString &err ) { + RageException::Throw( "Error running \"%s\": %s", str.c_str(), err.c_str() ); + } +} + +float Lua::RunExpressionF( const CString &str ) +{ + try { + if( L == NULL ) + OpenLua(); + + RunExpression( str ); + + float result = lua_tonumber( L, -1 ); + lua_pop( L, -1 ); + + return result; + } catch( const CString &err ) { + RageException::Throw( "Error running \"%s\": %s", str.c_str(), err.c_str() ); + } } void Lua::Fail( lua_State *L, const CString &err ) diff --git a/stepmania/src/LuaHelpers.h b/stepmania/src/LuaHelpers.h index d701f8c950..7860c2e30c 100644 --- a/stepmania/src/LuaHelpers.h +++ b/stepmania/src/LuaHelpers.h @@ -4,7 +4,8 @@ struct lua_State; namespace Lua { - bool RunExpression( const CString &str ); + bool RunExpressionB( const CString &str ); + float RunExpressionF( const CString &str ); void Fail( lua_State *L, const CString &err ); @@ -17,6 +18,7 @@ namespace Lua void PushStack( lua_State *L, const CString &out ); void PopStack( lua_State *L, CString &out ); bool GetStack( lua_State *L, int pos, int &out ); + void UpdateGlobals(); // call this when the theme changes }; #endif diff --git a/stepmania/src/ScreenBranch.cpp b/stepmania/src/ScreenBranch.cpp index a5460f0d86..41d1d3f943 100644 --- a/stepmania/src/ScreenBranch.cpp +++ b/stepmania/src/ScreenBranch.cpp @@ -22,7 +22,7 @@ ScreenBranch::ScreenBranch( CString sClassName ) : Screen( sClassName ) CString sChoice = Capitalize( as[i] ); CString sCondition = CONDITION(sChoice); - if( Lua::RunExpression(sCondition) ) + if( Lua::RunExpressionB(sCondition) ) { m_sChoice = sChoice; HandleScreenMessage( SM_GoToNextScreen ); diff --git a/stepmania/src/ThemeManager.cpp b/stepmania/src/ThemeManager.cpp index d8c9c64e5d..cd4ec45577 100644 --- a/stepmania/src/ThemeManager.cpp +++ b/stepmania/src/ThemeManager.cpp @@ -17,6 +17,7 @@ #include "StepMania.h" #include "Foreach.h" #include "ThemeMetric.h" +#include "LuaHelpers.h" ThemeManager* THEME = NULL; // global object accessable from anywhere in the program @@ -247,6 +248,8 @@ void ThemeManager::SwitchThemeAndLanguage( CString sThemeName, CString sLanguage // reload subscribers FOREACH( IThemeMetric*, *g_pvpSubscribers, p ) (*p)->Read(); + + Lua::UpdateGlobals(); } CString ThemeManager::GetThemeDirFromName( const CString &sThemeName ) @@ -611,19 +614,19 @@ int ThemeManager::GetMetricI( CString sClassName, CString sValueName ) float ThemeManager::GetMetricF( CString sClassName, CString sValueName ) { - return strtof( GetMetricRaw(sClassName,sValueName), NULL ); + const CString str = GetMetricRaw( sClassName,sValueName ); + return Lua::RunExpressionF( str ); } // #include "LuaHelpers.h" bool ThemeManager::GetMetricB( CString sClassName, CString sValueName ) { -// const CString str = GetMetricRaw( sClassName,sValueName ); -// if( str == "0" ) -// return false; /* optimization */ -// if( str == "1" ) -// return true; /* optimization */ -// return Lua::RunExpression( str ); - return atoi( GetMetricRaw(sClassName,sValueName) ) != 0; + const CString str = GetMetricRaw( sClassName,sValueName ); + if( str == "0" ) + return false; /* optimization */ + if( str == "1" ) + return true; /* optimization */ + return Lua::RunExpressionB( str ); } RageColor ThemeManager::GetMetricC( CString sClassName, CString sValueName )