Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | pmbaty | 1 | /* |
2 | * This file is part of the DXX-Rebirth project <https://www.dxx-rebirth.com/>. |
||
3 | * It is copyright by its individual contributors, as recorded in the |
||
4 | * project's Git history. See COPYING.txt at the top level for license |
||
5 | * terms and a link to the Git history. |
||
6 | */ |
||
7 | /* Maths.h library header file */ |
||
8 | |||
9 | #pragma once |
||
10 | |||
11 | #include <cstdint> |
||
12 | #include <stdlib.h> |
||
13 | #include "pstypes.h" |
||
14 | |||
15 | |||
16 | |||
17 | #define D_RAND_MAX 32767 |
||
18 | |||
19 | #ifdef __cplusplus |
||
20 | #include <cstddef> |
||
21 | #include "dxxsconf.h" |
||
22 | #include "dsx-ns.h" |
||
23 | #include <array> |
||
24 | |||
25 | namespace dcx { |
||
26 | |||
27 | void d_srand (unsigned int seed); |
||
28 | __attribute_warn_unused_result |
||
29 | int d_rand (); // Random number function which returns in the range 0-0x7FFF |
||
30 | |||
31 | |||
32 | //=============================== FIXED POINT =============================== |
||
33 | |||
34 | typedef int64_t fix64; //64 bits int, for timers |
||
35 | typedef int32_t fix; //16 bits int, 16 bits frac |
||
36 | typedef int16_t fixang; //angles |
||
37 | |||
38 | typedef struct quadint // integer 64 bit, previously called "quad" |
||
39 | { |
||
40 | union { |
||
41 | struct { |
||
42 | uint32_t low; |
||
43 | int32_t high; |
||
44 | }; |
||
45 | int64_t q; |
||
46 | }; |
||
47 | } |
||
48 | quadint; |
||
49 | |||
50 | |||
51 | //Convert an int to a fix/fix64 and back |
||
52 | static constexpr fix i2f(const int &i) |
||
53 | { |
||
54 | return i << 16; |
||
55 | } |
||
56 | |||
57 | static constexpr int f2i(const fix &f) |
||
58 | { |
||
59 | return f >> 16; |
||
60 | } |
||
61 | |||
62 | //Convert fix to float and float to fix |
||
63 | static constexpr float f2fl(const fix &f) |
||
64 | { |
||
65 | return static_cast<float>(f) / static_cast<float>(65536.0); |
||
66 | } |
||
67 | |||
68 | static constexpr double f2db(const fix &f) |
||
69 | { |
||
70 | return static_cast<double>(f) / 65536.0; |
||
71 | } |
||
72 | |||
73 | static constexpr fix fl2f(const float &f) |
||
74 | { |
||
75 | return static_cast<fix>(f * 65536); |
||
76 | } |
||
77 | |||
78 | //Some handy constants |
||
79 | #define f0_0 0 |
||
80 | #define f1_0 0x10000 |
||
81 | #define f2_0 0x20000 |
||
82 | #define f3_0 0x30000 |
||
83 | #define f10_0 0xa0000 |
||
84 | |||
85 | #define f0_5 0x8000 |
||
86 | #define f0_1 0x199a |
||
87 | |||
88 | //Get the int part of a fix, with rounding |
||
89 | static constexpr int f2ir(const fix &f) |
||
90 | { |
||
91 | return (f + f0_5) >> 16; |
||
92 | } |
||
93 | |||
94 | #define F0_0 f0_0 |
||
95 | #define F1_0 f1_0 |
||
96 | #define F2_0 f2_0 |
||
97 | #define F3_0 f3_0 |
||
98 | #define F10_0 f10_0 |
||
99 | |||
100 | #define F0_5 f0_5 |
||
101 | #define F0_1 f0_1 |
||
102 | |||
103 | //multiply two fixes, return a fix(64) |
||
104 | __attribute_warn_unused_result |
||
105 | fix64 fixmul64 (fix a, fix b); |
||
106 | |||
107 | /* On x86/amd64 for Windows/Linux, truncating fix64->fix is free. */ |
||
108 | __attribute_warn_unused_result |
||
109 | static inline fix fixmul(fix a, fix b) |
||
110 | { |
||
111 | return static_cast<fix>(fixmul64(a, b)); |
||
112 | } |
||
113 | |||
114 | //divide two fixes, return a fix |
||
115 | __attribute_warn_unused_result |
||
116 | fix fixdiv (fix a, fix b); |
||
117 | |||
118 | //multiply two fixes, then divide by a third, return a fix |
||
119 | __attribute_warn_unused_result |
||
120 | fix fixmuldiv (fix a, fix b, fix c); |
||
121 | |||
122 | //multiply two fixes, and add 64-bit product to a quadint |
||
123 | static inline void fixmulaccum (quadint * q, const fix &a, const fix &b) |
||
124 | { |
||
125 | q->q += static_cast<int64_t>(a) * static_cast<int64_t>(b); |
||
126 | } |
||
127 | |||
128 | //extract a fix from a quadint product |
||
129 | __attribute_warn_unused_result |
||
130 | static inline fix fixquadadjust (const quadint *q) |
||
131 | { |
||
132 | return static_cast<fix>(q->q >> 16); |
||
133 | } |
||
134 | |||
135 | //negate a quadint |
||
136 | static inline void fixquadnegate (quadint * q) |
||
137 | { |
||
138 | q->q = -q->q; |
||
139 | } |
||
140 | |||
141 | //computes the square root of a long, returning a short |
||
142 | __attribute_warn_unused_result |
||
143 | ushort long_sqrt (int32_t a); |
||
144 | |||
145 | //computes the square root of a quadint, returning a long |
||
146 | __attribute_warn_unused_result |
||
147 | uint32_t quad_sqrt (quadint); |
||
148 | |||
149 | //computes the square root of a fix, returning a fix |
||
150 | __attribute_warn_unused_result |
||
151 | fix fix_sqrt (fix a); |
||
152 | |||
153 | struct fix_sincos_result |
||
154 | { |
||
155 | fix sin, cos; |
||
156 | }; |
||
157 | |||
158 | __attribute_warn_unused_result |
||
159 | fix_sincos_result fix_sincos(fix); |
||
160 | |||
161 | //compute sine and cosine of an angle, filling in the variables |
||
162 | //either of the pointers can be NULL |
||
163 | |||
164 | __attribute_warn_unused_result |
||
165 | fix fix_sin(fix a); |
||
166 | |||
167 | __attribute_warn_unused_result |
||
168 | fix fix_cos(fix a); |
||
169 | |||
170 | __attribute_warn_unused_result |
||
171 | fix fix_fastsin(fix a); //no interpolation |
||
172 | |||
173 | //compute inverse sine & cosine |
||
174 | __attribute_warn_unused_result |
||
175 | fixang fix_asin (fix v); |
||
176 | |||
177 | __attribute_warn_unused_result |
||
178 | fixang fix_acos (fix v); |
||
179 | |||
180 | //given cos & sin of an angle, return that angle. |
||
181 | //parms need not be normalized, that is, the ratio of the parms cos/sin must |
||
182 | //equal the ratio of the actual cos & sin for the result angle, but the parms |
||
183 | //need not be the actual cos & sin. |
||
184 | //NOTE: this is different from the standard C atan2, since it is left-handed. |
||
185 | __attribute_warn_unused_result |
||
186 | fixang fix_atan2 (fix cos, fix sin); |
||
187 | |||
188 | __attribute_warn_unused_result |
||
189 | int checkmuldiv(fix *r,fix a,fix b,fix c); |
||
190 | |||
191 | extern const std::array<ubyte, 256> guess_table; |
||
192 | extern const std::array<int16_t, 256> sincos_table; |
||
193 | extern const std::array<ushort, 258> asin_table; |
||
194 | extern const std::array<ushort, 258> acos_table; |
||
195 | |||
196 | static inline void clamp_fix_lh(fix& f, const fix& low, const fix& high) |
||
197 | { |
||
198 | if (f < low) |
||
199 | f = low; |
||
200 | else if (high < f) |
||
201 | f = high; |
||
202 | } |
||
203 | |||
204 | static inline void clamp_fix_symmetric(fix& f, const fix& bound) |
||
205 | { |
||
206 | clamp_fix_lh(f, -bound, bound); |
||
207 | } |
||
208 | |||
209 | } |
||
210 | #endif |