Skip to content
Snippets Groups Projects
Select Git revision
  • better-distance-math
  • next default protected
  • movie
  • softcode-info
  • master protected
  • acs
  • spriteinfo-refactor
  • clipmidtex
  • custom-map-names
  • nogravity-trampolines
  • 2214-pre4
  • 2214-pre3
  • just-in-case
  • fix-opengl-parameter-crash
  • 2214-pre2
  • 2214-pre1
  • delfile2
  • cleanupmusic
  • gametype-refactor-1
  • extra-textures
  • SRB2_release_2.2.15
  • SRB2_release_2.2.13
  • SRB2_release_2.2.12
  • SRB2_release_2.2.11
  • SRB2_release_2.2.10
  • SRB2_release_2.2.9
  • SRB2_release_2.2.8
  • SRB2_release_2.2.7
  • SRB2_release_2.2.6
  • SRB2_release_2.2.5
  • SRB2_release_2.2.4
  • SRB2_release_2.2.3
  • SRB2_release_2.2.2
  • SRB2_release_2.2.1
  • SRB2_release_2.2.0
  • SRB2_release_2.1.25
  • SRB2_release_2.1.24
  • SRB2_release_2.1.23
  • SRB2_release_2.1.22
  • SRB2_release_2.1.21
40 results

lua_mathlib.c

