00001
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #ifndef _MGUI_FIXED_MATH_H
00033 #define _MGUI_FIXED_MATH_H
00034
00035 #include <errno.h>
00036 #include <math.h>
00037
00038
00039 #ifdef __cplusplus
00040 extern "C" {
00041 #endif
00042
00043 #ifdef _FIXED_MATH
00044
00085 MG_EXPORT fixed fixsqrt (fixed x);
00086
00097 MG_EXPORT fixed fixhypot (fixed x, fixed y);
00098
00111 MG_EXPORT fixed fixatan (fixed x);
00112
00127 MG_EXPORT fixed fixatan2 (fixed y, fixed x);
00128
00129 extern MG_EXPORT fixed _cos_tbl[];
00130 extern MG_EXPORT fixed _tan_tbl[];
00131 extern MG_EXPORT fixed _acos_tbl[];
00132
00133
00134
00135
00148 static inline fixed ftofix (double x)
00149 {
00150 if (x > 32767.0) {
00151 errno = ERANGE;
00152 return 0x7FFFFFFF;
00153 }
00154
00155 if (x < -32767.0) {
00156 errno = ERANGE;
00157 return -0x7FFFFFFF;
00158 }
00159
00160 return (long)(x * 65536.0 + (x < 0 ? -0.5 : 0.5));
00161 }
00162
00172 static inline double fixtof (fixed x)
00173 {
00174 return (double)x / 65536.0;
00175 }
00176
00177
00192 static inline fixed fixadd (fixed x, fixed y)
00193 {
00194 fixed result = x + y;
00195
00196 if (result >= 0) {
00197 if ((x < 0) && (y < 0)) {
00198 errno = ERANGE;
00199 return -0x7FFFFFFF;
00200 }
00201 else
00202 return result;
00203 }
00204 else {
00205 if ((x > 0) && (y > 0)) {
00206 errno = ERANGE;
00207 return 0x7FFFFFFF;
00208 }
00209 else
00210 return result;
00211 }
00212 }
00213
00229 static inline fixed fixsub (fixed x, fixed y)
00230 {
00231 fixed result = x - y;
00232
00233 if (result >= 0) {
00234 if ((x < 0) && (y > 0)) {
00235 errno = ERANGE;
00236 return -0x7FFFFFFF;
00237 }
00238 else
00239 return result;
00240 }
00241 else {
00242 if ((x > 0) && (y < 0)) {
00243 errno = ERANGE;
00244 return 0x7FFFFFFF;
00245 }
00246 else
00247 return result;
00248 }
00249 }
00250
00264 static inline fixed fixmul (fixed x, fixed y)
00265 {
00266 return ftofix(fixtof(x) * fixtof(y));
00267 }
00268
00282 static inline fixed fixdiv (fixed x, fixed y)
00283 {
00284 if (y == 0) {
00285 errno = ERANGE;
00286 return (x < 0) ? -0x7FFFFFFF : 0x7FFFFFFF;
00287 }
00288 else
00289 return ftofix(fixtof(x) / fixtof(y));
00290 }
00291
00302 static inline int fixceil (fixed x)
00303 {
00304 if (x > 0x7FFF0000) {
00305 errno = ERANGE;
00306 return 0x7FFF;
00307 }
00308
00309 x += 0xFFFF;
00310 if (x > 0)
00311 return (x >> 16);
00312 else
00313 return ~((~x) >> 16);
00314 }
00315
00324 static inline fixed itofix (int x)
00325 {
00326 return x << 16;
00327 }
00328
00337 static inline int fixtoi (fixed x)
00338 {
00339 return (x >> 16) + ((x & 0x8000) >> 15);
00340 }
00341
00351 static inline fixed fixcos (fixed x)
00352 {
00353 return _cos_tbl[((x + 0x4000) >> 15) & 0x1FF];
00354 }
00355
00365 static inline fixed fixsin (fixed x)
00366 {
00367 return _cos_tbl[((x - 0x400000 + 0x4000) >> 15) & 0x1FF];
00368 }
00369
00379 static inline fixed fixtan (fixed x)
00380 {
00381 return _tan_tbl[((x + 0x4000) >> 15) & 0xFF];
00382 }
00383
00397 static inline fixed fixacos (fixed x)
00398 {
00399 if ((x < -65536) || (x > 65536)) {
00400 errno = EDOM;
00401 return 0;
00402 }
00403
00404 return _acos_tbl[(x+65536+127)>>8];
00405 }
00406
00420 static inline fixed fixasin (fixed x)
00421 {
00422 if ((x < -65536) || (x > 65536)) {
00423 errno = EDOM;
00424 return 0;
00425 }
00426
00427 return 0x00400000 - _acos_tbl[(x+65536+127)>>8];
00428 }
00429
00437 #endif
00438
00439
00440 #ifdef __cplusplus
00441 }
00442 #endif
00443
00444 #endif
00445