SDL: Added SDL_rand_float and SDL_rand_n to API

From 83d21e20df8c93374f23edb7cd28ea0825da50e7 Mon Sep 17 00:00:00 2001
From: John Kaniarz <[EMAIL REDACTED]>
Date: Sun, 16 Jun 2024 22:10:54 -0400
Subject: [PATCH] Added SDL_rand_float and SDL_rand_n to API

---
 include/SDL3/SDL_stdinc.h         | 41 +++++++++++++++++++++++++++++++
 src/dynapi/SDL_dynapi_overrides.h |  2 ++
 src/dynapi/SDL_dynapi_procs.h     |  2 ++
 src/stdlib/SDL_random.c           | 11 ++-------
 4 files changed, 47 insertions(+), 9 deletions(-)

diff --git a/include/SDL3/SDL_stdinc.h b/include/SDL3/SDL_stdinc.h
index 5d978d769fa17..b0665504b5617 100644
--- a/include/SDL3/SDL_stdinc.h
+++ b/include/SDL3/SDL_stdinc.h
@@ -1319,6 +1319,47 @@ extern SDL_DECLSPEC Uint32 SDLCALL SDL_rand(void);
  */
 extern SDL_DECLSPEC Uint32 SDLCALL SDL_rand_r(Uint64 *state);
 
+/**
+ * Generates a pseudo-random number less than n
+ *
+ * The method used is faster and of better quality than `SDL_rand() % n`.
+ * However just like with `SDL_rand() % n`, bias increases with larger n.
+ *
+ * Example: to simulate a d6 use `SDL_rand_n(6) + 1`
+ * The +1 converts 0..5 to 1..6
+ *
+ * There are no guarantees as to the quality of the random sequence produced,
+ * and this should not be used for cryptography or anything that requires good
+ * random distribution.
+ *
+ * \param n the number of possible values
+ *
+ * \returns a random value in the range of [0 ..  n-1]
+ *
+ * \threadsafety All calls should be made from a single thread
+ *
+ * \since This function is available since SDL 3.0.0.
+ *
+ * \sa SDL_rand
+ */
+extern SDL_DECLSPEC Uint32 SDLCALL SDL_rand_n(Uint32 n);
+
+/**
+ * Generates a pseudo-random floating point number less than 1.0
+ *
+ * There are no guarantees as to the quality of the random sequence produced,
+ * and this should not be used for cryptography or anything that requires good
+ * random distribution.
+ *
+ * \returns a random value in the range of [0.0, 1.0)
+ *
+ * \threadsafety All calls should be made from a single thread
+ *
+ * \since This function is available since SDL 3.0.0.
+ *
+ * \sa SDL_rand
+ */
+extern SDL_DECLSPEC float SDLCALL SDL_rand_float(void);
 
 #ifndef SDL_PI_D
 #define SDL_PI_D   3.141592653589793238462643383279502884       /**< pi (double) */
diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h
index d79f758f6187e..5f779db4d3601 100644
--- a/src/dynapi/SDL_dynapi_overrides.h
+++ b/src/dynapi/SDL_dynapi_overrides.h
@@ -981,6 +981,8 @@
 #define SDL_qsort SDL_qsort_REAL
 #define SDL_qsort_r SDL_qsort_r_REAL
 #define SDL_rand SDL_rand_REAL
+#define SDL_rand_float SDL_rand_float_REAL
+#define SDL_rand_n SDL_rand_n_REAL
 #define SDL_rand_r SDL_rand_r_REAL
 #define SDL_realloc SDL_realloc_REAL
 #define SDL_round SDL_round_REAL
diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h
index 8bdecdb6c6ac5..264ade7563e2c 100644
--- a/src/dynapi/SDL_dynapi_procs.h
+++ b/src/dynapi/SDL_dynapi_procs.h
@@ -990,6 +990,8 @@ SDL_DYNAPI_PROC(float,SDL_powf,(float a, float b),(a,b),return)
 SDL_DYNAPI_PROC(void,SDL_qsort,(void *a, size_t b, size_t c, SDL_CompareCallback d),(a,b,c,d),)
 SDL_DYNAPI_PROC(void,SDL_qsort_r,(void *a, size_t b, size_t c, SDL_CompareCallback_r d, void *e),(a,b,c,d,e),)
 SDL_DYNAPI_PROC(Uint32,SDL_rand,(void),(),return)
+SDL_DYNAPI_PROC(float,SDL_rand_float,(void),(),return)
+SDL_DYNAPI_PROC(Uint32,SDL_rand_n,(Uint32 a),(a),return)
 SDL_DYNAPI_PROC(Uint32,SDL_rand_r,(Uint64 *a),(a),return)
 SDL_DYNAPI_PROC(void*,SDL_realloc,(void *a, size_t b),(a,b),return)
 SDL_DYNAPI_PROC(double,SDL_round,(double a),(a),return)
diff --git a/src/stdlib/SDL_random.c b/src/stdlib/SDL_random.c
index 4ac7401a91f8b..83be9ae6a170a 100644
--- a/src/stdlib/SDL_random.c
+++ b/src/stdlib/SDL_random.c
@@ -42,20 +42,13 @@ Uint32 SDL_rand(void)
     return SDL_rand_r(&SDL_rand_state);
 }
 
-/*
- * Return a number between [0, n)
- * Fast but slightly biased. Don't run your casino with this.
- */
-Sint32 SDL_rand_n(Sint32 n)
+Uint32 SDL_rand_n(Uint32 n)
 {
 	// On 32-bit arch, the compiler will optimize to a single 32-bit multiply
 	Uint64 val = (Uint64)SDL_rand() * n;
-	return (Sint32)(val >> 32);
+	return (Uint32)(val >> 32);
 }
 
-/*
- * Random float in range [0,1)
- */
 float SDL_rand_float(void)
 {
 	return (SDL_rand() >> (32-24)) * 0x1p-24f;