Blame
  • lua_mathlib.c 9.05 KiB
    // SONIC ROBO BLAST 2
    //-----------------------------------------------------------------------------
    // Copyright (C) 2012-2016 by John "JTE" Muniz.
    // Copyright (C) 2012-2023 by Sonic Team Junior.
    //
    // This program is free software distributed under the
    // terms of the GNU General Public License, version 2.
    // See the 'LICENSE' file for more details.
    //-----------------------------------------------------------------------------
    /// \file  lua_mathlib.c
    /// \brief basic math library for Lua scripting
    
    #include "doomdef.h"
    //#include "fastcmp.h"
    #include "tables.h"
    #include "p_local.h"
    #include "doomstat.h" // for ALL7EMERALDS
    #include "r_main.h" // for R_PointToDist2
    #include "m_easing.h"
    
    #include "lua_script.h"
    #include "lua_libs.h"
    
    // General math
    //////////////////
    
    static int lib_abs(lua_State *L)
    {
    	int a = (int)luaL_checkinteger(L, 1);
    	lua_pushinteger(L, abs(a));
    	return 1;
    }
    
    static int lib_min(lua_State *L)
    {
    	int a = luaL_checkinteger(L, 1);
    	int b = luaL_checkinteger(L, 2);
    	lua_pushinteger(L, min(a,b));
    	return 1;
    }
    
    static int lib_max(lua_State *L)
    {
    	int a = luaL_checkinteger(L, 1);
    	int b = luaL_checkinteger(L, 2);
    	lua_pushinteger(L, max(a,b));
    	return 1;
    }
    
    // Angle math
    ////////////////
    
    static int lib_fixedangle(lua_State *L)
    {
    	lua_pushangle(L, FixedAngle(luaL_checkfixed(L, 1)));
    	return 1;
    }
    
    static int lib_anglefixed(lua_State *L)
    {
    	lua_pushfixed(L, AngleFixed(luaL_checkangle(L, 1)));
    	return 1;
    }
    
    static int lib_invangle(lua_State *L)
    {
    	lua_pushangle(L, InvAngle(luaL_checkangle(L, 1)));
    	return 1;
    }
    
    static int lib_finesine(lua_State *L)
    {
    	lua_pushfixed(L, FINESINE((luaL_checkangle(L, 1)>>ANGLETOFINESHIFT) & FINEMASK));
    	return 1;
    }
    
    static int lib_finecosine(lua_State *L)
    {
    	lua_pushfixed(L, FINECOSINE((luaL_checkangle(L, 1)>>ANGLETOFINESHIFT) & FINEMASK));
    	return 1;
    }
    
    static int lib_finetangent(lua_State *L)
    {
    	// HACK: add ANGLE_90 to make tan() in Lua start at 0 like it should
    	// use & 4095 instead of & FINEMASK (8191), so it doesn't go out of the array's bounds
    	lua_pushfixed(L, FINETANGENT(((luaL_checkangle(L, 1)+ANGLE_90)>>ANGLETOFINESHIFT) & 4095));
    	return 1;
    }
    
    static int lib_fixedasin(lua_State *L)
    {
    	lua_pushangle(L, -FixedAcos(luaL_checkfixed(L, 1)) + ANGLE_90);
    	return 1;
    }
    
    static int lib_fixedacos(lua_State *L)
    {
    	lua_pushangle(L, FixedAcos(luaL_checkfixed(L, 1)));
    	return 1;
    }
    
    // Fixed math
    ////////////////
    
    static int lib_fixedmul(lua_State *L)
    {
    	lua_pushfixed(L, FixedMul(luaL_checkfixed(L, 1), luaL_checkfixed(L, 2)));
    	return 1;
    }
    
    static int lib_fixedint(lua_State *L)
    {
    	lua_pushinteger(L, FixedInt(luaL_checkfixed(L, 1)));
    	return 1;
    }
    
    static int lib_fixeddiv(lua_State *L)
    {
    	fixed_t i = luaL_checkfixed(L, 1);
    	fixed_t j = luaL_checkfixed(L, 2);
    	if (j == 0)
    		return luaL_error(L, "divide by zero");
    	lua_pushfixed(L, FixedDiv(i, j));
    	return 1;
    }
    
    // TODO: 2.3: Delete
    static int lib_fixedrem(lua_State *L)
    {
    	LUA_Deprecated(L, "FixedRem(a, b)", "a % b");
    	lua_pushfixed(L, luaL_checkfixed(L, 1) % luaL_checkfixed(L, 2));
    	return 1;
    }
    
    static int lib_fixedsqrt(lua_State *L)
    {
    	fixed_t i = luaL_checkfixed(L, 1);
    	if (i < 0)
    		return luaL_error(L, "square root domain error");
    	lua_pushfixed(L, FixedSqrt(i));
    	return 1;
    }
    
    static int lib_fixedhypot(lua_State *L)
    {
    	lua_pushfixed(L, R_PointToDist2(0, 0, luaL_checkfixed(L, 1), luaL_checkfixed(L, 2)));
    	return 1;
    }
    
    static int lib_fixedfloor(lua_State *L)
    {
    	lua_pushfixed(L, FixedFloor(luaL_checkfixed(L, 1)));
    	return 1;
    }
    
    static int lib_fixedtrunc(lua_State *L)
    {
    	lua_pushfixed(L, FixedTrunc(luaL_checkfixed(L, 1)));
    	return 1;
    }
    
    static int lib_fixedceil(lua_State *L)
    {
    	lua_pushfixed(L, FixedCeil(luaL_checkfixed(L, 1)));
    	return 1;
    }
    
    static int lib_fixedround(lua_State *L)
    {
    	lua_pushfixed(L, FixedRound(luaL_checkfixed(L, 1)));
    	return 1;
    }
    
    // Misc. math
    // (aka extra little funcs that don't quite fit in baselib)
    //////////////////////////////////////////////////////////////////
    
    static int lib_getsecspecial(lua_State *L)
    {
    	lua_pushinteger(L, GETSECSPECIAL(luaL_checkinteger(L, 1), luaL_checkinteger(L, 2)));
    	return 1;
    }
    
    static int lib_all7emeralds(lua_State *L)
    {
    	lua_pushboolean(L, ALL7EMERALDS(luaL_checkinteger(L, 1)));
    	return 1;
    }
    
    // Returns both color and signpost shade numbers!
    static int lib_coloropposite(lua_State *L)
    {
    	UINT16 colornum = (UINT16)luaL_checkinteger(L, 1);
    	if (!colornum || colornum >= numskincolors)
    		return luaL_error(L, "skincolor %d out of range (1 - %d).", colornum, numskincolors-1);
    	lua_pushinteger(L, skincolors[colornum].invcolor); // push color
    	lua_pushinteger(L, skincolors[colornum].invshade); // push sign shade index, 0-15
    	return 2;
    }
    
    static luaL_Reg lib_math[] = {
    	{"abs", lib_abs},
    	{"min", lib_min},
    	{"max", lib_max},
    	{"sin", lib_finesine},
    	{"cos", lib_finecosine},
    	{"tan", lib_finetangent},
    	{"asin", lib_fixedasin},
    	{"acos", lib_fixedacos},
    	{"FixedAngle", lib_fixedangle},
    	{"fixangle"  , lib_fixedangle},
    	{"AngleFixed", lib_anglefixed},
    	{"anglefix"  , lib_anglefixed},
    	{"InvAngle", lib_invangle},
    	{"FixedMul", lib_fixedmul},
    	{"fixmul"  , lib_fixedmul},
    	{"FixedInt", lib_fixedint},
    	{"fixint"  , lib_fixedint},
    	{"FixedDiv", lib_fixeddiv},
    	{"fixdiv"  , lib_fixeddiv},
    	{"FixedRem", lib_fixedrem},
    	{"fixrem"  , lib_fixedrem},
    	{"FixedSqrt", lib_fixedsqrt},
    	{"fixsqrt"  , lib_fixedsqrt},
    	{"FixedHypot", lib_fixedhypot},
    	{"fixhypot"  , lib_fixedhypot},
    	{"FixedFloor", lib_fixedfloor},
    	{"fixfloor"  , lib_fixedfloor},
    	{"FixedTrunc", lib_fixedtrunc},
    	{"fixtrunc"  , lib_fixedtrunc},
    	{"FixedCeil", lib_fixedceil},
    	{"fixceil"  , lib_fixedceil},
    	{"FixedRound", lib_fixedround},
    	{"fixround"  , lib_fixedround},
    	{"GetSecSpecial", lib_getsecspecial},
    	{"All7Emeralds", lib_all7emeralds},
    	{"ColorOpposite", lib_coloropposite},
    	{NULL, NULL}
    };
    
    //
    // Easing functions
    //
    
    #define EASINGFUNC(easetype) \
    { \
    	fixed_t start = 0; \
    	fixed_t end = FRACUNIT; \
    	fixed_t t = luaL_checkfixed(L, 1); \
    	int n = lua_gettop(L); \
    	if (n == 2) \
    		end = luaL_checkfixed(L, 2); \
    	else if (n >= 3) \
    	{ \
    		start = luaL_checkfixed(L, 2); \
    		end = luaL_checkfixed(L, 3); \
    	} \
    	lua_pushfixed(L, (Easing_ ## easetype)(t, start, end)); \
    	return 1; \
    } \
    
    static int lib_easelinear(lua_State *L) { EASINGFUNC(Linear) }
    
    static int lib_easeinsine(lua_State *L) { EASINGFUNC(InSine) }
    static int lib_easeoutsine(lua_State *L) { EASINGFUNC(OutSine) }
    static int lib_easeinoutsine(lua_State *L) { EASINGFUNC(InOutSine) }
    
    static int lib_easeinquad(lua_State *L) { EASINGFUNC(InQuad) }
    static int lib_easeoutquad(lua_State *L) { EASINGFUNC(OutQuad) }
    static int lib_easeinoutquad(lua_State *L) { EASINGFUNC(InOutQuad) }
    
    static int lib_easeincubic(lua_State *L) { EASINGFUNC(InCubic) }
    static int lib_easeoutcubic(lua_State *L) { EASINGFUNC(OutCubic) }
    static int lib_easeinoutcubic(lua_State *L) { EASINGFUNC(InOutCubic) }
    
    static int lib_easeinquart(lua_State *L) { EASINGFUNC(InQuart) }
    static int lib_easeoutquart(lua_State *L) { EASINGFUNC(OutQuart) }
    static int lib_easeinoutquart(lua_State *L) { EASINGFUNC(InOutQuart) }
    
    static int lib_easeinquint(lua_State *L) { EASINGFUNC(InQuint) }
    static int lib_easeoutquint(lua_State *L) { EASINGFUNC(OutQuint) }
    static int lib_easeinoutquint(lua_State *L) { EASINGFUNC(InOutQuint) }
    
    static int lib_easeinexpo(lua_State *L) { EASINGFUNC(InExpo) }
    static int lib_easeoutexpo(lua_State *L) { EASINGFUNC(OutExpo) }
    static int lib_easeinoutexpo(lua_State *L) { EASINGFUNC(InOutExpo) }
    
    #undef EASINGFUNC
    
    #define EASINGFUNC(easetype) \
    { \
    	boolean useparam = false; \
    	fixed_t param = 0; \
    	fixed_t start = 0; \
    	fixed_t end = FRACUNIT; \
    	fixed_t t = luaL_checkfixed(L, 1); \
    	int n = lua_gettop(L); \
    	if (n == 2) \
    		end = luaL_checkfixed(L, 2); \
    	else if (n >= 3) \
    	{ \
    		start = (fixed_t)luaL_optinteger(L, 2, start); \
    		end = (fixed_t)luaL_optinteger(L, 3, end); \
    		if ((n >= 4) && (useparam = (!lua_isnil(L, 4)))) \
    			param = luaL_checkfixed(L, 4); \
    	} \
    	if (useparam) \
    		lua_pushfixed(L, (Easing_ ## easetype ## Parameterized)(t, start, end, param)); \
    	else \
    		lua_pushfixed(L, (Easing_ ## easetype)(t, start, end)); \
    	return 1; \
    } \
    
    static int lib_easeinback(lua_State *L) { EASINGFUNC(InBack) }
    static int lib_easeoutback(lua_State *L) { EASINGFUNC(OutBack) }
    static int lib_easeinoutback(lua_State *L) { EASINGFUNC(InOutBack) }
    
    #undef EASINGFUNC
    
    static luaL_Reg lib_ease[] = {
    	{"linear", lib_easelinear},
    
    	{"insine", lib_easeinsine},
    	{"outsine", lib_easeoutsine},
    	{"inoutsine", lib_easeinoutsine},
    
    	{"inquad", lib_easeinquad},
    	{"outquad", lib_easeoutquad},
    	{"inoutquad", lib_easeinoutquad},
    
    	{"incubic", lib_easeincubic},
    	{"outcubic", lib_easeoutcubic},
    	{"inoutcubic", lib_easeinoutcubic},
    
    	{"inquart", lib_easeinquart},
    	{"outquart", lib_easeoutquart},
    	{"inoutquart", lib_easeinoutquart},
    
    	{"inquint", lib_easeinquint},
    	{"outquint", lib_easeoutquint},
    	{"inoutquint", lib_easeinoutquint},
    
    	{"inexpo", lib_easeinexpo},
    	{"outexpo", lib_easeoutexpo},
    	{"inoutexpo", lib_easeinoutexpo},
    
    	{"inback", lib_easeinback},
    	{"outback", lib_easeoutback},
    	{"inoutback", lib_easeinoutback},
    
    	{NULL, NULL}
    };
    
    int LUA_MathLib(lua_State *L)
    {
    	lua_pushvalue(L, LUA_GLOBALSINDEX);
    	luaL_register(L, NULL, lib_math);
    	luaL_register(L, "ease", lib_ease);
    	return 0;
    }