core/smn_float.cpp
author Borja Ferrer <faluco@alliedmods.net>
Sat Feb 23 20:18:49 2008 +0000 (2008-02-23)
changeset 1894 e6efc8ffa47a
parent 1330 ab94316bb52b
child 1936 89d6e5038933
permissions -rw-r--r--
Executable memory is now provided by MM:S's allocator, this should reduce virtual memory usage.
dvander@370
     1
/**
ds@653
     2
 * vim: set ts=4 :
ds@1330
     3
 * =============================================================================
dvander@1231
     4
 * SourceMod
dvander@1231
     5
 * Copyright (C) 2004-2007 AlliedModders LLC.  All rights reserved.
ds@1330
     6
 * =============================================================================
dvander@370
     7
 *
ds@1330
     8
 * This program is free software; you can redistribute it and/or modify it under
ds@1330
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
ds@1330
    10
 * Free Software Foundation.
dvander@1231
    11
 * 
ds@1330
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
ds@1330
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
ds@1330
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
ds@1330
    15
 * details.
dvander@1231
    16
 *
ds@1330
    17
 * You should have received a copy of the GNU General Public License along with
ds@1330
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
dvander@1231
    19
 *
ds@1330
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
ds@1330
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
ds@1330
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
ds@1330
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
ds@1330
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
ds@1330
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
ds@1330
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
ds@1330
    27
 * or <http://www.sourcemod.net/license.php>.
dvander@370
    28
 *
dvander@370
    29
 * Version: $Id$
dvander@370
    30
 */
dvander@370
    31
faluco@225
    32
#include <math.h>
dvander@464
    33
#include <string.h>
dvander@464
    34
#include <stdlib.h>
ds@432
    35
#include "sm_globals.h"
faluco@225
    36
faluco@225
    37
/****************************************
faluco@225
    38
*                                       *
faluco@225
    39
* FLOATING POINT NATIVE IMPLEMENTATIONS *
faluco@225
    40
*                                       *
faluco@225
    41
****************************************/
faluco@225
    42
faluco@225
    43
faluco@225
    44
static cell_t sm_float(IPluginContext *pCtx, const cell_t *params)
faluco@225
    45
{
faluco@225
    46
	float val = static_cast<float>(params[1]);
faluco@225
    47
dvander@233
    48
	return sp_ftoc(val);
faluco@225
    49
}
faluco@225
    50
faluco@260
    51
static cell_t sm_FloatAbs(IPluginContext *pCtx, const cell_t *params)
faluco@225
    52
{
dvander@233
    53
	float val = sp_ctof(params[1]);
faluco@831
    54
	val = (val >= 0.0f) ? val : -val;
faluco@225
    55
dvander@233
    56
	return sp_ftoc(val);
faluco@225
    57
}
faluco@225
    58
faluco@260
    59
static cell_t sm_FloatAdd(IPluginContext *pCtx, const cell_t *params)
faluco@225
    60
{
dvander@233
    61
	float val = sp_ctof(params[1]) + sp_ctof(params[2]);
faluco@225
    62
dvander@233
    63
	return sp_ftoc(val);
faluco@225
    64
}
faluco@225
    65
faluco@260
    66
static cell_t sm_FloatSub(IPluginContext *pCtx, const cell_t *params)
faluco@225
    67
{
dvander@233
    68
	float val = sp_ctof(params[1]) - sp_ctof(params[2]);
faluco@225
    69
dvander@233
    70
	return sp_ftoc(val);
faluco@225
    71
}
faluco@225
    72
faluco@260
    73
static cell_t sm_FloatMul(IPluginContext *pCtx, const cell_t *params)
faluco@225
    74
{
dvander@233
    75
	float val = sp_ctof(params[1]) * sp_ctof(params[2]);
faluco@225
    76
dvander@233
    77
	return sp_ftoc(val);
faluco@225
    78
}
faluco@225
    79
