mirror of
https://github.com/nunuhara/xsystem4.git
synced 2026-09-22 23:18:01 +03:00
Math: Replace rand() with mt19937
On Windows RAND_MAX is 0x7fff, which makes Rand() and RandF() far too coarse. Use mt19937 instead so that seeded sequences reproduce the original engine's behavior.
This commit is contained in:
+30
-4
@@ -23,9 +23,23 @@
|
||||
#define M_PI (3.14159265358979323846)
|
||||
#endif
|
||||
|
||||
#include "system4/mt19937int.h"
|
||||
|
||||
#include "hll.h"
|
||||
#include "vm/page.h"
|
||||
|
||||
static struct mt19937 mt;
|
||||
static bool mt_initialized;
|
||||
|
||||
static uint32_t math_genrand(void)
|
||||
{
|
||||
if (!mt_initialized) {
|
||||
mt19937_init(&mt, 4357);
|
||||
mt_initialized = true;
|
||||
}
|
||||
return mt19937_genrand(&mt);
|
||||
}
|
||||
|
||||
struct shuffle_table {
|
||||
int id;
|
||||
struct shuffle_table *next;
|
||||
@@ -64,9 +78,16 @@ static float Math_Tan(float x)
|
||||
return tanf(deg2rad(x));
|
||||
}
|
||||
|
||||
static void Math_SetSeed(int seed)
|
||||
{
|
||||
mt19937_init(&mt, (uint32_t)seed | 1);
|
||||
mt19937_genrand(&mt); // the original engine discards the first value
|
||||
mt_initialized = true;
|
||||
}
|
||||
|
||||
static void Math_SetSeedByCurrentTime(void)
|
||||
{
|
||||
srand(time(NULL));
|
||||
Math_SetSeed(time(NULL));
|
||||
}
|
||||
|
||||
static int Math_Min(int a, int b)
|
||||
@@ -105,9 +126,14 @@ static void Math_SwapF(float *a, float *b)
|
||||
|
||||
//void Math_SetRandMode(int mode);
|
||||
|
||||
static int Math_Rand(void)
|
||||
{
|
||||
return math_genrand() & 0x7fffffff;
|
||||
}
|
||||
|
||||
static float Math_RandF(void)
|
||||
{
|
||||
return rand() * (1.0 / (RAND_MAX + 1U));
|
||||
return (float)(math_genrand() * (1.0 / 4294967296.0));
|
||||
}
|
||||
|
||||
static void shuffle_array(int *a, int len)
|
||||
@@ -192,10 +218,10 @@ HLL_LIBRARY(Math,
|
||||
HLL_EXPORT(Abs, abs),
|
||||
HLL_EXPORT(AbsF, fabsf),
|
||||
HLL_EXPORT(Pow, powf),
|
||||
HLL_EXPORT(SetSeed, srand),
|
||||
HLL_EXPORT(SetSeed, Math_SetSeed),
|
||||
HLL_EXPORT(SetSeedByCurrentTime, Math_SetSeedByCurrentTime),
|
||||
//HLL_EXPORT(SetRandMode, Math_SetRandMode),
|
||||
HLL_EXPORT(Rand, rand),
|
||||
HLL_EXPORT(Rand, Math_Rand),
|
||||
HLL_EXPORT(RandF, Math_RandF),
|
||||
HLL_EXPORT(RandTableInit, Math_RandTableInit),
|
||||
HLL_EXPORT(RandTable, Math_RandTable),
|
||||
|
||||
Binary file not shown.
@@ -31,6 +31,25 @@ void test_math(void)
|
||||
test_float("Math.SwapF(a, b), a", fa, 2.0);
|
||||
test_float("Math.SwapF(a, b), b", fb, 1.0);
|
||||
|
||||
// The default seed is 4357. This must run before any other random
|
||||
// number is drawn.
|
||||
test_equal("Math.Rand() #1 (default seed)", Math.Rand(), 1362922229);
|
||||
test_equal("Math.Rand() #2 (default seed)", Math.Rand(), 2143450242);
|
||||
|
||||
Math.SetSeed(12345);
|
||||
test_equal("Math.Rand() #1 (seed 12345)", Math.Rand(), 2120104832);
|
||||
test_equal("Math.Rand() #2 (seed 12345)", Math.Rand(), 377474682);
|
||||
|
||||
// SetSeed ORs the seed with 1.
|
||||
Math.SetSeed(12344);
|
||||
test_equal("Math.Rand() #1 (seed 12344)", Math.Rand(), 2120104832);
|
||||
test_equal("Math.Rand() #2 (seed 12344)", Math.Rand(), 377474682);
|
||||
|
||||
Math.SetSeed(12345);
|
||||
test_float("Math.RandF() #1", Math.RandF(), 0.993625);
|
||||
test_float("Math.RandF() #2", Math.RandF(), 0.587888);
|
||||
test_float("Math.RandF() #3", Math.RandF(), 0.857469);
|
||||
|
||||
Math.RandTableInit(42, 10);
|
||||
for (i = 0; i < 10; i++) {
|
||||
ar[Math.RandTable(42)] = 1;
|
||||
|
||||
Reference in New Issue
Block a user