1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | #define SG_BUILD_LIBRARY |
16 | #include <siege/util/rand.h> |
17 | |
18 | #include <stdlib.h> |
19 | |
20 | void SG_CALL__cdecl _sgRandMersenne32Create(SGRand* rand) |
21 | { |
22 | rand->data = malloc(sizeof(SGuint) * 625); |
| Result of 'malloc' is converted to a pointer of type 'SGubyte', which is incompatible with sizeof operand type 'SGuint' |
23 | } |
24 | void SG_CALL__cdecl _sgRandMersenne32Destroy(SGRand* rand) |
25 | { |
26 | free(rand->data); |
27 | } |
28 | void SG_CALL__cdecl _sgRandMersenne32Seed(SGRand* rand, SGulong seed, SGulong index) |
29 | { |
30 | SGuint* ind = &((SGuint*)rand->data)[0]; |
31 | SGuint* mt = &((SGuint*)rand->data)[1]; |
32 | |
33 | mt[0] = seed; |
34 | *ind = index % 624; |
35 | SGuint i; |
36 | for(i = 1; i < 624; i++) |
37 | mt[i] = (0x6C078965 * (mt[i-1] ^ (mt[i-1] >> 30))) & 0xFFFFFFFF; |
38 | } |
39 | void SG_CALL__cdecl _sgRandMersenne32GenNumbers(SGRand* rand) |
40 | { |
41 | |
42 | SGuint* mt = &((SGuint*)rand->data)[1]; |
43 | |
44 | SGuint i; |
45 | for(i = 0; i < 624; i++) |
46 | { |
47 | SGuint y = (mt[i] >> 31) + (mt[(i+1)%624] & 0x7FFFFFFF); |
48 | mt[i] = mt[(i + 397)%624] ^ (y >> 1); |
49 | if((y % 2) == 1) |
50 | mt[i] = mt[i] ^ 0x9908B0DF; |
51 | } |
52 | } |
53 | SGulong SG_CALL__cdecl _sgRandMersenne32Gen(SGRand* rand) |
54 | { |
55 | SGuint* ind = &((SGuint*)rand->data)[0]; |
56 | SGuint* mt = &((SGuint*)rand->data)[1]; |
57 | |
58 | if(*ind == 0) |
59 | _sgRandMersenne32GenNumbers(rand); |
60 | |
61 | SGuint y = mt[*ind]; |
62 | y = y ^ (y >> 11); |
63 | y = y ^ ((y << 7) & 0x9D2C5680); |
64 | y = y ^ ((y << 15) & 0xEFC60000); |
65 | y = y ^ (y >> 18); |
66 | |
67 | *ind = (*ind + 1) % 624; |
68 | return y; |
69 | } |
70 | |
71 | SGRand* SG_CALL__cdecl sgRandCreate(SGenum type) |
72 | { |
73 | static SGRandCallbacks cbsMersenne32 = { |
74 | _sgRandMersenne32Create, _sgRandMersenne32Destroy, |
75 | _sgRandMersenne32Seed, _sgRandMersenne32Gen |
76 | }; |
77 | |
78 | SGRandCallbacks cbs = { NULL((void*)0) }; |
79 | SGulong max = (SGulong)-1; |
80 | switch(type) |
81 | { |
82 | case SG_RAND_MT199371: cbs = cbsMersenne32; max = (SGuint)-1; break; |
83 | } |
84 | |
85 | SGRand* rand = sgRandCreateCB(&cbs, max); |
86 | if(!rand) |
87 | return NULL((void*)0); |
88 | |
89 | rand->type = type; |
90 | |
91 | return rand; |
92 | } |
93 | SGRand* SG_CALL__cdecl sgRandCreateCB(SGRandCallbacks* cbs, SGulong max) |
94 | { |
95 | SGRand* rand = malloc(sizeof(SGRand)); |
96 | if(rand == NULL((void*)0)) |
97 | return NULL((void*)0); |
98 | |
99 | rand->type = SG_RAND_USER0; |
100 | rand->stime = time(NULL((void*)0)); |
101 | |
102 | rand->cbs = *cbs; |
103 | rand->max = max; |
104 | |
105 | if(rand->cbs.create) |
106 | rand->cbs.create(rand); |
107 | if(rand->cbs.seed) |
108 | rand->cbs.seed(rand, rand->stime, 0); |
109 | |
110 | return rand; |
111 | } |
112 | void SG_CALL__cdecl sgRandDestroy(SGRand* rand) |
113 | { |
114 | if(rand == NULL((void*)0)) |
115 | return; |
116 | |
117 | if(rand->cbs.destroy) |
118 | rand->cbs.destroy(rand); |
119 | free(rand); |
120 | } |
121 | |
122 | void SG_CALL__cdecl sgRandSeed(SGRand* rand, SGulong seed, SGulong index) |
123 | { |
124 | if(rand == NULL((void*)0)) |
125 | return; |
126 | |
127 | if(!seed) |
128 | seed = rand->stime; |
129 | |
130 | if(rand->cbs.seed) |
131 | rand->cbs.seed(rand, seed, index); |
132 | } |
133 | |
134 | SGulong SG_CALL__cdecl sgRandGen(SGRand* rand) |
135 | { |
136 | if(rand == NULL((void*)0)) |
137 | return 0; |
138 | |
139 | if(rand->cbs.gen) |
140 | return rand->cbs.gen(rand); |
141 | return 0; |
142 | } |
143 | float SG_CALL__cdecl sgRandGenf(SGRand* rand) |
144 | { |
145 | return sgRandGen(rand) / (float)rand->max; |
146 | } |
147 | float SG_CALL__cdecl sgRandGen1f(SGRand* rand, float max) |
148 | { |
149 | return sgRandGenf(rand) * max; |
150 | } |
151 | float SG_CALL__cdecl sgRandGen2f(SGRand* rand, float min, float max) |
152 | { |
153 | return min + sgRandGen1f(rand, max - min); |
154 | } |