faluco@260
    80
static cell_t sm_FloatDiv(IPluginContext *pCtx, const cell_t *params)
faluco@225
    81
{
dvander@233
    82
	float val = sp_ctof(params[1]) / sp_ctof(params[2]);
faluco@225
    83
dvander@233
    84
	return sp_ftoc(val);
faluco@225
    85
}
faluco@225
    86
faluco@260
    87
static cell_t sm_FloatCompare(IPluginContext *pCtx, const cell_t *params)
faluco@225
    88
{
dvander@233
    89
	float val1 = sp_ctof(params[1]);
dvander@233
    90
	float val2 = sp_ctof(params[2]);
faluco@225
    91
faluco@225
    92
	if (val1 > val2)
faluco@225
    93
	{
faluco@225
    94
		return 1;
faluco@225
    95
	} else if (val1 < val2) {
faluco@225
    96
		return -1;
faluco@225
    97
	}
faluco@225
    98
faluco@225
    99
	return 0;
faluco@225
   100
}
faluco@225
   101
faluco@260
   102
static cell_t sm_Logarithm(IPluginContext *pCtx, const cell_t *params)
faluco@225
   103
{
dvander@233
   104
	float val = sp_ctof(params[1]);
dvander@233
   105
	float base = sp_ctof(params[2]);
faluco@225
   106
faluco@831
   107
	if ((val <= 0.0f) || (base <= 0.0f))
faluco@225
   108
	{
ds@470
   109
		return pCtx->ThrowNativeError("Cannot evaluate the logarithm of zero or a negative number (val:%f base:%f)", val, base);
faluco@225
   110
	}
faluco@831
   111
	if (base == 10.0f)
faluco@225
   112
	{
faluco@225
   113
		val = log10(val);
faluco@225
   114
	} else {
faluco@225
   115
		val = log(val) / log(base);
faluco@225
   116
	}
faluco@225
   117
dvander@233
   118
	return sp_ftoc(val);
faluco@225
   119
}
faluco@225
   120
faluco@260
   121
static cell_t sm_Exponential(IPluginContext *pCtx, const cell_t *params)
faluco@225
   122
{
dvander@233
   123
	float val = sp_ctof(params[1]);
faluco@225
   124
dvander@233
   125
	return sp_ftoc(exp(val));
faluco@225
   126
}
faluco@225
   127
faluco@260
   128
static cell_t sm_Pow(IPluginContext *pCtx, const cell_t *params)
faluco@225
   129
{
dvander@233
   130
	float base = sp_ctof(params[1]);
dvander@233
   131
	float exponent = sp_ctof(params[2]);
faluco@225
   132
dvander@233
   133
	return sp_ftoc(pow(base, exponent));
faluco@225
   134
}
faluco@225
   135
faluco@260
   136
static cell_t sm_SquareRoot(IPluginContext *pCtx, const cell_t *params)
faluco@225
   137
{
dvander@233
   138
	float val = sp_ctof(params[1]);
faluco@225
   139
faluco@831
   140
	if (val < 0.0f)
faluco@225
   141
	{
ds@470
   142
		return pCtx->ThrowNativeError("Cannot evaluate the square root of a negative number (val:%f)", val);
faluco@225
   143
	}
faluco@225
   144
dvander@233
   145
	return sp_ftoc(sqrt(val));
faluco@225
   146
}
faluco@225
   147
faluco@851
   148
static cell_t sm_RoundToNearest(IPluginContext *pCtx, const cell_t *params)
faluco@831
   149
{
faluco@831
   150
	float val = sp_ctof(params[1]);
faluco@831
   151
	val = (float)floor(val + 0.5f);
faluco@831
   152
faluco@831
   153
	return static_cast<int>(val);
faluco@831
   154
}
faluco@831
   155
faluco@831
   156
