1 /*---------------------------------------------------------------------------*
2   Project:  TwlSDK - MATH - include
3   File:     rand.h
4 
5   Copyright 2003-2008 Nintendo. All rights reserved.
6 
7   These coded instructions, statements, and computer programs contain
8   proprietary information of Nintendo of America Inc. and/or Nintendo
9   Company Ltd., and are protected by Federal copyright law. They may
10   not be disclosed to third parties or copied or duplicated in any form,
11   in whole or in part, without the prior written consent of Nintendo.
12 
13   $Date::            $
14   $Rev:$
15   $Author:$
16  *---------------------------------------------------------------------------*/
17 
18 #include <nitro/types.h>
19 
20 #ifndef NITRO_MATH_RAND_H_
21 #define NITRO_MATH_RAND_H_
22 
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26 
27 typedef struct
28 {
29     u64     x;                         // Random number value
30     u64     mul;                       // Multiplier
31     u64     add;                       // The number to add
32 }
33 MATHRandContext32;
34 
35 
36 typedef struct
37 {
38     u32     x;                         // Random number value
39     u32     mul;                       // Multiplier
40     u32     add;                       // The number to add
41 }
42 MATHRandContext16;
43 
44 
45 /*---------------------------------------------------------------------------*
46   Name:         MATH_InitRand32
47 
48   Description:  Initialize 32-bit random number context using the linear congruency method.
49 
50   Arguments:    context:   Pointer to random number context
51 
52                 seed:    Random-number seed to set as initial value
53 
54   Returns:      None.
55  *---------------------------------------------------------------------------*/
MATH_InitRand32(MATHRandContext32 * context,u64 seed)56 static inline void MATH_InitRand32(MATHRandContext32 *context, u64 seed)
57 {
58     context->x = seed;
59     context->mul = (1566083941LL << 32) + 1812433253LL;
60     context->add = 2531011;
61 }
62 
63 
64 /*---------------------------------------------------------------------------*
65   Name:         MATH_Rand32
66 
67   Description:  Function to get a 32-bit random number context using the linear congruency method.
68 
69   Arguments:    context:   Pointer to random number context
70 
71                 max:     Specifies the range of numbers to obtain. The possible range is 0 to max-1.
72                         If 0 has been specified, the entire range of 32-bit values is used.
73 
74   Returns:      A 32-bit random number.
75  *---------------------------------------------------------------------------*/
MATH_Rand32(MATHRandContext32 * context,u32 max)76 static inline u32 MATH_Rand32(MATHRandContext32 *context, u32 max)
77 {
78     context->x = context->mul * context->x + context->add;
79 
80     // If the "max" argument is a constant, this is optimized by compiler.
81     if (max == 0)
82     {
83         return (u32)(context->x >> 32);
84     }
85     else
86     {
87         return (u32)(((context->x >> 32) * max) >> 32);
88     }
89 }
90 
91 
92 /*---------------------------------------------------------------------------*
93   Name:         MATH_InitRand16
94 
95   Description:  Initialize 16-bit random number context using the linear congruency method.
96 
97   Arguments:    context:   Pointer to random number context
98 
99                 seed:    Random-number seed to set as initial value
100 
101   Returns:      None.
102  *---------------------------------------------------------------------------*/
MATH_InitRand16(MATHRandContext16 * context,u32 seed)103 static inline void MATH_InitRand16(MATHRandContext16 *context, u32 seed)
104 {
105     context->x = seed;
106     context->mul = 1566083941LL;
107     context->add = 2531011;
108 }
109 
110 
111 /*---------------------------------------------------------------------------*
112   Name:         MATH_Rand16
113 
114   Description:  Function to get a 16-bit random number context using the linear congruency method.
115 
116   Arguments:    context:   Pointer to random number context
117 
118                 max:     Specifies the range of numbers to obtain. The possible range is 0 to max-1.
119                         If 0 has been specified, the entire range of 16-bit values is used.
120 
121   Returns:      A 16-bit random number.
122  *---------------------------------------------------------------------------*/
MATH_Rand16(MATHRandContext16 * context,u16 max)123 static inline u16 MATH_Rand16(MATHRandContext16 *context, u16 max)
124 {
125     context->x = context->mul * context->x + context->add;
126 
127     // If the "max" argument is a constant, this is optimized by the compiler.
128     if (max == 0)
129     {
130         return (u16)(context->x >> 16);
131     }
132     else
133     {
134         return (u16)(((context->x >> 16) * max) >> 16);
135     }
136 }
137 
138 
139 #ifdef __cplusplus
140 } /* extern "C" */
141 #endif
142 
143 
144 #endif // NITRO_MATH_RAND_H_
145