From ca4eb65b61754524d0f05ee639ca038a82e7e6ca Mon Sep 17 00:00:00 2001 From: Kyzentun Date: Thu, 23 Oct 2014 00:13:13 -0600 Subject: [PATCH] Added lerp, lerp_color, approach, and multiapproach lua functions. --- Docs/Changelog_sm5.txt | 4 ++ Docs/Luadoc/Lua.xml | 4 ++ Docs/Luadoc/LuaDocumentation.xml | 17 +++++- Themes/_fallback/Scripts/02 Utilities.lua | 2 + src/LuaManager.h | 5 ++ src/RageTypes.cpp | 25 +++++++- src/RageTypes.h | 1 + src/RageUtil.cpp | 70 +++++++++++++++++++++++ 8 files changed, 125 insertions(+), 3 deletions(-) diff --git a/Docs/Changelog_sm5.txt b/Docs/Changelog_sm5.txt index 4b5ee89309..8dc574e629 100644 --- a/Docs/Changelog_sm5.txt +++ b/Docs/Changelog_sm5.txt @@ -4,6 +4,10 @@ The StepMania 5 Changelog covers all post-sm-ssc changes. For a list of changes from StepMania 4 alpha 5 to sm-ssc v1.2.5, see Changelog_sm-ssc.txt. ________________________________________________________________________________ +2014/10/23 +---------- +* [Global] approach, multiapproach, lerp, and lerp_color lua functions added. + 2014/10/20 ---------- * [StageStats] GetStepsSeconds function added. diff --git a/Docs/Luadoc/Lua.xml b/Docs/Luadoc/Lua.xml index de8282d3f5..ab33c6e73d 100644 --- a/Docs/Luadoc/Lua.xml +++ b/Docs/Luadoc/Lua.xml @@ -203,6 +203,7 @@ + @@ -219,11 +220,14 @@ + + + diff --git a/Docs/Luadoc/LuaDocumentation.xml b/Docs/Luadoc/LuaDocumentation.xml index e9c33fedd4..ae50abaebf 100644 --- a/Docs/Luadoc/LuaDocumentation.xml +++ b/Docs/Luadoc/LuaDocumentation.xml @@ -31,6 +31,10 @@ save yourself some time, copy this for undocumented things: [02 Colors.lua] Returns a color with the specified alpha. + + Use this to make a current value approach a goal value at the given speed. Speed must not be negative. The value will not overshoot the goal.
+ Note: When you see the error "approach: speed 1 is negative." it means that the speed value passed was negative. The 1 is there because approach and multiapproach use the same internal function and can be ignored when using approach. +
[03 CustomSpeedMods.lua] @@ -136,7 +140,7 @@ save yourself some time, copy this for undocumented things: [03 Gameplay.lua]
- [02 Utilities.lua] + [02 Utilities.lua] Old name for approach. [02 Utilities.lua] Return the index of a true value in list. @@ -327,6 +331,12 @@ save yourself some time, copy this for undocumented things: [02 Colors.lua] + + Returns a number linearly interpolated between start and end by percent. + + + Same as lerp, but for colors. All channels will reach the end of the interpolation at the same time. + Returns an Actor definition for the actor at sPath. If sPath points to a Lua file, any additional arguments will be passed to that script. @@ -369,6 +379,11 @@ save yourself some time, copy this for undocumented things: Returns Month m as a string. + + Similar to approach, but operates on tables of values instead of single values. This will modify the contents of currents in place, as well as returning currents.
+ currents, goals, and speeds must all be the same size and contain only numbers.
+ Note: When you see the error "approach: speed 1 is negative." it means that a speed value passed was negative. The 1 tells you which entry in the table was invalid. +
"Allows a program to traverse all fields of a table. Its first argument is a table and its second argument is an index in this table. diff --git a/Themes/_fallback/Scripts/02 Utilities.lua b/Themes/_fallback/Scripts/02 Utilities.lua index 4750c48b7d..53a3acf534 100644 --- a/Themes/_fallback/Scripts/02 Utilities.lua +++ b/Themes/_fallback/Scripts/02 Utilities.lua @@ -66,6 +66,8 @@ function wrap(val,n) end function fapproach(val, other_val, to_move) + -- This does not use the (faster) C++ side version of approach because I + -- don't want to find out how many themes pass a negative speed. -Kyz if val == other_val then return val -- already done! end diff --git a/src/LuaManager.h b/src/LuaManager.h index 644780eb67..8573394ee4 100644 --- a/src/LuaManager.h +++ b/src/LuaManager.h @@ -266,6 +266,11 @@ void LuaFunc_Register_##func( lua_State *L ); \ void LuaFunc_Register_##func( lua_State *L ) { lua_register( L, #func, LuaFunc_##func ); } \ REGISTER_WITH_LUA_FUNCTION( LuaFunc_Register_##func ); +#define LUAFUNC_REGISTER_COMMON(func_name) \ +void LuaFunc_Register_##func_name(lua_State* L); \ +void LuaFunc_Register_##func_name(lua_State* L) { lua_register(L, #func_name, LuaFunc_##func_name); } \ +REGISTER_WITH_LUA_FUNCTION(LuaFunc_Register_##func_name); + #endif /* diff --git a/src/RageTypes.cpp b/src/RageTypes.cpp index b3d96215a2..b554a042e7 100644 --- a/src/RageTypes.cpp +++ b/src/RageTypes.cpp @@ -74,6 +74,14 @@ RString RageColor::NormalizeColorString( RString sColor ) return c.ToString(); } +void lerp_rage_color(RageColor& out, RageColor const& a, RageColor const& b, float t) +{ + out.b= lerp(t, a.b, b.b); + out.g= lerp(t, a.g, b.g); + out.r= lerp(t, a.r, b.r); + out.a= lerp(t, a.a, b.a); +} + void WeightedAvergeOfRSVs(RageSpriteVertex& average_out, RageSpriteVertex const& rsv1, RageSpriteVertex const& rsv2, float percent_between) { average_out.p= lerp(percent_between, rsv1.p, rsv2.p); @@ -207,8 +215,21 @@ int LuaFunc_color( lua_State *L ) c.PushTable( L ); return 1; } -void LuaFunc_Register_color( lua_State *L ) { lua_register( L, "color", LuaFunc_color ); } -REGISTER_WITH_LUA_FUNCTION( LuaFunc_Register_color ); +LUAFUNC_REGISTER_COMMON(color); + +int LuaFunc_lerp_color(lua_State *L) +{ + // Args: percent, color, color + // Returns: color + float percent= FArg(1); + RageColor a, b, c; + a.FromStack(L, 2); + b.FromStack(L, 3); + lerp_rage_color(c, a, b, percent); + c.PushTable(L); + return 1; +} +LUAFUNC_REGISTER_COMMON(lerp_color); /* * Copyright (c) 2006 Glenn Maynard diff --git a/src/RageTypes.h b/src/RageTypes.h index 0a5d51a1c9..ddfc3e88ec 100644 --- a/src/RageTypes.h +++ b/src/RageTypes.h @@ -342,6 +342,7 @@ struct RageSpriteVertex // has color RageVector2 t; // texture coordinates }; +void lerp_rage_color(RageColor& out, RageColor const& a, RageColor const& b, float t); void WeightedAvergeOfRSVs(RageSpriteVertex& average_out, RageSpriteVertex const& rsv1, RageSpriteVertex const& rsv2, float percent_between); struct RageModelVertex // doesn't have color. Relies on material color diff --git a/src/RageUtil.cpp b/src/RageUtil.cpp index 8255f9e96d..c2d033f87e 100644 --- a/src/RageUtil.cpp +++ b/src/RageUtil.cpp @@ -2329,6 +2329,76 @@ LuaFunction( PrettyPercent, PrettyPercent( FArg(1), FArg(2) ) ); //LuaFunction( IsHexVal, IsHexVal( SArg(1) ) ); static bool UndocumentedFeature( RString s ){ sm_crash(s); return true; } LuaFunction( UndocumentedFeature, UndocumentedFeature(SArg(1)) ); +LuaFunction( lerp, lerp(FArg(1), FArg(2), FArg(3)) ); + +void luafunc_approach_internal(lua_State* L, int valind, int goalind, int speedind); +void luafunc_approach_internal(lua_State* L, int valind, int goalind, int speedind, int process_index) +{ +#define TONUMBER_NICE(dest, num_name, index) \ + if(!lua_isnumber(L, index)) \ + { \ + luaL_error(L, "approach: " #num_name " for approach %d is not a number.", process_index); \ + } \ + dest= lua_tonumber(L, index); + float val= 0; + float goal= 0; + float speed= 0; + TONUMBER_NICE(val, current, valind); + TONUMBER_NICE(goal, goal, goalind); + TONUMBER_NICE(speed, speed, speedind); +#undef TONUMBER_NICE + if(speed < 0) + { + luaL_error(L, "approach: speed %d is negative.", process_index); + } + fapproach(val, goal, speed); + lua_pushnumber(L, val); +} + +int LuaFunc_approach(lua_State* L); +int LuaFunc_approach(lua_State* L) +{ + // Args: current, goal, speed + // Returns: new_current + luafunc_approach_internal(L, 1, 2, 3, 1); + return 1; +} +LUAFUNC_REGISTER_COMMON(approach); + +int LuaFunc_multiapproach(lua_State* L); +int LuaFunc_multiapproach(lua_State* L) +{ + // Args: {currents}, {goals}, {speeds} + // Returns: {currents} + // Modifies the values in {currents} in place. + if(lua_gettop(L) != 3) + { + luaL_error(L, "multiapproach: A table of current values, a table of goal values, and a table of speeds must be passed."); + } + size_t currents_len= lua_objlen(L, 1); + size_t goals_len= lua_objlen(L, 2); + size_t speeds_len= lua_objlen(L, 3); + if(currents_len != goals_len || currents_len != speeds_len) + { + luaL_error(L, "multiapproach: There must be the same number of current values, goal values, and speeds."); + } + if(!lua_istable(L, 1) || !lua_istable(L, 2) || !lua_istable(L, 3)) + { + luaL_error(L, "multiapproach: current, goal, and speed must all be tables."); + } + for(size_t i= 1; i <= currents_len; ++i) + { + lua_rawgeti(L, 1, i); + lua_rawgeti(L, 2, i); + lua_rawgeti(L, 3, i); + luafunc_approach_internal(L, -3, -2, -1, i); + lua_rawseti(L, 1, i); + lua_pop(L, 3); + } + lua_pushvalue(L, 1); + return 1; +} +LUAFUNC_REGISTER_COMMON(multiapproach); /* * Copyright (c) 2001-2005 Chris Danford, Glenn Maynard