1 | /* |
1 | /* |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
2 | * This file is part of Deliantra, the Roguelike Realtime MMORPG. |
3 | * |
3 | * |
4 | * Copyright (©) 2010 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
4 | * Copyright (©) 2010,2011,2012,2013,2014,2015,2016 Marc Alexander Lehmann / Robin Redeker / the Deliantra team |
5 | * |
5 | * |
6 | * Deliantra is free software: you can redistribute it and/or modify it under |
6 | * Deliantra is free software: you can redistribute it and/or modify it under |
7 | * the terms of the Affero GNU General Public License as published by the |
7 | * the terms of the Affero GNU General Public License as published by the |
8 | * Free Software Foundation, either version 3 of the License, or (at your |
8 | * Free Software Foundation, either version 3 of the License, or (at your |
9 | * option) any later version. |
9 | * option) any later version. |
10 | * |
10 | * |
11 | * This program is distributed in the hope that it will be useful, |
11 | * This program is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. |
14 | * GNU General Public License for more details. |
15 | * |
15 | * |
16 | * You should have received a copy of the Affero GNU General Public License |
16 | * You should have received a copy of the Affero GNU General Public License |
17 | * and the GNU General Public License along with this program. If not, see |
17 | * and the GNU General Public License along with this program. If not, see |
18 | * <http://www.gnu.org/licenses/>. |
18 | * <http://www.gnu.org/licenses/>. |
19 | * |
19 | * |
20 | * The authors can be reached via e-mail to <support@deliantra.net> |
20 | * The authors can be reached via e-mail to <support@deliantra.net> |
21 | */ |
21 | */ |
22 | |
22 | |
23 | #include <cmath> |
23 | #include <cmath> |
24 | |
24 | |
25 | #include <global.h> |
25 | #include <global.h> |
26 | |
26 | |
27 | rand_gen rndm, rmg_rndm; |
27 | rand_gen rndm, rmg_rndm; |
28 | |
28 | |
29 | void noinline |
29 | ecb_noinline void |
30 | tausworthe_rng::seed (uint32_t seed) |
30 | tausworthe_rng::seed (uint32_t seed) |
31 | { |
31 | { |
32 | state [0] = seed * 69069U; if (state [0] < 2U) state [0] += 2U; |
32 | state [0] = seed * 69069U; if (state [0] < 2U) state [0] += 2U; |
33 | state [1] = state [0] * 69069U; if (state [1] < 8U) state [1] += 8U; |
33 | state [1] = state [0] * 69069U; if (state [1] < 8U) state [1] += 8U; |
34 | state [2] = state [1] * 69069U; if (state [2] < 16U) state [2] += 16U; |
34 | state [2] = state [1] * 69069U; if (state [2] < 16U) state [2] += 16U; |
… | |
… | |
47 | state [3] = ((state [3] & 0xFFFFFF80U) << 13U) ^ (((state [3] << 3U) ^ state [3]) >> 12U); |
47 | state [3] = ((state [3] & 0xFFFFFF80U) << 13U) ^ (((state [3] << 3U) ^ state [3]) >> 12U); |
48 | |
48 | |
49 | return state [0] ^ state [1] ^ state [2] ^ state [3]; |
49 | return state [0] ^ state [1] ^ state [2] ^ state [3]; |
50 | } |
50 | } |
51 | |
51 | |
52 | void noinline |
52 | ecb_noinline void |
53 | r250521_rng::seed (uint32_t seed) |
53 | r250521_rng::seed (uint32_t seed) |
54 | { |
54 | { |
55 | xorshift_rng rng; |
55 | xorshift_rng rng; |
56 | |
56 | |
57 | rng.seed (seed); |
57 | rng.seed (seed); |
… | |
… | |
72 | { |
72 | { |
73 | return (this->next () * (uint64_t)num) >> 32U; |
73 | return (this->next () * (uint64_t)num) >> 32U; |
74 | } |
74 | } |
75 | |
75 | |
76 | template<class generator> |
76 | template<class generator> |
77 | uint32_t noinline |
77 | ecb_noinline uint32_t |
78 | random_number_generator<generator>::get_u32 () |
78 | random_number_generator<generator>::get_u32 () |
79 | { |
79 | { |
80 | return generator::next (); |
80 | return generator::next (); |
81 | } |
81 | } |
82 | |
82 | |
83 | template<class generator> |
83 | template<class generator> |
84 | uint64_t noinline |
84 | ecb_noinline uint64_t |
85 | random_number_generator<generator>::get_u64 () |
85 | random_number_generator<generator>::get_u64 () |
86 | { |
86 | { |
87 | return (uint64_t (get_u32 ()) << 32U) | get_u32 (); |
87 | return (uint64_t (get_u32 ()) << 32U) | get_u32 (); |
88 | } |
88 | } |
89 | |
89 | |
90 | template<class generator> |
90 | template<class generator> |
91 | float noinline |
91 | ecb_noinline float |
92 | random_number_generator<generator>::get_float () |
92 | random_number_generator<generator>::get_float () |
93 | { |
93 | { |
94 | return this->next () / (float)0x100000000ULL; |
94 | return this->next () / (float)0x100000000ULL; |
95 | } |
95 | } |
96 | |
96 | |
97 | template<class generator> |
97 | template<class generator> |
98 | double noinline |
98 | ecb_noinline double |
99 | random_number_generator<generator>::get_double () |
99 | random_number_generator<generator>::get_double () |
100 | { |
100 | { |
101 | return this->next () / (double)0x100000000ULL; |
101 | return this->next () / (double)0x100000000ULL; |
102 | } |
102 | } |
103 | |
103 | |
104 | // return a number within (min .. max) |
104 | // return a number within (min .. max) |
105 | template<class generator> |
105 | template<class generator> |
106 | int |
106 | int |
107 | random_number_generator<generator>::get_range (int r_min, int r_max) |
107 | random_number_generator<generator>::get_range (int r_min, int r_max) |
108 | { |
108 | { |
109 | return r_min + get_range (max (r_max - r_min + 1, 0)); |
109 | return r_min + get_range (max (r_max - r_min + 1, 0)); |
110 | } |
110 | } |
111 | |
111 | |