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