diff --git a/cbp/Module.cbp b/cbp/Module.cbp
index cb4a9a2b..a2028a33 100644
--- a/cbp/Module.cbp
+++ b/cbp/Module.cbp
@@ -431,6 +431,8 @@
+
+
diff --git a/source/Base/Shared.cpp b/source/Base/Shared.cpp
index b140b0bb..e71dd490 100644
--- a/source/Base/Shared.cpp
+++ b/source/Base/Shared.cpp
@@ -5,16 +5,7 @@
#include "Library/String.hpp"
// ------------------------------------------------------------------------------------------------
-#include "Base/AABB.hpp"
-#include "Base/Circle.hpp"
#include "Base/Color3.hpp"
-#include "Base/Color4.hpp"
-#include "Base/Quaternion.hpp"
-#include "Base/Sphere.hpp"
-#include "Base/Vector2.hpp"
-#include "Base/Vector2i.hpp"
-#include "Base/Vector3.hpp"
-#include "Base/Vector4.hpp"
// ------------------------------------------------------------------------------------------------
#include
@@ -23,9 +14,6 @@
#include
#include
-// ------------------------------------------------------------------------------------------------
-#include
-
// ------------------------------------------------------------------------------------------------
namespace SqMod {
@@ -67,123 +55,6 @@ Function & NullFunction()
return f;
}
-// ------------------------------------------------------------------------------------------------
-Object BufferToStrObj(const Buffer & b)
-{
- // Obtain the initial stack size
- const StackGuard sg(DefaultVM::Get());
- // Push the string onto the stack
- sq_pushstring(DefaultVM::Get(), b.Data(), b.Position());
- // Obtain the object from the stack and return it
- return Var< Object >(DefaultVM::Get(), -1).value;
-}
-
-// --------------------------------------------------------------------------------------------
-Object BufferToStrObj(const Buffer & b, Uint32 size)
-{
- // Perform a range check on the specified buffer
- if (size > b.Capacity())
- {
- STHROWF("The specified buffer size is out of range: %u >= %u", size, b.Capacity());
- }
- // Obtain the initial stack size
- const StackGuard sg(DefaultVM::Get());
- // Push the string onto the stack
- sq_pushstring(DefaultVM::Get(), b.Data(), size);
- // Obtain the object from the stack and return it
- return Var< Object >(DefaultVM::Get(), -1).value;
-}
-
-// --------------------------------------------------------------------------------------------
-StackStrF::StackStrF(HSQUIRRELVM vm, SQInteger idx, bool fmt)
- : mPtr(nullptr)
- , mLen(-1)
- , mRes(SQ_OK)
- , mObj()
- , mVM(vm)
-{
- const Int32 top = sq_gettop(vm);
- // Reset the converted value object
- sq_resetobject(&mObj);
- // Was the string or value specified?
- if (top <= (idx - 1))
- {
- mRes = sq_throwerror(vm, "Missing string or value");
- }
- // Do we have enough values to call the format function and are we allowed to?
- else if (top > idx && fmt)
- {
- // Pointer to the generated string
- SStr str = nullptr;
- // Attempt to generate the specified string format
- mRes = sqstd_format(vm, idx, &mLen, &str);
- // Did the format succeeded but ended up with a null string pointer?
- if (SQ_SUCCEEDED(mRes) && !str)
- {
- mRes = sq_throwerror(vm, "Unable to generate the string");
- }
- else
- {
- mPtr = const_cast< CSStr >(str);
- }
- }
- // Is the value on the stack an actual string?
- else if (sq_gettype(vm, idx) == OT_STRING)
- {
- // Obtain a reference to the string object
- mRes = sq_getstackobj(vm, idx, &mObj);
- // Could we retrieve the object from the stack?
- if (SQ_SUCCEEDED(mRes))
- {
- // Keep a strong reference to the object
- sq_addref(vm, &mObj);
- // Attempt to retrieve the string value from the stack
- mRes = sq_getstring(vm, idx, &mPtr);
- }
- // Did the retrieval succeeded but ended up with a null string pointer?
- if (SQ_SUCCEEDED(mRes) && !mPtr)
- {
- mRes = sq_throwerror(vm, "Unable to retrieve the string");
- }
- }
- // We have to try and convert it to string
- else
- {
- // Attempt to convert the value from the stack to a string
- mRes = sq_tostring(vm, idx);
- // Could we convert the specified value to string?
- if (SQ_SUCCEEDED(mRes))
- {
- // Obtain a reference to the resulted object
- mRes = sq_getstackobj(vm, -1, &mObj);
- // Could we retrieve the object from the stack?
- if (SQ_SUCCEEDED(mRes))
- {
- // Keep a strong reference to the object
- sq_addref(vm, &mObj);
- // Attempt to obtain the string pointer
- mRes = sq_getstring(vm, -1, &mPtr);
- }
- }
- // Pop a value from the stack regardless of the result
- sq_pop(vm, 1);
- // Did the retrieval succeeded but ended up with a null string pointer?
- if (SQ_SUCCEEDED(mRes) && !mPtr)
- {
- mRes = sq_throwerror(vm, "Unable to retrieve the value");
- }
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-StackStrF::~StackStrF()
-{
- if (mVM && !sq_isnull(mObj))
- {
- sq_release(mVM, &mObj);
- }
-}
-
// ------------------------------------------------------------------------------------------------
bool SToB(CSStr str)
{
diff --git a/source/Base/Shared.hpp b/source/Base/Shared.hpp
index 151467a7..ed28fce3 100644
--- a/source/Base/Shared.hpp
+++ b/source/Base/Shared.hpp
@@ -25,107 +25,6 @@ extern PluginFuncs* _Func;
extern PluginCallbacks* _Clbk;
extern PluginInfo* _Info;
-/* ------------------------------------------------------------------------------------------------
- * Implements RAII to restore the VM stack to it's initial size on function exit.
-*/
-struct StackGuard
-{
- /* --------------------------------------------------------------------------------------------
- * Default constructor.
- */
- StackGuard()
- : m_VM(DefaultVM::Get()), m_Top(sq_gettop(m_VM))
- {
- /* ... */
- }
-
- /* --------------------------------------------------------------------------------------------
- * Base constructor.
- */
- StackGuard(HSQUIRRELVM vm)
- : m_VM(vm), m_Top(sq_gettop(vm))
- {
- /* ... */
- }
-
- /* --------------------------------------------------------------------------------------------
- * Copy constructor. (disabled)
- */
- StackGuard(const StackGuard &) = delete;
-
- /* --------------------------------------------------------------------------------------------
- * Move constructor. (disabled)
- */
- StackGuard(StackGuard &&) = delete;
-
- /* --------------------------------------------------------------------------------------------
- * Destructor.
- */
- ~StackGuard()
- {
- sq_pop(m_VM, sq_gettop(m_VM) - m_Top);
- }
-
- /* --------------------------------------------------------------------------------------------
- * Copy assignment operator. (disabled)
- */
- StackGuard & operator = (const StackGuard &) = delete;
-
- /* --------------------------------------------------------------------------------------------
- * Move assignment operator. (disabled)
- */
- StackGuard & operator = (StackGuard &&) = delete;
-
-private:
-
- // --------------------------------------------------------------------------------------------
- HSQUIRRELVM m_VM; // The VM where the stack should be restored.
- Int32 m_Top; // The top of the stack when this instance was created.
-};
-
-/* ------------------------------------------------------------------------------------------------
- * Helper structure for retrieving a value from the stack as a string or a formatted string.
-*/
-struct StackStrF
-{
- // --------------------------------------------------------------------------------------------
- CSStr mPtr; // Pointer to the C string that was retrieved.
- SQInteger mLen; // The string length if it could be retrieved.
- SQRESULT mRes; // The result of the retrieval attempts.
- HSQOBJECT mObj; // Strong reference to the string object.
- HSQUIRRELVM mVM; // The associated virtual machine.
-
- /* --------------------------------------------------------------------------------------------
- * Base constructor.
- */
- StackStrF(HSQUIRRELVM vm, SQInteger idx, bool fmt = true);
-
- /* --------------------------------------------------------------------------------------------
- * Copy constructor. (disabled)
- */
- StackStrF(const StackStrF & o) = delete;
-
- /* --------------------------------------------------------------------------------------------
- * Copy constructor. (disabled)
- */
- StackStrF(StackStrF && o) = delete;
-
- /* --------------------------------------------------------------------------------------------
- * Destructor.
- */
- ~StackStrF();
-
- /* --------------------------------------------------------------------------------------------
- * Copy constructor. (disabled)
- */
- StackStrF & operator = (const StackStrF & o) = delete;
-
- /* --------------------------------------------------------------------------------------------
- * Copy constructor. (disabled)
- */
- StackStrF & operator = (StackStrF && o) = delete;
-};
-
/* ------------------------------------------------------------------------------------------------
* Perform an equality comparison between two values taking into account floating point issues.
*/
@@ -218,31 +117,549 @@ template <> inline bool EpsGtEq(const Float64 a, const Float64 b)
return !EpsEq(a, b) || (a - b) > 0.000000001d;
}
+/* ------------------------------------------------------------------------------------------------
+ *
+*/
+template < typename T > struct ConvTo
+{
+ // --------------------------------------------------------------------------------------------
+ static constexpr T Min = std::numeric_limits< T >::min();
+ static constexpr T Max = std::numeric_limits< T >::max();
+
+ // --------------------------------------------------------------------------------------------
+ template < typename U > static inline T From(U v)
+ {
+ if (v > Max)
+ {
+ return Max;
+ }
+ else if (v < Min)
+ {
+ return Min;
+ }
+ return static_cast< T >(v);
+ }
+};
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Int8 ConvTo< Int8 >::From< Uint8 >(Uint8 v)
+{
+ return (v >= static_cast< Uint8 >(Max)) ? Max : static_cast< Int8 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Int8 ConvTo< Int8 >::From< Uint16 >(Uint16 v)
+{
+ return (v >= static_cast< Uint16 >(Max)) ? Max : static_cast< Int8 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Int8 ConvTo< Int8 >::From< Uint32 >(Uint32 v)
+{
+ return (v >= static_cast< Uint32 >(Max)) ? Max : static_cast< Int8 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Int8 ConvTo< Int8 >::From< Uint64 >(Uint64 v)
+{
+ return (v >= static_cast< Uint64 >(Max)) ? Max : static_cast< Int8 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Int16 ConvTo< Int16 >::From< Uint8 >(Uint8 v)
+{
+ return static_cast< Int16 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Int16 ConvTo< Int16 >::From< Uint16 >(Uint16 v)
+{
+ return (v >= static_cast< Uint16 >(Max)) ? Max : static_cast< Int16 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Int16 ConvTo< Int16 >::From< Uint32 >(Uint32 v)
+{
+ return (v >= static_cast< Uint32 >(Max)) ? Max : static_cast< Int16 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Int16 ConvTo< Int16 >::From< Uint64 >(Uint64 v)
+{
+ return (v >= static_cast< Uint64 >(Max)) ? Max : static_cast< Int16 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Int32 ConvTo< Int32 >::From< Uint8 >(Uint8 v)
+{
+ return static_cast< Int32 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Int32 ConvTo< Int32 >::From< Uint16 >(Uint16 v)
+{
+ return static_cast< Int32 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Int32 ConvTo< Int32 >::From< Uint32 >(Uint32 v)
+{
+ return (v >= static_cast< Uint32 >(Max)) ? Max : static_cast< Int32 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Int32 ConvTo< Int32 >::From< Uint64 >(Uint64 v)
+{
+ return (v >= static_cast< Uint64 >(Max)) ? Max : static_cast< Int32 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Uint8 ConvTo< Uint8 >::From< Int8 >(Int8 v)
+{
+ return (v <= 0) ? 0 : static_cast< Uint8 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Uint8 ConvTo< Uint8 >::From< Int16 >(Int16 v)
+{
+ if (v <= 0)
+ {
+ return 0;
+ }
+ else if (v >= static_cast< Int16 >(Max))
+ {
+ return Max;
+ }
+ return static_cast< Uint8 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Uint8 ConvTo< Uint8 >::From< Int32 >(Int32 v)
+{
+ if (v <= 0)
+ {
+ return 0;
+ }
+ else if (v >= static_cast< Int32 >(Max))
+ {
+ return Max;
+ }
+ return static_cast< Uint8 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Uint8 ConvTo< Uint8 >::From< Int64 >(Int64 v)
+{
+ if (v <= 0)
+ {
+ return 0;
+ }
+ else if (v >= static_cast< Int64 >(Max))
+ {
+ return Max;
+ }
+ return static_cast< Uint8 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Uint16 ConvTo< Uint16 >::From< Int8 >(Int8 v)
+{
+ return (v <= 0) ? 0 : static_cast< Uint16 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Uint16 ConvTo< Uint16 >::From< Int16 >(Int16 v)
+{
+ return (v <= 0) ? 0 : static_cast< Uint16 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Uint16 ConvTo< Uint16 >::From< Int32 >(Int32 v)
+{
+ if (v <= 0)
+ {
+ return 0;
+ }
+ else if (v >= static_cast< Int32 >(Max))
+ {
+ return Max;
+ }
+ return static_cast< Uint16 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Uint16 ConvTo< Uint16 >::From< Int64 >(Int64 v)
+{
+ if (v <= 0)
+ {
+ return 0;
+ }
+ else if (v >= static_cast< Int64 >(Max))
+ {
+ return Max;
+ }
+ return static_cast< Uint16 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Uint32 ConvTo< Uint32 >::From< Int8 >(Int8 v)
+{
+ return (v <= 0) ? 0 : static_cast< Uint32 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Uint32 ConvTo< Uint32 >::From< Int16 >(Int16 v)
+{
+ return (v <= 0) ? 0 : static_cast< Uint32 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Uint32 ConvTo< Uint32 >::From< Int32 >(Int32 v)
+{
+ return (v <= 0) ? 0 : static_cast< Uint32 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Uint32 ConvTo< Uint32 >::From< Int64 >(Int64 v)
+{
+ if (v <= 0)
+ {
+ return 0;
+ }
+ else if (v >= static_cast< Int64 >(Max))
+ {
+ return Max;
+ }
+ return static_cast< Uint32 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Int8 ConvTo< Int8 >::From< Float32 >(Float32 v)
+{
+ if (EpsLt(v, static_cast< Float32 >(Min)))
+ {
+ return Min;
+ }
+ else if (EpsGt(v, static_cast< Float32 >(Max)))
+ {
+ return Max;
+ }
+ return static_cast< Int8 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Int16 ConvTo< Int16 >::From< Float32 >(Float32 v)
+{
+ if (EpsLt(v, static_cast< Float32 >(Min)))
+ {
+ return Min;
+ }
+ else if (EpsGt(v, static_cast< Float32 >(Max)))
+ {
+ return Max;
+ }
+ return static_cast< Int16 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Int32 ConvTo< Int32 >::From< Float32 >(Float32 v)
+{
+ if (EpsLt(v, static_cast< Float32 >(Min)))
+ {
+ return Min;
+ }
+ else if (EpsGt(v, static_cast< Float32 >(Max)))
+ {
+ return Max;
+ }
+ return static_cast< Int32 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Int8 ConvTo< Int8 >::From< Float64 >(Float64 v)
+{
+ if (EpsLt(v, static_cast< Float64 >(Min)))
+ {
+ return Min;
+ }
+ else if (EpsGt(v, static_cast< Float64 >(Max)))
+ {
+ return Max;
+ }
+ return static_cast< Int8 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Int16 ConvTo< Int16 >::From< Float64 >(Float64 v)
+{
+ if (EpsLt(v, static_cast< Float64 >(Min)))
+ {
+ return Min;
+ }
+ else if (EpsGt(v, static_cast< Float64 >(Max)))
+ {
+ return Max;
+ }
+ return static_cast< Int16 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Int32 ConvTo< Int32 >::From< Float64 >(Float64 v)
+{
+ if (EpsLt(v, static_cast< Float64 >(Min)))
+ {
+ return Min;
+ }
+ else if (EpsGt(v, static_cast< Float64 >(Max)))
+ {
+ return Max;
+ }
+ return static_cast< Int32 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Uint8 ConvTo< Uint8 >::From< Float32 >(Float32 v)
+{
+ if (EpsLt(v, static_cast< Float32 >(Min)))
+ {
+ return Min;
+ }
+ else if (EpsGt(v, static_cast< Float32 >(Max)))
+ {
+ return Max;
+ }
+ return static_cast< Uint8 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Uint16 ConvTo< Uint16 >::From< Float32 >(Float32 v)
+{
+ if (EpsLt(v, static_cast< Float32 >(Min)))
+ {
+ return Min;
+ }
+ else if (EpsGt(v, static_cast< Float32 >(Max)))
+ {
+ return Max;
+ }
+ return static_cast< Uint16 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Uint32 ConvTo< Uint32 >::From< Float32 >(Float32 v)
+{
+ if (EpsLt(v, static_cast< Float32 >(Min)))
+ {
+ return Min;
+ }
+ else if (EpsGt(v, static_cast< Float32 >(Max)))
+ {
+ return Max;
+ }
+ return static_cast< Uint32 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Uint8 ConvTo< Uint8 >::From< Float64 >(Float64 v)
+{
+ if (EpsLt(v, static_cast< Float64 >(Min)))
+ {
+ return Min;
+ }
+ else if (EpsGt(v, static_cast< Float64 >(Max)))
+ {
+ return Max;
+ }
+ return static_cast< Uint8 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Uint16 ConvTo< Uint16 >::From< Float64 >(Float64 v)
+{
+ if (EpsLt(v, static_cast< Float64 >(Min)))
+ {
+ return Min;
+ }
+ else if (EpsGt(v, static_cast< Float64 >(Max)))
+ {
+ return Max;
+ }
+ return static_cast< Uint16 >(v);
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> template <> inline Uint32 ConvTo< Uint32 >::From< Float64 >(Float64 v)
+{
+ if (EpsLt(v, static_cast< Float64 >(Min)))
+ {
+ return Min;
+ }
+ else if (EpsGt(v, static_cast< Float64 >(Max)))
+ {
+ return Max;
+ }
+ return static_cast< Uint32 >(v);
+}
+
+/* ------------------------------------------------------------------------------------------------
+ * Convert other numeric values to signed long long integer.
+*/
+template <> struct ConvTo< Int64 >
+{
+ // --------------------------------------------------------------------------------------------
+ static constexpr Int64 Min = std::numeric_limits< Int64 >::min();
+ static constexpr Int64 Max = std::numeric_limits< Int64 >::max();
+
+ // --------------------------------------------------------------------------------------------
+ template < typename T > static inline Int64 From(T v)
+ {
+ return static_cast< Int64 >(v);
+ }
+};
+
+// ------------------------------------------------------------------------------------------------
+template <> inline Int64 ConvTo< Int64 >::From< Uint64 >(Uint64 v)
+{
+ return (v >= static_cast< Uint64 >(Max)) ? Max : static_cast< Int64 >(v);
+}
+
+/* ------------------------------------------------------------------------------------------------
+ * Convert other numeric values to unsigned long long integer.
+*/
+template <> struct ConvTo< Uint64 >
+{
+ // --------------------------------------------------------------------------------------------
+ static constexpr Uint64 Min = std::numeric_limits< Uint64 >::min();
+ static constexpr Uint64 Max = std::numeric_limits< Uint64 >::max();
+
+ // --------------------------------------------------------------------------------------------
+ template < typename T > static inline Uint64 From(T v)
+ {
+ return (v <= static_cast< T >(0)) ? 0 : static_cast< Uint64 >(v);
+ }
+};
+
+// ------------------------------------------------------------------------------------------------
+template <> inline Uint64 ConvTo< Uint64 >::From< Float32 >(Float32 v)
+{
+ return From(ConvTo< Int64 >::From(v));
+}
+
+// ------------------------------------------------------------------------------------------------
+template <> inline Uint64 ConvTo< Uint64 >::From< Float64 >(Float64 v)
+{
+ return From(ConvTo< Int64 >::From(v));
+}
+
+/* ------------------------------------------------------------------------------------------------
+ * Convert other numeric values to a floating point value.
+*/
+template <> struct ConvTo< Float32 >
+{
+ // --------------------------------------------------------------------------------------------
+ static constexpr Float32 Min = std::numeric_limits< Float32 >::min();
+ static constexpr Float32 Max = std::numeric_limits< Float32 >::max();
+
+ // --------------------------------------------------------------------------------------------
+ template < typename T > static inline Float32 From(T v)
+ {
+ return static_cast< Float32 >(v);
+ }
+};
+
+// ------------------------------------------------------------------------------------------------
+template <> inline Float32 ConvTo< Float32 >::From< Float64 >(Float64 v)
+{
+ if (EpsGt(v, static_cast< Float64 >(Max)))
+ {
+ return Max;
+ }
+ else if (EpsLt(v, static_cast< Float64 >(Min)))
+ {
+ return Min;
+ }
+ return static_cast< Float32 >(v);
+}
+
+/* ------------------------------------------------------------------------------------------------
+ * Convert other numeric values to a double floating point value.
+*/
+template <> struct ConvTo< Float64 >
+{
+ // --------------------------------------------------------------------------------------------
+ static constexpr Float64 Min = std::numeric_limits< Float64 >::min();
+ static constexpr Float64 Max = std::numeric_limits< Float64 >::max();
+
+ // --------------------------------------------------------------------------------------------
+ template < typename T > static inline Float64 From(T v)
+ {
+ return static_cast< Float64 >(v);
+ }
+};
+
/* ------------------------------------------------------------------------------------------------
* Force a value to be within a certain range.
*/
template< typename T > inline T Clamp(T val, T min, T max)
{
- return val < min ? min : (val > max ? max : val);
+ // Is the specified value bellow the minimum?
+ if (val < min)
+ {
+ return min;
+ }
+ // Is the specified value above the maximum?
+ else if (val > max)
+ {
+ return max;
+ }
+ // Return the value as is
+ return val;
+}
+
+/* ------------------------------------------------------------------------------------------------
+ * Force a value to be within a certain range.
+*/
+template<> inline Float32 Clamp(Float32 val, Float32 min, Float32 max)
+{
+ // Is the specified value bellow the minimum?
+ if (EpsLt(val, min))
+ {
+ return min;
+ }
+ // Is the specified value above the maximum?
+ else if (EpsGt(val, max))
+ {
+ return max;
+ }
+ // Return the value as is
+ return val;
+}
+
+/* ------------------------------------------------------------------------------------------------
+ * Force a value to be within a certain range.
+*/
+template<> inline Float64 Clamp(Float64 val, Float64 min, Float64 max)
+{
+ // Is the specified value bellow the minimum?
+ if (EpsLt(val, min))
+ {
+ return min;
+ }
+ // Is the specified value above the maximum?
+ else if (EpsGt(val, max))
+ {
+ return max;
+ }
+ // Return the value as is
+ return val;
}
/* ------------------------------------------------------------------------------------------------
* Force a value to be the boundaries of the specified type.
*/
-template< typename T, typename U > inline U ClampL(T val)
+template < typename T, typename U > inline U ClampL(T v)
{
- // Is the specified value bellow the minimum?
- if (val < std::numeric_limits< U >::min())
- {
- return std::numeric_limits< U >::min();
- }
- // Is the specified value above the maximum?
- else if (val > std::numeric_limits< U >::max())
- {
- return std::numeric_limits< U >::max();
- }
- // Return the value as is
- return static_cast< U >(val);
+ return ConvTo< U >::From(v);
}
/* ------------------------------------------------------------------------------------------------
@@ -289,42 +706,6 @@ Array & NullArray();
*/
Function & NullFunction();
-/* ------------------------------------------------------------------------------------------------
- * Create a script string object from a buffer.
-*/
-Object BufferToStrObj(const Buffer & b);
-
-/* ------------------------------------------------------------------------------------------------
- * Create a script string object from a portion of a buffer.
-*/
-Object BufferToStrObj(const Buffer & b, Uint32 size);
-
-/* ------------------------------------------------------------------------------------------------
- * Create a script object from the specified value on the default VM.
-*/
-template < typename T > Object MakeObject(const T & v)
-{
- // Remember the current stack size
- const StackGuard sg;
- // Transform the specified value into a script object
- PushVar< T >(DefaultVM::Get(), v);
- // Get the object from the stack and return it
- return Var< Object >(DefaultVM::Get(), -1).value;
-}
-
-/* ------------------------------------------------------------------------------------------------
- * Create a script object from the specified value on the specified VM.
-*/
-template < typename T > Object MakeObject(HSQUIRRELVM vm, const T & v)
-{
- // Remember the current stack size
- const StackGuard sg;
- // Transform the specified value into a script object
- PushVar< T >(vm, v);
- // Get the object from the stack and return it
- return Var< Object >(vm, -1).value;
-}
-
/* ------------------------------------------------------------------------------------------------
* Simple function to check whether the specified string can be considered as a boolean value
*/
diff --git a/source/Base/Stack.cpp b/source/Base/Stack.cpp
new file mode 100644
index 00000000..fd4c70f3
--- /dev/null
+++ b/source/Base/Stack.cpp
@@ -0,0 +1,413 @@
+// ------------------------------------------------------------------------------------------------
+#include "Base/Stack.hpp"
+#include "Base/Shared.hpp"
+#include "Base/Buffer.hpp"
+#include "Library/Numeric.hpp"
+
+// ------------------------------------------------------------------------------------------------
+#include
+
+// ------------------------------------------------------------------------------------------------
+namespace SqMod {
+
+// ------------------------------------------------------------------------------------------------
+SQInteger PopStackInteger(HSQUIRRELVM vm, SQInteger idx)
+{
+ // Identify which type must be extracted
+ switch (sq_gettype(vm, idx))
+ {
+ case OT_INTEGER:
+ {
+ SQInteger val;
+ sq_getinteger(vm, idx, &val);
+ return val;
+ } break;
+ case OT_FLOAT:
+ {
+ SQFloat val;
+ sq_getfloat(vm, idx, &val);
+ return ConvTo< SQInteger >::From(val);
+ } break;
+ case OT_BOOL:
+ {
+ SQBool val;
+ sq_getbool(vm, idx, &val);
+ return static_cast< SQInteger >(val);
+ } break;
+ case OT_STRING:
+ {
+ CSStr val = nullptr;
+ // Attempt to retrieve and convert the string
+ if (SQ_SUCCEEDED(sq_getstring(vm, idx, &val)) && val != nullptr && *val != '\0')
+ {
+ return ConvTo< SQInteger >::From(std::strtoll(val, nullptr, 10));
+ }
+ } break;
+ case OT_ARRAY:
+ case OT_TABLE:
+ case OT_CLASS:
+ case OT_USERDATA:
+ {
+ return sq_getsize(vm, idx);
+ } break;
+ case OT_INSTANCE:
+ {
+ // Attempt to treat the value as a signed long instance
+ try
+ {
+ return ConvTo< SQInteger >::From(Var< const SLongInt & >(vm, idx).value.GetNum());
+ }
+ catch (...)
+ {
+ // Just ignore it...
+ }
+ // Attempt to treat the value as a unsigned long instance
+ try
+ {
+ return ConvTo< SQInteger >::From(Var< const ULongInt & >(vm, idx).value.GetNum());
+ }
+ catch (...)
+ {
+ // Just ignore it...
+ }
+ // Attempt to get the size of the instance as a fallback
+ return sq_getsize(vm, idx);
+ } break;
+ default: break;
+ }
+ // Default to 0
+ return 0;
+}
+
+// ------------------------------------------------------------------------------------------------
+SQFloat PopStackFloat(HSQUIRRELVM vm, SQInteger idx)
+{
+ // Identify which type must be extracted
+ switch (sq_gettype(vm, idx))
+ {
+ case OT_FLOAT:
+ {
+ SQFloat val;
+ sq_getfloat(vm, idx, &val);
+ return val;
+ } break;
+ case OT_INTEGER:
+ {
+ SQInteger val;
+ sq_getinteger(vm, idx, &val);
+ return ConvTo< SQFloat >::From(val);
+ } break;
+ case OT_BOOL:
+ {
+ SQBool val;
+ sq_getbool(vm, idx, &val);
+ return ConvTo< SQFloat >::From(val);
+ } break;
+ case OT_STRING:
+ {
+ CSStr val = nullptr;
+ // Attempt to retrieve and convert the string
+ if (SQ_SUCCEEDED(sq_getstring(vm, idx, &val)) && val != nullptr && *val != '\0')
+ {
+#ifdef SQUSEDOUBLE
+ return std::strtod(val, nullptr);
+#else
+ return std::strtof(val, nullptr);
+#endif // SQUSEDOUBLE
+ }
+ } break;
+ case OT_ARRAY:
+ case OT_TABLE:
+ case OT_CLASS:
+ case OT_USERDATA:
+ {
+ return ConvTo< SQFloat >::From(sq_getsize(vm, idx));
+ } break;
+ case OT_INSTANCE:
+ {
+ // Attempt to treat the value as a signed long instance
+ try
+ {
+ return ConvTo< SQFloat >::From(Var< const SLongInt & >(vm, idx).value.GetNum());
+ }
+ catch (...)
+ {
+ // Just ignore it...
+ }
+ // Attempt to treat the value as a unsigned long instance
+ try
+ {
+ return ConvTo< SQFloat >::From(Var< const ULongInt & >(vm, idx).value.GetNum());
+ }
+ catch (...)
+ {
+ // Just ignore it...
+ }
+ // Attempt to get the size of the instance as a fallback
+ return ConvTo< SQFloat >::From(sq_getsize(vm, idx));
+ } break;
+ default: break;
+ }
+ // Default to 0
+ return 0.0;
+}
+
+// ------------------------------------------------------------------------------------------------
+Int64 PopStackLong(HSQUIRRELVM vm, SQInteger idx)
+{
+ // Identify which type must be extracted
+ switch (sq_gettype(vm, idx))
+ {
+ case OT_INTEGER:
+ {
+ SQInteger val;
+ sq_getinteger(vm, idx, &val);
+ return static_cast< Int64 >(val);
+ } break;
+ case OT_FLOAT:
+ {
+ SQFloat val;
+ sq_getfloat(vm, idx, &val);
+ return ConvTo< Int64 >::From(val);
+ } break;
+ case OT_BOOL:
+ {
+ SQBool val;
+ sq_getbool(vm, idx, &val);
+ return static_cast< Int64 >(val);
+ } break;
+ case OT_STRING:
+ {
+ CSStr val = nullptr;
+ // Attempt to retrieve and convert the string
+ if (SQ_SUCCEEDED(sq_getstring(vm, idx, &val)) && val != nullptr && *val != '\0')
+ {
+ return std::strtoll(val, nullptr, 10);
+ }
+ } break;
+ case OT_ARRAY:
+ case OT_TABLE:
+ case OT_CLASS:
+ case OT_USERDATA:
+ {
+ return static_cast< Int64 >(sq_getsize(vm, idx));
+ } break;
+ case OT_INSTANCE:
+ {
+ // Attempt to treat the value as a signed long instance
+ try
+ {
+ return Var< const SLongInt & >(vm, idx).value.GetNum();
+ }
+ catch (...)
+ {
+ // Just ignore it...
+ }
+ // Attempt to treat the value as a unsigned long instance
+ try
+ {
+ return ConvTo< Int64 >::From(Var< const ULongInt & >(vm, idx).value.GetNum());
+ }
+ catch (...)
+ {
+ // Just ignore it...
+ }
+ // Attempt to get the size of the instance as a fallback
+ return static_cast< Int64 >(sq_getsize(vm, idx));
+ } break;
+ default: break;
+ }
+ // Default to 0
+ return 0;
+}
+
+// ------------------------------------------------------------------------------------------------
+Uint64 PopStackULong(HSQUIRRELVM vm, SQInteger idx)
+{
+ // Identify which type must be extracted
+ switch (sq_gettype(vm, idx))
+ {
+ case OT_INTEGER:
+ {
+ SQInteger val;
+ sq_getinteger(vm, idx, &val);
+ return ConvTo< Uint64 >::From(val);
+ } break;
+ case OT_FLOAT:
+ {
+ SQFloat val;
+ sq_getfloat(vm, idx, &val);
+ return ConvTo< Uint64 >::From(val);
+ } break;
+ case OT_BOOL:
+ {
+ SQBool val;
+ sq_getbool(vm, idx, &val);
+ return ConvTo< Uint64 >::From(val);
+ } break;
+ case OT_STRING:
+ {
+ CSStr val = nullptr;
+ // Attempt to retrieve and convert the string
+ if (SQ_SUCCEEDED(sq_getstring(vm, idx, &val)) && val != nullptr && *val != '\0')
+ {
+ return std::strtoull(val, nullptr, 10);
+ }
+ } break;
+ case OT_ARRAY:
+ case OT_TABLE:
+ case OT_CLASS:
+ case OT_USERDATA:
+ {
+ return ConvTo< Uint64 >::From(sq_getsize(vm, idx));
+ } break;
+ case OT_INSTANCE:
+ {
+ // Attempt to treat the value as a signed long instance
+ try
+ {
+ return ConvTo< Uint64 >::From(Var< const SLongInt & >(vm, idx).value.GetNum());
+ }
+ catch (...)
+ {
+ // Just ignore it...
+ }
+ // Attempt to treat the value as a unsigned long instance
+ try
+ {
+ return Var< const ULongInt & >(vm, idx).value.GetNum();
+ }
+ catch (...)
+ {
+ // Just ignore it...
+ }
+ // Attempt to get the size of the instance as a fallback
+ return ConvTo< Uint64 >::From(sq_getsize(vm, idx));
+ } break;
+ default: break;
+ }
+ // Default to 0
+ return 0;
+}
+
+// --------------------------------------------------------------------------------------------
+StackStrF::StackStrF(HSQUIRRELVM vm, SQInteger idx, bool fmt)
+ : mPtr(nullptr)
+ , mLen(-1)
+ , mRes(SQ_OK)
+ , mObj()
+ , mVM(vm)
+{
+ const Int32 top = sq_gettop(vm);
+ // Reset the converted value object
+ sq_resetobject(&mObj);
+ // Was the string or value specified?
+ if (top <= (idx - 1))
+ {
+ mRes = sq_throwerror(vm, "Missing string or value");
+ }
+ // Do we have enough values to call the format function and are we allowed to?
+ else if (top > idx && fmt)
+ {
+ // Pointer to the generated string
+ SStr str = nullptr;
+ // Attempt to generate the specified string format
+ mRes = sqstd_format(vm, idx, &mLen, &str);
+ // Did the format succeeded but ended up with a null string pointer?
+ if (SQ_SUCCEEDED(mRes) && !str)
+ {
+ mRes = sq_throwerror(vm, "Unable to generate the string");
+ }
+ else
+ {
+ mPtr = const_cast< CSStr >(str);
+ }
+ }
+ // Is the value on the stack an actual string?
+ else if (sq_gettype(vm, idx) == OT_STRING)
+ {
+ // Obtain a reference to the string object
+ mRes = sq_getstackobj(vm, idx, &mObj);
+ // Could we retrieve the object from the stack?
+ if (SQ_SUCCEEDED(mRes))
+ {
+ // Keep a strong reference to the object
+ sq_addref(vm, &mObj);
+ // Attempt to retrieve the string value from the stack
+ mRes = sq_getstring(vm, idx, &mPtr);
+ }
+ // Did the retrieval succeeded but ended up with a null string pointer?
+ if (SQ_SUCCEEDED(mRes) && !mPtr)
+ {
+ mRes = sq_throwerror(vm, "Unable to retrieve the string");
+ }
+ }
+ // We have to try and convert it to string
+ else
+ {
+ // Attempt to convert the value from the stack to a string
+ mRes = sq_tostring(vm, idx);
+ // Could we convert the specified value to string?
+ if (SQ_SUCCEEDED(mRes))
+ {
+ // Obtain a reference to the resulted object
+ mRes = sq_getstackobj(vm, -1, &mObj);
+ // Could we retrieve the object from the stack?
+ if (SQ_SUCCEEDED(mRes))
+ {
+ // Keep a strong reference to the object
+ sq_addref(vm, &mObj);
+ // Attempt to obtain the string pointer
+ mRes = sq_getstring(vm, -1, &mPtr);
+ }
+ }
+ // Pop a value from the stack regardless of the result
+ sq_pop(vm, 1);
+ // Did the retrieval succeeded but ended up with a null string pointer?
+ if (SQ_SUCCEEDED(mRes) && !mPtr)
+ {
+ mRes = sq_throwerror(vm, "Unable to retrieve the value");
+ }
+ }
+}
+
+// ------------------------------------------------------------------------------------------------
+StackStrF::~StackStrF()
+{
+ if (mVM && !sq_isnull(mObj))
+ {
+ sq_release(mVM, &mObj);
+ }
+}
+
+// ------------------------------------------------------------------------------------------------
+Object BufferToStrObj(const Buffer & b)
+{
+ // Obtain the initial stack size
+ const StackGuard sg(DefaultVM::Get());
+ // Push the string onto the stack
+ sq_pushstring(DefaultVM::Get(), b.Data(), b.Position());
+ // Obtain the object from the stack and return it
+ return Var< Object >(DefaultVM::Get(), -1).value;
+}
+
+// --------------------------------------------------------------------------------------------
+Object BufferToStrObj(const Buffer & b, Uint32 size)
+{
+ // Perform a range check on the specified buffer
+ if (size > b.Capacity())
+ {
+ STHROWF("The specified buffer size is out of range: %u >= %u", size, b.Capacity());
+ }
+ // Obtain the initial stack size
+ const StackGuard sg(DefaultVM::Get());
+ // Push the string onto the stack
+ sq_pushstring(DefaultVM::Get(), b.Data(), size);
+ // Obtain the object from the stack and return it
+ return Var< Object >(DefaultVM::Get(), -1).value;
+}
+
+// ------------------------------------------------------------------------------------------------
+
+
+} // Namespace:: SqMod
diff --git a/source/Base/Stack.hpp b/source/Base/Stack.hpp
new file mode 100644
index 00000000..5324fa4f
--- /dev/null
+++ b/source/Base/Stack.hpp
@@ -0,0 +1,172 @@
+#ifndef _BASE_STACK_HPP_
+#define _BASE_STACK_HPP_
+
+// ------------------------------------------------------------------------------------------------
+#include "SqBase.hpp"
+
+// ------------------------------------------------------------------------------------------------
+#include
+
+// ------------------------------------------------------------------------------------------------
+namespace SqMod {
+
+/* ------------------------------------------------------------------------------------------------
+ * Attempt to pop the value at the specified index on the stack as a native integer.
+*/
+SQInteger PopStackInteger(HSQUIRRELVM vm, SQInteger idx);
+
+/* ------------------------------------------------------------------------------------------------
+ * Attempt to pop the value at the specified index on the stack as a native float.
+*/
+SQFloat PopStackFloat(HSQUIRRELVM vm, SQInteger idx);
+
+/* ------------------------------------------------------------------------------------------------
+ * Attempt to pop the value at the specified index on the stack as a signed long integer.
+*/
+Int64 PopStackLong(HSQUIRRELVM vm, SQInteger idx);
+
+/* ------------------------------------------------------------------------------------------------
+ * Attempt to pop the value at the specified index on the stack as an unsigned long integer.
+*/
+Uint64 PopStackULong(HSQUIRRELVM vm, SQInteger idx);
+
+/* ------------------------------------------------------------------------------------------------
+ * Create a script string object from a buffer.
+*/
+Object BufferToStrObj(const Buffer & b);
+
+/* ------------------------------------------------------------------------------------------------
+ * Create a script string object from a portion of a buffer.
+*/
+Object BufferToStrObj(const Buffer & b, Uint32 size);
+
+/* ------------------------------------------------------------------------------------------------
+ * Implements RAII to restore the VM stack to it's initial size on function exit.
+*/
+struct StackGuard
+{
+ /* --------------------------------------------------------------------------------------------
+ * Default constructor.
+ */
+ StackGuard()
+ : m_VM(DefaultVM::Get()), m_Top(sq_gettop(m_VM))
+ {
+ /* ... */
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Base constructor.
+ */
+ StackGuard(HSQUIRRELVM vm)
+ : m_VM(vm), m_Top(sq_gettop(vm))
+ {
+ /* ... */
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Copy constructor. (disabled)
+ */
+ StackGuard(const StackGuard &) = delete;
+
+ /* --------------------------------------------------------------------------------------------
+ * Move constructor. (disabled)
+ */
+ StackGuard(StackGuard &&) = delete;
+
+ /* --------------------------------------------------------------------------------------------
+ * Destructor.
+ */
+ ~StackGuard()
+ {
+ sq_pop(m_VM, sq_gettop(m_VM) - m_Top);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Copy assignment operator. (disabled)
+ */
+ StackGuard & operator = (const StackGuard &) = delete;
+
+ /* --------------------------------------------------------------------------------------------
+ * Move assignment operator. (disabled)
+ */
+ StackGuard & operator = (StackGuard &&) = delete;
+
+private:
+
+ // --------------------------------------------------------------------------------------------
+ HSQUIRRELVM m_VM; // The VM where the stack should be restored.
+ Int32 m_Top; // The top of the stack when this instance was created.
+};
+
+/* ------------------------------------------------------------------------------------------------
+ * Helper structure for retrieving a value from the stack as a string or a formatted string.
+*/
+struct StackStrF
+{
+ // --------------------------------------------------------------------------------------------
+ CSStr mPtr; // Pointer to the C string that was retrieved.
+ SQInteger mLen; // The string length if it could be retrieved.
+ SQRESULT mRes; // The result of the retrieval attempts.
+ HSQOBJECT mObj; // Strong reference to the string object.
+ HSQUIRRELVM mVM; // The associated virtual machine.
+
+ /* --------------------------------------------------------------------------------------------
+ * Base constructor.
+ */
+ StackStrF(HSQUIRRELVM vm, SQInteger idx, bool fmt = true);
+
+ /* --------------------------------------------------------------------------------------------
+ * Copy constructor. (disabled)
+ */
+ StackStrF(const StackStrF & o) = delete;
+
+ /* --------------------------------------------------------------------------------------------
+ * Copy constructor. (disabled)
+ */
+ StackStrF(StackStrF && o) = delete;
+
+ /* --------------------------------------------------------------------------------------------
+ * Destructor.
+ */
+ ~StackStrF();
+
+ /* --------------------------------------------------------------------------------------------
+ * Copy constructor. (disabled)
+ */
+ StackStrF & operator = (const StackStrF & o) = delete;
+
+ /* --------------------------------------------------------------------------------------------
+ * Copy constructor. (disabled)
+ */
+ StackStrF & operator = (StackStrF && o) = delete;
+};
+
+/* ------------------------------------------------------------------------------------------------
+ * Create a script object from the specified value on the default VM.
+*/
+template < typename T > Object MakeObject(const T & v)
+{
+ // Remember the current stack size
+ const StackGuard sg;
+ // Transform the specified value into a script object
+ PushVar< T >(DefaultVM::Get(), v);
+ // Get the object from the stack and return it
+ return Var< Object >(DefaultVM::Get(), -1).value;
+}
+
+/* ------------------------------------------------------------------------------------------------
+ * Create a script object from the specified value on the specified VM.
+*/
+template < typename T > Object MakeObject(HSQUIRRELVM vm, const T & v)
+{
+ // Remember the current stack size
+ const StackGuard sg;
+ // Transform the specified value into a script object
+ PushVar< T >(vm, v);
+ // Get the object from the stack and return it
+ return Var< Object >(vm, -1).value;
+}
+
+} // Namespace:: SqMod
+
+#endif // _BASE_STACK_HPP_
diff --git a/source/Command.cpp b/source/Command.cpp
index 078791b1..957fe474 100644
--- a/source/Command.cpp
+++ b/source/Command.cpp
@@ -1,6 +1,7 @@
// ------------------------------------------------------------------------------------------------
#include "Command.hpp"
#include "Core.hpp"
+#include "Base/Stack.hpp"
#include "Entity/Player.hpp"
// ------------------------------------------------------------------------------------------------
diff --git a/source/Constants.cpp b/source/Constants.cpp
index a528ec08..7b1b1abf 100644
--- a/source/Constants.cpp
+++ b/source/Constants.cpp
@@ -38,6 +38,20 @@ void Register_Constants(HSQUIRRELVM vm)
.Const(_SC("MaxFloat"), std::numeric_limits< SQFloat >::max())
.Const(_SC("MinFloat32"), std::numeric_limits< Float32 >::min())
.Const(_SC("MaxFloat32"), std::numeric_limits< Float32 >::max())
+ .Const(_SC("FpNormal"), FP_NORMAL)
+ .Const(_SC("FpSubnormal"), FP_SUBNORMAL)
+ .Const(_SC("FpZero"), FP_ZERO)
+ .Const(_SC("FpInfinite"), FP_INFINITE)
+ .Const(_SC("FpNan"), FP_NAN)
+#ifdef SQUSEDOUBLE
+ .Const(_SC("HugeVal"), HUGE_VAL)
+#else
+ .Const(_SC("HugeVal"), HUGE_VALF)
+#endif // SQUSEDOUBLE
+ .Const(_SC("Infinity"), static_cast< float >(INFINITY))
+ .Const(_SC("Inf"), static_cast< float >(INFINITY))
+ .Const(_SC("Nan"), static_cast< float >(NAN))
+
);
ConstTable(vm).Enum(_SC("SqArchitectre"), Enumeration(vm)
diff --git a/source/Entity/Blip.cpp b/source/Entity/Blip.cpp
index d7a8a5ea..34b1cd8b 100644
--- a/source/Entity/Blip.cpp
+++ b/source/Entity/Blip.cpp
@@ -1,5 +1,6 @@
// ------------------------------------------------------------------------------------------------
#include "Entity/Blip.hpp"
+#include "Base/Stack.hpp"
#include "Core.hpp"
// ------------------------------------------------------------------------------------------------
diff --git a/source/Entity/Checkpoint.cpp b/source/Entity/Checkpoint.cpp
index 00cb9a6a..8546a141 100644
--- a/source/Entity/Checkpoint.cpp
+++ b/source/Entity/Checkpoint.cpp
@@ -3,6 +3,7 @@
#include "Entity/Player.hpp"
#include "Base/Color4.hpp"
#include "Base/Vector3.hpp"
+#include "Base/Stack.hpp"
#include "Core.hpp"
// ------------------------------------------------------------------------------------------------
diff --git a/source/Entity/Forcefield.cpp b/source/Entity/Forcefield.cpp
index 404319af..4b69115b 100644
--- a/source/Entity/Forcefield.cpp
+++ b/source/Entity/Forcefield.cpp
@@ -3,6 +3,7 @@
#include "Entity/Player.hpp"
#include "Base/Color3.hpp"
#include "Base/Vector3.hpp"
+#include "Base/Stack.hpp"
#include "Core.hpp"
// ------------------------------------------------------------------------------------------------
diff --git a/source/Entity/Keybind.cpp b/source/Entity/Keybind.cpp
index 070638b9..208e79e7 100644
--- a/source/Entity/Keybind.cpp
+++ b/source/Entity/Keybind.cpp
@@ -1,5 +1,6 @@
// ------------------------------------------------------------------------------------------------
#include "Entity/Keybind.hpp"
+#include "Base/Stack.hpp"
#include "Core.hpp"
// ------------------------------------------------------------------------------------------------
@@ -288,4 +289,4 @@ void Register_CKeybind(HSQUIRRELVM vm)
);
}
-} // Namespace:: SqMod
\ No newline at end of file
+} // Namespace:: SqMod
diff --git a/source/Entity/Object.cpp b/source/Entity/Object.cpp
index b085c0ae..4c430b0b 100644
--- a/source/Entity/Object.cpp
+++ b/source/Entity/Object.cpp
@@ -3,6 +3,7 @@
#include "Entity/Player.hpp"
#include "Base/Quaternion.hpp"
#include "Base/Vector3.hpp"
+#include "Base/Stack.hpp"
#include "Core.hpp"
// ------------------------------------------------------------------------------------------------
diff --git a/source/Entity/Pickup.cpp b/source/Entity/Pickup.cpp
index cd124db5..c91c24ff 100644
--- a/source/Entity/Pickup.cpp
+++ b/source/Entity/Pickup.cpp
@@ -2,6 +2,7 @@
#include "Entity/Pickup.hpp"
#include "Entity/Player.hpp"
#include "Base/Vector3.hpp"
+#include "Base/Stack.hpp"
#include "Core.hpp"
// ------------------------------------------------------------------------------------------------
@@ -490,4 +491,4 @@ void Register_CPickup(HSQUIRRELVM vm)
);
}
-} // Namespace:: SqMod
\ No newline at end of file
+} // Namespace:: SqMod
diff --git a/source/Entity/Player.cpp b/source/Entity/Player.cpp
index f691809d..b06832f4 100644
--- a/source/Entity/Player.cpp
+++ b/source/Entity/Player.cpp
@@ -3,6 +3,7 @@
#include "Entity/Vehicle.hpp"
#include "Base/Color3.hpp"
#include "Base/Vector3.hpp"
+#include "Base/Stack.hpp"
#include "Core.hpp"
// ------------------------------------------------------------------------------------------------
diff --git a/source/Entity/Sprite.cpp b/source/Entity/Sprite.cpp
index 41397fdc..14be71a4 100644
--- a/source/Entity/Sprite.cpp
+++ b/source/Entity/Sprite.cpp
@@ -2,6 +2,7 @@
#include "Entity/Sprite.hpp"
#include "Entity/Player.hpp"
#include "Base/Vector2i.hpp"
+#include "Base/Stack.hpp"
#include "Core.hpp"
// ------------------------------------------------------------------------------------------------
diff --git a/source/Entity/Textdraw.cpp b/source/Entity/Textdraw.cpp
index be7f25de..190f89ad 100644
--- a/source/Entity/Textdraw.cpp
+++ b/source/Entity/Textdraw.cpp
@@ -2,6 +2,7 @@
#include "Entity/Textdraw.hpp"
#include "Entity/Player.hpp"
#include "Base/Vector2i.hpp"
+#include "Base/Stack.hpp"
#include "Core.hpp"
// ------------------------------------------------------------------------------------------------
diff --git a/source/Entity/Vehicle.cpp b/source/Entity/Vehicle.cpp
index bd1c792b..c7802fc2 100644
--- a/source/Entity/Vehicle.cpp
+++ b/source/Entity/Vehicle.cpp
@@ -3,6 +3,7 @@
#include "Entity/Player.hpp"
#include "Base/Quaternion.hpp"
#include "Base/Vector4.hpp"
+#include "Base/Stack.hpp"
#include "Core.hpp"
// ------------------------------------------------------------------------------------------------
diff --git a/source/Library/Chrono.cpp b/source/Library/Chrono.cpp
index a2c29627..622e1d1a 100644
--- a/source/Library/Chrono.cpp
+++ b/source/Library/Chrono.cpp
@@ -173,7 +173,7 @@ extern void Register_ChronoTime(HSQUIRRELVM vm, Table & cns);
extern void Register_ChronoTimer(HSQUIRRELVM vm, Table & cns);
extern void Register_ChronoTimestamp(HSQUIRRELVM vm, Table & cns);
-// ------------------------------------------------------------------------------------------------
+// ================================================================================================
void Register_Chrono(HSQUIRRELVM vm)
{
Table cns(vm);
diff --git a/source/Library/Crypt.cpp b/source/Library/Crypt.cpp
index a6cd7f20..7acc7e9e 100644
--- a/source/Library/Crypt.cpp
+++ b/source/Library/Crypt.cpp
@@ -1,6 +1,7 @@
// ------------------------------------------------------------------------------------------------
#include "Library/Crypt.hpp"
#include "Base/Shared.hpp"
+#include "Base/Stack.hpp"
// ------------------------------------------------------------------------------------------------
#include
diff --git a/source/Library/Math.cpp b/source/Library/Math.cpp
index e69de29b..b3990a7e 100644
--- a/source/Library/Math.cpp
+++ b/source/Library/Math.cpp
@@ -0,0 +1,1142 @@
+// ------------------------------------------------------------------------------------------------
+#include "Library/Math.hpp"
+#include "Library/Numeric.hpp"
+#include "Base/Stack.hpp"
+
+// ------------------------------------------------------------------------------------------------
+#include
+
+// ------------------------------------------------------------------------------------------------
+namespace SqMod {
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqDiv(HSQUIRRELVM vm)
+{
+ // The return type of the function
+#ifdef _SQ64
+ typedef std::lldiv_t DivT;
+#else
+ typedef std::div_t DivT;
+#endif // _SQ64
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 2)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ const DivT r = std::div(PopStackInteger(vm, 2), PopStackInteger(vm, 3));
+ // Create a new table on the stack
+ sq_newtable(vm);
+ // Push the quotient index
+ sq_pushstring(vm, _SC("quot"), -1);
+ // Push the quotient value
+ sq_pushinteger(vm, r.quot);
+ // Attempt to create the array element
+ if (SQ_FAILED(sq_rawset(vm, -3)))
+ {
+ return sq_throwerror(vm, "Unable to insert the quotient element");
+ }
+ // Push the remainder index
+ sq_pushstring(vm, _SC("rem"), -1);
+ // Push the remainder value
+ sq_pushinteger(vm, r.rem);
+ // Attempt to create the array element
+ if (SQ_FAILED(sq_rawset(vm, -3)))
+ {
+ return sq_throwerror(vm, "Unable to insert the remainder element");
+ }
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqRemainder(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 2)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Are we both arguments floats?
+ if ((sq_gettype(vm, 2) == OT_FLOAT) && sq_gettype(vm, 3) == OT_FLOAT)
+ {
+ sq_pushfloat(vm, std::remainder(PopStackFloat(vm, 2), PopStackFloat(vm, 3)));
+ }
+ // Are we both arguments integers?
+ else if ((sq_gettype(vm, 2) == OT_INTEGER) && sq_gettype(vm, 3) == OT_INTEGER)
+ {
+ sq_pushinteger(vm, std::remainder(PopStackInteger(vm, 2), PopStackInteger(vm, 3)));
+ }
+ // Is the first argument float?
+ else if ((sq_gettype(vm, 2) == OT_FLOAT))
+ {
+ sq_pushfloat(vm, std::remainder(PopStackFloat(vm, 2), PopStackFloat(vm, 3)));
+ }
+ // Is the first argument integer?
+ else if ((sq_gettype(vm, 2) == OT_INTEGER))
+ {
+ sq_pushinteger(vm, std::remainder(PopStackInteger(vm, 2), PopStackInteger(vm, 3)));
+ }
+ // Default to both arhuments as float so we don't loos precision from the float one
+ else
+ {
+ sq_pushfloat(vm, std::remainder(PopStackFloat(vm, 2), PopStackFloat(vm, 3)));
+ }
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqFma(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 3)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::fma(PopStackFloat(vm, 2), PopStackFloat(vm, 3), PopStackFloat(vm, 4)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqMax(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 2)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::fmax(PopStackFloat(vm, 2), PopStackFloat(vm, 3)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqMin(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 2)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::fmin(PopStackFloat(vm, 2), PopStackFloat(vm, 3)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqDim(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 2)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::fdim(PopStackFloat(vm, 2), PopStackFloat(vm, 3)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqNan(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Attempt to generate the string value
+ StackStrF val(vm, 2);
+ // Have we failed to retrieve the string?
+ if (SQ_FAILED(val.mRes))
+ {
+ return val.mRes; // Propagate the error!
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+#ifdef _SQ64
+ sq_pushfloat(vm, std::nan(val.mPtr));
+#else
+ sq_pushfloat(vm, std::nanf(val.mPtr));
+#endif // _SQ64
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqNanL(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Attempt to generate the string value
+ StackStrF val(vm, 2);
+ // Have we failed to retrieve the string?
+ if (SQ_FAILED(val.mRes))
+ {
+ return val.mRes; // Propagate the error!
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ try
+ {
+ Var< SLongInt * >::push(vm, new SLongInt(std::nanl(val.mPtr)));
+ }
+ catch (const Sqrat::Exception & e)
+ {
+ return sq_throwerror(vm, e.Message().c_str());
+ }
+ catch (const std::exception e)
+ {
+ return sq_throwerror(vm, e.what());
+ }
+ catch (...)
+ {
+ return sq_throwerror(vm, _SC("Failed to create a long integer instance"));
+ }
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqExp(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::exp(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqExp2(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::exp2(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqExpm1(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::expm1(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqLog(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::log(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqLog10(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::log10(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqLog2(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::log2(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqLog1p(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::log1p(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqPow(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 2)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::pow(PopStackFloat(vm, 2), PopStackFloat(vm, 3)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqSqrt(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::sqrt(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqCbrt(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::cbrt(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqHypot(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 2)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::hypot(PopStackFloat(vm, 2), PopStackFloat(vm, 3)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqSin(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::sin(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqCos(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::cos(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqTan(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::tan(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqAsin(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::asin(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqAcos(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::acos(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqAtan(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::atan(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqAtan2(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 2)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::atan2(PopStackFloat(vm, 2), PopStackFloat(vm, 3)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqSinh(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::sinh(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqCosh(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::cosh(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqTanh(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::tanh(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqAsinh(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::asinh(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqAcosh(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::acosh(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqAtanh(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::atanh(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqErf(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::erf(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqErfc(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::erfc(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqTgamma(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::tgamma(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqLgamma(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::lgamma(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqCeil(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::ceil(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqFloor(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::floor(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqTrunc(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::trunc(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqRound(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::round(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqRoundI(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ if (sq_gettype(vm, 2) == OT_FLOAT)
+ {
+ sq_pushinteger(vm, ConvTo< SQInteger >::From(std::llround(PopStackFloat(vm, 2))));
+ }
+ else
+ {
+ sq_pushinteger(vm, ConvTo< SQInteger >::From(std::llround(PopStackInteger(vm, 2))));
+ }
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqRoundL(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ try
+ {
+ if (sq_gettype(vm, 2) == OT_FLOAT)
+ {
+ Var< SLongInt * >::push(vm, new SLongInt(std::llround(PopStackFloat(vm, 2))));
+ }
+ else
+ {
+ Var< SLongInt * >::push(vm, new SLongInt(std::llround(PopStackInteger(vm, 2))));
+ }
+ }
+ catch (const Sqrat::Exception & e)
+ {
+ return sq_throwerror(vm, e.Message().c_str());
+ }
+ catch (const std::exception e)
+ {
+ return sq_throwerror(vm, e.what());
+ }
+ catch (...)
+ {
+ return sq_throwerror(vm, _SC("Failed to create a long integer instance"));
+ }
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqNearByInt(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::nearbyint(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqFrexp(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Where the exponent is retrieved
+ Int32 expv = 0;
+ // Fetch the arguments from the stack and perform the requested operation
+ const SQFloat sigv = std::frexp(PopStackFloat(vm, 2), &expv);
+ // Create a new table on the stack
+ sq_newtable(vm);
+ // Push the significand index
+ sq_pushstring(vm, _SC("sig"), -1);
+ // Push the significand value
+ sq_pushfloat(vm, sigv);
+ // Attempt to create the array element
+ if (SQ_FAILED(sq_rawset(vm, -3)))
+ {
+ return sq_throwerror(vm, "Unable to insert the significand element");
+ }
+ // Push the exponent index
+ sq_pushstring(vm, _SC("exp"), -1);
+ // Push the exponent value
+ sq_pushinteger(vm, expv);
+ // Attempt to create the array element
+ if (SQ_FAILED(sq_rawset(vm, -3)))
+ {
+ return sq_throwerror(vm, "Unable to insert the exponent element");
+ }
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqLdexp(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 2)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::ldexp(PopStackFloat(vm, 2), PopStackInteger(vm, 3)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqModF(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Where the fractional part is retrieved
+ SQFloat intv = 0;
+ // Fetch the arguments from the stack and perform the requested operation
+ const SQFloat fracv = std::modf(PopStackFloat(vm, 2), &intv);
+ // Create a new table on the stack
+ sq_newtable(vm);
+ // Push the integral index
+ sq_pushstring(vm, _SC("integral"), -1);
+ // Push the integral value
+ sq_pushfloat(vm, intv);
+ // Attempt to create the array element
+ if (SQ_FAILED(sq_rawset(vm, -3)))
+ {
+ return sq_throwerror(vm, "Unable to insert the integral element");
+ }
+ // Push the fractional index
+ sq_pushstring(vm, _SC("fractional"), -1);
+ // Push the fractional value
+ sq_pushfloat(vm, fracv);
+ // Attempt to create the array element
+ if (SQ_FAILED(sq_rawset(vm, -3)))
+ {
+ return sq_throwerror(vm, "Unable to insert the fractional element");
+ }
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqScalbn(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 2)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+#ifdef _SQ64
+ sq_pushfloat(vm, std::scalbln(PopStackFloat(vm, 2), PopStackInteger(vm, 3)));
+#else
+ sq_pushfloat(vm, std::scalbn(PopStackFloat(vm, 2), PopStackInteger(vm, 3)));
+#endif // _SQ64
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqIlogb(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushinteger(vm, std::ilogb(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqLogb(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::logb(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqNextAfter(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 2)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::nextafter(PopStackFloat(vm, 2), PopStackFloat(vm, 3)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqNextForward(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 2)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::nexttoward(PopStackFloat(vm, 2), PopStackFloat(vm, 3)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqCopySign(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 2)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushfloat(vm, std::copysign(PopStackFloat(vm, 2), PopStackFloat(vm, 3)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqFpClassify(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushinteger(vm, std::fpclassify(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqIsFinite(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushbool(vm, std::isfinite(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqIsInf(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushbool(vm, std::isinf(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqIsNan(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushbool(vm, std::isnan(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqIsNormal(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushbool(vm, std::isnormal(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqSignBit(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 1)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushbool(vm, std::signbit(PopStackFloat(vm, 2)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqIsGreater(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 2)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushbool(vm, std::isgreater(PopStackFloat(vm, 2), PopStackFloat(vm, 3)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqIsGreaterEqual(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 2)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushbool(vm, std::isgreaterequal(PopStackFloat(vm, 2), PopStackFloat(vm, 3)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqIsLess(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 2)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushbool(vm, std::isless(PopStackFloat(vm, 2), PopStackFloat(vm, 3)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqIsLessEqual(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 2)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushbool(vm, std::islessequal(PopStackFloat(vm, 2), PopStackFloat(vm, 3)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqIsLessGreater(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 2)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushbool(vm, std::islessgreater(PopStackFloat(vm, 2), PopStackFloat(vm, 3)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ------------------------------------------------------------------------------------------------
+static SQInteger SqIsUnordered(HSQUIRRELVM vm)
+{
+ // Do we have the correct number of arguments?
+ if (sq_gettop(vm) <= 2)
+ {
+ return sq_throwerror(vm, "Wrong number of arguments");
+ }
+ // Fetch the arguments from the stack and perform the requested operation
+ sq_pushbool(vm, std::isunordered(PopStackFloat(vm, 2), PopStackFloat(vm, 3)));
+ // Specify that we have a value on the stack
+ return 1;
+}
+
+// ================================================================================================
+void Register_Math(HSQUIRRELVM vm)
+{
+ Table mns(vm);
+
+ mns
+ .SquirrelFunc(_SC("Div"), &SqDiv)
+ .SquirrelFunc(_SC("Remainder"), &SqRemainder)
+ .SquirrelFunc(_SC("Fma"), &SqFma)
+ .SquirrelFunc(_SC("Max"), &SqMax)
+ .SquirrelFunc(_SC("Min"), &SqMin)
+ .SquirrelFunc(_SC("Dim"), &SqDim)
+ .SquirrelFunc(_SC("Nan"), &SqNan)
+ .SquirrelFunc(_SC("NanL"), &SqNanL)
+ .SquirrelFunc(_SC("Exp"), &SqExp)
+ .SquirrelFunc(_SC("Exp2"), &SqExp2)
+ .SquirrelFunc(_SC("Expm1"), &SqExpm1)
+ .SquirrelFunc(_SC("Log"), &SqLog)
+ .SquirrelFunc(_SC("Log10"), &SqLog10)
+ .SquirrelFunc(_SC("Log2"), &SqLog2)
+ .SquirrelFunc(_SC("Log1p"), &SqLog1p)
+ .SquirrelFunc(_SC("Pow"), &SqPow)
+ .SquirrelFunc(_SC("Sqrt"), &SqSqrt)
+ .SquirrelFunc(_SC("Cbrt"), &SqCbrt)
+ .SquirrelFunc(_SC("Hypot"), &SqHypot)
+ .SquirrelFunc(_SC("Sin"), &SqSin)
+ .SquirrelFunc(_SC("Cos"), &SqCos)
+ .SquirrelFunc(_SC("Tan"), &SqTan)
+ .SquirrelFunc(_SC("Asin"), &SqAsin)
+ .SquirrelFunc(_SC("Acos"), &SqAcos)
+ .SquirrelFunc(_SC("Atan"), &SqAtan)
+ .SquirrelFunc(_SC("Atan2"), &SqAtan2)
+ .SquirrelFunc(_SC("Sinh"), &SqSinh)
+ .SquirrelFunc(_SC("Cosh"), &SqCosh)
+ .SquirrelFunc(_SC("Tanh"), &SqTanh)
+ .SquirrelFunc(_SC("Asinh"), &SqAsinh)
+ .SquirrelFunc(_SC("Acosh"), &SqAcosh)
+ .SquirrelFunc(_SC("Atanh"), &SqAtanh)
+ .SquirrelFunc(_SC("Erf"), &SqErf)
+ .SquirrelFunc(_SC("Erfc"), &SqErfc)
+ .SquirrelFunc(_SC("Tgamma"), &SqTgamma)
+ .SquirrelFunc(_SC("Lgamma"), &SqLgamma)
+ .SquirrelFunc(_SC("Ceil"), &SqCeil)
+ .SquirrelFunc(_SC("Floor"), &SqFloor)
+ .SquirrelFunc(_SC("Trunc"), &SqTrunc)
+ .SquirrelFunc(_SC("Round"), &SqRound)
+ .SquirrelFunc(_SC("RoundI"), &SqRoundI)
+ .SquirrelFunc(_SC("RoundL"), &SqRoundL)
+ .SquirrelFunc(_SC("NearByInt"), &SqNearByInt)
+ .SquirrelFunc(_SC("Frexp"), &SqFrexp)
+ .SquirrelFunc(_SC("Ldexp"), &SqLdexp)
+ .SquirrelFunc(_SC("ModF"), &SqModF)
+ .SquirrelFunc(_SC("Scalbn"), &SqScalbn)
+ .SquirrelFunc(_SC("Ilogb"), &SqIlogb)
+ .SquirrelFunc(_SC("Logb"), &SqLogb)
+ .SquirrelFunc(_SC("NextAfter"), &SqNextAfter)
+ .SquirrelFunc(_SC("NextForward"), &SqNextForward)
+ .SquirrelFunc(_SC("CopySign"), &SqCopySign)
+ .SquirrelFunc(_SC("FpClassify"), &SqFpClassify)
+ .SquirrelFunc(_SC("IsFinite"), &SqIsFinite)
+ .SquirrelFunc(_SC("IsInf"), &SqIsInf)
+ .SquirrelFunc(_SC("IsNan"), &SqIsNan)
+ .SquirrelFunc(_SC("IsNormal"), &SqIsNormal)
+ .SquirrelFunc(_SC("SignBit"), &SqSignBit)
+ .SquirrelFunc(_SC("IsGreater"), &SqIsGreater)
+ .SquirrelFunc(_SC("IsGreaterEqual"), &SqIsGreaterEqual)
+ .SquirrelFunc(_SC("IsLess"), &SqIsLess)
+ .SquirrelFunc(_SC("IsLessEqual"), &SqIsLessEqual)
+ .SquirrelFunc(_SC("IsLessGreater"), &SqIsLessGreater)
+ .SquirrelFunc(_SC("IsUnordered"), &SqIsUnordered);
+
+ RootTable(vm).Bind(_SC("SqMath"), mns);
+}
+
+
+} // Namespace:: SqMod
diff --git a/source/Library/Math.hpp b/source/Library/Math.hpp
index e69de29b..6adc5428 100644
--- a/source/Library/Math.hpp
+++ b/source/Library/Math.hpp
@@ -0,0 +1,12 @@
+#ifndef _LIBRARY_MATH_HPP_
+#define _LIBRARY_MATH_HPP_
+
+// ------------------------------------------------------------------------------------------------
+#include "Base/Shared.hpp"
+
+// ------------------------------------------------------------------------------------------------
+namespace SqMod {
+
+} // Namespace:: SqMod
+
+#endif // _LIBRARY_MATH_HPP_
diff --git a/source/Library/Numeric.cpp b/source/Library/Numeric.cpp
index 1491fdc8..2c6efc8a 100644
--- a/source/Library/Numeric.cpp
+++ b/source/Library/Numeric.cpp
@@ -54,7 +54,7 @@ LongInt< Uint64 > & LongInt< Uint64 >::operator = (CSStr text)
// ------------------------------------------------------------------------------------------------
CSStr LongInt< Uint64 >::ToString()
{
- if (snprintf(m_Text, sizeof(m_Text), "%llu", m_Data) < 0)
+ if (std::snprintf(m_Text, sizeof(m_Text), "%llu", m_Data) < 0)
{
m_Text[0] = 0;
}
@@ -82,6 +82,12 @@ void Register_Numeric(HSQUIRRELVM vm)
.Func(_SC("_tostring"), &SLongInt::ToString)
.Func(_SC("_typename"), &SLongInt::Typename)
.Func(_SC("_cmp"), &SLongInt::Cmp)
+ /* Core Functions */
+ .Func(_SC("tointeger"), &SLongInt::ToSqInteger)
+ .Func(_SC("tofloat"), &SLongInt::ToSqFloat)
+ .Func(_SC("tostring"), &SLongInt::ToSqString)
+ .Func(_SC("tobool"), &SLongInt::ToSqBool)
+ .Func(_SC("tochar"), &SLongInt::ToSqChar)
/* Metamethods */
.Func< SLongInt (SLongInt::*)(const SLongInt &) const >(_SC("_add"), &SLongInt::operator +)
.Func< SLongInt (SLongInt::*)(const SLongInt &) const >(_SC("_sub"), &SLongInt::operator -)
@@ -112,6 +118,12 @@ void Register_Numeric(HSQUIRRELVM vm)
.Func(_SC("_tostring"), &ULongInt::ToString)
.Func(_SC("_typename"), &ULongInt::Typename)
.Func(_SC("_cmp"), &ULongInt::Cmp)
+ /* Core Functions */
+ .Func(_SC("tointeger"), &ULongInt::ToSqInteger)
+ .Func(_SC("tofloat"), &ULongInt::ToSqFloat)
+ .Func(_SC("tostring"), &ULongInt::ToSqString)
+ .Func(_SC("tobool"), &ULongInt::ToSqBool)
+ .Func(_SC("tochar"), &ULongInt::ToSqChar)
/* Metamethods */
.Func< ULongInt (ULongInt::*)(const ULongInt &) const >(_SC("_add"), &ULongInt::operator +)
.Func< ULongInt (ULongInt::*)(const ULongInt &) const >(_SC("_sub"), &ULongInt::operator -)
diff --git a/source/Library/Numeric.hpp b/source/Library/Numeric.hpp
index 68c3cbe1..abb3130e 100644
--- a/source/Library/Numeric.hpp
+++ b/source/Library/Numeric.hpp
@@ -199,7 +199,7 @@ public:
*/
SQInteger GetSNum() const
{
- return (SQInteger)(m_Data);
+ return ClampL< Type, SQInteger >(m_Data);
}
/* --------------------------------------------------------------------------------------------
@@ -222,6 +222,46 @@ public:
void Random(Type n);
void Random(Type m, Type n);
+ /* --------------------------------------------------------------------------------------------
+ * Attempt to convert the long integer to a squirrel integer.
+ */
+ SQInteger ToSqInteger() const
+ {
+ return ClampL< Type, SQInteger >(m_Data);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Attempt to convert the long integer to a squirrel float.
+ */
+ SQFloat ToSqFloat() const
+ {
+ return ClampL< Float64, SQFloat >(static_cast< Float64 >(m_Data));
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Attempt to convert the long integer to a squirrel string.
+ */
+ CSStr ToSqString()
+ {
+ return ToString();
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Attempt to convert the long integer to a squirrel boolean.
+ */
+ bool ToSqBool() const
+ {
+ return (m_Data > 0);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Attempt to convert the long integer to a squirrel character.
+ */
+ SQChar ToSqChar() const
+ {
+ return ClampL< Type, SQChar >(m_Data);
+ }
+
private:
// --------------------------------------------------------------------------------------------
@@ -441,6 +481,46 @@ public:
void Random(Type n);
void Random(Type m, Type n);
+ /* --------------------------------------------------------------------------------------------
+ * Attempt to convert the long integer to a squirrel integer.
+ */
+ SQInteger ToSqInteger() const
+ {
+ return ClampL< Type, SQInteger >(m_Data);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Attempt to convert the long integer to a squirrel float.
+ */
+ SQFloat ToSqFloat() const
+ {
+ return ClampL< Float64, SQFloat >(static_cast< Float64 >(m_Data));
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Attempt to convert the long integer to a squirrel string.
+ */
+ CSStr ToSqString()
+ {
+ return ToString();
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Attempt to convert the long integer to a squirrel boolean.
+ */
+ bool ToSqBool() const
+ {
+ return (m_Data > 0);
+ }
+
+ /* --------------------------------------------------------------------------------------------
+ * Attempt to convert the long integer to a squirrel character.
+ */
+ SQChar ToSqChar() const
+ {
+ return ClampL< Type, SQChar >(m_Data);
+ }
+
private:
// --------------------------------------------------------------------------------------------
diff --git a/source/Library/String.cpp b/source/Library/String.cpp
index 40f54848..9d4f9b90 100644
--- a/source/Library/String.cpp
+++ b/source/Library/String.cpp
@@ -2,6 +2,7 @@
#include "Library/String.hpp"
#include "Base/Shared.hpp"
#include "Base/Buffer.hpp"
+#include "Base/Stack.hpp"
// ------------------------------------------------------------------------------------------------
#include
diff --git a/source/Library/SysEnv.cpp b/source/Library/SysEnv.cpp
index 58ac320f..8d6fc49a 100644
--- a/source/Library/SysEnv.cpp
+++ b/source/Library/SysEnv.cpp
@@ -1,5 +1,6 @@
// ------------------------------------------------------------------------------------------------
#include "Library/SysEnv.hpp"
+#include "Base/Stack.hpp"
// ------------------------------------------------------------------------------------------------
#include
diff --git a/source/Library/SysPath.cpp b/source/Library/SysPath.cpp
index c0fc0eb5..b4d5a519 100644
--- a/source/Library/SysPath.cpp
+++ b/source/Library/SysPath.cpp
@@ -1,6 +1,7 @@
// ------------------------------------------------------------------------------------------------
#include "Library/SysPath.hpp"
#include "Library/SysEnv.hpp"
+#include "Base/Stack.hpp"
// ------------------------------------------------------------------------------------------------
#include
diff --git a/source/Register.cpp b/source/Register.cpp
index 908de542..0dffc171 100644
--- a/source/Register.cpp
+++ b/source/Register.cpp
@@ -37,6 +37,7 @@ extern void Register_Entity(HSQUIRRELVM vm);
extern void Register_Chrono(HSQUIRRELVM vm);
extern void Register_Crypt(HSQUIRRELVM vm);
extern void Register_Numeric(HSQUIRRELVM vm);
+extern void Register_Math(HSQUIRRELVM vm);
extern void Register_Random(HSQUIRRELVM vm);
extern void Register_String(HSQUIRRELVM vm);
extern void Register_SysEnv(HSQUIRRELVM vm);
@@ -82,6 +83,7 @@ bool RegisterAPI(HSQUIRRELVM vm)
Register_Crypt(vm);
Register_Random(vm);
Register_Numeric(vm);
+ Register_Math(vm);
Register_String(vm);
Register_SysEnv(vm);
Register_SysPath(vm);
diff --git a/source/Routine.cpp b/source/Routine.cpp
index ccda3299..46059451 100644
--- a/source/Routine.cpp
+++ b/source/Routine.cpp
@@ -1,5 +1,6 @@
// ------------------------------------------------------------------------------------------------
#include "Routine.hpp"
+#include "Base/Stack.hpp"
#include "Library/Chrono.hpp"
// ------------------------------------------------------------------------------------------------