T2-CPP/Mod Sources/RandomMod/BaseMod/randomCmds.cpp
2014-08-05 00:46:46 -04:00

169 lines
3.4 KiB
C++

#include "stdafx.h"
#include <math.h>
#include <cstdlib>
#include <stdio.h>
#include "mt.h"
#include "t2api.h"
// Merscenne Twister
MersenneTwister *mt = NULL;
const char *conMRandom(SimObject *obj, S32 argc, const char *argv[])
{
if (!mt)
{
mt = new MersenneTwister;
mt->init_genrand(time(NULL));
}
char mem[256];
memset(mem, 0x00, 255);
if (argc == 1)
{
sprintf_s(mem, 256, "%f", mt->random());
return mem;
}
char *a_c = (char*)argv[1];
char *b_c;
if (argc == 3)
b_c = (char*)argv[2];
else if (argc == 2)
{
b_c = a_c;
a_c = "0";
}
int a = atoi(a_c);
int b = atoi(b_c);
// Check to see if we have any negative arguments
if (a < 0)
{
int max = b + abs(a);
int rand = mt->genrand_int32() % (max);
if (rand > b)
rand = -(rand-b);
sprintf_s(mem, 256, "%d", rand);
return mem;
}
sprintf_s(mem, 256, "%f", floor(mt->random() * b + a));
return mem;
}
const char *conMRandomFloat(SimObject *obj, S32 argc, const char *argv[])
{
if (!mt)
{
mt = new MersenneTwister;
mt->init_genrand(time(NULL));
}
char mem[256];
memset(mem, 0x00, 255);
if (argc == 1)
{
sprintf_s(mem, 256, "%f", mt->random());
return mem;
}
char *a_c = (char*)argv[1];
char *b_c;
if (argc == 3)
b_c = (char*)argv[2];
else if (argc == 2)
{
b_c = a_c;
a_c = "0";
}
float a = atof(a_c);
float b = atof(b_c);
if (a > b)
{
int d = b;
b = a;
a = d;
}
sprintf_s(mem, 256, "%f", mt->random() * b + a);
return mem;
}
const char *conMSeed(SimObject *obj, S32 argc, const char *argv[])
{
if (!mt)
{
mt = new MersenneTwister;
mt->init_genrand(time(NULL));
}
const char *a_c = argv[1];
unsigned long a = 0;
unsigned int len = strlen(a_c);
for (unsigned int i = 0; i < len; i++)
if ( a_c[i] > 57 || a_c[i] < 48)
{
mt->init_by_array((unsigned long*)a_c, len+1);
return "1";
}
a = atof(a_c);
mt->init_genrand(a);
return "1";
}
#define QPC_MAX_STOPWATCHES 20
static unsigned int CURRENT_STOPWATCH_COUNT = 0;
static __int64 QPC_STOPWATCHES[QPC_MAX_STOPWATCHES];
__int64 STARTING_QPC_TIME;
const char*conQPCBegin(SimObject *obj, S32 argc, const char *argv[])
{
if (!QueryPerformanceCounter((LARGE_INTEGER*)&QPC_STOPWATCHES[CURRENT_STOPWATCH_COUNT]))
{
Con::errorf(0, "QPCBegin(): Failed to start timer! (%u)", GetLastError());
return "-1";
}
else if (CURRENT_STOPWATCH_COUNT >= QPC_MAX_STOPWATCHES)
{
Con::errorf(0, "QPCBegin(): Too many stopwatches active! (Maximum: %u)", QPC_MAX_STOPWATCHES);
return "-1";
}
unsigned int return_value = CURRENT_STOPWATCH_COUNT;
char result[256];
sprintf_s<256>(result, "%u", return_value);
CURRENT_STOPWATCH_COUNT++;
return result;
}
const char*conQPCEnd(SimObject *obj, S32 argc, const char *argv[])
{
__int64 ENDING_QPC_TIME;
if (!QueryPerformanceCounter((LARGE_INTEGER*)&ENDING_QPC_TIME))
{
Con::errorf(0, "QPCEnd(): Failed to stop timer! (%u)", GetLastError());
return "-1";
}
else if (CURRENT_STOPWATCH_COUNT == 0)
{
Con::errorf(0, "QPCEnd(): No stopwatches to stop!");
return "-1";
}
__int64 qpc_frequency;
QueryPerformanceFrequency((LARGE_INTEGER*)&qpc_frequency);
char result[256];
sprintf_s<256>(result, "%f", ((QPC_STOPWATCHES[CURRENT_STOPWATCH_COUNT - 1]) - ENDING_QPC_TIME) * 1.0 / qpc_frequency);
CURRENT_STOPWATCH_COUNT--;
return result;
}