Line data Source code
1 0 : /*
2 :
3 : legacy_random.h
4 :
5 : Pseudo-random number generator designed to produce identical results to that
6 : used in BBC Elite (for dynamic world generation), and related functions.
7 :
8 :
9 : Oolite
10 : Copyright (C) 2004-2013 Giles C Williams and contributors
11 :
12 : This program is free software; you can redistribute it and/or
13 : modify it under the terms of the GNU General Public License
14 : as published by the Free Software Foundation; either version 2
15 : of the License, or (at your option) any later version.
16 :
17 : This program is distributed in the hope that it will be useful,
18 : but WITHOUT ANY WARRANTY; without even the implied warranty of
19 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 : GNU General Public License for more details.
21 :
22 : You should have received a copy of the GNU General Public License
23 : along with this program; if not, write to the Free Software
24 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
25 : MA 02110-1301, USA.
26 :
27 : */
28 :
29 : #ifndef LEGACY_RANDOM_H
30 : #define LEGACY_RANDOM_H
31 :
32 : #include "OOFunctionAttributes.h"
33 : #include <math.h>
34 : #include <stdint.h>
35 :
36 :
37 0 : typedef struct Random_Seed
38 : {
39 0 : uint8_t a, /* 6c */
40 0 : b, /* 6d */
41 0 : c, /* 6e */
42 0 : d, /* 6f */
43 0 : e, /* 70 */
44 0 : f; /* 71 */
45 0 : } Random_Seed;
46 :
47 :
48 0 : typedef struct RNG_Seed
49 : {
50 0 : int32_t a,
51 0 : b,
52 0 : c,
53 0 : d;
54 0 : } RNG_Seed;
55 :
56 :
57 0 : typedef struct RANROTSeed
58 : {
59 0 : uint32_t high,
60 0 : low;
61 0 : } RANROTSeed;
62 :
63 :
64 0 : extern const Random_Seed kNilRandomSeed;
65 :
66 :
67 : // checksum stuff
68 0 : void clear_checksum(void);
69 0 : int16_t munge_checksum(long long value);
70 :
71 : // cunning price rounding routine:
72 0 : double cunningFee(double value, double precision); // precision is the fraction below which numbers become insignificant.
73 :
74 : // an implementation of RANROT
75 : // pseudo random number generator
76 0 : void ranrot_srand(uint32_t seed);
77 0 : unsigned Ranrot(void);
78 0 : #define ranrot_rand() ((int)Ranrot()) // Some uses perform arithmetic that does weird things if result is unsigned -- DustEntity.m, for instance.
79 0 : float randf(void);
80 0 : float bellf(int n);
81 :
82 0 : RANROTSeed RANROTGetFullSeed(void);
83 0 : void RANROTSetFullSeed(RANROTSeed seed);
84 :
85 0 : RANROTSeed MakeRanrotSeed(uint32_t seed);
86 0 : RANROTSeed RanrotSeedFromRNGSeed(RNG_Seed seed);
87 0 : RANROTSeed RanrotSeedFromRandomSeed(Random_Seed seed);
88 :
89 0 : unsigned RanrotWithSeed(RANROTSeed *ioSeed);
90 0 : float randfWithSeed(RANROTSeed *ioSeed);
91 :
92 :
93 : OOINLINE double distanceBetweenPlanetPositions(int x1, int y1, int x2, int y2) INLINE_CONST_FUNC;
94 : OOINLINE double accurateDistanceBetweenPlanetPositions(int x1, int y1, int x2, int y2) INLINE_CONST_FUNC;
95 :
96 0 : void seed_for_planet_description(Random_Seed s_seed);
97 0 : void seed_RNG_only_for_planet_description(Random_Seed s_seed);
98 0 : RNG_Seed currentRandomSeed(void);
99 0 : void setRandomSeed(RNG_Seed a_seed);
100 :
101 : // Range: 0..255
102 0 : int gen_rnd_number (void);
103 :
104 0 : void make_pseudo_random_seed (Random_Seed *seed_ptr);
105 :
106 : OOINLINE int is_nil_seed(Random_Seed a_seed) INLINE_CONST_FUNC;
107 :
108 0 : void rotate_seed (Random_Seed *seed_ptr);
109 : OOINLINE int rotate_byte_left (int x) INLINE_CONST_FUNC;
110 :
111 : OOINLINE int equal_seeds(Random_Seed seed1, Random_Seed seed2) INLINE_CONST_FUNC;
112 :
113 :
114 : /*
115 : The "really really random" PRNG. This is a separate RANROT seed that is
116 : seeded once at startup and never reset under any circumstances. It can
117 : also be used to seed get_rnd_number and the main RANROT seed. If doing this,
118 : save and restore the seeds using the functions above ore OOSaveRandomState()
119 : and OORestoreRandomState().
120 :
121 : Since these use a global seed, they may only be used from the main thread.
122 : */
123 :
124 0 : uint32_t OOReallyRandom(void);
125 0 : void OOInitReallyRandom(uint64_t seed);
126 :
127 0 : void OOSetReallyRandomRANROTSeed(void);
128 0 : void OOSetReallyRandomRndSeed(void);
129 0 : void OOSetReallyRandomRANROTAndRndSeeds(void);
130 :
131 : /*
132 : OOSaveRandomState()/OORestoreRandomState(): save and restore both the main
133 : RANROT seed and the rnd seed in one shot.
134 : */
135 0 : typedef struct
136 : {
137 0 : RANROTSeed ranrot;
138 0 : RNG_Seed rnd;
139 : } OORandomState;
140 :
141 0 : OORandomState OOSaveRandomState(void);
142 0 : void OORestoreRandomState(OORandomState state);
143 :
144 :
145 :
146 : /*** Only inline definitions beyond this point ***/
147 :
148 0 : OOINLINE int equal_seeds(Random_Seed seed1, Random_Seed seed2)
149 : {
150 : return ((seed1.a == seed2.a)&&(seed1.b == seed2.b)&&(seed1.c == seed2.c)&&(seed1.d == seed2.d)&&(seed1.e == seed2.e)&&(seed1.f == seed2.f));
151 : }
152 :
153 :
154 0 : OOINLINE int is_nil_seed(Random_Seed a_seed)
155 : {
156 : return equal_seeds(a_seed, kNilRandomSeed);
157 : }
158 :
159 :
160 0 : OOINLINE int rotate_byte_left(int x)
161 : {
162 : return ((x << 1) | (x >> 7)) & 255;
163 : }
164 :
165 :
166 : // a method used to determine interplanetary distances,
167 : // if accurate, it has to scale distance down by a factor of 7.15:7.0
168 : // to allow routes navigable in the original!
169 0 : OOINLINE double distanceBetweenPlanetPositions(int x1, int y1, int x2, int y2)
170 : {
171 : int dx = x1 - x2;
172 : int dy = (y1 - y2)/2;
173 : int dist = sqrt(dx*dx + dy*dy); // N.b. Rounding error due to truncation is desired.
174 : return 0.4 * dist;
175 : }
176 :
177 :
178 0 : OOINLINE double accurateDistanceBetweenPlanetPositions(int x1, int y1, int x2, int y2)
179 : {
180 : double dx = x1 - x2;
181 : double dy = (y1 - y2) / 2.0;
182 : double dist = hypot(dx, dy);
183 : return 0.4 * dist;
184 : }
185 :
186 :
187 0 : OOINLINE double travelTimeBetweenPlanetPositions(int x1, int y1, int x2, int y2)
188 : {
189 : double distance = distanceBetweenPlanetPositions(x1, y1, x2, y2);
190 : return distance * distance;
191 : }
192 :
193 : #endif
|