From 0a990046156515e5710d742e09711aa8290ac94a Mon Sep 17 00:00:00 2001
From: RD42 <42702181+dashr9230@users.noreply.github.com>
Date: Sun, 4 Feb 2024 19:18:38 +0800
Subject: [PATCH] [server/bot] Add and match `amxfloat.c` functions
---
bot/bot.vcproj | 3 +
server/amx/amxfloat.c | 362 ++++++++++++++++++++++++++++++++++++++++++
server/server.vcproj | 3 +
3 files changed, 368 insertions(+)
create mode 100644 server/amx/amxfloat.c
diff --git a/bot/bot.vcproj b/bot/bot.vcproj
index a027512..d3034cd 100644
--- a/bot/bot.vcproj
+++ b/bot/bot.vcproj
@@ -259,6 +259,9 @@
+
+
diff --git a/server/amx/amxfloat.c b/server/amx/amxfloat.c
new file mode 100644
index 0000000..26eae2a
--- /dev/null
+++ b/server/amx/amxfloat.c
@@ -0,0 +1,362 @@
+/* Float arithmetic for the Pawn Abstract Machine
+ *
+ * Copyright (c) Artran, Inc. 1999
+ * Written by Greg Garner (gmg@artran.com)
+ * This file may be freely used. No warranties of any kind.
+ *
+ * CHANGES -
+ * 2002-08-27: Basic conversion of source from C++ to C by Adam D. Moss
+ *
+ * 2003-08-29: Removal of the dynamic memory allocation and replacing two
+ * type conversion functions by macros, by Thiadmer Riemersma
+ * 2003-09-22: Moved the type conversion macros to AMX.H, and simplifications
+ * of some routines, by Thiadmer Riemersma
+ * 2003-11-24: A few more native functions (geometry), plus minor modifications,
+ * mostly to be compatible with dynamically loadable extension
+ * modules, by Thiadmer Riemersma
+ * 2004-01-09: Adaptions for 64-bit cells (using "double precision"), by
+ * Thiadmer Riemersma
+ */
+#include /* for atof() */
+#include /* for NULL */
+#include
+#include
+#include "amx.h"
+
+/*
+ #if defined __BORLANDC__
+ #pragma resource "amxFloat.res"
+ #endif
+*/
+
+#if PAWN_CELL_SIZE==32
+ #define REAL float
+#elif PAWN_CELL_SIZE==64
+ #define REAL double
+#else
+ #error Unsupported cell size
+#endif
+
+#define PI 3.1415926535897932384626433832795
+
+/******************************************************************/
+static cell AMX_NATIVE_CALL n_float(AMX *amx,cell *params)
+{
+ /*
+ * params[0] = number of bytes
+ * params[1] = long value to convert to a float
+ */
+ REAL fValue;
+
+ (void)amx;
+ /* Convert to a float. Calls the compilers long to float conversion. */
+ fValue = (REAL) params[1];
+
+ /* Return the cell. */
+ return amx_ftoc(fValue);
+}
+
+/******************************************************************/
+static cell AMX_NATIVE_CALL n_floatstr(AMX *amx,cell *params)
+{
+ /*
+ * params[0] = number of bytes
+ * params[1] = virtual string address to convert to a float
+ */
+ char szSource[60];
+ cell *pString;
+ REAL fNum;
+ int nLen;
+
+ (void)amx;
+ /* They should have sent us 1 cell. */
+ assert(params[0]/sizeof(cell)==1);
+
+ /* Get the real address of the string. */
+ amx_GetAddr(amx,params[1],&pString);
+
+ /* Find out how long the string is in characters. */
+ amx_StrLen(pString, &nLen);
+ if (nLen == 0 || nLen >= sizeof szSource)
+ return 0;
+
+ /* Now convert the Pawn string into a C type null terminated string */
+ amx_GetString(szSource, pString, 0, sizeof szSource);
+
+ /* Now convert this to a float. */
+ fNum = (REAL)atof(szSource);
+
+ return amx_ftoc(fNum);
+}
+
+/******************************************************************/
+static cell AMX_NATIVE_CALL n_floatmul(AMX *amx,cell *params)
+{
+ /*
+ * params[0] = number of bytes
+ * params[1] = float operand 1
+ * params[2] = float operand 2
+ */
+ REAL fRes = amx_ctof(params[1]) * amx_ctof(params[2]);
+ (void)amx;
+ return amx_ftoc(fRes);
+}
+
+/******************************************************************/
+static cell AMX_NATIVE_CALL n_floatdiv(AMX *amx,cell *params)
+{
+ /*
+ * params[0] = number of bytes
+ * params[1] = float dividend (top)
+ * params[2] = float divisor (bottom)
+ */
+ REAL fRes = amx_ctof(params[1]) / amx_ctof(params[2]);
+ (void)amx;
+ return amx_ftoc(fRes);
+}
+
+/******************************************************************/
+static cell AMX_NATIVE_CALL n_floatadd(AMX *amx,cell *params)
+{
+ /*
+ * params[0] = number of bytes
+ * params[1] = float operand 1
+ * params[2] = float operand 2
+ */
+ REAL fRes = amx_ctof(params[1]) + amx_ctof(params[2]);
+ (void)amx;
+ return amx_ftoc(fRes);
+}
+
+/******************************************************************/
+static cell AMX_NATIVE_CALL n_floatsub(AMX *amx,cell *params)
+{
+ /*
+ * params[0] = number of bytes
+ * params[1] = float operand 1
+ * params[2] = float operand 2
+ */
+ REAL fRes = amx_ctof(params[1]) - amx_ctof(params[2]);
+ (void)amx;
+ return amx_ftoc(fRes);
+}
+
+/******************************************************************/
+/* Return fractional part of float */
+static cell AMX_NATIVE_CALL n_floatfract(AMX *amx,cell *params)
+{
+ /*
+ * params[0] = number of bytes
+ * params[1] = float operand
+ */
+ REAL fA = amx_ctof(params[1]);
+ fA = fA - (REAL)(floor((double)fA));
+ (void)amx;
+ return amx_ftoc(fA);
+}
+
+/******************************************************************/
+/* Return integer part of float, rounded */
+static cell AMX_NATIVE_CALL n_floatround(AMX *amx,cell *params)
+{
+ /*
+ * params[0] = number of bytes
+ * params[1] = float operand
+ * params[2] = Type of rounding (long)
+ */
+ REAL fA = amx_ctof(params[1]);
+
+ (void)amx;
+ switch (params[2])
+ {
+ case 1: /* round downwards (truncate) */
+ fA = (REAL)(floor((double)fA));
+ break;
+ case 2: /* round upwards */
+ fA = (REAL)(ceil((double)fA));
+ break;
+ case 3: /* round towards zero */
+ if ( fA>=0.0 )
+ fA = (REAL)(floor((double)fA));
+ else
+ fA = (REAL)(ceil((double)fA));
+ break;
+ default: /* standard, round to nearest */
+ fA = (REAL)(floor((double)fA+.5));
+ break;
+ }
+
+ return (long)fA;
+}
+
+/******************************************************************/
+static cell AMX_NATIVE_CALL n_floatcmp(AMX *amx,cell *params)
+{
+ /*
+ * params[0] = number of bytes
+ * params[1] = float operand 1
+ * params[2] = float operand 2
+ */
+ REAL fA, fB;
+
+ (void)amx;
+ fA = amx_ctof(params[1]);
+ fB = amx_ctof(params[2]);
+ if (fA == fB)
+ return 0;
+ else if (fA>fB)
+ return 1;
+ else
+ return -1;
+
+}
+
+/******************************************************************/
+static cell AMX_NATIVE_CALL n_floatsqroot(AMX *amx,cell *params)
+{
+ /*
+ * params[0] = number of bytes
+ * params[1] = float operand
+ */
+ REAL fA = amx_ctof(params[1]);
+ fA = (REAL)sqrt(fA);
+ if (fA < 0)
+ return amx_RaiseError(amx, AMX_ERR_DOMAIN);
+ return amx_ftoc(fA);
+}
+
+/******************************************************************/
+static cell AMX_NATIVE_CALL n_floatpower(AMX *amx,cell *params)
+{
+ /*
+ * params[0] = number of bytes
+ * params[1] = float operand 1 (base)
+ * params[2] = float operand 2 (exponent)
+ */
+ REAL fA = amx_ctof(params[1]);
+ REAL fB = amx_ctof(params[2]);
+ fA = (REAL)pow(fA, fB);
+ (void)amx;
+ return amx_ftoc(fA);
+}
+
+/******************************************************************/
+static cell AMX_NATIVE_CALL n_floatlog(AMX *amx,cell *params)
+{
+ /*
+ * params[0] = number of bytes
+ * params[1] = float operand 1 (value)
+ * params[2] = float operand 2 (base)
+ */
+ REAL fValue = amx_ctof(params[1]);
+ REAL fBase = amx_ctof(params[2]);
+ (void)amx;
+ if (fValue <= 0.0 || fBase <= 0)
+ return amx_RaiseError(amx, AMX_ERR_DOMAIN);
+ if (fBase == 10.0) // ??? epsilon
+ fValue = (REAL)log10(fValue);
+ else
+ fValue = (REAL)(log(fValue) / log(fBase));
+ return amx_ftoc(fValue);
+}
+
+static REAL ToRadians(REAL angle, int radix)
+{
+ switch (radix)
+ {
+ case 1: /* degrees, sexagesimal system (technically: degrees/minutes/seconds) */
+ return (REAL)(angle * PI / 180.0);
+ case 2: /* grades, centesimal system */
+ return (REAL)(angle * PI / 200.0);
+ default: /* assume already radian */
+ return angle;
+ } /* switch */
+}
+
+/******************************************************************/
+static cell AMX_NATIVE_CALL n_floatsin(AMX *amx,cell *params)
+{
+ /*
+ * params[0] = number of bytes
+ * params[1] = float operand 1 (angle)
+ * params[2] = float operand 2 (radix)
+ */
+ REAL fA = amx_ctof(params[1]);
+ fA = ToRadians(fA, params[2]);
+ fA = sin(fA);
+ (void)amx;
+ return amx_ftoc(fA);
+}
+
+/******************************************************************/
+static cell AMX_NATIVE_CALL n_floatcos(AMX *amx,cell *params)
+{
+ /*
+ * params[0] = number of bytes
+ * params[1] = float operand 1 (angle)
+ * params[2] = float operand 2 (radix)
+ */
+ REAL fA = amx_ctof(params[1]);
+ fA = ToRadians(fA, params[2]);
+ fA = cos(fA);
+ (void)amx;
+ return amx_ftoc(fA);
+}
+
+/******************************************************************/
+static cell AMX_NATIVE_CALL n_floattan(AMX *amx,cell *params)
+{
+ /*
+ * params[0] = number of bytes
+ * params[1] = float operand 1 (angle)
+ * params[2] = float operand 2 (radix)
+ */
+ REAL fA = amx_ctof(params[1]);
+ fA = ToRadians(fA, params[2]);
+ fA = tan(fA);
+ (void)amx;
+ return amx_ftoc(fA);
+}
+
+/******************************************************************/
+static cell AMX_NATIVE_CALL n_floatabs(AMX *amx,cell *params)
+{
+ REAL fA = amx_ctof(params[1]);
+ fA = (fA >= 0) ? fA : -fA;
+ (void)amx;
+ return amx_ftoc(fA);
+}
+
+#if defined __cplusplus
+ extern "C"
+#endif
+const AMX_NATIVE_INFO float_Natives[] = {
+ { "float", n_float },
+ { "floatstr", n_floatstr },
+ { "floatmul", n_floatmul },
+ { "floatdiv", n_floatdiv },
+ { "floatadd", n_floatadd },
+ { "floatsub", n_floatsub },
+ { "floatfract", n_floatfract },
+ { "floatround", n_floatround },
+ { "floatcmp", n_floatcmp },
+ { "floatsqroot", n_floatsqroot},
+ { "floatpower", n_floatpower },
+ { "floatlog", n_floatlog },
+ { "floatsin", n_floatsin },
+ { "floatcos", n_floatcos },
+ { "floattan", n_floattan },
+ { "floatabs", n_floatabs },
+ { NULL, NULL } /* terminator */
+};
+
+int AMXEXPORT amx_FloatInit(AMX *amx)
+{
+ return amx_Register(amx,float_Natives,-1);
+}
+
+int AMXEXPORT amx_FloatCleanup(AMX *amx)
+{
+ (void)amx;
+ return AMX_ERR_NONE;
+}
diff --git a/server/server.vcproj b/server/server.vcproj
index 58a1905..3a249d9 100644
--- a/server/server.vcproj
+++ b/server/server.vcproj
@@ -235,6 +235,9 @@
+
+