pokeemerald/src/random.c

124 lines
2.7 KiB
C
Raw Normal View History

2017-02-02 16:30:08 -08:00
#include "global.h"
#include "random.h"
2023-07-12 20:07:39 +01:00
#if MODERN
#include <alloca.h>
#endif
2017-02-02 16:30:08 -08:00
2017-02-03 09:32:51 -08:00
EWRAM_DATA static u8 sUnknown = 0;
EWRAM_DATA static u32 sRandCount = 0;
2017-02-02 16:30:08 -08:00
2018-04-29 14:21:59 +02:00
// IWRAM common
u32 gRngValue;
u32 gRng2Value;
2018-04-29 14:21:59 +02:00
2017-09-08 18:28:00 +02:00
u16 Random(void)
2017-02-02 16:30:08 -08:00
{
gRngValue = ISO_RANDOMIZE1(gRngValue);
2017-02-02 16:30:08 -08:00
sRandCount++;
return gRngValue >> 16;
}
void SeedRng(u16 seed)
{
gRngValue = seed;
sUnknown = 0;
}
void SeedRng2(u16 seed)
{
gRng2Value = seed;
}
u16 Random2(void)
{
gRng2Value = ISO_RANDOMIZE1(gRng2Value);
2017-02-02 16:30:08 -08:00
return gRng2Value >> 16;
}
2023-07-05 18:46:40 +01:00
#define SHUFFLE_IMPL \
u32 tmp; \
--n; \
while (n > 1) \
{ \
2023-07-12 20:07:39 +01:00
int j = (Random() * (n+1)) >> 16; \
2023-07-05 18:46:40 +01:00
SWAP(data[n], data[j], tmp); \
--n; \
}
void Shuffle8(void *data_, size_t n)
{
u8 *data = data_;
SHUFFLE_IMPL;
}
void Shuffle16(void *data_, size_t n)
{
u16 *data = data_;
SHUFFLE_IMPL;
}
void Shuffle32(void *data_, size_t n)
{
u32 *data = data_;
SHUFFLE_IMPL;
}
void ShuffleN(void *data, size_t n, size_t size)
{
void *tmp = alloca(size);
--n;
while (n > 1)
{
2023-07-12 20:07:39 +01:00
int j = (Random() * (n+1)) >> 16;
2023-07-05 18:46:40 +01:00
memcpy(tmp, (u8 *)data + n*size, size); // tmp = data[n];
memcpy((u8 *)data + n*size, (u8 *)data + j*size, size); // data[n] = data[j];
memcpy((u8 *)data + j*size, tmp, size); // data[j] = tmp;
--n;
}
}
__attribute__((weak, alias("RandomUniformDefault")))
u32 RandomUniform(enum RandomTag tag, u32 lo, u32 hi);
2023-07-19 16:44:21 +01:00
__attribute__((weak, alias("RandomUniformExceptDefault")))
u32 RandomUniformExcept(enum RandomTag, u32 lo, u32 hi, bool32 (*reject)(u32));
__attribute__((weak, alias("RandomWeightedArrayDefault")))
u32 RandomWeightedArray(enum RandomTag tag, u32 sum, u32 n, const u8 *weights);
__attribute__((weak, alias("RandomElementArrayDefault")))
const void *RandomElementArray(enum RandomTag tag, const void *array, size_t size, size_t count);
u32 RandomUniformDefault(enum RandomTag tag, u32 lo, u32 hi)
{
return lo + (((hi - lo + 1) * Random()) >> 16);
}
2023-07-19 16:44:21 +01:00
u32 RandomUniformExceptDefault(enum RandomTag tag, u32 lo, u32 hi, bool32 (*reject)(u32))
{
while (TRUE)
{
u32 n = RandomUniformDefault(tag, lo, hi);
if (!reject(n))
return n;
}
}
u32 RandomWeightedArrayDefault(enum RandomTag tag, u32 sum, u32 n, const u8 *weights)
{
s32 i, targetSum;
targetSum = (sum * Random()) >> 16;
for (i = 0; i < n - 1; i++)
{
targetSum -= weights[i];
if (targetSum < 0)
return i;
}
return n - 1;
}
const void *RandomElementArrayDefault(enum RandomTag tag, const void *array, size_t size, size_t count)
{
return (const u8 *)array + size * RandomUniformDefault(tag, 0, count - 1);
}