Changeset - r2073:6be1dac46f17
[Not reviewed]
master
0 9 1
ludde - 19 years ago 2005-07-15 20:29:06
ludde@openttd.org
(svn r2583) Move OS specific code out of misc.c
Added support for Mersenne Twister random number generator (not implemented in network yet)
Wrap player randoms around #ifdef
10 files changed with 173 insertions and 56 deletions:
0 comments (0 inline, 0 general)
functions.h
Show inline comments
 
@@ -93,6 +93,21 @@ void NORETURN CDECL error(const char *st
 

	
 
//#define RANDOM_DEBUG
 

	
 

	
 
// Enable this to produce higher quality random numbers.
 
// Doesn't work with network yet.
 
//#define MERSENNE_TWISTER
 

	
 
// Mersenne twister functions
 
void SeedMT(uint32 seed);
 
uint32 RandomMT(void);
 

	
 

	
 
#ifdef MERSENNE_TWISTER
 
	static inline uint32 Random(void) { return RandomMT(); }
 
	uint RandomRange(uint max);
 
#else
 

	
 
#ifdef RANDOM_DEBUG
 
	#define Random() DoRandom(__LINE__, __FILE__)
 
	uint32 DoRandom(int line, const char *file);
 
@@ -101,12 +116,18 @@ void NORETURN CDECL error(const char *st
 
#else
 
	uint32 Random(void);
 
	uint RandomRange(uint max);
 
#endif
 
#endif // MERSENNE_TWISTER
 

	
 
	static inline TileIndex RandomTileSeed(uint32 r) { return TILE_MASK(r); }
 
	static inline TileIndex RandomTile(void) { return TILE_MASK(Random()); }
 
static inline TileIndex RandomTileSeed(uint32 r) { return TILE_MASK(r); }
 
static inline TileIndex RandomTile(void) { return TILE_MASK(Random()); }
 

	
 

	
 
#ifdef PLAYER_SEED_RANDOM
 
void InitPlayerRandoms(void);
 
#endif
 

	
 
void InitPlayerRandoms(void);
 

	
 

	
 
uint32 InteractiveRandom(void); /* Used for random sequences that are not the same on the other end of the multiplayer link */
 
uint InteractiveRandomRange(uint max);
mersenne.c
Show inline comments
 
new file 100644
 
#include "stdafx.h"
 
#include "openttd.h"
 
 
#ifdef MERSENNE_TWISTER
 
 
// Source code for Mersenne Twister.
 
// A Random number generator with much higher quality random numbers.
 
 
#define N              (624)                 // length of _mt_state vector
 
#define M              (397)                 // a period parameter
 
#define K              (0x9908B0DFU)         // a magic constant
 
#define hiBit(u)       ((u) & 0x80000000U)   // mask all but highest   bit of u
 
#define loBit(u)       ((u) & 0x00000001U)   // mask all but lowest    bit of u
 
#define loBits(u)      ((u) & 0x7FFFFFFFU)   // mask     the highest   bit of u
 
#define mixBits(u, v)  (hiBit(u)|loBits(v))  // move hi bit of u to hi bit of v
 
 
static uint32   _mt_state[N+1];     // _mt_state vector + 1 extra to not violate ANSI C
 
static uint32   *_mt_next;          // _mt_next random value is computed from here
 
static int      _mt_left = -1;      // can *_mt_next++ this many times before reloading
 
 
void SeedMT(uint32 seed)
 
{
 
    register uint32 x = (seed | 1U) & 0xFFFFFFFFU, *s = _mt_state;
 
    register int    j;
 
 
    for(_mt_left=0, *s++=x, j=N; --j;
 
        *s++ = (x*=69069U) & 0xFFFFFFFFU);
 
 }
 
 
 
static uint32 ReloadMT(void)
 
 {
 
    register uint32 *p0=_mt_state, *p2=_mt_state+2, *pM=_mt_state+M, s0, s1;
 
    register int    j;
 
 
    if(_mt_left < -1)
 
        SeedMT(4357U);
 
 
    _mt_left=N-1, _mt_next=_mt_state+1;
 
 
    for(s0=_mt_state[0], s1=_mt_state[1], j=N-M+1; --j; s0=s1, s1=*p2++)
 
        *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
 
 
    for(pM=_mt_state, j=M; --j; s0=s1, s1=*p2++)
 
        *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
 
 
    s1=_mt_state[0], *p0 = *pM ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U);
 
    s1 ^= (s1 >> 11);
 
    s1 ^= (s1 <<  7) & 0x9D2C5680U;
 
    s1 ^= (s1 << 15) & 0xEFC60000U;
 
    return(s1 ^ (s1 >> 18));
 
 }
 
 
 
uint32 RandomMT(void)
 
{
 
	uint32 y;
 
 
	if(--_mt_left < 0)
 
		return ReloadMT();
 
 
	y  = *_mt_next++;
 
	y ^= (y >> 11);
 
	y ^= (y <<  7) & 0x9D2C5680U;
 
	y ^= (y << 15) & 0xEFC60000U;
 
	return y ^ (y >> 18);
 
}
 
#else
 
 
void SeedMT(uint32 seed) {}
 
 
#endif
 
\ No newline at end of file
misc.c
Show inline comments
 
@@ -29,13 +29,14 @@ static inline uint32 ROR(uint32 x, int n
 
     it completely! -- TrueLight */
 
#undef PLAYER_SEED_RANDOM
 

	
 
#ifndef MERSENNE_TWISTER
 

	
 
#ifdef RANDOM_DEBUG
 
#include "network_data.h"
 

	
 
uint32 DoRandom(int line, const char *file)
 
#else
 
#else // RANDOM_DEBUG
 
uint32 Random(void)
 
#endif
 
#endif // RANDOM_DEBUG
 
{
 

	
 
uint32 s;
 
@@ -66,8 +67,9 @@ uint32 t;
 
	return _random_seeds[0][1] = ROR(s, 3) - 1;
 
#endif
 
}
 
#endif // MERSENNE_TWISTER
 

	
 
#ifdef RANDOM_DEBUG
 
#if defined(RANDOM_DEBUG) && !defined(MERSENNE_TWISTER)
 
uint DoRandomRange(uint max, int line, const char *file)
 
{
 
	return (uint16)DoRandom(line, file) * max >> 16;
 
@@ -79,6 +81,7 @@ uint RandomRange(uint max)
 
}
 
#endif
 

	
 

	
 
uint32 InteractiveRandom(void)
 
{
 
	uint32 t = _random_seeds[1][1];
 
@@ -92,6 +95,8 @@ uint InteractiveRandomRange(uint max)
 
	return (uint16)InteractiveRandom() * max >> 16;
 
}
 

	
 

	
 
#ifdef PLAYER_SEED_RANDOM
 
void InitPlayerRandoms(void)
 
{
 
	int i;
 
@@ -100,6 +105,7 @@ void InitPlayerRandoms(void)
 
		_player_seeds[i][1]=InteractiveRandom();
 
	}
 
}
 
#endif
 

	
 
void SetDate(uint date)
 
{
 
@@ -112,55 +118,6 @@ void SetDate(uint date)
 
#endif /* ENABLE_NETWORK */
 
}
 

	
 

	
 
#ifdef ENABLE_NETWORK
 

	
 
// multi os compatible sleep function
 

	
 
#ifdef __AMIGA__
 
// usleep() implementation
 
#	include <devices/timer.h>
 
#	include <dos/dos.h>
 

	
 
	extern struct Device      *TimerBase    = NULL;
 
	extern struct MsgPort     *TimerPort    = NULL;
 
	extern struct timerequest *TimerRequest = NULL;
 
#endif // __AMIGA__
 

	
 
void CSleep(int milliseconds)
 
{
 
	#if defined(WIN32)
 
		Sleep(milliseconds);
 
	#endif
 
	#if defined(UNIX)
 
		#if !defined(__BEOS__) && !defined(__AMIGA__)
 
			usleep(milliseconds * 1000);
 
		#endif
 
		#ifdef __BEOS__
 
			snooze(milliseconds * 1000);
 
		#endif
 
		#if defined(__AMIGA__)
 
		{
 
			ULONG signals;
 
			ULONG TimerSigBit = 1 << TimerPort->mp_SigBit;
 

	
 
			// send IORequest
 
			TimerRequest->tr_node.io_Command = TR_ADDREQUEST;
 
			TimerRequest->tr_time.tv_secs    = (milliseconds * 1000) / 1000000;
 
			TimerRequest->tr_time.tv_micro   = (milliseconds * 1000) % 1000000;
 
			SendIO((struct IORequest *)TimerRequest);
 

	
 
			if (!((signals = Wait(TimerSigBit | SIGBREAKF_CTRL_C)) & TimerSigBit) ) {
 
				AbortIO((struct IORequest *)TimerRequest);
 
			}
 
			WaitIO((struct IORequest *)TimerRequest);
 
		}
 
		#endif // __AMIGA__
 
	#endif
 
}
 

	
 
#endif /* ENABLE_NETWORK */
 

	
 
void InitializeVehicles(void);
 
void InitializeWaypoints(void);
 
void InitializeDepot(void);
network.c
Show inline comments
 
@@ -773,7 +773,9 @@ static void NetworkInitialize(void)
 

	
 
	_network_reconnect = 0;
 

	
 
#ifdef PLAYER_SEED_RANDOM
 
	InitPlayerRandoms();
 
#endif
 

	
 
	NetworkUDPInitialize();
 
}
network_client.c
Show inline comments
 
