Files
TeslaRel410/restoration/source410/MUNGA/RANDOM.CPP
T
CydandClaude Fable 5 af80d52e22 source410: engine COMPLETE (165/165) - link reaches PE emission; deep ledger cut
The tlink32 campaign after the checkpoint: eleven engine bodies back-dated
from BT412 (rotation player team explode dropzone terrain cultural receiver
subsystm app l4gauge - the Application core included), the WinTesla-ectomy
handled by backdate.py's new unwrap rules (accessor-fn statics -> 1995 static
objects, decl rewrites, pointer->reference Derivation ctor, 2007 windowed-
gauge/console-marshal/idle-pump excisions), staged statics TUs opened for the
game classes (MECH/BTPLAYER/BTDIRECT/PROJTILE/MISSILE/BTL4MPPR .CPP + L4APP/
NETWORK engine statics).

State: every compiled symbol short of the shallow graph RESOLVED (the 52- and
17-symbol ledgers burned to zero); with 32stub.exe in place the linker reaches
full vtable closure and emits the deep ledger (~210 symbols, UNRESOLVED-
LEDGER.txt): remaining engine bodies (objstrm cstr gauge/gaugrend graphics
pixelmap palette resfile ray scnrole explosion-table), the DOS driver extern
layer (_SVGA*/_PCSerial*/_PCSPAK*/joystick/netnub/sosMIDI), the full L4App
body, and the real game-TU frontier (Mech::Make et al.). Recipe proven for
every category.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-19 11:25:49 -05:00

181 lines
4.9 KiB
C++

# if !defined(MUNGA_HPP)
# include <munga.hpp>
# endif
#pragma hdrstop
# if !defined(RANDOM_HPP)
# include <random.hpp>
# endif
int RandomGenerator::Numbers[250];
int RandomGenerator::Index = -1;
RandomGenerator Random;
//
//###########################################################################
//###########################################################################
//
void RandomGenerator::Init()
{
int i, msb, mask;
//
//--------------------------------------------------------------------
// After making sure the table is built only once, initialize the
// Borland C++ random numbers with the low word of the current time in
// milliseconds, and initialize the index pointer
//--------------------------------------------------------------------
//
char *seed_spec = getenv("RANDOM");
unsigned seed;
if (seed_spec)
{
seed = (unsigned)atol(seed_spec);
}
else
{
seed = (unsigned)time(NULL);
}
#if defined(TEST_CLASS)
cout << "Random Seed = " << seed << endl;
#endif
srand(seed);
Index = 0;
//
//------------------------------------------------------------------
// Load the random number buffer, then go thru and set the sign bit
// randomly, increasing the range of random numbers from 0..32767 to
// 0..65535
//------------------------------------------------------------------
//
for (i=0; i<250; i++)
{
Numbers[i] = rand();
}
//
//--------------------------------------------------------------------
// In order to preserve a good random number mix for the XOR function,
// mask and set the bits of 16 words in a descending manner as in
// 1xx..., 01xx..., 001xx..., 0001xx..., ...
//--------------------------------------------------------------------
//
mask = RAND_MAX >> 1;
msb = mask + 1;
int rand_size;
for (rand_size=0; !(msb&(1<<rand_size)); ++rand_size);
i = 14;
while (rand_size--)
{
Verify(i<ELEMENTS(Numbers));
Numbers[i] &= mask;
Numbers[i] |= msb;
mask >>= 1;
msb >>= 1;
i += 11;
}
}
//
//###########################################################################
//###########################################################################
//
int RandomGenerator::GetRandomInt()
{
int indent, result;
//
//------------------------------------------------------------------
// The random number generated will be the result of an XOR with the
// element 103 positions further (wrapping around) in the table
//------------------------------------------------------------------
//
indent = (Index>=147)?Index-147:Index+103;
result = Numbers[Index]^Numbers[indent];
//
//------------------------------------------------------------------------
// Replace the current random number with the new one generated, increment
// the buffer index pointer, and return the number
//------------------------------------------------------------------------
//
Numbers[Index] = result;
if (++Index == ELEMENTS(Numbers))
Index=0;
return result;
}
//
//###########################################################################
//###########################################################################
//
RandomGenerator::operator Scalar()
{
Scalar result;
result = GetRandomInt();
result /= (float)(RAND_MAX + 1);
return result;
}
//
//###########################################################################
//###########################################################################
//
int RandomGenerator::operator ()(int range)
{
int result, max;
max = RAND_MAX - ((RAND_MAX + 1)%range);
do
{
result = GetRandomInt();
} while (result>max);
return result%range;
}
//
//###########################################################################
//###########################################################################
//
Die::Die(int n)
{
dieSides = (n>1)?n:2;
highestRandom = RAND_MAX - ((RAND_MAX+1)%dieSides);
}
//
//###########################################################################
//###########################################################################
//
Die::operator int()
{
int result;
//
//------------------------------------------------------------------------
// In order to not skew the probabilities to the low numbers, make sure
// that the random # used is not greater than the limit determined for the
// number of sides.
//------------------------------------------------------------------------
//
do
{
result = Random.GetInt();
} while (result>highestRandom);
//
//-------------------------------------------------------------------
// Once the base random number is determined, do modulus division and
// increment by 1 to map into the die range.
//-------------------------------------------------------------------
//
return result % dieSides + 1;
}
#if defined(TEST_CLASS)
#include "random.tcp"
#endif