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 @@ + +