@@ -488,11 +488,13 @@ DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER
 
	// Check if this was the last packet
 
	if (maptype == MAP_PACKET_END) {
 
		// We also get, very nice, the player_seeds in this packet
 
#ifdef PLAYER_SEED_RANDOM
 
		int i;
 
		for (i = 0; i < MAX_PLAYERS; i++) {
 
			_player_seeds[i][0] = NetworkRecv_uint32(MY_CLIENT, p);
 
			_player_seeds[i][1] = NetworkRecv_uint32(MY_CLIENT, p);
 
		}
 
#endif
 

	
 
		fclose(file_pointer);
 

	
network_server.c
Show inline comments
 
@@ -323,7 +323,9 @@ DEF_SERVER_SEND_COMMAND(PACKET_SERVER_MA
 
			NetworkSend_Packet(p, cs);
 
			if (feof(file_pointer)) {
 
				// Done reading!
 
#ifdef PLAYER_SEED_RANDOM
 
				int i;
 
#endif
 
				Packet *p;
 

	
 
				// XXX - Delete this when patch-settings are saved in-game
 
@@ -331,11 +333,13 @@ DEF_SERVER_SEND_COMMAND(PACKET_SERVER_MA
 

	
 
				p = NetworkSend_Init(PACKET_SERVER_MAP);
 
				NetworkSend_uint8(p, MAP_PACKET_END);
 
#ifdef PLAYER_SEED_RANDOM
 
				// Send the player_seeds in this packet
 
				for (i = 0; i < MAX_PLAYERS; i++) {
 
					NetworkSend_uint32(p, _player_seeds[i][0]);
 
					NetworkSend_uint32(p, _player_seeds[i][1]);
 
				}
 
#endif
 
				NetworkSend_Packet(p, cs);
 

	
 
				// Set the status to DONE_MAP, no we will wait for the client
openttd.c
Show inline comments
 
@@ -676,7 +676,9 @@ int ttd_main(int argc, char* argv[])
 
	InitializeGUI();
 
	IConsoleCmdExec("exec scripts/autoexec.scr 0");
 

	
 
#ifdef PLAYER_SEED_RANDOM
 
	InitPlayerRandoms();
 
#endif
 

	
 
	GenerateWorld(1, 64, 64); // Make the viewport initialization happy
 

	
unix.c
Show inline comments
 
@@ -474,6 +474,7 @@ int CDECL main(int argc, char* argv[])
 
#endif
 

	
 
	_random_seeds[0][1] = _random_seeds[0][0] = time(NULL);
 
	SeedMT(_random_seeds[0][1]);
 

	
 
	signal(SIGPIPE, SIG_IGN);
 

	
 
@@ -581,3 +582,49 @@ void JoinOTTDThread(void)
 

	
 
	pthread_join(thread1, NULL);
 
}
 

	
 

	
 

	
 
#ifdef ENABLE_NETWORK
 

	
 
// multi os compatible sleep function
 

	
 
#ifdef __AMIGA__
 
// usleep() implementation
 
#	include <devices/timer.h>
 
#	include <dos/dos.h>
 

	
 
	extern struct Device      *TimerBase    = NULL;
 
	extern struct MsgPort     *TimerPort    = NULL;
 
	extern struct timerequest *TimerRequest = NULL;
 
#endif // __AMIGA__
 

	
 
void CSleep(int milliseconds)
 
{
 
	#if !defined(__BEOS__) && !defined(__AMIGA__)
 
		usleep(milliseconds * 1000);
 
	#endif
 
	#ifdef __BEOS__
 
		snooze(milliseconds * 1000);
 
	#endif
 
	#if defined(__AMIGA__)
 
	{
 
		ULONG signals;
 
		ULONG TimerSigBit = 1 << TimerPort->mp_SigBit;
 

	
 
		// send IORequest
 
		TimerRequest->tr_node.io_Command = TR_ADDREQUEST;
 
		TimerRequest->tr_time.tv_secs    = (milliseconds * 1000) / 1000000;
 
		TimerRequest->tr_time.tv_micro   = (milliseconds * 1000) % 1000000;
 
		SendIO((struct IORequest *)TimerRequest);
 

	
 
		if (!((signals = Wait(TimerSigBit | SIGBREAKF_CTRL_C)) & TimerSigBit) ) {
 
			AbortIO((struct IORequest *)TimerRequest);
 
		}
 
		WaitIO((struct IORequest *)TimerRequest);
 
	}
 
	#endif // __AMIGA__
 
}
 

	
 
#endif /* ENABLE_NETWORK */
 

	
variables.h
Show inline comments
 
@@ -82,7 +82,10 @@ VARDEF uint16 _disaster_delay;
 
VARDEF uint16 _station_tick_ctr;
 

	
 
VARDEF uint32 _random_seeds[2][2];
 

	
 
#ifdef PLAYER_SEED_RANDOM
 
VARDEF uint32 _player_seeds[MAX_PLAYERS][2];
 
#endif
 

	
 
// Iterator through all towns in OnTick_Town
 
VARDEF uint32 _cur_town_ctr;
win32.c
Show inline comments
 
@@ -2124,6 +2124,7 @@ int APIENTRY WinMain(HINSTANCE hInstance
 
	_random_seeds[0][0] = GetTickCount();
 
	_random_seeds[0][1] = _random_seeds[0][0] * 0x1234567;
 
#endif
 
	SeedMT(_random_seeds[0][0]);
 

	
 
	argc = ParseCommandLine(GetCommandLine(), argv, lengthof(argv));
 

	
 
@@ -2263,3 +2264,9 @@ void JoinOTTDThread(void)
 

	
 
	WaitForSingleObject(hThread, INFINITE);
 
}
 

	
 

	
 
void CSleep(int milliseconds)
 
{
 
	Sleep(milliseconds);
 
}
 
\ No newline at end of file
0 comments (0 inline, 0 general)