diff --git a/desktop_version/CMakeLists.txt b/desktop_version/CMakeLists.txt index c68f9715..4f56179d 100644 --- a/desktop_version/CMakeLists.txt +++ b/desktop_version/CMakeLists.txt @@ -112,6 +112,7 @@ set(VVV_SRC src/GlitchrunnerMode.c src/Network.c src/ThirdPartyDeps.c + src/Xoshiro.c ) if(NOT CUSTOM_LEVEL_SUPPORT STREQUAL "DISABLED") list(APPEND VVV_SRC src/editor.cpp) diff --git a/desktop_version/src/Entity.cpp b/desktop_version/src/Entity.cpp index efa6c3cc..e334fec9 100644 --- a/desktop_version/src/Entity.cpp +++ b/desktop_version/src/Entity.cpp @@ -11,6 +11,7 @@ #include "Music.h" #include "Script.h" #include "UtilityClass.h" +#include "Xoshiro.h" bool entityclass::checktowerspikes(int t) { @@ -210,7 +211,7 @@ void entityclass::generateswnwave( int t ) if (game.deathcounts - game.swndeaths > 25) game.swndelay += 4; break; case 1: - createentity(-150, 58 + (int(fRandom() * 6) * 20), 23, 0, 0); + createentity(-150, 58 + (int(xoshiro_rand() * 6) * 20), 23, 0, 0); game.swnstate = 0; game.swndelay = 0; //return to decision state break; @@ -238,13 +239,13 @@ void entityclass::generateswnwave( int t ) game.swndelay = 0; //return to decision state break; case 3: - createentity(320+150, 58 + (int(fRandom() * 6) * 20), 23, 1, 0); + createentity(320+150, 58 + (int(xoshiro_rand() * 6) * 20), 23, 1, 0); game.swnstate = 0; game.swndelay = 0; //return to decision state break; case 4: //left and right compliments - game.swnstate2 = int(fRandom() * 6); + game.swnstate2 = int(xoshiro_rand() * 6); createentity(-150, 58 + (game.swnstate2 * 20), 23, 0, 0); createentity(320+150, 58 + ((5-game.swnstate2) * 20), 23, 1, 0); game.swnstate = 0; @@ -319,7 +320,7 @@ void entityclass::generateswnwave( int t ) game.swnstate3 = 0; game.swnstate4 = 0; - game.swnstate2 = int(fRandom() * 100); + game.swnstate2 = int(xoshiro_rand() * 100); if (game.swnstate2 < 25) { //simple @@ -336,7 +337,7 @@ void entityclass::generateswnwave( int t ) break; case 1: //complex chain - game.swnstate2 = int(fRandom() * 8); + game.swnstate2 = int(xoshiro_rand() * 8); if (game.swnstate2 == 0) { game.swnstate = 10; @@ -382,7 +383,7 @@ void entityclass::generateswnwave( int t ) break; case 2: //simple chain - game.swnstate2 = int(fRandom() * 6); + game.swnstate2 = int(xoshiro_rand() * 6); if (game.swnstate2 == 0) { game.swnstate = 23; @@ -418,7 +419,7 @@ void entityclass::generateswnwave( int t ) break; case 3: //Choose a major action - game.swnstate2 = int(fRandom() * 100); + game.swnstate2 = int(xoshiro_rand() * 100); game.swnstate4 = 0; if (game.swnstate2 < 25) { @@ -435,7 +436,7 @@ void entityclass::generateswnwave( int t ) break; case 4: //filler chain - game.swnstate2 = int(fRandom() * 6); + game.swnstate2 = int(xoshiro_rand() * 6); if (game.swnstate2 == 0) { game.swnstate = 28; @@ -624,7 +625,7 @@ void entityclass::generateswnwave( int t ) case 22: game.swnstate4++; //left and right compliments - game.swnstate2 = int(fRandom() * 6); + game.swnstate2 = int(xoshiro_rand() * 6); createentity(-150, 58 + (game.swnstate2 * 20), 23, 0, 0); createentity(320 + 150, 58 + ((5 - game.swnstate2) * 20), 23, 1, 0); if(game.swnstate4<=12) @@ -685,7 +686,7 @@ void entityclass::generateswnwave( int t ) break; case 28: game.swnstate4++; - game.swnstate2 = int(fRandom() * 6); + game.swnstate2 = int(xoshiro_rand() * 6); createentity(-150, 58 + (game.swnstate2 * 20), 23, 0, 0); if(game.swnstate4<=6) { @@ -701,7 +702,7 @@ void entityclass::generateswnwave( int t ) break; case 29: game.swnstate4++; - game.swnstate2 = int(fRandom() * 6); + game.swnstate2 = int(xoshiro_rand() * 6); gravcreate(game.swnstate2, 1); if(game.swnstate4<=6) { @@ -717,7 +718,7 @@ void entityclass::generateswnwave( int t ) break; case 30: game.swnstate4++; - game.swnstate2 = int(fRandom() * 3); + game.swnstate2 = int(xoshiro_rand() * 3); gravcreate(game.swnstate2, 0); gravcreate(5-game.swnstate2, 0); if(game.swnstate4<=2) @@ -734,7 +735,7 @@ void entityclass::generateswnwave( int t ) break; case 31: game.swnstate4++; - game.swnstate2 = int(fRandom() * 3); + game.swnstate2 = int(xoshiro_rand() * 3); gravcreate(game.swnstate2, 1); gravcreate(5-game.swnstate2, 1); if(game.swnstate4<=2) diff --git a/desktop_version/src/Script.cpp b/desktop_version/src/Script.cpp index 48ce1f16..88634e34 100644 --- a/desktop_version/src/Script.cpp +++ b/desktop_version/src/Script.cpp @@ -2,6 +2,7 @@ #include "Script.h" #include +#include #include "editor.h" #include "Entity.h" @@ -13,6 +14,7 @@ #include "Map.h" #include "Music.h" #include "UtilityClass.h" +#include "Xoshiro.h" scriptclass::scriptclass(void) { @@ -3377,6 +3379,8 @@ void scriptclass::hardreset(void) { const bool version2_2 = GlitchrunnerMode_less_than_or_equal(Glitchrunner2_2); + xoshiro_seed(SDL_GetTicks()); + //Game: game.hascontrol = true; game.gravitycontrol = 0; diff --git a/desktop_version/src/Xoshiro.c b/desktop_version/src/Xoshiro.c new file mode 100644 index 00000000..29335006 --- /dev/null +++ b/desktop_version/src/Xoshiro.c @@ -0,0 +1,62 @@ +#include + +/* Implements the xoshiro128+ PRNG. */ + +static uint32_t rotl(const uint32_t x, const int k) +{ + return (x << k) | (x >> (32 - k)); +} + +static uint32_t s[4]; + +static uint32_t splitmix32(uint32_t* x) +{ + uint32_t z = (*x += 0x9e3779b9UL); + z = (z ^ (z >> 15)) * 0xbf58476dUL; + z = (z ^ (z >> 13)) * 0x94d049bbUL; + return z ^ (z >> 16); +} + +static void seed( + const uint32_t s0, + const uint32_t s1, + const uint32_t s2, + const uint32_t s3 +) { + s[0] = s0; + s[1] = s1; + s[2] = s2; + s[3] = s3; +} + +uint32_t xoshiro_next(void) +{ + const uint32_t result = s[0] + s[3]; + + const uint32_t t = s[1] << 9; + + s[2] ^= s[0]; + s[3] ^= s[1]; + s[1] ^= s[2]; + s[0] ^= s[3]; + + s[2] ^= t; + + s[3] = rotl(s[3], 11); + + return result; +} + +void xoshiro_seed(uint32_t s) +{ + const uint32_t s0 = splitmix32(&s); + const uint32_t s1 = splitmix32(&s); + const uint32_t s2 = splitmix32(&s); + const uint32_t s3 = splitmix32(&s); + seed(s0, s1, s2, s3); +} + +float xoshiro_rand(void) +{ + return ((float) xoshiro_next()) / ((float) UINT32_MAX); +} diff --git a/desktop_version/src/Xoshiro.h b/desktop_version/src/Xoshiro.h new file mode 100644 index 00000000..235643b1 --- /dev/null +++ b/desktop_version/src/Xoshiro.h @@ -0,0 +1,21 @@ +#ifndef XOSHIRO_H +#define XOSHIRO_H + +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + +void xoshiro_seed(uint32_t s); + +uint32_t xoshiro_next(void); + +float xoshiro_rand(void); + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* XOSHIRO_H */