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