static cell_t sm_RoundToFloor(IPluginContext *pCtx, const cell_t *params)
faluco@225
   157
{
dvander@233
   158
	float val = sp_ctof(params[1]);
faluco@831
   159
	val = floor(val);
faluco@225
   160
faluco@831
   161
	return static_cast<int>(val);
faluco@831
   162
}
faluco@831
   163
faluco@831
   164
static cell_t sm_RoundToCeil(IPluginContext *pCtx, const cell_t *params)
faluco@831
   165
{
faluco@831
   166
	float val = sp_ctof(params[1]);
faluco@831
   167
	val = ceil(val);
faluco@831
   168
faluco@831
   169
	return static_cast<int>(val);
faluco@831
   170
}
faluco@831
   171
faluco@831
   172
static cell_t sm_RoundToZero(IPluginContext *pCtx, const cell_t *params)
faluco@831
   173
{
faluco@831
   174
	float val = sp_ctof(params[1]);
faluco@831
   175
	if (val >= 0.0f)
faluco@225
   176
	{
faluco@831
   177
		val = floor(val);
faluco@831
   178
	} else {
faluco@831
   179
		val = ceil(val);
faluco@225
   180
	}
faluco@225
   181
faluco@242
   182
	return static_cast<int>(val);
faluco@225
   183
}
faluco@225
   184
faluco@260
   185
static cell_t sm_FloatFraction(IPluginContext *pCtx, const cell_t *params)
faluco@225
   186
{
dvander@233
   187
	float val = sp_ctof(params[1]);
faluco@225
   188
	val = val - floor(val);
faluco@225
   189
dvander@233
   190
	return sp_ftoc(val);
faluco@225
   191
}
faluco@225
   192
faluco@260
   193
static cell_t sm_Sine(IPluginContext *pCtx, const cell_t *params)
faluco@225
   194
{
dvander@233
   195
	float val = sp_ctof(params[1]);
faluco@235
   196
	val = sin(val);
faluco@225
   197
dvander@233
   198
	return sp_ftoc(val);
faluco@225
   199
}
faluco@225
   200
faluco@260
   201
static cell_t sm_Cosine(IPluginContext *pCtx, const cell_t *params)
faluco@225
   202
{
dvander@233
   203
	float val = sp_ctof(params[1]);
faluco@235
   204
	val = cos(val);
faluco@225
   205
dvander@233
   206
	return sp_ftoc(val);
faluco@225
   207
}
faluco@225
   208
faluco@260
   209
static cell_t sm_Tangent(IPluginContext *pCtx, const cell_t *params)
faluco@225
   210
{
dvander@233
   211
	float val = sp_ctof(params[1]);
faluco@235
   212
	val = tan(val);
faluco@225
   213
dvander@233
   214
	return sp_ftoc(val);
faluco@225
   215
}
faluco@225
   216
faluco@260
   217
static cell_t sm_ArcSine(IPluginContext *pCtx, const cell_t *params)
faluco@225
   218
{
dvander@233
   219
	float val = sp_ctof(params[1]);
faluco@225
   220
	val = asin(val);
faluco@225
   221
faluco@235
   222
	return sp_ftoc(val);
faluco@225
   223
}
faluco@225
   224
faluco@260
   225
static cell_t sm_ArcCosine(IPluginContext *pCtx, const cell_t *params)
faluco@225
   226
{
dvander@233
   227
	float val = sp_ctof(params[1]);
faluco@225
   228
	val = acos(val);
faluco@225
   229
faluco@235
   230
	return sp_ftoc(val);
faluco@225
   231
}
faluco@225
   232
faluco@260
   233
static cell_t sm_ArcTangent(IPluginContext *pCtx, const cell_t *params)
faluco@225
   234
{
dvander@233
   235
	float val = sp_ctof(params[1]);
faluco@225
   236
	val = atan(val);
faluco@225
   237
faluco@235
   238
	return sp_ftoc(val);
faluco@225
   239
}
faluco@225
   240
