diff options
| author | flatmush <flatmush@d3e1167c-abe1-51d5-8199-f9061ebe54e4> | 2011-02-23 09:47:08 +0000 |
|---|---|---|
| committer | flatmush <flatmush@d3e1167c-abe1-51d5-8199-f9061ebe54e4> | 2011-02-23 09:47:08 +0000 |
| commit | 5d939700e8a1ed33903067c641b7ca93abedab96 (patch) | |
| tree | 460ec561af0ca1bb66ddaec8b709a4abae6e08ed | |
| parent | e06f8263886ba7ec96265b8d64ddc62a4409077b (diff) | |
| download | libfixmath-5d939700e8a1ed33903067c641b7ca93abedab96.tar.gz | |
Fixed errors in asin/atan, where incorrect integer maths was used.
Added a macro (FIXMATH_NO_CACHE) to disable caching.
Added fix16_lerp8 and fix16_lerp32 (should be part of fract module really).
| -rw-r--r-- | libfixmath/fix16.c | 16 | ||||
| -rw-r--r-- | libfixmath/fix16.h | 2 | ||||
| -rw-r--r-- | libfixmath/fix16_sqrt.c | 6 | ||||
| -rw-r--r-- | libfixmath/fix16_trig.c | 32 |
4 files changed, 45 insertions, 11 deletions
diff --git a/libfixmath/fix16.c b/libfixmath/fix16.c index 3fef27d..32fc3d1 100644 --- a/libfixmath/fix16.c +++ b/libfixmath/fix16.c @@ -91,6 +91,14 @@ fix16_t fix16_sdiv(fix16_t inArg0, fix16_t inArg1) { +fix16_t fix16_lerp8(fix16_t inArg0, fix16_t inArg1, uint8_t inFract) {
+ int64_t tempOut;
+ tempOut = ((int64_t)inArg0 * (256 - inFract));
+ tempOut += ((int64_t)inArg1 * inFract);
+ tempOut >>= 8;
+ return (fix16_t)tempOut;
+}
+
fix16_t fix16_lerp16(fix16_t inArg0, fix16_t inArg1, uint16_t inFract) {
int64_t tempOut;
tempOut = ((int64_t)inArg0 * (fix16_one - inFract));
@@ -98,3 +106,11 @@ fix16_t fix16_lerp16(fix16_t inArg0, fix16_t inArg1, uint16_t inFract) { tempOut >>= 16;
return (fix16_t)tempOut;
}
+
+fix16_t fix16_lerp32(fix16_t inArg0, fix16_t inArg1, uint32_t inFract) {
+ int64_t tempOut;
+ tempOut = ((int64_t)inArg0 * (0 - inFract));
+ tempOut += ((int64_t)inArg1 * inFract);
+ tempOut >>= 32;
+ return (fix16_t)tempOut;
+}
diff --git a/libfixmath/fix16.h b/libfixmath/fix16.h index aacfd8e..7913b9c 100644 --- a/libfixmath/fix16.h +++ b/libfixmath/fix16.h @@ -73,7 +73,9 @@ extern fix16_t fix16_sdiv(fix16_t inArg0, fix16_t inArg1); /*! Returns the linear interpolation: (inArg0 * (1 - inFract)) + (inArg1 * inFract)
*/
+extern fix16_t fix16_lerp8(fix16_t inArg0, fix16_t inArg1, uint8_t inFract);
extern fix16_t fix16_lerp16(fix16_t inArg0, fix16_t inArg1, uint16_t inFract);
+extern fix16_t fix16_lerp32(fix16_t inArg0, fix16_t inArg1, uint32_t inFract);
diff --git a/libfixmath/fix16_sqrt.c b/libfixmath/fix16_sqrt.c index f913a62..3d8e164 100644 --- a/libfixmath/fix16_sqrt.c +++ b/libfixmath/fix16_sqrt.c @@ -2,15 +2,19 @@ +#ifndef FIXMATH_NO_CACHE
fix16_t _fix16_sqrt_cache_index[4096] = { 0 };
fix16_t _fix16_sqrt_cache_value[4096] = { 0 };
+#endif
fix16_t fix16_sqrt(fix16_t inValue) {
+ #ifndef FIXMATH_NO_CACHE
fix16_t tempIndex = (((inValue >> 16) ^ (inValue >> 4)) & 0x00000FFF);
if(_fix16_sqrt_cache_index[tempIndex] == inValue)
return _fix16_sqrt_cache_value[tempIndex];
+ #endif
int64_t tempOp = inValue; tempOp <<= 16;
int64_t tempOut = 0;
@@ -28,8 +32,10 @@ fix16_t fix16_sqrt(fix16_t inValue) { tempOne >>= 2;
}
+ #ifndef FIXMATH_NO_CACHE
_fix16_sqrt_cache_index[tempIndex] = inValue;
_fix16_sqrt_cache_value[tempIndex] = tempOut;
+ #endif
return tempOut;
}
diff --git a/libfixmath/fix16_trig.c b/libfixmath/fix16_trig.c index 9d5046b..c162b61 100644 --- a/libfixmath/fix16_trig.c +++ b/libfixmath/fix16_trig.c @@ -2,10 +2,12 @@ -fix16_t _fix16_sin_cache_index[4096] = { 0 };
-fix16_t _fix16_sin_cache_value[4096] = { 0 };
-fix16_t _fix16_atan_cache_index[4096] = { 0 };
-fix16_t _fix16_atan_cache_value[4096] = { 0 };
+#ifndef FIXMATH_NO_CACHE
+static fix16_t _fix16_sin_cache_index[4096] = { 0 };
+static fix16_t _fix16_sin_cache_value[4096] = { 0 };
+static fix16_t _fix16_atan_cache_index[4096] = { 0 };
+static fix16_t _fix16_atan_cache_value[4096] = { 0 };
+#endif
@@ -16,9 +18,11 @@ fix16_t fix16_sin(fix16_t inAngle) { else if(tempAngle < -fix16_pi)
tempAngle += (fix16_pi << 1);
+ #ifndef FIXMATH_NO_CACHE
fix16_t tempIndex = ((inAngle >> 5) & 0x00000FFF);
if(_fix16_sin_cache_index[tempIndex] == inAngle)
return _fix16_sin_cache_value[tempIndex];
+ #endif
fix16_t tempAngleSq = fix16_mul(tempAngle, tempAngle);
@@ -34,8 +38,10 @@ fix16_t fix16_sin(fix16_t inAngle) { tempAngle = fix16_mul(tempAngle, tempAngleSq);
tempOut -= (tempAngle / 39916800);
+ #ifndef FIXMATH_NO_CACHE
_fix16_sin_cache_index[tempIndex] = inAngle;
_fix16_sin_cache_value[tempIndex] = tempOut;
+ #endif
return tempOut;
}
@@ -49,11 +55,11 @@ fix16_t fix16_tan(fix16_t inAngle) { }
fix16_t fix16_asin(fix16_t inValue) {
- if((inValue > 1) || (inValue < -1))
+ if((inValue > fix16_one) || (inValue < -fix16_one))
return 0;
fix16_t tempOut;
- tempOut = (1 - fix16_mul(inValue, inValue));
- tempOut = (inValue / fix16_sqrt(tempOut));
+ tempOut = (fix16_one - fix16_mul(inValue, inValue));
+ tempOut = fix16_div(inValue, fix16_sqrt(tempOut));
tempOut = fix16_atan(tempOut);
return tempOut;
}
@@ -62,12 +68,12 @@ fix16_t fix16_acos(fix16_t inValue) { return ((fix16_pi >> 1) - fix16_asin(inValue));
}
-fix16_t _fix16_atan(fix16_t inValue) {
+static fix16_t _fix16_atan(fix16_t inValue) {
fix16_t tempOut;
if(inValue > 29736) {
- tempOut = (1 + fix16_mul(inValue, inValue));
- tempOut = (1 + fix16_sqrt(tempOut));
- tempOut = (inValue / tempOut);
+ tempOut = (fix16_one + fix16_mul(inValue, inValue));
+ tempOut = (fix16_one + fix16_sqrt(tempOut));
+ tempOut = fix16_div(inValue, tempOut);
tempOut = _fix16_atan(tempOut);
return (tempOut << 1);
}
@@ -90,12 +96,16 @@ fix16_t _fix16_atan(fix16_t inValue) { }
fix16_t fix16_atan(fix16_t inValue) {
+ #ifndef FIXMATH_NO_CACHE
fix16_t tempIndex = (((inValue >> 16) ^ (inValue >> 4)) & 0x00000FFF);
if(_fix16_atan_cache_index[tempIndex] == inValue)
return _fix16_atan_cache_value[tempIndex];
+ #endif
fix16_t tempOut = _fix16_atan(inValue);
+ #ifndef FIXMATH_NO_CACHE
_fix16_atan_cache_index[tempIndex] = inValue;
_fix16_atan_cache_value[tempIndex] = tempOut;
+ #endif
return tempOut;
}
|
