ds@1952: /** ds@1952: * vim: set ts=4 : ds@1952: * ============================================================================= ds@1952: * SourceMod ds@1952: * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. ds@1952: * ============================================================================= ds@1952: * ds@1952: * This program is free software; you can redistribute it and/or modify it under ds@1952: * the terms of the GNU General Public License, version 3.0, as published by the ds@1952: * Free Software Foundation. ds@1952: * ds@1952: * This program is distributed in the hope that it will be useful, but WITHOUT ds@1952: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ds@1952: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ds@1952: * details. ds@1952: * ds@1952: * You should have received a copy of the GNU General Public License along with ds@1952: * this program. If not, see . ds@1952: * ds@1952: * As a special exception, AlliedModders LLC gives you permission to link the ds@1952: * code of this program (as well as its derivative works) to "Half-Life 2," the ds@1952: * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software ds@1952: * by the Valve Corporation. You must obey the GNU General Public License in ds@1952: * all respects for all other code used. Additionally, AlliedModders LLC grants ds@1952: * this exception to all derivative works. AlliedModders LLC defines further ds@1952: * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), ds@1952: * or . ds@1952: * ds@1952: * Version: $Id$ ds@1952: */ ds@1952: ds@1952: #include ds@1952: #include ds@1952: #include ds@1952: #include "sm_globals.h" ds@1952: ds@1952: /**************************************** ds@1952: * * ds@1952: * FLOATING POINT NATIVE IMPLEMENTATIONS * ds@1952: * * ds@1952: ****************************************/ ds@1952: ds@1952: ds@1952: static cell_t sm_float(IPluginContext *pCtx, const cell_t *params) ds@1952: { ds@1952: float val = static_cast(params[1]); ds@1952: ds@1952: return sp_ftoc(val); ds@1952: } ds@1952: ds@1952: static cell_t sm_FloatAbs(IPluginContext *pCtx, const cell_t *params) ds@1952: { ds@1952: float val = sp_ctof(params[1]); ds@1952: val = (val >= 0.0f) ? val : -val; ds@1952: ds@1952: return sp_ftoc(val); ds@1952: } ds@1952: ds@1952: static cell_t sm_FloatAdd(IPluginContext *pCtx, const cell_t *params) ds@1952: { ds@1952: float val = sp_ctof(params[1]) + sp_ctof(params[2]); ds@1952: ds@1952: return sp_ftoc(val); ds@1952: } ds@1952: ds@1952: static cell_t sm_FloatSub(IPluginContext *pCtx, const cell_t *params) ds@1952: { ds@1952: float val = sp_ctof(params[1]) - sp_ctof(params[2]); ds@1952: ds@1952: return sp_ftoc(val); ds@1952: } ds@1952: ds@1952: static cell_t sm_FloatMul(IPluginContext *pCtx, const cell_t *params) ds@1952: { ds@1952: float val = sp_ctof(params[1]) * sp_ctof(params[2]); ds@1952: ds@1952: return sp_ftoc(val); ds@1952: } ds@1952: ds@1952: static cell_t sm_FloatDiv(IPluginContext *pCtx, const cell_t *params) ds@1952: { ds@1952: float val = sp_ctof(params[1]) / sp_ctof(params[2]); ds@1952: ds@1952: return sp_ftoc(val); ds@1952: } ds@1952: ds@1952: static cell_t sm_FloatCompare(IPluginContext *pCtx, const cell_t *params) ds@1952: { ds@1952: float val1 = sp_ctof(params[1]); ds@1952: float val2 = sp_ctof(params[2]); ds@1952: ds@1952: if (val1 > val2) ds@1952: { ds@1952: return 1; ds@1952: } else if (val1 < val2) { ds@1952: return -1; ds@1952: } ds@1952: ds@1952: return 0; ds@1952: } ds@1952: ds@1952: static cell_t sm_Logarithm(IPluginContext *pCtx, const cell_t *params) ds@1952: { ds@1952: float val = sp_ctof(params[1]); ds@1952: float base = sp_ctof(params[2]); ds@1952: ds@1952: if ((val <= 0.0f) || (base <= 0.0f)) ds@1952: { ds@1952: return pCtx->ThrowNativeError("Cannot evaluate the logarithm of zero or a negative number (val:%f base:%f)", val, base); ds@1952: } ds@1952: if (base == 10.0f) ds@1952: { ds@1952: val = log10(val); ds@1952: } else { ds@1952: val = log(val) / log(base); ds@1952: } ds@1952: ds@1952: return sp_ftoc(val); ds@1952: } ds@1952: ds@1952: static cell_t sm_Exponential(IPluginContext *pCtx, const cell_t *params) ds@1952: { ds@1952: float val = sp_ctof(params[1]); ds@1952: ds@1952: return sp_ftoc(exp(val)); ds@1952: } ds@1952: ds@1952: static cell_t sm_Pow(IPluginContext *pCtx, const cell_t *params) ds@1952: { ds@1952: float base = sp_ctof(params[1]); ds@1952: float exponent = sp_ctof(params[2]); ds@1952: ds@1952: return sp_ftoc(pow(base, exponent)); ds@1952: } ds@1952: ds@1952: static cell_t sm_SquareRoot(IPluginContext *pCtx, const cell_t *params) ds@1952: { ds@1952: float val = sp_ctof(params[1]); ds@1952: ds@1952: if (val < 0.0f) ds@1952: { ds@1952: return pCtx->ThrowNativeError("Cannot evaluate the square root of a negative number (val:%f)", val); ds@1952: } ds@1952: ds@1952: return sp_ftoc(sqrt(val)); ds@1952: } ds@1952: ds@1952: static cell_t sm_RoundToNearest(IPluginContext *pCtx, const cell_t *params) ds@1952: { ds@1952: float val = sp_ctof(params[1]); ds@1952: val = (float)floor(val + 0.5f); ds@1952: ds@1952: return static_cast(val); ds@1952: } ds@1952: ds@1952: static cell_t sm_RoundToFloor(IPluginContext *pCtx, const cell_t *params) ds@1952: { ds@1952: float val = sp_ctof(params[1]); ds@1952: val = floor(val); ds@1952: ds@1952: return static_cast(val); ds@1952: } ds@1952: ds@1952: static cell_t sm_RoundToCeil(IPluginContext *pCtx, const cell_t *params) ds@1952: { ds@1952: float val = sp_ctof(params[1]); ds@1952: val = ceil(val); ds@1952: ds@1952: return static_cast(val); ds@1952: } ds@1952: ds@1952: static cell_t sm_RoundToZero(IPluginContext *pCtx, const cell_t *params) ds@1952: { ds@1952: float val = sp_ctof(params[1]); ds@1952: if (val >= 0.0f) ds@1952: { ds@1952: val = floor(val); ds@1952: } else { ds@1952: val = ceil(val); ds@1952: } ds@1952: ds@1952: return static_cast(val); ds@1952: } ds@1952: ds@1952: static cell_t sm_FloatFraction(IPluginContext *pCtx, const cell_t *params) ds@1952: { ds@1952: float val = sp_ctof(params[1]); ds@1952: val = val - floor(val); ds@1952: ds@1952: return sp_ftoc(val); ds@1952: } ds@1952: ds@1952: static cell_t sm_Sine(IPluginContext *pCtx, const cell_t *params) ds@1952: { ds@1952: float val = sp_ctof(params[1]); ds@1952: val = sin(val); ds@1952: ds@1952: return sp_ftoc(val); ds@1952: } ds@1952: ds@1952: static cell_t sm_Cosine(IPluginContext *pCtx, const cell_t *params) ds@1952: { ds@1952: float val = sp_ctof(params[1]); ds@1952: val = cos(val); ds@1952: ds@1952: return sp_ftoc(val); ds@1952: } ds@1952: ds@1952: static cell_t sm_Tangent(IPluginContext *pCtx, const cell_t *params) ds@1952: { ds@1952: float val = sp_ctof(params[1]); ds@1952: val = tan(val); ds@1952: ds@1952: return sp_ftoc(val); ds@1952: } ds@1952: ds@1952: static cell_t sm_ArcSine(IPluginContext *pCtx, const cell_t *params) ds@1952: { ds@1952: float val = sp_ctof(params[1]); ds@1952: val = asin(val); ds@1952: ds@1952: return sp_ftoc(val); ds@1952: } ds@1952: ds@1952: static cell_t sm_ArcCosine(IPluginContext *pCtx, const cell_t *params) ds@1952: { ds@1952: float val = sp_ctof(params[1]); ds@1952: val = acos(val); ds@1952: ds@1952: return sp_ftoc(val); ds@1952: } ds@1952: ds@1952: static cell_t sm_ArcTangent(IPluginContext *pCtx, const cell_t *params) ds@1952: { ds@1952: float val = sp_ctof(params[1]); ds@1952: val = atan(val); ds@1952: ds@1952: return sp_ftoc(val); ds@1952: } ds@1952: ds@1952: static cell_t sm_ArcTangent2(IPluginContext *pCtx, const cell_t *params) ds@1952: { ds@1952: float val1 = sp_ctof(params[1]); ds@1952: float val2 = sp_ctof(params[2]); ds@1952: val1 = atan2(val1, val2); ds@1952: ds@1952: return sp_ftoc(val1); ds@1952: } ds@1952: ds@1952: #if 0 ds@1952: static cell_t sm_FloatRound(IPluginContext *pCtx, const cell_t *params) ds@1952: { ds@1952: float val = sp_ctof(params[1]); ds@1952: ds@1952: switch (params[2]) ds@1952: { ds@1952: case 1: ds@1952: { ds@1952: val = floor(val); ds@1952: break; ds@1952: } ds@1952: case 2: ds@1952: { ds@1952: val = ceil(val); ds@1952: break; ds@1952: } ds@1952: case 3: ds@1952: { ds@1952: if (val >= 0.0f) ds@1952: { ds@1952: val = floor(val); ds@1952: } else { ds@1952: val = ceil(val); ds@1952: } ds@1952: break; ds@1952: } ds@1952: default: ds@1952: { ds@1952: val = (float)floor(val + 0.5f); ds@1952: break; ds@1952: } ds@1952: } ds@1952: ds@1952: return static_cast(val); ds@1952: } ds@1952: #endif ds@1952: ds@1952: REGISTER_NATIVES(floatnatives) ds@1952: { ds@1952: {"float", sm_float}, ds@1952: {"FloatMul", sm_FloatMul}, ds@1952: {"FloatDiv", sm_FloatDiv}, ds@1952: {"FloatAdd", sm_FloatAdd}, ds@1952: {"FloatSub", sm_FloatSub}, ds@1952: {"FloatFraction", sm_FloatFraction}, ds@1952: {"RoundToZero", sm_RoundToZero}, ds@1952: {"RoundToCeil", sm_RoundToCeil}, ds@1952: {"RoundToFloor", sm_RoundToFloor}, ds@1952: {"RoundToNearest", sm_RoundToNearest}, ds@1952: {"FloatCompare", sm_FloatCompare}, ds@1952: {"SquareRoot", sm_SquareRoot}, ds@1952: {"Pow", sm_Pow}, ds@1952: {"Exponential", sm_Exponential}, ds@1952: {"Logarithm", sm_Logarithm}, ds@1952: {"Sine", sm_Sine}, ds@1952: {"Cosine", sm_Cosine}, ds@1952: {"Tangent", sm_Tangent}, ds@1952: {"FloatAbs", sm_FloatAbs}, ds@1952: {"ArcTangent", sm_ArcTangent}, ds@1952: {"ArcCosine", sm_ArcCosine}, ds@1952: {"ArcSine", sm_ArcSine}, ds@1952: {"ArcTangent2", sm_ArcTangent2}, ds@1952: {NULL, NULL} ds@1952: };