-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optional high-quality RNG #3780
Changes from 10 commits
2bf775f
99666d4
f580028
ca7e5dd
35ae0b3
25358c4
82bc6f5
50b70f2
9bac69d
2c5a5e2
9b6439a
4b39ace
f5a2765
16614b1
ecfa3d9
94d8da5
575e512
b68e897
7075780
79a7e99
a539f3f
bb6cc7c
52b73e7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,88 @@ | ||
#ifndef GUARD_RANDOM_H | ||
#define GUARD_RANDOM_H | ||
|
||
extern u32 gRngValue; | ||
extern u32 gRng2Value; | ||
// The number 1103515245 comes from the example implementation of rand and srand | ||
// in the ISO C standard. | ||
#define ISO_RANDOMIZE1(val)(1103515245 * (val) + 24691) | ||
#define ISO_RANDOMIZE2(val)(1103515245 * (val) + 12345) | ||
|
||
/* Notes about new functions: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it might be good to avoid "new". Perhaps "HQ", or maybe just describe the API? My gripe with "new" is that more functions could be added in the future, and also that functions like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe something like “HQ_RANDOM support functions”? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good to me :) |
||
* If using HQ_RANDOM, you MUST call AdvanceRandom() in VBlank handlers. | ||
* If you do not, you risk corruption of the RNG state. | ||
tertu-m marked this conversation as resolved.
Show resolved
Hide resolved
|
||
* LocalRandom(*val) adapts to either choice of RNG implementation. | ||
* Other new functions should be self-explanatory. | ||
*/ | ||
|
||
#if HQ_RANDOM == TRUE | ||
struct Sfc32State { | ||
u32 a; | ||
u32 b; | ||
u32 c; | ||
u32 ctr; | ||
}; | ||
|
||
typedef struct Sfc32State rng_value_t; | ||
|
||
#define RNG_VALUE_EMPTY {} | ||
|
||
// Calling this function directly is discouraged. | ||
// Use LocalRandom() instead. | ||
static inline u32 _SFC32_Next(struct Sfc32State *state) | ||
{ | ||
const u32 result = state->a + state->b + state->ctr++; | ||
state->a = state->b ^ (state->b >> 9); | ||
state->b = state->c * 9; | ||
state->c = result + ((state->c << 21) | (state->c >> 11)); | ||
return result; | ||
} | ||
|
||
static inline u16 LocalRandom(rng_value_t *val) | ||
{ | ||
return _SFC32_Next(val) >> 16; | ||
} | ||
|
||
u32 Random32(void); | ||
u32 Random2_32(void); | ||
|
||
static inline u16 Random(void) | ||
{ | ||
return Random32() >> 16; | ||
} | ||
|
||
static inline u16 Random2(void) | ||
{ | ||
return Random2_32() >> 16; | ||
} | ||
|
||
void AdvanceRandom(void); | ||
#else | ||
typedef u32 rng_value_t; | ||
|
||
#define RNG_VALUE_EMPTY 0 | ||
|
||
//Returns a 16-bit pseudorandom number | ||
u16 Random(void); | ||
u16 Random2(void); | ||
|
||
//Returns a 32-bit pseudorandom number | ||
#define Random32() (Random() | (Random() << 16)) | ||
#define Random2_32() (Random2() | (Random2() << 16)) | ||
|
||
// The number 1103515245 comes from the example implementation of rand and srand | ||
// in the ISO C standard. | ||
#define ISO_RANDOMIZE1(val)(1103515245 * (val) + 24691) | ||
#define ISO_RANDOMIZE2(val)(1103515245 * (val) + 12345) | ||
static inline u16 LocalRandom(rng_value_t *val) | ||
{ | ||
*val = ISO_RANDOMIZE1(*val); | ||
return *val >> 16; | ||
} | ||
|
||
static inline void AdvanceRandom(void) | ||
{ | ||
Random(); | ||
} | ||
|
||
#endif | ||
|
||
extern rng_value_t gRngValue; | ||
extern rng_value_t gRng2Value; | ||
|
||
//Sets the initial seed value of the pseudorandom number generator | ||
void SeedRng(u16 seed); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you have a particular reason for adding these
// for rng_value_t
comments to the includes?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a very justifiable one.