1 // SONIC ROBO BLAST 2
2 //-----------------------------------------------------------------------------
3 // Copyright (C) 2012-2016 by John "JTE" Muniz.
4 // Copyright (C) 2012-2020 by Sonic Team Junior.
5 //
6 // This program is free software distributed under the
7 // terms of the GNU General Public License, version 2.
8 // See the 'LICENSE' file for more details.
9 //-----------------------------------------------------------------------------
10 /// \file lua_mathlib.c
11 /// \brief basic math library for Lua scripting
12
13 #include "doomdef.h"
14 //#include "fastcmp.h"
15 #include "tables.h"
16 #include "p_local.h"
17 #include "doomstat.h" // for ALL7EMERALDS
18 #include "r_main.h" // for R_PointToDist2
19
20 #include "lua_script.h"
21 #include "lua_libs.h"
22
23 // General math
24 //////////////////
25
lib_abs(lua_State * L)26 static int lib_abs(lua_State *L)
27 {
28 int a = (int)luaL_checkinteger(L, 1);
29 lua_pushinteger(L, abs(a));
30 return 1;
31 }
32
lib_min(lua_State * L)33 static int lib_min(lua_State *L)
34 {
35 int a = luaL_checkinteger(L, 1);
36 int b = luaL_checkinteger(L, 2);
37 lua_pushinteger(L, min(a,b));
38 return 1;
39 }
40
lib_max(lua_State * L)41 static int lib_max(lua_State *L)
42 {
43 int a = luaL_checkinteger(L, 1);
44 int b = luaL_checkinteger(L, 2);
45 lua_pushinteger(L, max(a,b));
46 return 1;
47 }
48
49 // Angle math
50 ////////////////
51
lib_fixedangle(lua_State * L)52 static int lib_fixedangle(lua_State *L)
53 {
54 lua_pushangle(L, FixedAngle(luaL_checkfixed(L, 1)));
55 return 1;
56 }
57
lib_anglefixed(lua_State * L)58 static int lib_anglefixed(lua_State *L)
59 {
60 lua_pushfixed(L, AngleFixed(luaL_checkangle(L, 1)));
61 return 1;
62 }
63
lib_invangle(lua_State * L)64 static int lib_invangle(lua_State *L)
65 {
66 lua_pushangle(L, InvAngle(luaL_checkangle(L, 1)));
67 return 1;
68 }
69
lib_finesine(lua_State * L)70 static int lib_finesine(lua_State *L)
71 {
72 lua_pushfixed(L, FINESINE((luaL_checkangle(L, 1)>>ANGLETOFINESHIFT) & FINEMASK));
73 return 1;
74 }
75
lib_finecosine(lua_State * L)76 static int lib_finecosine(lua_State *L)
77 {
78 lua_pushfixed(L, FINECOSINE((luaL_checkangle(L, 1)>>ANGLETOFINESHIFT) & FINEMASK));
79 return 1;
80 }
81
lib_finetangent(lua_State * L)82 static int lib_finetangent(lua_State *L)
83 {
84 // HACK: add ANGLE_90 to make tan() in Lua start at 0 like it should
85 // use & 4095 instead of & FINEMASK (8191), so it doesn't go out of the array's bounds
86 lua_pushfixed(L, FINETANGENT(((luaL_checkangle(L, 1)+ANGLE_90)>>ANGLETOFINESHIFT) & 4095));
87 return 1;
88 }
89
90 // Fixed math
91 ////////////////
92
lib_fixedmul(lua_State * L)93 static int lib_fixedmul(lua_State *L)
94 {
95 lua_pushfixed(L, FixedMul(luaL_checkfixed(L, 1), luaL_checkfixed(L, 2)));
96 return 1;
97 }
98
lib_fixedint(lua_State * L)99 static int lib_fixedint(lua_State *L)
100 {
101 lua_pushinteger(L, FixedInt(luaL_checkfixed(L, 1)));
102 return 1;
103 }
104
lib_fixeddiv(lua_State * L)105 static int lib_fixeddiv(lua_State *L)
106 {
107 fixed_t i = luaL_checkfixed(L, 1);
108 fixed_t j = luaL_checkfixed(L, 2);
109 if (j == 0)
110 return luaL_error(L, "divide by zero");
111 lua_pushfixed(L, FixedDiv(i, j));
112 return 1;
113 }
114
lib_fixedrem(lua_State * L)115 static int lib_fixedrem(lua_State *L)
116 {
117 LUA_Deprecated(L, "FixedRem(a, b)", "a % b");
118 lua_pushfixed(L, luaL_checkfixed(L, 1) % luaL_checkfixed(L, 2));
119 return 1;
120 }
121
lib_fixedsqrt(lua_State * L)122 static int lib_fixedsqrt(lua_State *L)
123 {
124 fixed_t i = luaL_checkfixed(L, 1);
125 if (i < 0)
126 return luaL_error(L, "square root domain error");
127 lua_pushfixed(L, FixedSqrt(i));
128 return 1;
129 }
130
lib_fixedhypot(lua_State * L)131 static int lib_fixedhypot(lua_State *L)
132 {
133 lua_pushfixed(L, R_PointToDist2(0, 0, luaL_checkfixed(L, 1), luaL_checkfixed(L, 2)));
134 return 1;
135 }
136
lib_fixedfloor(lua_State * L)137 static int lib_fixedfloor(lua_State *L)
138 {
139 lua_pushfixed(L, FixedFloor(luaL_checkfixed(L, 1)));
140 return 1;
141 }
142
lib_fixedtrunc(lua_State * L)143 static int lib_fixedtrunc(lua_State *L)
144 {
145 lua_pushfixed(L, FixedTrunc(luaL_checkfixed(L, 1)));
146 return 1;
147 }
148
lib_fixedceil(lua_State * L)149 static int lib_fixedceil(lua_State *L)
150 {
151 lua_pushfixed(L, FixedCeil(luaL_checkfixed(L, 1)));
152 return 1;
153 }
154
lib_fixedround(lua_State * L)155 static int lib_fixedround(lua_State *L)
156 {
157 lua_pushfixed(L, FixedRound(luaL_checkfixed(L, 1)));
158 return 1;
159 }
160
161 // Misc. math
162 // (aka extra little funcs that don't quite fit in baselib)
163 //////////////////////////////////////////////////////////////////
164
lib_getsecspecial(lua_State * L)165 static int lib_getsecspecial(lua_State *L)
166 {
167 lua_pushinteger(L, GETSECSPECIAL(luaL_checkinteger(L, 1), luaL_checkinteger(L, 2)));
168 return 1;
169 }
170
lib_all7emeralds(lua_State * L)171 static int lib_all7emeralds(lua_State *L)
172 {
173 lua_pushboolean(L, ALL7EMERALDS(luaL_checkinteger(L, 1)));
174 return 1;
175 }
176
177 // Returns both color and signpost shade numbers!
lib_coloropposite(lua_State * L)178 static int lib_coloropposite(lua_State *L)
179 {
180 UINT16 colornum = (UINT16)luaL_checkinteger(L, 1);
181 if (!colornum || colornum >= numskincolors)
182 return luaL_error(L, "skincolor %d out of range (1 - %d).", colornum, numskincolors-1);
183 lua_pushinteger(L, skincolors[colornum].invcolor); // push color
184 lua_pushinteger(L, skincolors[colornum].invshade); // push sign shade index, 0-15
185 return 2;
186 }
187
188 static luaL_Reg lib[] = {
189 {"abs", lib_abs},
190 {"min", lib_min},
191 {"max", lib_max},
192 {"sin", lib_finesine},
193 {"cos", lib_finecosine},
194 {"tan", lib_finetangent},
195 {"FixedAngle", lib_fixedangle},
196 {"fixangle" , lib_fixedangle},
197 {"AngleFixed", lib_anglefixed},
198 {"anglefix" , lib_anglefixed},
199 {"InvAngle", lib_invangle},
200 {"FixedMul", lib_fixedmul},
201 {"fixmul" , lib_fixedmul},
202 {"FixedInt", lib_fixedint},
203 {"fixint" , lib_fixedint},
204 {"FixedDiv", lib_fixeddiv},
205 {"fixdiv" , lib_fixeddiv},
206 {"FixedRem", lib_fixedrem},
207 {"fixrem" , lib_fixedrem},
208 {"FixedSqrt", lib_fixedsqrt},
209 {"fixsqrt" , lib_fixedsqrt},
210 {"FixedHypot", lib_fixedhypot},
211 {"fixhypot" , lib_fixedhypot},
212 {"FixedFloor", lib_fixedfloor},
213 {"fixfloor" , lib_fixedfloor},
214 {"FixedTrunc", lib_fixedtrunc},
215 {"fixtrunc" , lib_fixedtrunc},
216 {"FixedCeil", lib_fixedceil},
217 {"fixceil" , lib_fixedceil},
218 {"FixedRound", lib_fixedround},
219 {"fixround" , lib_fixedround},
220 {"GetSecSpecial", lib_getsecspecial},
221 {"All7Emeralds", lib_all7emeralds},
222 {"ColorOpposite", lib_coloropposite},
223 {NULL, NULL}
224 };
225
LUA_MathLib(lua_State * L)226 int LUA_MathLib(lua_State *L)
227 {
228 lua_pushvalue(L, LUA_GLOBALSINDEX);
229 luaL_register(L, NULL, lib);
230 return 0;
231 }
232