faluco@260
   241
static cell_t sm_ArcTangent2(IPluginContext *pCtx, const cell_t *params)
faluco@225
   242
{
dvander@233
   243
	float val1 = sp_ctof(params[1]);
dvander@233
   244
	float val2 = sp_ctof(params[2]);
faluco@225
   245
	val1 = atan2(val1, val2);
faluco@225
   246
faluco@235
   247
	return sp_ftoc(val1);
faluco@225
   248
}
faluco@260
   249
faluco@836
   250
static cell_t sm_FloatRound(IPluginContext *pCtx, const cell_t *params)
faluco@836
   251
{
faluco@836
   252
	float val = sp_ctof(params[1]);
faluco@836
   253
faluco@836
   254
	switch (params[2])
faluco@836
   255
	{
faluco@836
   256
	case 1:
faluco@836
   257
		{
faluco@836
   258
			val = floor(val);
faluco@836
   259
			break;
faluco@836
   260
		}
faluco@836
   261
	case 2:
faluco@836
   262
		{
faluco@836
   263
			val = ceil(val);
faluco@836
   264
			break;
faluco@836
   265
		}
faluco@836
   266
	case 3:
faluco@836
   267
		{
faluco@836
   268
			if (val >= 0.0f)
faluco@836
   269
			{
faluco@836
   270
				val = floor(val);
faluco@836
   271
			} else {
faluco@836
   272
				val = ceil(val);
faluco@836
   273
			}
faluco@836
   274
			break;
faluco@836
   275
		}
faluco@836
   276
	default:
faluco@836
   277
		{
faluco@836
   278
			val = (float)floor(val + 0.5f);
faluco@836
   279
			break;
faluco@836
   280
		}
faluco@836
   281
	}
faluco@836
   282
faluco@836
   283
	return static_cast<int>(val);
faluco@836
   284
}
faluco@836
   285
faluco@260
   286
REGISTER_NATIVES(floatnatives)
faluco@260
   287
{
faluco@260
   288
	{"float",			sm_float},
faluco@260
   289
	{"FloatMul",		sm_FloatMul},
faluco@260
   290
	{"FloatDiv",		sm_FloatDiv},
faluco@260
   291
	{"FloatAdd",		sm_FloatAdd},
faluco@260
   292
	{"FloatSub",		sm_FloatSub},
faluco@260
   293
	{"FloatFraction",	sm_FloatFraction},
faluco@831
   294
	{"RoundToZero",		sm_RoundToZero},
faluco@831
   295
	{"RoundToCeil",		sm_RoundToCeil},
faluco@831
   296
	{"RoundToFloor",	sm_RoundToFloor},
faluco@851
   297
	{"RoundToNearest",	sm_RoundToNearest},
faluco@260
   298
	{"FloatCompare",	sm_FloatCompare},
faluco@260
   299
	{"SquareRoot",		sm_SquareRoot},
faluco@260
   300
	{"Pow",				sm_Pow},
faluco@260
   301
	{"Exponential",		sm_Exponential},
faluco@260
   302
	{"Logarithm",		sm_Logarithm},
faluco@260
   303
	{"Sine",			sm_Sine},
faluco@260
   304
	{"Cosine",			sm_Cosine},
faluco@260
   305
	{"Tangent",			sm_Tangent},
faluco@260
   306
	{"FloatAbs",		sm_FloatAbs},
faluco@260
   307
	{"ArcTangent",		sm_ArcTangent},
faluco@260
   308
	{"ArcCosine",		sm_ArcCosine},
faluco@260
   309
	{"ArcSine",			sm_ArcSine},
faluco@260
   310
	{"ArcTangent2",		sm_ArcTangent2},
faluco@836
   311
	{"FloatRound",		sm_FloatRound},			/* Backwards compat shim */
faluco@260
   312
	{NULL,				NULL}
dvander@351
   313
};