00001
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 #ifndef _MGUI_FIXED_MATH_H
00035 #define _MGUI_FIXED_MATH_H
00036
00037 #include <errno.h>
00038 #include <math.h>
00039
00040
00041 #ifdef __cplusplus
00042 extern "C" {
00043 #endif
00044
00045 #ifdef _FIXED_MATH
00046
00087 MG_EXPORT fixed fixsqrt (fixed x);
00088
00099 MG_EXPORT fixed fixhypot (fixed x, fixed y);
00100
00113 MG_EXPORT fixed fixatan (fixed x);
00114
00129 MG_EXPORT fixed fixatan2 (fixed y, fixed x);
00130
00131 extern MG_EXPORT fixed _cos_tbl[];
00132 extern MG_EXPORT fixed _tan_tbl[];
00133 extern MG_EXPORT fixed _acos_tbl[];
00134
00135
00136
00137
00150 static inline fixed ftofix (double x)
00151 {
00152 if (x > 32767.0) {
00153 errno = ERANGE;
00154 return 0x7FFFFFFF;
00155 }
00156
00157 if (x < -32767.0) {
00158 errno = ERANGE;
00159 return -0x7FFFFFFF;
00160 }
00161
00162 return (long)(x * 65536.0 + (x < 0 ? -0.5 : 0.5));
00163 }
00164
00174 static inline double fixtof (fixed x)
00175 {
00176 return (double)x / 65536.0;
00177 }
00178
00179
00194 static inline fixed fixadd (fixed x, fixed y)
00195 {
00196 fixed result = x + y;
00197
00198 if (result >= 0) {
00199 if ((x < 0) && (y < 0)) {
00200 errno = ERANGE;
00201 return -0x7FFFFFFF;
00202 }
00203 else
00204 return result;
00205 }
00206 else {
00207 if ((x > 0) && (y > 0)) {
00208 errno = ERANGE;
00209 return 0x7FFFFFFF;
00210 }
00211 else
00212 return result;
00213 }
00214 }
00215
00231 static inline fixed fixsub (fixed x, fixed y)
00232 {
00233 fixed result = x - y;
00234
00235 if (result >= 0) {
00236 if ((x < 0) && (y > 0)) {
00237 errno = ERANGE;
00238 return -0x7FFFFFFF;
00239 }
00240 else
00241 return result;
00242 }
00243 else {
00244 if ((x > 0) && (y < 0)) {
00245 errno = ERANGE;
00246 return 0x7FFFFFFF;
00247 }
00248 else
00249 return result;
00250 }
00251 }
00252
00266 static inline fixed fixmul (fixed x, fixed y)
00267 {
00268 return ftofix(fixtof(x) * fixtof(y));
00269 }
00270
00284 static inline fixed fixdiv (fixed x, fixed y)
00285 {
00286 if (y == 0) {
00287 errno = ERANGE;
00288 return (x < 0) ? -0x7FFFFFFF : 0x7FFFFFFF;
00289 }
00290 else
00291 return ftofix(fixtof(x) / fixtof(y));
00292 }
00293
00304 static inline int fixceil (fixed x)
00305 {
00306 if (x > 0x7FFF0000) {
00307 errno = ERANGE;
00308 return 0x7FFF;
00309 }
00310
00311 x += 0xFFFF;
00312 if (x > 0)
00313 return (x >> 16);
00314 else
00315 return ~((~x) >> 16);
00316 }
00317
00326 static inline fixed itofix (int x)
00327 {
00328 return x << 16;
00329 }
00330
00339 static inline int fixtoi (fixed x)
00340 {
00341 return (x >> 16) + ((x & 0x8000) >> 15);
00342 }
00343
00353 static inline fixed fixcos (fixed x)
00354 {
00355 return _cos_tbl[((x + 0x4000) >> 15) & 0x1FF];
00356 }
00357
00367 static inline fixed fixsin (fixed x)
00368 {
00369 return _cos_tbl[((x - 0x400000 + 0x4000) >> 15) & 0x1FF];
00370 }
00371
00381 static inline fixed fixtan (fixed x)
00382 {
00383 return _tan_tbl[((x + 0x4000) >> 15) & 0xFF];
00384 }
00385
00399 static inline fixed fixacos (fixed x)
00400 {
00401 if ((x < -65536) || (x > 65536)) {
00402 errno = EDOM;
00403 return 0;
00404 }
00405
00406 return _acos_tbl[(x+65536+127)>>8];
00407 }
00408
00422 static inline fixed fixasin (fixed x)
00423 {
00424 if ((x < -65536) || (x > 65536)) {
00425 errno = EDOM;
00426 return 0;
00427 }
00428
00429 return 0x00400000 - _acos_tbl[(x+65536+127)>>8];
00430 }
00431
00439 #endif
00440
00441
00442 #ifdef __cplusplus
00443 }
00444 #endif
00445
00446 #endif
00447