More Windows build fix.
2 * vim: set ts=4 sw=4 tw=99 :
3 * =============================================================================
5 * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
6 * =============================================================================
8 * This program is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, version 3.0, as published by the
10 * Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
20 * As a special exception, AlliedModders LLC gives you permission to link the
21 * code of this program (as well as its derivative works) to "Half-Life 2," the
22 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
23 * by the Valve Corporation. You must obey the GNU General Public License in
24 * all respects for all other code used. Additionally, AlliedModders LLC grants
25 * this exception to all derivative works. AlliedModders LLC defines further
26 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
27 * or <http://www.sourcemod.net/license.php>.
35 #include "common_logic.h"
36 #include "MersenneTwister.h"
37 #include <IPluginSys.h>
39 /****************************************
41 * FLOATING POINT NATIVE IMPLEMENTATIONS *
43 ****************************************/
46 static cell_t sm_float(IPluginContext *pCtx, const cell_t *params)
48 float val = static_cast<float>(params[1]);
53 static cell_t sm_FloatAbs(IPluginContext *pCtx, const cell_t *params)
55 float val = sp_ctof(params[1]);
56 val = (val >= 0.0f) ? val : -val;
61 static cell_t sm_FloatAdd(IPluginContext *pCtx, const cell_t *params)
63 float val = sp_ctof(params[1]) + sp_ctof(params[2]);
68 static cell_t sm_FloatSub(IPluginContext *pCtx, const cell_t *params)
70 float val = sp_ctof(params[1]) - sp_ctof(params[2]);
75 static cell_t sm_FloatMul(IPluginContext *pCtx, const cell_t *params)
77 float val = sp_ctof(params[1]) * sp_ctof(params[2]);
82 static cell_t sm_FloatDiv(IPluginContext *pCtx, const cell_t *params)
84 float val = sp_ctof(params[1]) / sp_ctof(params[2]);
89 static cell_t sm_FloatCompare(IPluginContext *pCtx, const cell_t *params)
91 float val1 = sp_ctof(params[1]);
92 float val2 = sp_ctof(params[2]);
97 } else if (val1 < val2) {
104 static cell_t sm_Logarithm(IPluginContext *pCtx, const cell_t *params)
106 float val = sp_ctof(params[1]);
107 float base = sp_ctof(params[2]);
109 if ((val <= 0.0f) || (base <= 0.0f))
111 return pCtx->ThrowNativeError("Cannot evaluate the logarithm of zero or a negative number (val:%f base:%f)", val, base);
117 val = log(val) / log(base);
123 static cell_t sm_Exponential(IPluginContext *pCtx, const cell_t *params)
125 float val = sp_ctof(params[1]);
127 return sp_ftoc(exp(val));
130 static cell_t sm_Pow(IPluginContext *pCtx, const cell_t *params)
132 float base = sp_ctof(params[1]);
133 float exponent = sp_ctof(params[2]);
135 return sp_ftoc(pow(base, exponent));
138 static cell_t sm_SquareRoot(IPluginContext *pCtx, const cell_t *params)
140 float val = sp_ctof(params[1]);
144 return pCtx->ThrowNativeError("Cannot evaluate the square root of a negative number (val:%f)", val);
147 return sp_ftoc(sqrt(val));
150 static cell_t sm_RoundToNearest(IPluginContext *pCtx, const cell_t *params)
152 float val = sp_ctof(params[1]);
153 val = (float)floor(val + 0.5f);
155 return static_cast<int>(val);
158 static cell_t sm_RoundToFloor(IPluginContext *pCtx, const cell_t *params)
160 float val = sp_ctof(params[1]);
163 return static_cast<int>(val);
166 static cell_t sm_RoundToCeil(IPluginContext *pCtx, const cell_t *params)
168 float val = sp_ctof(params[1]);
171 return static_cast<int>(val);
174 static cell_t sm_RoundToZero(IPluginContext *pCtx, const cell_t *params)
176 float val = sp_ctof(params[1]);
184 return static_cast<int>(val);
187 static cell_t sm_FloatFraction(IPluginContext *pCtx, const cell_t *params)
189 float val = sp_ctof(params[1]);
190 val = val - floor(val);
195 static cell_t sm_Sine(IPluginContext *pCtx, const cell_t *params)
197 float val = sp_ctof(params[1]);
203 static cell_t sm_Cosine(IPluginContext *pCtx, const cell_t *params)
205 float val = sp_ctof(params[1]);
211 static cell_t sm_Tangent(IPluginContext *pCtx, const cell_t *params)
213 float val = sp_ctof(params[1]);
219 static cell_t sm_ArcSine(IPluginContext *pCtx, const cell_t *params)
221 float val = sp_ctof(params[1]);
227 static cell_t sm_ArcCosine(IPluginContext *pCtx, const cell_t *params)
229 float val = sp_ctof(params[1]);
235 static cell_t sm_ArcTangent(IPluginContext *pCtx, const cell_t *params)
237 float val = sp_ctof(params[1]);
243 static cell_t sm_ArcTangent2(IPluginContext *pCtx, const cell_t *params)
245 float val1 = sp_ctof(params[1]);
246 float val2 = sp_ctof(params[2]);
247 val1 = atan2(val1, val2);
249 return sp_ftoc(val1);
253 static cell_t sm_FloatRound(IPluginContext *pCtx, const cell_t *params)
255 float val = sp_ctof(params[1]);
281 val = (float)floor(val + 0.5f);
286 return static_cast<int>(val);
290 class RandomHelpers :
291 public SMGlobalClass,
292 public IPluginsListener
295 void OnSourceModAllInitialized()
297 pluginsys->AddPluginsListener(this);
300 void OnSourceModShutdown()
302 pluginsys->RemovePluginsListener(this);
305 void OnPluginDestroyed(IPlugin *plugin)
308 if (plugin->GetProperty("core.logic.mtrand", (void**)&mtrand, true))
314 MTRand *RandObjForPlugin(IPluginContext *ctx)
316 IPlugin *plugin = pluginsys->FindPluginByContext(ctx->GetContext());
318 if (!plugin->GetProperty("core.logic.mtrand", (void**)&mtrand))
320 mtrand = new MTRand();
321 plugin->SetProperty("core.logic.mtrand", mtrand);
327 static cell_t GetURandomInt(IPluginContext *ctx, const cell_t *params)
329 MTRand *randobj = s_RandHelpers.RandObjForPlugin(ctx);
330 /* Note the sign bit must be stripped off because cell_t is signed,
331 * and this guarantees a range of [0,max_int]
333 return randobj->randInt() & 0x7FFFFFFF;
336 static cell_t GetURandomFloat(IPluginContext *ctx, const cell_t *params)
338 MTRand *randobj = s_RandHelpers.RandObjForPlugin(ctx);
339 return sp_ftoc((float)randobj->rand());
342 static cell_t SetURandomSeed(IPluginContext *ctx, const cell_t *params)
344 MTRand *randobj = s_RandHelpers.RandObjForPlugin(ctx);
346 ctx->LocalToPhysAddr(params[1], &addr);
347 /* We're 32-bit only. */
348 randobj->seed((MTRand::uint32*)addr, params[2]);
352 REGISTER_NATIVES(floatnatives)
355 {"FloatMul", sm_FloatMul},
356 {"FloatDiv", sm_FloatDiv},
357 {"FloatAdd", sm_FloatAdd},
358 {"FloatSub", sm_FloatSub},
359 {"FloatFraction", sm_FloatFraction},
360 {"RoundToZero", sm_RoundToZero},
361 {"RoundToCeil", sm_RoundToCeil},
362 {"RoundToFloor", sm_RoundToFloor},
363 {"RoundToNearest", sm_RoundToNearest},
364 {"FloatCompare", sm_FloatCompare},
365 {"SquareRoot", sm_SquareRoot},
367 {"Exponential", sm_Exponential},
368 {"Logarithm", sm_Logarithm},
370 {"Cosine", sm_Cosine},
371 {"Tangent", sm_Tangent},
372 {"FloatAbs", sm_FloatAbs},
373 {"ArcTangent", sm_ArcTangent},
374 {"ArcCosine", sm_ArcCosine},
375 {"ArcSine", sm_ArcSine},
376 {"ArcTangent2", sm_ArcTangent2},
377 {"GetURandomInt", GetURandomInt},
378 {"GetURandomFloat", GetURandomFloat},
379 {"SetURandomSeed", SetURandomSeed},