2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
8 /** @file squirrel_std.cpp Implements the Squirrel Standard Function class */
10 #include "../stdafx.h"
12 #include <sqstdmath.h>
14 #include "squirrel_std.hpp"
15 #include "../core/math_func.hpp"
16 #include "../string_func.h"
18 #include "../safeguards.h"
21 SQInteger
SquirrelStd::min(HSQUIRRELVM vm
)
25 sq_getinteger(vm
, 2, &tmp1
);
26 sq_getinteger(vm
, 3, &tmp2
);
27 sq_pushinteger(vm
, std::min(tmp1
, tmp2
));
31 SQInteger
SquirrelStd::max(HSQUIRRELVM vm
)
35 sq_getinteger(vm
, 2, &tmp1
);
36 sq_getinteger(vm
, 3, &tmp2
);
37 sq_pushinteger(vm
, std::max(tmp1
, tmp2
));
41 SQInteger
SquirrelStd::require(HSQUIRRELVM vm
)
43 SQInteger top
= sq_gettop(vm
);
44 const SQChar
*filename
;
46 sq_getstring(vm
, 2, &filename
);
48 /* Get the script-name of the current file, so we can work relative from it */
50 sq_stackinfos(vm
, 1, &si
);
51 if (si
.source
== nullptr) {
52 Debug(misc
, 0, "[squirrel] Couldn't detect the script-name of the 'require'-caller; this should never happen!");
56 /* Keep the dir, remove the rest */
57 std::string path
= si
.source
;
58 auto p
= path
.find_last_of(PATHSEPCHAR
);
59 /* Keep the PATHSEPCHAR there, remove the rest */
60 if (p
!= std::string::npos
) path
.erase(p
+ 1);
62 #if (PATHSEPCHAR != '/')
63 std::transform(path
.begin(), path
.end(), path
.begin(), [](char &c
) { return c
== '/' ? PATHSEPCHAR
: c
; });
66 Squirrel
*engine
= (Squirrel
*)sq_getforeignptr(vm
);
67 bool ret
= engine
->LoadScript(vm
, path
);
69 /* Reset the top, so the stack stays correct */
72 return ret
? 0 : SQ_ERROR
;
75 SQInteger
SquirrelStd::notifyallexceptions(HSQUIRRELVM vm
)
79 if (sq_gettop(vm
) >= 1) {
80 if (SQ_SUCCEEDED(sq_getbool(vm
, -1, &b
))) {
81 sq_notifyallexceptions(vm
, b
);
89 void squirrel_register_global_std(Squirrel
*engine
)
91 /* We don't use squirrel_helper here, as we want to register to the global
92 * scope and not to a class. */
93 engine
->AddMethod("require", &SquirrelStd::require
, 2, ".s");
94 engine
->AddMethod("notifyallexceptions", &SquirrelStd::notifyallexceptions
, 2, ".b");
97 void squirrel_register_std(Squirrel
*engine
)
99 /* We don't use squirrel_helper here, as we want to register to the global
100 * scope and not to a class. */
101 engine
->AddMethod("min", &SquirrelStd::min
, 3, ".ii");
102 engine
->AddMethod("max", &SquirrelStd::max
, 3, ".ii");
104 sqstd_register_mathlib(engine
->GetVM());