Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master'
Browse files Browse the repository at this point in the history
  • Loading branch information
dusty-qw committed Jan 31, 2024
2 parents 59d9b6b + 9fb575f commit 80e7a11
Show file tree
Hide file tree
Showing 16 changed files with 220 additions and 65 deletions.
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ set(SRC_COMMON
"${DIR_SRC}/player.c"
"${DIR_SRC}/q_shared.c"
"${DIR_SRC}/race.c"
"${DIR_SRC}/rng.c"
"${DIR_SRC}/rng_gen_impl.c"
"${DIR_SRC}/rng_seed_impl.c"
"${DIR_SRC}/route_calc.c"
"${DIR_SRC}/route_fields.c"
"${DIR_SRC}/route_lookup.c"
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ For the versions available, see the [tags on this repository][ktx-tags].

* **Ivan** *"qqshka"* **Bolsunov**
* **Dominic** *"oldman"* **Evans**
* **Foobar**
* **Anton** *"tonik"* **Gavrilov**
* **Andrew** *"ult"* **Grondalski**
* **Paul Klumpp**
Expand Down
2 changes: 2 additions & 0 deletions include/g_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "g_consts.h"
#include "g_syscalls.h"
#include "player.h"
#include "rng.h"

#if defined(_WIN32)
#define QW_PLATFORM "Windows"
Expand Down Expand Up @@ -238,6 +239,7 @@ typedef enum
// K_SPW_0_NONRANDOM changes "Normal QW respawns" to "pre-qtest nonrandom respawns"
#define K_SPW_0_NONRANDOM

void g_random_seed(int);
float g_random(void);
float crandom(void);
int i_rnd(int from, int to);
Expand Down
14 changes: 14 additions & 0 deletions include/rng.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// rng.h -- High-quality random number generation.

#ifndef __RNG_H__
#define __RNG_H__

#include "rng_gen_state.h"

void rng_seed(RngState*, int seed);
uint32_t rng_next(RngState*);

void rng_seed_global(int seed);
uint32_t rng_next_global(void);

#endif
13 changes: 13 additions & 0 deletions include/rng_gen_impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// rng_gen_impl.h -- Xoroshiro128** implementation.

#ifndef __RNG_GEN_IMPL_H__
#define __RNG_GEN_IMPL_H__

#include <stdint.h>

#include "rng_gen_state.h"

RngState rng_gen_impl_initial_state(int seed);
uint32_t rng_gen_impl_next(RngState* state);

#endif
7 changes: 7 additions & 0 deletions include/rng_gen_state.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#ifndef __RNG_STATE_H__
#define __RNG_STATE_H__

// You must initialize this with rng_seed/rng_seed_global!
typedef struct RngState { uint32_t s[4]; } RngState;

#endif
10 changes: 10 additions & 0 deletions include/rng_seed_impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// rng_seed_impl.h -- SplitMix64 implementation.

#ifndef __RNG_SEED_IMPL_H__
#define __RNG_SEED_IMPL_H__

#include <stdint.h>

uint64_t rng_seed_impl_next(uint64_t*);

#endif
8 changes: 3 additions & 5 deletions src/bg_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,18 +177,16 @@ double fabs(double x)
}

//=====================================
static int randSeed = 0;
static RngState rng_state = { 0 };

void srand(unsigned seed)
{
randSeed = seed;
rng_seed(&rng_state, (int)seed);
}

int rand(void)
{
randSeed = (69069 * randSeed + 1);

return (randSeed & 0x7fff);
return (int)rng_next(&rng_state);
}

//=====================================
Expand Down
16 changes: 16 additions & 0 deletions src/func_bob.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@

// Stripped down port of dumptruckDS's func_bob.qc

// progsdump / Arcane Dimensions spawnflags
#define BOB_COLLISION 2
#define BOB_NONSOLID 4

// Dimension of the Machine spawnflags
// Not yet supported, uses different easing function, might be possible to detect.
// https://github.com/id-Software/quake-rerelease-qc/blob/main/quakec_mg1/func_bob.qc
#define FUNC_BOB_NONSOLID 1
#define FUNC_BOB_START_ON 2

