This commit was manufactured by cvs2svn to create tag 'd2x-0_1_2'.
[btb/d2x.git] / include / maths.h
1 /* Maths.h library header file */
2
3 #ifndef _MATHS_H
4 #define _MATHS_H
5
6 #define NO_FIX_INLINE 1
7
8 #include <stdlib.h>
9 #include "pstypes.h"
10
11
12
13 #define D_RAND_MAX 32767
14
15 void d_srand (unsigned int seed);
16 int d_rand ();                  // Random number function which returns in the range 0-0x7FFF
17
18
19 //=============================== FIXED POINT ===============================
20
21 typedef int32_t fix;            //16 bits int, 16 bits frac
22 typedef int16_t fixang;         //angles
23
24 typedef struct quad
25   {
26     u_int32_t low;
27     int32_t high;
28   }
29 quad;
30
31
32 //Convert an int to a fix
33 #define i2f(i) ((i)<<16)
34
35 //Get the int part of a fix
36 #define f2i(f) ((f)>>16)
37
38 //Get the int part of a fix, with rounding
39 #define f2ir(f) (((f)+f0_5)>>16)
40
41 //Convert fix to float and float to fix
42 #define f2fl(f) (((float)  (f)) / 65536.0)
43 #define f2db(f) (((double) (f)) / 65536.0)
44 #define fl2f(f) ((fix) ((f) * 65536))
45
46 //Some handy constants
47 #define f0_0    0
48 #define f1_0    0x10000
49 #define f2_0    0x20000
50 #define f3_0    0x30000
51 #define f10_0   0xa0000
52
53 #define f0_5 0x8000
54 #define f0_1 0x199a
55
56 #define F0_0    f0_0
57 #define F1_0    f1_0
58 #define F2_0    f2_0
59 #define F3_0    f3_0
60 #define F10_0   f10_0
61
62 #define F0_5    f0_5
63 #define F0_1    f0_1
64
65 //#if defined(NO_FIX_INLINE) || (!defined(__GNUC__) && !defined(__WATCOMC__))
66 //multiply two fixes, return a fix
67 fix fixmul (fix a, fix b);
68
69 //divide two fixes, return a fix
70 fix fixdiv (fix a, fix b);
71
72 //multiply two fixes, then divide by a third, return a fix
73 fix fixmuldiv (fix a, fix b, fix c);
74 #if 0
75
76 //#else
77
78 //#ifdef __WATCOMC__
79 fix fixmul (fix a, fix b);
80
81 #pragma aux fixmul parm [eax] [edx] = \
82 "imul   edx" \
83 "shrd   eax,edx,16";
84
85
86
87 fix fixdiv (fix a, fix b);
88
89 #pragma aux fixdiv parm [eax] [ebx] modify exact [eax edx] = \
90 "mov    edx,eax" \
91 "sar    edx,16" \
92 "shl    eax,16" \
93 "idiv   ebx";
94
95
96 fix fixmuldiv (fix a, fix b, fix c);
97
98 #pragma aux fixmuldiv parm [eax] [edx] [ebx] modify exact [eax edx] = \
99 "imul   edx" \
100 "idiv   ebx";
101
102 //#elif defined (__GNUC__)
103 /*
104 static inline fix
105 fixmul (fix a, fix b)
106 {
107   
108     fix __retval;
109   
110     asm (" imul   %2;"
111          " shrd   $16,%%edx,%%eax" 
112 : "=a" (__retval): "a" (a), "d" (b):"%edx");
113   
114     return __retval;
115   
116 } */
117
118 //multiply two fixes, return a fix
119 fix fixmul (fix a, fix b);
120
121
122 //divide two fixes, return a fix
123 fix fixdiv (fix a, fix b);
124
125 //multiply two fixes, then divide by a third, return a fix
126 fix fixmuldiv (fix a, fix b, fix c);
127
128 //#if 0
129 static inline fix
130 fixdiv (fix a, fix b)
131 {
132   
133     register fix __retval;
134   
135     asm (" mov %%eax,%%edx;" 
136          " sar $16,%%edx;" 
137          " shl $16,%%eax;" 
138          " idiv %%ecx" /* adb: how to make this %0 w/o chance of edx? */  
139 : "=a" (__retval): "a" (a), "c" (b):"%edx");
140   
141     return __retval;
142   
143 }
144
145 static inline fix
146 fixmuldiv (fix a, fix b, fix c)
147 {
148   
149     register fix __retval;
150   
151     asm (" imul   %0;" 
152          " idiv   %%ecx" /* adb: how to make this %0 w/o chance of edx? */  
153 : "=a" (__retval): "a" (a), "r" (b), "c" (c):"%edx");
154   
155     return __retval;
156
157 }
158 //#endif
159
160 //#endif // __GNUC__ / __WATCOMC__
161 //#endif /* defined NO_FIX_INLINE || (!defined __GNUC__ && !defined __WATCOMC__) */
162
163 #endif
164
165 //multiply two fixes, and add 64-bit product to a quad
166 void fixmulaccum (quad * q, fix a, fix b);
167
168 //extract a fix from a quad product
169 fix fixquadadjust (quad * q);
170
171 //divide a quad by a long
172 int32_t fixdivquadlong (u_int32_t qlow, u_int32_t qhigh, u_int32_t d);
173
174 //negate a quad
175 void fixquadnegate (quad * q);
176
177 //computes the square root of a long, returning a short
178 ushort long_sqrt (int32_t a);
179
180 //computes the square root of a quad, returning a long
181 u_int32_t quad_sqrt (u_int32_t low, int32_t high);
182 //ulong quad_sqrt (long low, long high);
183
184 //computes the square root of a fix, returning a fix
185 fix fix_sqrt (fix a);
186
187 //compute sine and cosine of an angle, filling in the variables
188 //either of the pointers can be NULL
189 void fix_sincos (fix a, fix * s, fix * c);      //with interpolation
190
191 void fix_fastsincos (fix a, fix * s, fix * c);  //no interpolation
192
193 //compute inverse sine & cosine
194 fixang fix_asin (fix v);
195
196 fixang fix_acos (fix v);
197
198 //given cos & sin of an angle, return that angle.
199 //parms need not be normalized, that is, the ratio of the parms cos/sin must
200 //equal the ratio of the actual cos & sin for the result angle, but the parms 
201 //need not be the actual cos & sin.  
202 //NOTE: this is different from the standard C atan2, since it is left-handed.
203 fixang fix_atan2 (fix cos, fix sin);
204
205 //for passed value a, returns 1/sqrt(a) 
206 fix fix_isqrt (fix a);
207
208 #endif