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