Port randk() from baseq2

This commit is contained in:
Yamagi Burmeister 2012-06-27 14:34:56 +02:00
parent 6aeeda2a9d
commit e341087a80
5 changed files with 179 additions and 43 deletions

View file

@ -126,6 +126,9 @@ game_export_t *GetGameAPI (game_import_t *import)
globals.edict_size = sizeof(edict_t);
/* Seed the PRNG */
randk_seed();
return &globals;
}

View file

@ -604,8 +604,8 @@ extern edict_t *g_edicts;
#define LLOFS(x) (size_t)&(((level_locals_t *)NULL)->x)
#define CLOFS(x) (size_t)&(((gclient_t *)NULL)->x)
#define random() ((rand () & 0x7fff) / ((float)0x7fff))
#define crandom() (2.0 * (random() - 0.5))
#define random() ((randk() & 0x7fff) / ((float)0x7fff))
#define crandom() (2.0 * (random() - 0.5))
extern cvar_t *maxentities;
extern cvar_t *deathmatch;

View file

@ -7,8 +7,8 @@
* =======================================================================
*/
#ifndef COMMON_SHARED_H
#define COMMON_SHARED_H
#ifndef ROGUE_SHARED_H
#define ROGUE_SHARED_H
#include <assert.h>
#include <math.h>
@ -35,7 +35,12 @@ typedef enum {false, true} qboolean;
#define MAX_TOKEN_CHARS 128 /* max length of an individual token */
#define MAX_QPATH 64 /* max length of a quake game pathname */
#ifdef _WIN32
#define MAX_OSPATH 256 /* max length of a filesystem pathname (same as MAX_PATH) */
#else
#define MAX_OSPATH 128 /* max length of a filesystem pathname */
#endif
/* */
/* per-level limits */
@ -178,6 +183,8 @@ void Com_sprintf(char *dest, int size, char *fmt, ...);
void Com_PageInMemory(byte *buffer, int size);
char *strlwr ( char *s );
/* ============================================= */
/* portable case insensitive compare */
@ -209,6 +216,14 @@ void Info_RemoveKey(char *s, char *key);
void Info_SetValueForKey(char *s, char *key, char *value);
qboolean Info_Validate(char *s);
/* ============================================= */
/* Random number generator */
int randk(void);
float frandk(void);
float crandk(void);
void randk_seed(void);
/*
* ==============================================================
*
@ -221,7 +236,6 @@ extern int curtime; /* time returned by last Sys_Milliseconds */
int Sys_Milliseconds(void);
void Sys_Mkdir(char *path);
void Sys_Rmdir(char *path);
char *strlwr(char *s);
/* large block stack allocation routines */
@ -426,9 +440,9 @@ typedef enum
#define PMF_NO_PREDICTION 64 /* temporarily disables prediction (used for grappling hook) */
/* this structure needs to be communicated bit-accurate/
from the server to the client to guarantee that
prediction stays in sync, so no floats are used.
if any part of the game code modifies this struct, it
from the server to the client to guarantee that
prediction stays in sync, so no floats are used.
if any part of the game code modifies this struct, it
will result in a prediction error of some degree. */
typedef struct
{
@ -439,7 +453,7 @@ typedef struct
byte pm_flags; /* ducked, jump_held, etc */
byte pm_time; /* each unit = 8 ms */
short gravity;
short delta_angles[3]; /* add to command angles to get view direction
short delta_angles[3]; /* add to command angles to get view direction
changed by spawns, rotating objects, and teleporters */
} pmove_state_t;
@ -487,9 +501,9 @@ typedef struct
int (*pointcontents)(vec3_t point);
} pmove_t;
/* entity_state_t->effects
/* entity_state_t->effects
Effects are things handled on the client side (lights, particles,
frame animations) that happen constantly on the given entity.
frame animations) that happen constantly on the given entity.
An entity that has effects will be sent to the client even if
it has a zero index model. */
#define EF_ROTATE 0x00000001 /* rotate (bonus items) */
@ -748,7 +762,7 @@ typedef struct
#define MZ2_WIDOW_DISRUPTOR 148
#define MZ2_WIDOW_BLASTER 149
#define MZ2_WIDOW_RAIL 150
#define MZ2_WIDOW_PLASMABEAM 151
#define MZ2_WIDOW_PLASMABEAM 151
#define MZ2_CARRIER_MACHINEGUN_L2 152
#define MZ2_CARRIER_MACHINEGUN_R2 153
#define MZ2_WIDOW_RAIL_LEFT 154
@ -811,9 +825,9 @@ typedef struct
extern vec3_t monster_flash_offset[];
/* Temp entity events are for things that happen
at a location seperate from any existing entity.
Temporary entity messages are explicitly constructed
/* Temp entity events are for things that happen
at a location seperate from any existing entity.
Temporary entity messages are explicitly constructed
and broadcast. */
typedef enum
{
@ -884,7 +898,7 @@ typedef enum
#define SPLASH_BLOOD 6
/* sound channels:
channel 0 never willingly overrides
channel 0 never willingly overrides
other channels (1-7) allways override
a playing sound on that channel */
#define CHAN_AUTO 0
@ -960,8 +974,8 @@ typedef enum
#define ANGLE2SHORT(x) ((int)((x) * 65536 / 360) & 65535)
#define SHORT2ANGLE(x) ((x) * (360.0 / 65536))
/* config strings are a general means of communication from
the server to all connected clients. Each config string
/* config strings are a general means of communication from
the server to all connected clients. Each config string
can be at most MAX_QPATH characters. */
#define CS_NAME 0
#define CS_CDTRACK 1
@ -985,9 +999,9 @@ typedef enum
/* ============================================== */
/* entity_state_t->event values
entity events are for effects that take place reletive
to an existing entities origin. Very network efficient.
/* entity_state_t->event values
entity events are for effects that take place reletive
to an existing entities origin. Very network efficient.
All muzzle flashes really should be converted to events... */
typedef enum
{
@ -1001,8 +1015,8 @@ typedef enum
EV_OTHER_TELEPORT
} entity_event_t;
/* entity_state_t is the information conveyed from the server
in an update message about entities that the client will
/* entity_state_t is the information conveyed from the server
in an update message about entities that the client will
need to render in some way */
typedef struct entity_state_s
{
@ -1015,7 +1029,7 @@ typedef struct entity_state_s
int modelindex2, modelindex3, modelindex4; /* weapons, CTF flags, etc */
int frame;
int skinnum;
unsigned int effects;
unsigned int effects;
int renderfx;
int solid; /* for client side prediction, 8*(bits 0-4) is x/y radius */
/* 8*(bits 5-9) is z down distance, 8(bits10-15) is z up */
@ -1028,9 +1042,9 @@ typedef struct entity_state_s
/* ============================================== */
/* player_state_t is the information needed in addition to pmove_state_t
to rendered a view. There will only be 10 player_state_t sent each second,
but the number of pmove_state_t changes will be reletive to client
/* player_state_t is the information needed in addition to pmove_state_t
to rendered a view. There will only be 10 player_state_t sent each second,
but the number of pmove_state_t changes will be reletive to client
frame rates */
typedef struct
{
@ -1062,4 +1076,4 @@ extern int vidref_val;
size_t verify_fread(void *, size_t, size_t, FILE *);
size_t verify_fwrite(void *, size_t, size_t, FILE *);
#endif /* COMMON_SHARED_H */
#endif /* ROGUE_SHARED_H */

97
src/shared/rand.c Normal file
View file

@ -0,0 +1,97 @@
/*
* KISS PRNG (c) 2011 Shinobu
*
* This file was optained from zuttobenkyou.wordpress.com
* and modified by the Yamagi Quake II developers.
*
* LICENSE: Public domain
*
* =======================================================================
*
* KISS PRNG, as devised by Dr. George Marsaglia
*
* =======================================================================
*/
#include <stdint.h>
#define QSIZE 0x200000
#define CNG (cng = 6906969069ULL * cng + 13579)
#define XS (xs ^= (xs << 13), xs ^= (xs >> 17), xs ^= (xs << 43))
#define KISS (B64MWC() + CNG + XS)
static uint64_t QARY[QSIZE];
static int j;
static uint64_t carry;
static uint64_t xs;
static uint64_t cng;
uint64_t
B64MWC(void)
{
uint64_t t, x;
j = (j + 1) & (QSIZE - 1);
x = QARY[j];
t = (x << 28) + carry;
carry = (x >> 36) - (t < x);
return QARY[j] = t - x;
}
/*
* Generate a pseudorandom
* integer >0.
*/
int
randk(void)
{
int r;
r = (int)KISS;
r = (r < 0) ? (r * -1) : r;
return r;
}
/*
* Generate a pseudorandom
* signed float between
* 0 and 1.
*/
float
frandk(void)
{
return (randk()&32767)* (1.0/32767);
}
/* Generate a pseudorandom
* float between -1 and 1.
*/
float
crandk(void)
{
return (randk()&32767)* (2.0/32767) - 1;
}
/*
* Seeds the PRNG
*/
void
randk_seed(void)
{
uint64_t i;
/* Seed QARY[] with CNG+XS: */
for (i = 0; i < QSIZE; i++)
{
QARY[i] = CNG + XS;
}
/* Run through several rounds
to warm up the state */
for (i = 0; i < 256; i++)
{
randk();
}
}

View file

@ -6,6 +6,8 @@
* =======================================================================
*/
#include <ctype.h>
#include "../header/shared.h"
#define DEG2RAD(a) (a * M_PI) / 180.0F
@ -304,8 +306,8 @@ anglemod(float a)
int i;
vec3_t corners[2];
/*
* This is the slow, general version
/*
* This is the slow, general version
*/
int
BoxOnPlaneSide2(vec3_t emins, vec3_t emaxs, struct cplane_s *p)
@ -423,7 +425,7 @@ BoxOnPlaneSide(vec3_t emins, vec3_t emaxs, struct cplane_s *p)
p->normal[2] * emaxs[2];
break;
default:
dist1 = dist2 = 0;
dist1 = dist2 = 0;
break;
}
@ -756,7 +758,7 @@ COM_DefaultExtension(char *path, const char *extension)
qboolean bigendien;
/* can't just use function pointers, or dll linkage can
/* can't just use function pointers, or dll linkage can
mess up when qcommon is included in multiple places */
short (*_BigShort)(short l);
short (*_LittleShort)(short l);
@ -768,37 +770,37 @@ float (*_LittleFloat)(float l);
short
BigShort(short l)
{
return _BigShort(l);
return _BigShort(l);
}
short
LittleShort(short l)
{return
_LittleShort(l);
{
return _LittleShort(l);
}
int
BigLong(int l)
{
return _BigLong(l);
return _BigLong(l);
}
int
LittleLong(int l)
{
return _LittleLong(l);
return _LittleLong(l);
}
float
BigFloat(float l)
{
return _BigFloat(l);
return _BigFloat(l);
}
float
LittleFloat(float l)
{
return _LittleFloat(l);
return _LittleFloat(l);
}
short
@ -875,6 +877,7 @@ Swap_Init(void)
_LittleLong = LongNoSwap;
_BigFloat = FloatSwap;
_LittleFloat = FloatNoSwap;
Com_Printf("Byte ordering: little endian\n\n");
}
else
{
@ -885,11 +888,15 @@ Swap_Init(void)
_LittleLong = LongSwap;
_BigFloat = FloatNoSwap;
_LittleFloat = FloatSwap;
Com_Printf("Byte ordering: big endian\n\n");
}
if (LittleShort(*(short *)swaptest) != 1)
assert("Error in the endian conversion!");
}
/*
* does a varargs printf into a temp buffer, so I don't
* does a varargs printf into a temp buffer, so I don't
* need to have varargs versions of all text functions.
*/
char *
@ -1085,13 +1092,29 @@ Com_sprintf(char *dest, int size, char *fmt, ...)
if ((len >= size) || (len == size))
{
Com_Printf("Com_sprintf: overflow\n");
len = size - 1;
dest = NULL;
return;
}
bigbuffer[size - 1] = '\0';
strcpy(dest, bigbuffer);
}
char *
strlwr ( char *s )
{
char *p = s;
while ( *s )
{
*s = tolower( *s );
s++;
}
return ( p );
}
/*
* =====================================================================
*
@ -1109,7 +1132,7 @@ char *
Info_ValueForKey(char *s, char *key)
{
char pkey[512];
static char value[2][512]; /* use two buffers so compares
static char value[2][512]; /* use two buffers so compares
work without stomping on each other */
static int valueindex;
char *o;
@ -1313,4 +1336,3 @@ Info_SetValueForKey(char *s, char *key, char *value)
*s = 0;
}