static void func_bob_timer()
{
vec3_t delta;
Expand Down Expand Up @@ -46,6 +56,12 @@ static void func_bob_timer()

void SP_func_bob()
{
// Non-solid bobs not implemented yet, remove for now to not block player.
if ((int) self->s.v.spawnflags & (BOB_NONSOLID | FUNC_BOB_NONSOLID)) {
ent_remove(self);
return;
}

self->s.v.movetype = MOVETYPE_PUSH;
self->s.v.solid = SOLID_BSP;

Expand Down
3 changes: 2 additions & 1 deletion src/g_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
*/

#include "g_local.h"
#include "rng.h"
/* global 4 fix
entity self;
entity other;
Expand Down Expand Up @@ -464,7 +465,7 @@ void G_InitGame(int levelTime, int randomSeed)
{
int i;

srand(randomSeed);
g_random_seed(randomSeed);
framecount = 0;
starttime = levelTime * 0.001;
G_Printf("Init Game\n");
Expand Down
6 changes: 5 additions & 1 deletion src/g_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,13 @@ int NUM_FOR_EDICT(gedict_t *e)
return b;
}

void g_random_seed(int seed) {
rng_seed_global(seed);
}

float g_random()
{
return ((rand() & 0x7fff) / ((float)0x8000));
return ((rng_next_global() & 0x7fff) / ((float)0x8000));
}

float crandom()
Expand Down
41 changes: 41 additions & 0 deletions src/rng.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#include <stdint.h>

#include "rng.h"

#include "rng_gen_impl.h"
#include "rng_seed_impl.h"

/* Seed the PRNG.
Since the main game loop only provides 4 bytes of entropy, but the
xoroshiro128** PRNG expects 16 bytes of entropy, this function uses the
splitmix64 algorithm to expand the seed. This approach is recommended by
the authors of xoroshiro128**, as described here: https://prng.di.unimi.it .
You must initialize your RngStates with rng_seed/rng_seed_global!
(The all-zeros state has bad statistics.)
*/
void rng_seed(RngState* s, int seed) {
uint64_t x = (uint64_t)(seed);

s->s[0] = (uint32_t)rng_seed_impl_next(&x);
s->s[1] = (uint32_t)rng_seed_impl_next(&x);
s->s[2] = (uint32_t)rng_seed_impl_next(&x);
s->s[3] = (uint32_t)rng_seed_impl_next(&x);
}

uint32_t rng_next(RngState* state) {
return rng_gen_impl_next(state);
}

// You must initialize this with rng_seed/rng_seed_global!
static RngState global_rng = { 0 };

void rng_seed_global(int seed) {
return rng_seed(&global_rng, seed);
}

uint32_t rng_next_global(void) {
return rng_next(&global_rng);
}

58 changes: 58 additions & 0 deletions src/rng_gen_impl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#include "rng_gen_impl.h"

//// Start imported code.
// Code in this section copied from
// https://prng.di.unimi.it/xoshiro128starstar.c
// It was lightly edited to change a global variable to a local variable.

/* Written in 2018 by David Blackman and Sebastiano Vigna (vigna@acm.org)
To the extent possible under law, the author has dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
See <http://creativecommons.org/publicdomain/zero/1.0/>. */

#include <stdint.h>

/* This is xoshiro128** 1.1, one of our 32-bit all-purpose, rock-solid
generators. It has excellent speed, a state size (128 bits) that is
large enough for mild parallelism, and it passes all tests we are aware
of.
Note that version 1.0 had mistakenly s[0] instead of s[1] as state
word passed to the scrambler.
For generating just single-precision (i.e., 32-bit) floating-point
numbers, xoshiro128+ is even faster.
The state must be seeded so that it is not everywhere zero. */


static inline uint32_t rotl(const uint32_t x, int k) {
return (x << k) | (x >> (32 - k));
}


static inline uint32_t next(RngState* s) {
const uint32_t result = rotl(s->s[1] * 5, 7) * 9;

const uint32_t t = s->s[1] << 9;

s->s[2] ^= s->s[0];
s->s[3] ^= s->s[1];
s->s[1] ^= s->s[2];
s->s[0] ^= s->s[3];

s->s[2] ^= t;

s->s[3] = rotl(s->s[3], 11);

return result;
}
//// End imported code.

// Code in this section wraps the PRNG implementation.
uint32_t rng_gen_impl_next(RngState* state) {
return next(state);
}
29 changes: 29 additions & 0 deletions src/rng_seed_impl.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//// Start imported code.
// Code in this section was copied from
// https://prng.di.unimi.it/splitmix64.c
// then lightly edited to remove a global variable and rename a function.

/* Written in 2015 by Sebastiano Vigna (vigna@acm.org)
To the extent possible under law, the author has dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
See <http://creativecommons.org/publicdomain/zero/1.0/>. */

#include <stdint.h>

/* This is a fixed-increment version of Java 8's SplittableRandom generator
See http://dx.doi.org/10.1145/2714064.2660195 and
http://docs.oracle.com/javase/8/docs/api/java/util/SplittableRandom.html
It is a very fast generator passing BigCrush, and it can be useful if
for some reason you absolutely want 64 bits of state. */

uint64_t rng_seed_impl_next(uint64_t* x) {
uint64_t z = (*x += 0x9e3779b97f4a7c15);
z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9;
z = (z ^ (z >> 27)) * 0x94d049bb133111eb;
return z ^ (z >> 31);
}
//// End imported code.
2 changes: 1 addition & 1 deletion src/stats.c
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,7 @@ void OnePlayerStats(gedict_t *p, int tp)
// weapons
G_bprint(2, "%s:%s%s%s%s%s\n", redtext("Wp"),
(a_lg ? va(" %s%.1f%% (%d/%d)", redtext("lg"), e_lg, (int)h_lg, (int)a_lg) : ""),
(ph_rl ? va(" %s%.1f%%", redtext("rl"), ph_rl) : ""),
(ph_rl ? va(" %s%.1f%% (%d/%d)", redtext("rl"), ph_rl, (int)vh_rl, (int)a_rl) : ""),
(ph_gl ? va(" %s%.1f%%", redtext("gl"), ph_gl) : ""),
(e_sg ? va(" %s%.1f%%", redtext("sg"), e_sg) : ""),
(e_ssg ? va(" %s%.1f%%", redtext("ssg"), e_ssg) : ""));
Expand Down
Loading

0 comments on commit 80e7a11

Please sign in to comment.