1 /*
2 
3 Copyright (C) 2015-2018 Night Dive Studios, LLC.
4 
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9 
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 
18 */
19 /*
20  * $Source: r:/prj/lib/src/fix/RCS/fix.h $
21  * $Revision: 1.41 $
22  * $Author: jaemz $
23  * $Date: 1994/08/18 18:10:21 $
24  *
25  * Code, prototypes and types for fixed-point routines.
26  *
27  * $Log: fix.h $
28  * Revision 1.41  1994/08/18  18:10:21  jaemz
29  * Added sloppy_sqrt
30  *
31  * Revision 1.40  1994/08/11  12:11:14  dfan
32  * multiple source directories
33  *
34  * Revision 1.39  1994/03/16  10:29:25  lmfeeney
35  * ,
36  * added extern fn fix_pow
37  *
38  * Revision 1.38  1994/03/16  10:29:25  dfan
39  * fix_safe_pyth_dist etc.
40  * also conversions to and from degrees
41  *
42  * Revision 1.37  1994/01/22  19:05:46  dc
43  * fast_fix_mul_int
44  *
45  * Revision 1.36  1994/01/22  19:04:22  dc
46  * shrd not shr\shl\or for fix_mul
47  * neat
48  *
49  * Revision 1.34  1993/11/11  13:50:46  rex
50  * Changed fix_from_float() to much simpler macro, added atofix() and atofix24()
51  *
52  * Revision 1.33  1993/11/05  13:56:16  dfan
53  * 2pi was wrong.
54  *
55  * Revision 1.32  1993/11/04  11:13:42  dfan
56  * long_fast_pyth_dist
57  *
58  * Revision 1.31  1993/09/17  13:03:36  dfan
59  * fast_pyth_dist
60  *
61  * Revision 1.30  1993/08/17  15:10:04  kaboom
62  * Added fix_cint and fix_fint macros.
63  *
64  * Revision 1.29  1993/07/30  12:42:58  dfan
65  * fix_exp
66  *
67  * Revision 1.28  1993/07/07  12:26:58  xemu
68  * fixed a numerical error in fixang_to_fixrad
69  *
70  * Revision 1.27  1993/07/02  15:10:01  xemu
71  * conversion from fixed-point radians to fixangs
72  *
73  * Revision 1.26  1993/06/27  02:30:47  dc
74  * added char return to fix_sprint prototypes, added fix_sprint_hex prototypes
75  *
76  * Revision 1.25  1993/06/07  10:29:36  jak
77  * Reversed #pragma and C decls for some functions
78  * so that C++ parser will be happy.
79  *
80  * Revision 1.24  1993/06/05  07:38:36  mahk
81  * Added abs, sgn, FIXANG_PI
82  *
83  * Revision 1.23  1993/04/19  13:31:42  dfan
84  * individual sin & cos functions
85  *
86  * Revision 1.22  1993/04/14  17:13:23  jaemz
87  * Added FIX_MIN and FIX_MAX
88  *
89  * Revision 1.21  1993/04/14  16:57:23  jaemz
90  * Added floor and ceil
91  *
92  * Revision 1.20  1993/04/07  10:15:06  matt
93  * Removed include of math.h, which seemed unneccesary.
94  *
95  * Revision 1.19  1993/03/15  16:55:45  matt
96  * Added include of "types.h"
97  *
98  * Revision 1.18  1993/03/03  14:46:59  dfan
99  * fix_from_float: short should have been ushort to prevent nasty sign-extend
100  *
101  * Revision 1.17  1993/03/03  11:50:53  dfan
102  * float conversion
103  *
104  * Revision 1.16  1993/02/16  10:44:33  matt
105  * Added parens around macro args
106  *
107  *
108  * Revision 1.15  1993/02/15  12:15:29  dfan
109  * more fix24 functions
110  *
111  * Revision 1.14  1993/02/15  11:40:22  dfan
112  * fix24 support
113  *
114  * Revision 1.13  1993/02/04  16:25:33  matt
115  * Added new fix_mul_div() function
116  *
117  * Revision 1.12  1993/01/29  11:10:45  dfan
118  * hey, fix_sqrt returns a 32-bit value
119  *
120  * Revision 1.11  1993/01/29  10:42:34  dfan
121  * type in fix_sqrt pragma
122  *
123  * Revision 1.10  1993/01/27  16:47:16  dfan
124  * sqrt functions
125  * by the way, the arctrig functions did work after all
126  *
127  * Revision 1.9  1993/01/22  15:52:36  dfan
128  * Asin, acos, and atan2 do work after all
129  *
130  * Revision 1.8  1993/01/22  09:57:19  dfan
131  * Added lots of functions, including trig ones
132  * Arctrig doesn't work yet
133  *
134  * Revision 1.7  1992/10/14  23:37:46  kaboom
135  * Added fix_rint macro to round & take integer part.
136  *
137  * Revision 1.6  1992/10/13  22:34:24  kaboom
138  * Added #ifdef __FIX_H clause around body of file.
139  *
140  * Revision 1.5  1992/09/16  19:52:06  kaboom
141  * Modified the fix_int macro not to round off before converting fix to int.
142  * Added fix_trunc to remove fractional part, fix_frac to return fractional
143  * part.
144  *
145  * Revision 1.4  1992/09/16  19:28:26  kaboom
146  * Changed fix_mul and fix_div to be inline assembly-language functions
147  * instead of called functions.  That makes this the only file in the
148  * fixed-point math library and fix.asm is obsolete.
149  *
150  * Revision 1.3  1992/09/15  14:08:22  kaboom
151  * Made typedef for fixed point variables.  Added fix_make macro.
152  *
153  * Revision 1.2  1992/08/24  17:27:17  kaboom
154  * Added RCS keywords and header at top of file.
155  *
156  * Revision 1.1  1992/08/24  17:27:17  kaboom
157  * Initial revision.
158  */
159 
160 #ifndef __FIX_H
161 #define __FIX_H
162 
163 #include <stdbool.h>
164 #include <stdint.h>
165 #include <stdlib.h>
166 
167 #include "lg_types.h"
168 
169 #if defined(__cplusplus)
170 extern "C" {
171 #endif
172 
173 // Globals
174 extern int gOVResult;
175 
176 ///////////////////////////////
177 //
178 // First some math functions that don't use fixes.
179 //
180 /*  @@@ Change this
181 // Returns 0 if x < 0
182 #pragma aux long_sqrt parm [eax] value [ax] modify [eax ebx ecx edx esi edi]
183 */
184 int long_sqrt(int x);
185 
186 //////////////////////////////
187 //
188 // fix.c
189 //
190 
191 int long_fast_pyth_dist(int a, int b);
192 
193 //========================================
194 //
195 // Now for fixes themselves.  Macros.
196 //
197 //========================================
198 
199 /* these functions operate on fixed-point numbers with one bit of sign, 15
200    bits of integer, and 16 bits of fraction.  thus, a rational number a is
201    represented as a 32-bit number as a*2^16. */
202 
203 typedef int32_t fix;
204 typedef fix fix16;
205 
206 // define min and max
207 #define FIX_MAX (0x7fffffff)
208 #define FIX_MIN (0x80000000)
209 
210 // A fixang (fixed-point angle) can be converted to radians by multiplying
211 // by 2 * PI and dividing by 2^16.
212 //
213 // 0x0000 -> 0
214 // 0x4000 -> PI/2
215 // 0x8000 -> PI
216 // 0xc000 -> 3PI/2
217 //
218 
219 #define FIXANG_PI 0x8000
220 #define fix_2pi fix_make(6, 18559) // that's 6 + 18559/65536 = 6.28319
221 
222 typedef uint16_t fixang;
223 
224 /* makes a fixed point number with integral part a and fractional part b. */
225 #define fix_make(a, b) (int32_t)((((uint32_t)(a)) << 16) | (b))
226 
227 #define FIX_UNIT fix_make(1, 0)
228 
229 /* lops off the fractional part of a fixed point number. */
230 #define fix_trunc(n) ((n)&0xffff0000)
231 
232 /* Does a floor */
233 #define fix_floor(n) ((n)&0xffff0000)
234 
235 /* Does a ceil */
236 #define fix_ceil(n) (((n) + 65535) & 0xffff0000)
237 
238 /* round a fix to the nearest integer, leaving in fix format. */
239 #define fix_round(n) (((n) + 32768) & 0xffff0000)
240 
241 /* returns the integral part of a fixed point number. */
242 #define fix_int(n) ((int16_t)((n) >> 16))
243 
244 // Absolute value and signum
245 #define fix_abs(n) (((n) < 0) ? -(n) : (n))
246 #define fix_sgn(n) (((n) < 0) ? -FIX_UNIT : (((n) == 0) ? 0 : FIX_UNIT))
247 
248 /* converts the floor of n to an integer. */
249 #define fix_fint(n) ((n) >> 16)
250 
251 /* converts the ceiling of n to an integer. */
252 #define fix_cint(n) (((n) + 0xffff) >> 16)
253 
254 /* returns the integral part of a fixed point number rounded up. */
255 // #define fix_rint(n) (fix_int (fix_round (n)))
256 // the following macro does it all explictly to avoid the spurious & in
257 // fix_round
258 #define fix_rint(n) (((n) + 0x8000) >> 16)
259 
260 /* returns the fractional part of a fixed point number. */
261 #define fix_frac(n) ((uint16_t)((n)&0xffff))
262 
263 // fixrad_to_fixang converts a fixed-point in radians to a fixang
264 // fixang_to_fixrad converts a fixang to a fixed point radians
265 // degrees_to_fixang converts an integer number of degrees to a fixang
266 // fixang_to_degrees converts a fixang to an integer number of degrees
267 
268 #define fixrad_to_fixang(fixradian) (fix_frac(fix_div((fixradian), fix_2pi)))
269 #define fixang_to_fixrad(ang) fix_div(fix_mul(ang, fix_2pi), 0x10000)
270 #define degrees_to_fixang(d) ((fixang)(((d)*FIXANG_PI) / 180))
271 #define fixang_to_degrees(ang) (((int)(ang)*180) / FIXANG_PI)
272 
273 // turns a fixed point into a float.
274 #define fix_float(n) ((float)(fix_int(n)) + (float)(fix_frac(n)) / 65536.0)
275 
276 // makes a fixed point from a float.
277 #define fix_from_float(n) ((fix)(65536.0 * (n)))
278 
279 //========================================
280 //
281 // Multiplication and division.
282 //
283 //========================================
284 
285 // For Mac version: The PowerPC version uses two assembly language routines
286 // to do the multiply and divide.
287 fix fix_mul(fix a, fix b);
288 fix fix_mul_asm_safe(fix a, fix b);
289 fix fix_div(fix a, fix b);
290 fix fix_div_int(fix a, fix b);
291 fix fix_div_safe_cint(fix a, fix b);
292 fix fix_mul_div(fix m0, fix m1, fix d);
293 fix fast_fix_mul_int(fix a, fix b);
294 #define fast_fix_mul fix_mul
295 
296 //========================================
297 //
298 //  Square rooty kind of stuff.
299 //
300 //========================================
301 
302 // Returns sqrt (a^2 + b^2)
303 fix fix_pyth_dist(fix a, fix b);
304 
305 // Returns approximately sqrt (a^2 + b^2)
306 // Is never off by more than 12% (it's worst at 45 deg)
307 fix fix_fast_pyth_dist(fix a, fix b);
308 
309 // pyth_dist with less fear of overflow.  Either number
310 // can be up to 0x2fffffff.
311 fix fix_safe_pyth_dist(fix a, fix b);
312 
313 // Now in FIX_SQRT.C
314 // Returns 0 if x < 0
315 fix fix_sqrt(fix x);
316 
317 int32_t quad_sqrt(int32_t hi, uint32_t lo);
318 
319 //========================================
320 //
321 //  Trigonometric functions.
322 //
323 //========================================
324 
325 // Computes sin and cos of theta
326 void fix_sincos(fixang theta, fix *sin, fix *cos);
327 
328 fix fix_sin(fixang theta);
329 
330 fix fix_cos(fixang theta);
331 
332 // Computes sin and cos of theta
333 // Faster than fix_sincos() but not as accurate (does not interpolate)
334 void fix_fastsincos(fixang theta, fix *sin, fix *cos);
335 
336 fix fix_fastsin(fixang theta);
337 
338 fix fix_fastcos(fixang theta);
339 
340 // Computes the arcsin of x
341 fixang fix_asin(fix x);
342 
343 // Computes the arccos of x
344 fixang fix_acos(fix x);
345 
346 // Computes the atan of y/x, in the correct quadrant and everything
347 fixang fix_atan2(fix y, fix x);
348 
349 #if defined(__cplusplus)
350 }
351 #endif
352 
353 /* fixpoint x ^ y */
354 extern fix fix_pow(fix x, fix y);
355 
356 //////////////////////////////
357 //
358 // f_exp.c
359 
360 // Computes e to the x
361 //
362 fix fix_exp(fix x);
363 
364 //////////////////////////////
365 //
366 // fix24 - 24 bits integer, 8 bits fraction
367 //
368 
369 typedef int32_t fix24;
370 
371 #define fix24_make(a, b) ((((int32_t)(a)) << 8) | (b))
372 #define fix24_trunc(n) ((n)&0xffffff00)
373 #define fix24_round(n) (((n) + 128) & 0xffffff00)
374 #define fix24_int(n) ((n) >> 8)
375 #define fix24_frac(n) ((n)&0xff)
376 #define fix24_float(n) ((float)(fix24_int(n)) + (float)(fix24_frac(n)) / 256.0)
377 
378 #define fix24_from_fix16(n) ((n) >> 8)
379 #define fix16_from_fix24(n) ((n) << 8)
380 
381 // For Mac version: The PowerPC version uses an assembly language routine
382 // to do the multiply.
383 fix24 fix24_mul(fix24 a, fix24 b);
384 fix24 fix24_div(fix24 a, fix24 b);
385 
386 // Wide (64-bit) fix functions
387 
388 // 64-bit fix type (high 32 bit - integer, low 32 bit - fractional)
389 typedef int64_t fix64;
390 
391 #define fix64_make(a, b) ((((int64_t)(a)) << 32) | (b))
392 #define fix64_int(n) ((int32_t)((n) >> 32))
393 #define fix64_frac(n) ((uint32_t)((n) & 0xffffffff))
394 #define fix64_to_fix(n) (fix64_int(n) << 16 | fix64_frac(n) >> 16)
395 
396 // fix64 algebraic functions
397 /**
398  * Divide two numbers. There no divide by zero check!
399  * @param a dividend
400  * @param b divisor
401  * @return int32_t result of division
402  */
403 extern int32_t fix64_div(int64_t a, int32_t b);
404 
405 /**
406  * Multiply two numbers.
407  * @param a number
408  * @param b number
409  * @return result of multiplication
410  */
411 extern int64_t fix64_mul(int32_t a, int32_t b);
412 
413 //============================================
414 //
415 //  Other multiply/div/add variants used by 2D and 3D.
416 //
417 //============================================
418 extern fix fix_mul_3_3_3(fix a, fix b);
419 extern fix fix_mul_3_32_16(fix a, fix b);
420 extern fix fix_mul_3_16_20(fix a, fix b);
421 extern fix fix_mul_16_32_20(fix a, fix b);
422 
423 extern fix fix_div_16_16_3(fix a, fix b);
424 
425 #define fix_mul_div_3_16_16_3 fix_mul_div
426 
427 extern fix fix_div_16_16_3(fix a, fix b);
428 extern fix fix_mul_3_3_3(fix a, fix b);
429 extern fix fix_mul_3_32_16(fix a, fix b);
430 extern fix fix_mul_3_16_20(fix a, fix b);
431 extern fix fix_mul_16_32_20(fix a, fix b);
432 
433 #define fix_div_16_3_16 fix_div_16_16_3
434 #define fix_div_3_3_16 fix_div
435 #define fix_mul_3_16_16 fix_mul_3_3_3
436 
437 #define fix_sal(a, b) ((a) << (b))
438 #define fix_sar(a, b) ((a) >> (b))
439 
440 #define fix_3_16(a) ((a) >> 13)
441 
442 #define FIX_UNIT_3 0x20000000
443 
444 #endif /* !__fix24_H */
445