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