Subversion Repositories Games.Descent

Rev

Blame | Last modification | View Log | Download | RSS feed

  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
  211.