aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorflatmush <flatmush@d3e1167c-abe1-51d5-8199-f9061ebe54e4>2011-02-23 09:47:08 +0000
committerflatmush <flatmush@d3e1167c-abe1-51d5-8199-f9061ebe54e4>2011-02-23 09:47:08 +0000
commit5d939700e8a1ed33903067c641b7ca93abedab96 (patch)
tree460ec561af0ca1bb66ddaec8b709a4abae6e08ed
parente06f8263886ba7ec96265b8d64ddc62a4409077b (diff)
downloadlibfixmath-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.c16
-rw-r--r--libfixmath/fix16.h2
-rw-r--r--libfixmath/fix16_sqrt.c6
-rw-r--r--libfixmath/fix16_trig.c32
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;
}