From aba273f93d5f6e204f447220ed18c85f0a3dbf69 Mon Sep 17 00:00:00 2001 From: Borja Ferrer Date: Sat, 23 Dec 2006 02:20:53 +0000 Subject: [PATCH] IPlugin context pointer is passed now to natives Added basic string natives Added floating point natives --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40230 --- core/msvc8/sourcemod_mm.vcproj | 8 + core/smn_float.cpp | 280 +++++++++++++++++++++++++++++++ core/smn_string.cpp | 111 ++++++++++++ sourcepawn/include/sp_vm_types.h | 2 +- sourcepawn/jit/x86/jit_x86.cpp | 5 +- 5 files changed, 403 insertions(+), 3 deletions(-) create mode 100644 core/smn_float.cpp create mode 100644 core/smn_string.cpp diff --git a/core/msvc8/sourcemod_mm.vcproj b/core/msvc8/sourcemod_mm.vcproj index f0900e3f..f729f595 100644 --- a/core/msvc8/sourcemod_mm.vcproj +++ b/core/msvc8/sourcemod_mm.vcproj @@ -194,6 +194,14 @@ RelativePath="..\sm_trie.cpp" > + + + + diff --git a/core/smn_float.cpp b/core/smn_float.cpp new file mode 100644 index 00000000..cba159f9 --- /dev/null +++ b/core/smn_float.cpp @@ -0,0 +1,280 @@ +#include +#include +#include "sp_vm_api.h" + +using namespace SourcePawn; + +#define PI 3.14159265358979323846 + +inline cell_t ftoc(float val) +{ + return *(cell_t *)&val; +} +inline float ctof(cell_t val) +{ + return *(float *)&val; +} + +inline float AngleToRadians(float val, int mode) +{ + switch (mode) + { + case 1: + { + return (float)((val * PI) / 180.0); + } + case 2: + { + return (float)((val * PI) / 200.0); + } + default: + { + return val; + } + } +} + +inline float RadiansToAngle(float val, int mode) +{ + switch (mode) + { + case 1: + { + return (float)((val / PI) * 180.0); + } + case 2: + { + return (float)((val / PI) * 200.0); + } + default: + { + return val; + } + } +} + + +/**************************************** +* * +* FLOATING POINT NATIVE IMPLEMENTATIONS * +* * +****************************************/ + + +static cell_t sm_float(IPluginContext *pCtx, const cell_t *params) +{ + float val = static_cast(params[1]); + + return ftoc(val); +} + +static cell_t sm_floatabs(IPluginContext *pCtx, const cell_t *params) +{ + float val = ctof(params[1]); + val = (val >= 0) ? val : -val; + + return ftoc(val); +} + +static cell_t sm_floatadd(IPluginContext *pCtx, const cell_t *params) +{ + float val = ctof(params[1]) + ctof(params[2]); + + return ftoc(val); +} + +static cell_t sm_floatsub(IPluginContext *pCtx, const cell_t *params) +{ + float val = ctof(params[1]) - ctof(params[2]); + + return ftoc(val); +} + +static cell_t sm_floatmul(IPluginContext *pCtx, const cell_t *params) +{ + float val = ctof(params[1]) * ctof(params[2]); + + return ftoc(val); +} + +static cell_t sm_floatdiv(IPluginContext *pCtx, const cell_t *params) +{ + float val = ctof(params[1]) / ctof(params[2]); + + return ftoc(val); +} + +static cell_t sm_floatcmp(IPluginContext *pCtx, const cell_t *params) +{ + float val1 = ctof(params[1]); + float val2 = ctof(params[2]); + + if (val1 > val2) + { + return 1; + } else if (val1 < val2) { + return -1; + } + + return 0; +} + +static cell_t sm_floatlog(IPluginContext *pCtx, const cell_t *params) +{ + float val = ctof(params[1]); + float base = ctof(params[2]); + + if ((val <= 0) || (base <= 0)) + { + //:TODO: error out! logs cant take in negative numbers and log 0=-inf + } + if (base == 10.0) + { + val = log10(val); + } else { + val = log(val) / log(base); + } + + return ftoc(val); +} + +static cell_t sm_floatexp(IPluginContext *pCtx, const cell_t *params) +{ + float val = ctof(params[1]); + + return ftoc(exp(val)); +} + +static cell_t sm_floatpower(IPluginContext *pCtx, const cell_t *params) +{ + float base = ctof(params[1]); + float exponent = ctof(params[2]); + + return ftoc(pow(base, exponent)); +} + +static cell_t sm_floatsqroot(IPluginContext *pCtx, const cell_t *params) +{ + float val = ctof(params[1]); + + if (val < 0.0) + { + //:TODO: error out! we dont support complex numbers + } + + return ftoc(sqrt(val)); +} + +static cell_t sm_floatround(IPluginContext *pCtx, const cell_t *params) +{ + float val = ctof(params[1]); + + switch (params[2]) + { + case 1: + { + val = floor(val); + break; + } + case 2: + { + val = ceil(val); + break; + } + case 3: + { + if (val >= 0.0) + { + val = floor(val); + } else { + val = ceil(val); + } + break; + } + default: + { + val = (float)floor(val + 0.5); + break; + } + } + + return ftoc(val); +} + +static cell_t sm_floatstr(IPluginContext *pCtx, const cell_t *params) +{ + char *str; + + pCtx->LocalToString(params[1], &str); + if (!strlen(str)) + { + return 0; + } + + return ftoc((float)atof(str)); +} + +static cell_t sm_floatfract(IPluginContext *pCtx, const cell_t *params) +{ + float val = ctof(params[1]); + val = val - floor(val); + + return ftoc(val); +} + +static cell_t sm_floatsin(IPluginContext *pCtx, const cell_t *params) +{ + float val = ctof(params[1]); + val = sin(AngleToRadians(val, params[2])); + + return ftoc(val); +} + +static cell_t sm_floatcos(IPluginContext *pCtx, const cell_t *params) +{ + float val = ctof(params[1]); + val = cos(AngleToRadians(val, params[2])); + + return ftoc(val); +} + +static cell_t sm_floattan(IPluginContext *pCtx, const cell_t *params) +{ + float val = ctof(params[1]); + val = tan(AngleToRadians(val, params[2])); + + return ftoc(val); +} + +static cell_t sm_floatasin(IPluginContext *pCtx, const cell_t *params) +{ + float val = ctof(params[1]); + val = asin(val); + + return ftoc(RadiansToAngle(val, params[2])); +} + +static cell_t sm_floatacos(IPluginContext *pCtx, const cell_t *params) +{ + float val = ctof(params[1]); + val = acos(val); + + return ftoc(RadiansToAngle(val, params[2])); +} + +static cell_t sm_floatatan(IPluginContext *pCtx, const cell_t *params) +{ + float val = ctof(params[1]); + val = atan(val); + + return ftoc(RadiansToAngle(val, params[2])); +} + +static cell_t sm_floatatan2(IPluginContext *pCtx, const cell_t *params) +{ + float val1 = ctof(params[1]); + float val2 = ctof(params[2]); + val1 = atan2(val1, val2); + + return ftoc(RadiansToAngle(val1, params[3])); +} diff --git a/core/smn_string.cpp b/core/smn_string.cpp new file mode 100644 index 00000000..627d1a90 --- /dev/null +++ b/core/smn_string.cpp @@ -0,0 +1,111 @@ +#include "sm_platform.h" +#include +#include +#include "sp_vm_api.h" + +using namespace SourcePawn; + +const char *stristr(const char *str, const char *substr) +{ + if (!*substr) + { + return ((char *)str); + } + + char *needle = (char *)substr; + char *prevloc = (char *)str; + char *haystack = (char *)str; + + while (*haystack) + { + if (tolower(*haystack) == tolower(*needle)) + { + haystack++; + if (!*++needle) + { + return prevloc; + } + } else { + haystack = ++prevloc; + needle = (char *)substr; + } + } + + return NULL; +} + +inline const char *_strstr(const char *str, const char *substr) +{ +#ifdef PLATFORM_WINDOWS + return strstr(str, substr); +#elif PLATFORM_LINUX + return (const char *)strstr(str, substr); +#endif +} + +/********************************************* +* * +* STRING MANIPULATION NATIVE IMPLEMENTATIONS * +* * +*********************************************/ + + +static cell_t sm_strlen(IPluginContext *pCtx, const cell_t *params) +{ + char *str; + pCtx->LocalToString(params[1], &str); + + return strlen(str); +} + +static cell_t sm_contain(IPluginContext *pCtx, const cell_t *params) +{ + typedef const char *(*STRSEARCH)(const char *, const char *); + STRSEARCH func; + char *str, *substr; + + pCtx->LocalToString(params[1], &str); + pCtx->LocalToString(params[2], &substr); + + func = (params[3]) ? _strstr : stristr; + const char *pos = func(str, substr); + if (pos) + { + return (pos - str); + } + + return -1; +} + +static cell_t sm_equal(IPluginContext *pCtx, const cell_t *params) +{ + typedef int (*STRCOMPARE)(const char *, const char *); + STRCOMPARE func; + char *str1, *str2; + + pCtx->LocalToString(params[1], &str1); + pCtx->LocalToString(params[2], &str2); + + func = (params[3]) ? strcmp : stricmp; + + return (func(str1, str2)) ? 0 : 1; +} + +static cell_t sm_strcopy(IPluginContext *pCtx, const cell_t *params) +{ + char *dest, *src, *start; + int len; + + pCtx->LocalToString(params[1], &dest); + pCtx->LocalToString(params[3], &src); + len = params[2]; + + start = dest; + while ((*src) && (len--)) + { + *dest++ = *src++; + } + *dest = '\0'; + + return (dest - start); +} diff --git a/sourcepawn/include/sp_vm_types.h b/sourcepawn/include/sp_vm_types.h index a5987d64..3065915c 100644 --- a/sourcepawn/include/sp_vm_types.h +++ b/sourcepawn/include/sp_vm_types.h @@ -107,7 +107,7 @@ namespace SourcePawn struct sp_context_s; -typedef cell_t (*SPVM_NATIVE_FUNC)(struct sp_context_s *, const cell_t *); +typedef cell_t (*SPVM_NATIVE_FUNC)(SourcePawn::IPluginContext *, const cell_t *); /********************************************** *** The following structures are bound to the VM/JIT. diff --git a/sourcepawn/jit/x86/jit_x86.cpp b/sourcepawn/jit/x86/jit_x86.cpp index 44d5b33f..3cafd163 100644 --- a/sourcepawn/jit/x86/jit_x86.cpp +++ b/sourcepawn/jit/x86/jit_x86.cpp @@ -1776,11 +1776,12 @@ cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params) return 0; } - return native->pfn(ctx, params); + return native->pfn(ctx->context, params); } -cell_t InvalidNative(sp_context_t *ctx, const cell_t *params) +static cell_t InvalidNative(IPluginContext *pCtx, const cell_t *params) { + sp_context_t *ctx = pCtx->GetContext(); ctx->err = SP_ERROR_INVALID_NATIVE; return 0;