diff options
Diffstat (limited to 'Client/ThirdParty/libfixmath')
18 files changed, 2059 insertions, 2059 deletions
diff --git a/Client/ThirdParty/libfixmath/fixsingen/fixsingen.depend b/Client/ThirdParty/libfixmath/fixsingen/fixsingen.depend index 5876a80..e0c975d 100644 --- a/Client/ThirdParty/libfixmath/fixsingen/fixsingen.depend +++ b/Client/ThirdParty/libfixmath/fixsingen/fixsingen.depend @@ -1,22 +1,22 @@ -# depslib dependency file v1.0 -1298649568 source:g:\vrfx\libfixmath\fixsingen\main.c - <stdio.h> - <stdlib.h> - <inttypes.h> - <math.h> - <libfixmath/fixmath.h> - -1298453688 g:\vrfx\libfixmath\\libfixmath\fixmath.h - "uint32.h" - "fract32.h" - "fix16.h" - -1298453688 g:\vrfx\libfixmath\\libfixmath\uint32.h - <stdint.h> - -1298453688 g:\vrfx\libfixmath\\libfixmath\fract32.h - <stdint.h> - -1298648502 g:\vrfx\libfixmath\\libfixmath\fix16.h - <stdint.h> - +# depslib dependency file v1.0
+1298649568 source:g:\vrfx\libfixmath\fixsingen\main.c
+ <stdio.h>
+ <stdlib.h>
+ <inttypes.h>
+ <math.h>
+ <libfixmath/fixmath.h>
+
+1298453688 g:\vrfx\libfixmath\\libfixmath\fixmath.h
+ "uint32.h"
+ "fract32.h"
+ "fix16.h"
+
+1298453688 g:\vrfx\libfixmath\\libfixmath\uint32.h
+ <stdint.h>
+
+1298453688 g:\vrfx\libfixmath\\libfixmath\fract32.h
+ <stdint.h>
+
+1298648502 g:\vrfx\libfixmath\\libfixmath\fix16.h
+ <stdint.h>
+
diff --git a/Client/ThirdParty/libfixmath/fixsingen/main.c b/Client/ThirdParty/libfixmath/fixsingen/main.c index 104b990..05461dc 100644 --- a/Client/ThirdParty/libfixmath/fixsingen/main.c +++ b/Client/ThirdParty/libfixmath/fixsingen/main.c @@ -1,44 +1,44 @@ -#include <stdio.h> -#include <stdlib.h> -#include <inttypes.h> -#include <math.h> -#include <libfixmath/fixmath.h> - -int main(int argc, char** argv) { - FILE* fp = fopen("fix16_trig_sin_lut.h", "wb"); - if(fp == NULL) { - fprintf(stderr, "Error: Unable to open file for writing.\n"); - return EXIT_FAILURE; - } - - // TODO - Store as uint16_t with a count to determine the end and return 1. - - fprintf(fp, "#ifndef __fix16_trig_sin_lut_h__\n"); - fprintf(fp, "#define __fix16_trig_sin_lut_h__\n"); - fprintf(fp, "\n"); - - fix16_t fix16_sin_lut_count = (fix16_pi >> 1); - fix16_t fix16_sin_lut[fix16_sin_lut_count]; - - uintptr_t i; - for(i = 0; i < fix16_sin_lut_count; i++) - fix16_sin_lut[i] = fix16_from_dbl(sin(fix16_to_dbl(i))); - for(i--; fix16_sin_lut[i] == fix16_one; i--, fix16_sin_lut_count--); - - fprintf(fp, "static const uint32_t _fix16_sin_lut_count = %"PRIi32";\n", fix16_sin_lut_count); - fprintf(fp, "static uint16_t _fix16_sin_lut[%"PRIi32"] = {", fix16_sin_lut_count); - - for(i = 0; i < fix16_sin_lut_count; i++) { - if((i & 7) == 0) - fprintf(fp, "\n\t"); - fprintf(fp, "%"PRIi32", ", fix16_sin_lut[i]); - } - fprintf(fp, "\n\t};\n"); - - fprintf(fp, "\n"); - fprintf(fp, "#endif\n"); - - fclose(fp); - - return EXIT_SUCCESS; -} +#include <stdio.h>
+#include <stdlib.h>
+#include <inttypes.h>
+#include <math.h>
+#include <libfixmath/fixmath.h>
+
+int main(int argc, char** argv) {
+ FILE* fp = fopen("fix16_trig_sin_lut.h", "wb");
+ if(fp == NULL) {
+ fprintf(stderr, "Error: Unable to open file for writing.\n");
+ return EXIT_FAILURE;
+ }
+
+ // TODO - Store as uint16_t with a count to determine the end and return 1.
+
+ fprintf(fp, "#ifndef __fix16_trig_sin_lut_h__\n");
+ fprintf(fp, "#define __fix16_trig_sin_lut_h__\n");
+ fprintf(fp, "\n");
+
+ fix16_t fix16_sin_lut_count = (fix16_pi >> 1);
+ fix16_t fix16_sin_lut[fix16_sin_lut_count];
+
+ uintptr_t i;
+ for(i = 0; i < fix16_sin_lut_count; i++)
+ fix16_sin_lut[i] = fix16_from_dbl(sin(fix16_to_dbl(i)));
+ for(i--; fix16_sin_lut[i] == fix16_one; i--, fix16_sin_lut_count--);
+
+ fprintf(fp, "static const uint32_t _fix16_sin_lut_count = %"PRIi32";\n", fix16_sin_lut_count);
+ fprintf(fp, "static uint16_t _fix16_sin_lut[%"PRIi32"] = {", fix16_sin_lut_count);
+
+ for(i = 0; i < fix16_sin_lut_count; i++) {
+ if((i & 7) == 0)
+ fprintf(fp, "\n\t");
+ fprintf(fp, "%"PRIi32", ", fix16_sin_lut[i]);
+ }
+ fprintf(fp, "\n\t};\n");
+
+ fprintf(fp, "\n");
+ fprintf(fp, "#endif\n");
+
+ fclose(fp);
+
+ return EXIT_SUCCESS;
+}
diff --git a/Client/ThirdParty/libfixmath/fixtest/fixtest.depend b/Client/ThirdParty/libfixmath/fixtest/fixtest.depend index 7227a2f..26758c6 100644 --- a/Client/ThirdParty/libfixmath/fixtest/fixtest.depend +++ b/Client/ThirdParty/libfixmath/fixtest/fixtest.depend @@ -1,67 +1,67 @@ -# depslib dependency file v1.0 -1298636296 source:g:\vrfx\libfixmath\fixtest\main.c - <stdio.h> - <stdlib.h> - <math.h> - <time.h> - <inttypes.h> - <libfixmath/fixmath.h> - "hiclock.h" - -1298453688 g:\vrfx\libfixmath\\libfixmath\fixmath.h - "uint32.h" - "fract32.h" - "fix16.h" - -1298453688 g:\vrfx\libfixmath\\libfixmath\uint32.h - <stdint.h> - -1298453688 g:\vrfx\libfixmath\\libfixmath\fract32.h - <stdint.h> - -1298648502 g:\vrfx\libfixmath\\libfixmath\fix16.h - <stdint.h> - -1298562746 source:g:\vrfx\libfixmath\fixtest\hiclock.c - "hiclock.h" - -1298564182 g:\vrfx\libfixmath\fixtest\hiclock.h - <stdint.h> - <inttypes.h> - <sys/time.h> - <windows.h> - <time.h> - -1298567472 source:i:\vrfx\libfixmath\fixtest\main.c - <stdio.h> - <stdlib.h> - <math.h> - <time.h> - <inttypes.h> - <libfixmath/fixmath.h> - "hiclock.h" - -1298453688 i:\vrfx\libfixmath\\libfixmath\fixmath.h - "uint32.h" - "fract32.h" - "fix16.h" - -1298453688 i:\vrfx\libfixmath\\libfixmath\uint32.h - <stdint.h> - -1298453688 i:\vrfx\libfixmath\\libfixmath\fract32.h - <stdint.h> - -1298577432 i:\vrfx\libfixmath\\libfixmath\fix16.h - <stdint.h> - -1298564182 i:\vrfx\libfixmath\fixtest\hiclock.h - <stdint.h> - <inttypes.h> - <sys/time.h> - <windows.h> - <time.h> - -1298562746 source:i:\vrfx\libfixmath\fixtest\hiclock.c - "hiclock.h" - +# depslib dependency file v1.0
+1298636296 source:g:\vrfx\libfixmath\fixtest\main.c
+ <stdio.h>
+ <stdlib.h>
+ <math.h>
+ <time.h>
+ <inttypes.h>
+ <libfixmath/fixmath.h>
+ "hiclock.h"
+
+1298453688 g:\vrfx\libfixmath\\libfixmath\fixmath.h
+ "uint32.h"
+ "fract32.h"
+ "fix16.h"
+
+1298453688 g:\vrfx\libfixmath\\libfixmath\uint32.h
+ <stdint.h>
+
+1298453688 g:\vrfx\libfixmath\\libfixmath\fract32.h
+ <stdint.h>
+
+1298648502 g:\vrfx\libfixmath\\libfixmath\fix16.h
+ <stdint.h>
+
+1298562746 source:g:\vrfx\libfixmath\fixtest\hiclock.c
+ "hiclock.h"
+
+1298564182 g:\vrfx\libfixmath\fixtest\hiclock.h
+ <stdint.h>
+ <inttypes.h>
+ <sys/time.h>
+ <windows.h>
+ <time.h>
+
+1298567472 source:i:\vrfx\libfixmath\fixtest\main.c
+ <stdio.h>
+ <stdlib.h>
+ <math.h>
+ <time.h>
+ <inttypes.h>
+ <libfixmath/fixmath.h>
+ "hiclock.h"
+
+1298453688 i:\vrfx\libfixmath\\libfixmath\fixmath.h
+ "uint32.h"
+ "fract32.h"
+ "fix16.h"
+
+1298453688 i:\vrfx\libfixmath\\libfixmath\uint32.h
+ <stdint.h>
+
+1298453688 i:\vrfx\libfixmath\\libfixmath\fract32.h
+ <stdint.h>
+
+1298577432 i:\vrfx\libfixmath\\libfixmath\fix16.h
+ <stdint.h>
+
+1298564182 i:\vrfx\libfixmath\fixtest\hiclock.h
+ <stdint.h>
+ <inttypes.h>
+ <sys/time.h>
+ <windows.h>
+ <time.h>
+
+1298562746 source:i:\vrfx\libfixmath\fixtest\hiclock.c
+ "hiclock.h"
+
diff --git a/Client/ThirdParty/libfixmath/fixtest/hiclock.c b/Client/ThirdParty/libfixmath/fixtest/hiclock.c index 81f5b94..5ce58df 100644 --- a/Client/ThirdParty/libfixmath/fixtest/hiclock.c +++ b/Client/ThirdParty/libfixmath/fixtest/hiclock.c @@ -1,28 +1,28 @@ -#include "hiclock.h" -#include <stddef.h> - -#if defined(__WIN32) || defined(__WIN64) -LONGLONG HICLOCKS_PER_SEC = 0; - -void hiclock_init() -{ - LARGE_INTEGER freq; - QueryPerformanceFrequency(&freq); - HICLOCKS_PER_SEC = freq.QuadPart; -} -#endif - -hiclock_t hiclock() -{ -#if defined(__unix__) - struct timeval clocks; - gettimeofday(&clocks, NULL); - return ((uint64_t)clocks.tv_sec * 1000000ULL) + clocks.tv_usec; -#elif defined(__WIN32) || defined(__WIN64) - LARGE_INTEGER clocks; - QueryPerformanceCounter(&clocks); - return clocks.QuadPart; -#else - return clock(); -#endif -} +#include "hiclock.h"
+#include <stddef.h>
+
+#if defined(__WIN32) || defined(__WIN64)
+LONGLONG HICLOCKS_PER_SEC = 0;
+
+void hiclock_init()
+{
+ LARGE_INTEGER freq;
+ QueryPerformanceFrequency(&freq);
+ HICLOCKS_PER_SEC = freq.QuadPart;
+}
+#endif
+
+hiclock_t hiclock()
+{
+#if defined(__unix__)
+ struct timeval clocks;
+ gettimeofday(&clocks, NULL);
+ return ((uint64_t)clocks.tv_sec * 1000000ULL) + clocks.tv_usec;
+#elif defined(__WIN32) || defined(__WIN64)
+ LARGE_INTEGER clocks;
+ QueryPerformanceCounter(&clocks);
+ return clocks.QuadPart;
+#else
+ return clock();
+#endif
+}
diff --git a/Client/ThirdParty/libfixmath/fixtest/hiclock.h b/Client/ThirdParty/libfixmath/fixtest/hiclock.h index 7cabf47..89e32c8 100644 --- a/Client/ThirdParty/libfixmath/fixtest/hiclock.h +++ b/Client/ThirdParty/libfixmath/fixtest/hiclock.h @@ -1,33 +1,33 @@ -#ifndef __hiclock_h__ -#define __hiclock_h__ - -#include <stdint.h> -#include <inttypes.h> - -#if defined(__unix__) -#include <sys/time.h> -#define PRIuHICLOCK PRIu64 -#define PRIiHICLOCK PRIi64 -typedef uint64_t hiclock_t; -#define HICLOCKS_PER_SEC 1000000 -#define hiclock_init() -#elif defined(__WIN32) || defined(__WIN64) -#include <windows.h> -#define PRIuHICLOCK PRIu64 -#define PRIiHICLOCK PRIi64 -typedef LONGLONG hiclock_t; -extern LONGLONG HICLOCKS_PER_SEC; -extern void hiclock_init(); -#else -#include <time.h> -#define PRIuHICLOCK PRIu32 -#define PRIiHICLOCK PRIi32 -typedef clock_t hiclock_t; -#define HICLOCKS_PER_SEC CLOCKS_PER_SEC -#define hiclock_init() -#endif - -extern hiclock_t hiclock(); - -#endif - +#ifndef __hiclock_h__
+#define __hiclock_h__
+
+#include <stdint.h>
+#include <inttypes.h>
+
+#if defined(__unix__)
+#include <sys/time.h>
+#define PRIuHICLOCK PRIu64
+#define PRIiHICLOCK PRIi64
+typedef uint64_t hiclock_t;
+#define HICLOCKS_PER_SEC 1000000
+#define hiclock_init()
+#elif defined(__WIN32) || defined(__WIN64)
+#include <windows.h>
+#define PRIuHICLOCK PRIu64
+#define PRIiHICLOCK PRIi64
+typedef LONGLONG hiclock_t;
+extern LONGLONG HICLOCKS_PER_SEC;
+extern void hiclock_init();
+#else
+#include <time.h>
+#define PRIuHICLOCK PRIu32
+#define PRIiHICLOCK PRIi32
+typedef clock_t hiclock_t;
+#define HICLOCKS_PER_SEC CLOCKS_PER_SEC
+#define hiclock_init()
+#endif
+
+extern hiclock_t hiclock();
+
+#endif
+
diff --git a/Client/ThirdParty/libfixmath/fixtest/main.c b/Client/ThirdParty/libfixmath/fixtest/main.c index 822f290..5f6dd92 100644 --- a/Client/ThirdParty/libfixmath/fixtest/main.c +++ b/Client/ThirdParty/libfixmath/fixtest/main.c @@ -1,96 +1,96 @@ -#include "hiclock.h" -#include <inttypes.h> -#include <libfixmath/fixmath.h> -#include <math.h> -#include <stdio.h> -#include <stdlib.h> -#include <time.h> - -#define EXP -//#define ATAN -//#define SIN -//#define SQRT - -#ifdef EXP -#define fix_func fix16_exp -#define fix_func_str "fix16_exp" -#define flt_func expf -#define flt_func_str "expf" -#endif - -#ifdef ATAN -#define fix_func fix16_atan -#define fix_func_str "fix16_atan" -#define flt_func atanf -#define flt_func_str "atanf" -#endif - -#ifdef SIN -#define fix_func fix16_sin -#define fix_func_str "fix16_sin" -#define flt_func sinf -#define flt_func_str "sinf" -#endif - -#ifdef SQRT -#define fix_func fix16_sqrt -#define fix_func_str "fix16_sqrt" -#define flt_func sqrtf -#define flt_func_str "sqrtf" -#endif - -int main(int argc, char **argv) -{ - printf("libfixmath test tool\n"); - - hiclock_init(); - - uintptr_t args = (1 << 8); - uintptr_t iter = (1 << 8); - uintptr_t pass = (1 << 8); - - uintptr_t i; - srand(time(NULL)); - - hiclock_t fix_duration = 0; - hiclock_t flt_duration = 0; - fix16_t fix_error = 0; - - uintptr_t k; - for (k = 0; k < pass; k++) - { - fix16_t fix_args[args]; - for (i = 0; i < args; i++) fix_args[i] = (rand() ^ (rand() << 16)); - fix16_t fix_result[args]; - hiclock_t fix_start = hiclock(); - for (i = 0; i < iter; i++) - { - uintptr_t j; - for (j = 0; j < args; j++) fix_result[j] = fix_func(fix_args[j]); - } - hiclock_t fix_end = hiclock(); - - float flt_args[args]; - for (i = 0; i < args; i++) flt_args[i] = fix16_to_float(fix_args[i]); - float flt_result[args]; - hiclock_t flt_start = hiclock(); - for (i = 0; i < iter; i++) - { - uintptr_t j; - for (j = 0; j < args; j++) flt_result[j] = flt_func(flt_args[j]); - } - hiclock_t flt_end = hiclock(); - - for (i = 0; i < args; i++) - fix_error += abs(fix16_from_float(flt_result[i]) - fix_result[i]); - flt_duration += (flt_end - flt_start); - fix_duration += (fix_end - fix_start); - } - - printf("%16s: %08" PRIuHICLOCK " @ %" PRIu32 "Hz\n", flt_func_str, flt_duration, HICLOCKS_PER_SEC); - printf("%16s: %08" PRIuHICLOCK " @ %" PRIu32 "Hz\n", fix_func_str, fix_duration, HICLOCKS_PER_SEC); - printf(" Difference: %08" PRIiHICLOCK " (% 3.2f%%)\n", (flt_duration - fix_duration), ((fix_duration * 100.0) / flt_duration)); - printf(" Error: %f%%\n", ((fix16_to_dbl(fix_error) * 100.0) / (args * pass))); - - return EXIT_SUCCESS; -} +#include "hiclock.h"
+#include <inttypes.h>
+#include <libfixmath/fixmath.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#define EXP
+//#define ATAN
+//#define SIN
+//#define SQRT
+
+#ifdef EXP
+#define fix_func fix16_exp
+#define fix_func_str "fix16_exp"
+#define flt_func expf
+#define flt_func_str "expf"
+#endif
+
+#ifdef ATAN
+#define fix_func fix16_atan
+#define fix_func_str "fix16_atan"
+#define flt_func atanf
+#define flt_func_str "atanf"
+#endif
+
+#ifdef SIN
+#define fix_func fix16_sin
+#define fix_func_str "fix16_sin"
+#define flt_func sinf
+#define flt_func_str "sinf"
+#endif
+
+#ifdef SQRT
+#define fix_func fix16_sqrt
+#define fix_func_str "fix16_sqrt"
+#define flt_func sqrtf
+#define flt_func_str "sqrtf"
+#endif
+
+int main(int argc, char **argv)
+{
+ printf("libfixmath test tool\n");
+
+ hiclock_init();
+
+ uintptr_t args = (1 << 8);
+ uintptr_t iter = (1 << 8);
+ uintptr_t pass = (1 << 8);
+
+ uintptr_t i;
+ srand(time(NULL));
+
+ hiclock_t fix_duration = 0;
+ hiclock_t flt_duration = 0;
+ fix16_t fix_error = 0;
+
+ uintptr_t k;
+ for (k = 0; k < pass; k++)
+ {
+ fix16_t fix_args[args];
+ for (i = 0; i < args; i++) fix_args[i] = (rand() ^ (rand() << 16));
+ fix16_t fix_result[args];
+ hiclock_t fix_start = hiclock();
+ for (i = 0; i < iter; i++)
+ {
+ uintptr_t j;
+ for (j = 0; j < args; j++) fix_result[j] = fix_func(fix_args[j]);
+ }
+ hiclock_t fix_end = hiclock();
+
+ float flt_args[args];
+ for (i = 0; i < args; i++) flt_args[i] = fix16_to_float(fix_args[i]);
+ float flt_result[args];
+ hiclock_t flt_start = hiclock();
+ for (i = 0; i < iter; i++)
+ {
+ uintptr_t j;
+ for (j = 0; j < args; j++) flt_result[j] = flt_func(flt_args[j]);
+ }
+ hiclock_t flt_end = hiclock();
+
+ for (i = 0; i < args; i++)
+ fix_error += abs(fix16_from_float(flt_result[i]) - fix_result[i]);
+ flt_duration += (flt_end - flt_start);
+ fix_duration += (fix_end - fix_start);
+ }
+
+ printf("%16s: %08" PRIuHICLOCK " @ %" PRIu32 "Hz\n", flt_func_str, flt_duration, HICLOCKS_PER_SEC);
+ printf("%16s: %08" PRIuHICLOCK " @ %" PRIu32 "Hz\n", fix_func_str, fix_duration, HICLOCKS_PER_SEC);
+ printf(" Difference: %08" PRIiHICLOCK " (% 3.2f%%)\n", (flt_duration - fix_duration), ((fix_duration * 100.0) / flt_duration));
+ printf(" Error: %f%%\n", ((fix16_to_dbl(fix_error) * 100.0) / (args * pass)));
+
+ return EXIT_SUCCESS;
+}
diff --git a/Client/ThirdParty/libfixmath/libfixmath/fix16.c b/Client/ThirdParty/libfixmath/libfixmath/fix16.c index 7bcc969..5063544 100644 --- a/Client/ThirdParty/libfixmath/libfixmath/fix16.c +++ b/Client/ThirdParty/libfixmath/libfixmath/fix16.c @@ -1,511 +1,511 @@ -#include "fix16.h" -#include "int64.h" - - -/* Subtraction and addition with overflow detection. - * The versions without overflow detection are inlined in the header. - */ -#ifndef FIXMATH_NO_OVERFLOW -fix16_t fix16_add(fix16_t a, fix16_t b) -{ - // Use unsigned integers because overflow with signed integers is - // an undefined operation (http://www.airs.com/blog/archives/120). - uint32_t _a = a; - uint32_t _b = b; - uint32_t sum = _a + _b; - - // Overflow can only happen if sign of a == sign of b, and then - // it causes sign of sum != sign of a. - if (!((_a ^ _b) & 0x80000000) && ((_a ^ sum) & 0x80000000)) - return fix16_overflow; - - return sum; -} - -fix16_t fix16_sub(fix16_t a, fix16_t b) -{ - uint32_t _a = a; - uint32_t _b = b; - uint32_t diff = _a - _b; - - // Overflow can only happen if sign of a != sign of b, and then - // it causes sign of diff != sign of a. - if (((_a ^ _b) & 0x80000000) && ((_a ^ diff) & 0x80000000)) - return fix16_overflow; - - return diff; -} - -/* Saturating arithmetic */ -fix16_t fix16_sadd(fix16_t a, fix16_t b) -{ - fix16_t result = fix16_add(a, b); - - if (result == fix16_overflow) - return (a >= 0) ? fix16_maximum : fix16_minimum; - - return result; -} - -fix16_t fix16_ssub(fix16_t a, fix16_t b) -{ - fix16_t result = fix16_sub(a, b); - - if (result == fix16_overflow) - return (a >= 0) ? fix16_maximum : fix16_minimum; - - return result; -} -#endif - - - -/* 64-bit implementation for fix16_mul. Fastest version for e.g. ARM Cortex M3. - * Performs a 32*32 -> 64bit multiplication. The middle 32 bits are the result, - * bottom 16 bits are used for rounding, and upper 16 bits are used for overflow - * detection. - */ - -#if !defined(FIXMATH_NO_64BIT) && !defined(FIXMATH_OPTIMIZE_8BIT) -fix16_t fix16_mul(fix16_t inArg0, fix16_t inArg1) -{ - int64_t product = (int64_t)inArg0 * inArg1; - - #ifndef FIXMATH_NO_OVERFLOW - // The upper 17 bits should all be the same (the sign). - uint32_t upper = (product >> 47); - #endif - - if (product < 0) - { - #ifndef FIXMATH_NO_OVERFLOW - if (~upper) - return fix16_overflow; - #endif - - #ifndef FIXMATH_NO_ROUNDING - // This adjustment is required in order to round -1/2 correctly - product--; - #endif - } - else - { - #ifndef FIXMATH_NO_OVERFLOW - if (upper) - return fix16_overflow; - #endif - } - - #ifdef FIXMATH_NO_ROUNDING - return product >> 16; - #else - fix16_t result = product >> 16; - result += (product & 0x8000) >> 15; - - return result; - #endif -} -#endif - -/* 32-bit implementation of fix16_mul. Potentially fast on 16-bit processors, - * and this is a relatively good compromise for compilers that do not support - * uint64_t. Uses 16*16->32bit multiplications. - */ -#if defined(FIXMATH_NO_64BIT) && !defined(FIXMATH_OPTIMIZE_8BIT) -fix16_t fix16_mul(fix16_t inArg0, fix16_t inArg1) -{ - // Each argument is divided to 16-bit parts. - // AB - // * CD - // ----------- - // BD 16 * 16 -> 32 bit products - // CB - // AD - // AC - // |----| 64 bit product - int32_t A = (inArg0 >> 16), C = (inArg1 >> 16); - uint32_t B = (inArg0 & 0xFFFF), D = (inArg1 & 0xFFFF); - - int32_t AC = A*C; - int32_t AD_CB = A*D + C*B; - uint32_t BD = B*D; - - int32_t product_hi = AC + (AD_CB >> 16); - - // Handle carry from lower 32 bits to upper part of result. - uint32_t ad_cb_temp = AD_CB << 16; - uint32_t product_lo = BD + ad_cb_temp; - if (product_lo < BD) - product_hi++; - -#ifndef FIXMATH_NO_OVERFLOW - // The upper 17 bits should all be the same (the sign). - if (product_hi >> 31 != product_hi >> 15) - return fix16_overflow; -#endif - -#ifdef FIXMATH_NO_ROUNDING - return (product_hi << 16) | (product_lo >> 16); -#else - // Subtracting 0x8000 (= 0.5) and then using signed right shift - // achieves proper rounding to result-1, except in the corner - // case of negative numbers and lowest word = 0x8000. - // To handle that, we also have to subtract 1 for negative numbers. - uint32_t product_lo_tmp = product_lo; - product_lo -= 0x8000; - product_lo -= (uint32_t)product_hi >> 31; - if (product_lo > product_lo_tmp) - product_hi--; - - // Discard the lowest 16 bits. Note that this is not exactly the same - // as dividing by 0x10000. For example if product = -1, result will - // also be -1 and not 0. This is compensated by adding +1 to the result - // and compensating this in turn in the rounding above. - fix16_t result = (product_hi << 16) | (product_lo >> 16); - result += 1; - return result; -#endif -} -#endif - -/* 8-bit implementation of fix16_mul. Fastest on e.g. Atmel AVR. - * Uses 8*8->16bit multiplications, and also skips any bytes that - * are zero. - */ -#if defined(FIXMATH_OPTIMIZE_8BIT) -fix16_t fix16_mul(fix16_t inArg0, fix16_t inArg1) -{ - uint32_t _a = fix_abs(inArg0); - uint32_t _b = fix_abs(inArg1); - - uint8_t va[4] = {_a, (_a >> 8), (_a >> 16), (_a >> 24)}; - uint8_t vb[4] = {_b, (_b >> 8), (_b >> 16), (_b >> 24)}; - - uint32_t low = 0; - uint32_t mid = 0; - - // Result column i depends on va[0..i] and vb[i..0] - - #ifndef FIXMATH_NO_OVERFLOW - // i = 6 - if (va[3] && vb[3]) return fix16_overflow; - #endif - - // i = 5 - if (va[2] && vb[3]) mid += (uint16_t)va[2] * vb[3]; - if (va[3] && vb[2]) mid += (uint16_t)va[3] * vb[2]; - mid <<= 8; - - // i = 4 - if (va[1] && vb[3]) mid += (uint16_t)va[1] * vb[3]; - if (va[2] && vb[2]) mid += (uint16_t)va[2] * vb[2]; - if (va[3] && vb[1]) mid += (uint16_t)va[3] * vb[1]; - - #ifndef FIXMATH_NO_OVERFLOW - if (mid & 0xFF000000) return fix16_overflow; - #endif - mid <<= 8; - - // i = 3 - if (va[0] && vb[3]) mid += (uint16_t)va[0] * vb[3]; - if (va[1] && vb[2]) mid += (uint16_t)va[1] * vb[2]; - if (va[2] && vb[1]) mid += (uint16_t)va[2] * vb[1]; - if (va[3] && vb[0]) mid += (uint16_t)va[3] * vb[0]; - - #ifndef FIXMATH_NO_OVERFLOW - if (mid & 0xFF000000) return fix16_overflow; - #endif - mid <<= 8; - - // i = 2 - if (va[0] && vb[2]) mid += (uint16_t)va[0] * vb[2]; - if (va[1] && vb[1]) mid += (uint16_t)va[1] * vb[1]; - if (va[2] && vb[0]) mid += (uint16_t)va[2] * vb[0]; - - // i = 1 - if (va[0] && vb[1]) low += (uint16_t)va[0] * vb[1]; - if (va[1] && vb[0]) low += (uint16_t)va[1] * vb[0]; - low <<= 8; - - // i = 0 - if (va[0] && vb[0]) low += (uint16_t)va[0] * vb[0]; - - #ifndef FIXMATH_NO_ROUNDING - low += 0x8000; - #endif - mid += (low >> 16); - - #ifndef FIXMATH_NO_OVERFLOW - if (mid & 0x80000000) - return fix16_overflow; - #endif - - fix16_t result = mid; - - /* Figure out the sign of result */ - if ((inArg0 >= 0) != (inArg1 >= 0)) - { - result = -result; - } - - return result; -} -#endif - -#ifndef FIXMATH_NO_OVERFLOW -/* Wrapper around fix16_mul to add saturating arithmetic. */ -fix16_t fix16_smul(fix16_t inArg0, fix16_t inArg1) -{ - fix16_t result = fix16_mul(inArg0, inArg1); - - if (result == fix16_overflow) - { - if ((inArg0 >= 0) == (inArg1 >= 0)) - return fix16_maximum; - else - return fix16_minimum; - } - - return result; -} -#endif - -/* 32-bit implementation of fix16_div. Fastest version for e.g. ARM Cortex M3. - * Performs 32-bit divisions repeatedly to reduce the remainder. For this to - * be efficient, the processor has to have 32-bit hardware division. - */ -#if !defined(FIXMATH_OPTIMIZE_8BIT) -#ifdef __GNUC__ -// Count leading zeros, using processor-specific instruction if available. -#define clz(x) (__builtin_clzl(x) - (8 * sizeof(long) - 32)) -#else -static uint8_t clz(uint32_t x) -{ - uint8_t result = 0; - if (x == 0) return 32; - while (!(x & 0xF0000000)) { result += 4; x <<= 4; } - while (!(x & 0x80000000)) { result += 1; x <<= 1; } - return result; -} -#endif - -fix16_t fix16_div(fix16_t a, fix16_t b) -{ - // This uses a hardware 32/32 bit division multiple times, until we have - // computed all the bits in (a<<17)/b. Usually this takes 1-3 iterations. - - if (b == 0) - return fix16_minimum; - - uint32_t remainder = fix_abs(a); - uint32_t divider = fix_abs(b); - uint64_t quotient = 0; - int bit_pos = 17; - - // Kick-start the division a bit. - // This improves speed in the worst-case scenarios where N and D are large - // It gets a lower estimate for the result by N/(D >> 17 + 1). - if (divider & 0xFFF00000) - { - uint32_t shifted_div = ((divider >> 17) + 1); - quotient = remainder / shifted_div; - uint64_t tmp = ((uint64_t)quotient * (uint64_t)divider) >> 17; - remainder -= (uint32_t)(tmp); - } - - // If the divider is divisible by 2^n, take advantage of it. - while (!(divider & 0xF) && bit_pos >= 4) - { - divider >>= 4; - bit_pos -= 4; - } - - while (remainder && bit_pos >= 0) - { - // Shift remainder as much as we can without overflowing - int shift = clz(remainder); - if (shift > bit_pos) shift = bit_pos; - remainder <<= shift; - bit_pos -= shift; - - uint32_t div = remainder / divider; - remainder = remainder % divider; - quotient += (uint64_t)div << bit_pos; - - #ifndef FIXMATH_NO_OVERFLOW - if (div & ~(0xFFFFFFFF >> bit_pos)) - return fix16_overflow; - #endif - - remainder <<= 1; - bit_pos--; - } - - #ifndef FIXMATH_NO_ROUNDING - // Quotient is always positive so rounding is easy - quotient++; - #endif - - fix16_t result = quotient >> 1; - - // Figure out the sign of the result - if ((a ^ b) & 0x80000000) - { - #ifndef FIXMATH_NO_OVERFLOW - if (result == fix16_minimum) - return fix16_overflow; - #endif - - result = -result; - } - - return result; -} -#endif - -/* Alternative 32-bit implementation of fix16_div. Fastest on e.g. Atmel AVR. - * This does the division manually, and is therefore good for processors that - * do not have hardware division. - */ -#if defined(FIXMATH_OPTIMIZE_8BIT) -fix16_t fix16_div(fix16_t a, fix16_t b) -{ - // This uses the basic binary restoring division algorithm. - // It appears to be faster to do the whole division manually than - // trying to compose a 64-bit divide out of 32-bit divisions on - // platforms without hardware divide. - - if (b == 0) - return fix16_minimum; - - uint32_t remainder = fix_abs(a); - uint32_t divider = fix_abs(b); - - uint32_t quotient = 0; - uint32_t bit = 0x10000; - - /* The algorithm requires D >= R */ - while (divider < remainder) - { - divider <<= 1; - bit <<= 1; - } - - #ifndef FIXMATH_NO_OVERFLOW - if (!bit) - return fix16_overflow; - #endif - - if (divider & 0x80000000) - { - // Perform one step manually to avoid overflows later. - // We know that divider's bottom bit is 0 here. - if (remainder >= divider) - { - quotient |= bit; - remainder -= divider; - } - divider >>= 1; - bit >>= 1; - } - - /* Main division loop */ - while (bit && remainder) - { - if (remainder >= divider) - { - quotient |= bit; - remainder -= divider; - } - - remainder <<= 1; - bit >>= 1; - } - - #ifndef FIXMATH_NO_ROUNDING - if (remainder >= divider) - { - quotient++; - } - #endif - - fix16_t result = quotient; - - /* Figure out the sign of result */ - if ((a ^ b) & 0x80000000) - { - #ifndef FIXMATH_NO_OVERFLOW - if (result == fix16_minimum) - return fix16_overflow; - #endif - - result = -result; - } - - return result; -} -#endif - -#ifndef FIXMATH_NO_OVERFLOW -/* Wrapper around fix16_div to add saturating arithmetic. */ -fix16_t fix16_sdiv(fix16_t inArg0, fix16_t inArg1) -{ - fix16_t result = fix16_div(inArg0, inArg1); - - if (result == fix16_overflow) - { - if ((inArg0 >= 0) == (inArg1 >= 0)) - return fix16_maximum; - else - return fix16_minimum; - } - - return result; -} -#endif - -fix16_t fix16_mod(fix16_t x, fix16_t y) -{ - #ifdef FIXMATH_OPTIMIZE_8BIT - /* The reason we do this, rather than use a modulo operator - * is that if you don't have a hardware divider, this will result - * in faster operations when the angles are close to the bounds. - */ - while(x >= y) x -= y; - while(x <= -y) x += y; - #else - /* Note that in C90, the sign of result of the modulo operation is - * undefined. in C99, it's the same as the dividend (aka numerator). - */ - x %= y; - #endif - - return x; -} - -fix16_t fix16_lerp8(fix16_t inArg0, fix16_t inArg1, uint8_t inFract) -{ - int64_t tempOut = int64_mul_i32_i32(inArg0, (((int32_t)1 << 8) - inFract)); - tempOut = int64_add(tempOut, int64_mul_i32_i32(inArg1, inFract)); - tempOut = int64_shift(tempOut, -8); - return (fix16_t)int64_lo(tempOut); -} - -fix16_t fix16_lerp16(fix16_t inArg0, fix16_t inArg1, uint16_t inFract) -{ - int64_t tempOut = int64_mul_i32_i32(inArg0, (((int32_t)1 << 16) - inFract)); - tempOut = int64_add(tempOut, int64_mul_i32_i32(inArg1, inFract)); - tempOut = int64_shift(tempOut, -16); - return (fix16_t)int64_lo(tempOut); -} - -fix16_t fix16_lerp32(fix16_t inArg0, fix16_t inArg1, uint32_t inFract) -{ - if(inFract == 0) - return inArg0; - int64_t inFract64 = int64_const(0, inFract); - int64_t subbed = int64_sub(int64_const(1,0), inFract64); - int64_t tempOut = int64_mul_i64_i32(subbed, inArg0); - tempOut = int64_add(tempOut, int64_mul_i64_i32(inFract64, inArg1)); - return int64_hi(tempOut); -} +#include "fix16.h"
+#include "int64.h"
+
+
+/* Subtraction and addition with overflow detection.
+ * The versions without overflow detection are inlined in the header.
+ */
+#ifndef FIXMATH_NO_OVERFLOW
+fix16_t fix16_add(fix16_t a, fix16_t b)
+{
+ // Use unsigned integers because overflow with signed integers is
+ // an undefined operation (http://www.airs.com/blog/archives/120).
+ uint32_t _a = a;
+ uint32_t _b = b;
+ uint32_t sum = _a + _b;
+
+ // Overflow can only happen if sign of a == sign of b, and then
+ // it causes sign of sum != sign of a.
+ if (!((_a ^ _b) & 0x80000000) && ((_a ^ sum) & 0x80000000))
+ return fix16_overflow;
+
+ return sum;
+}
+
+fix16_t fix16_sub(fix16_t a, fix16_t b)
+{
+ uint32_t _a = a;
+ uint32_t _b = b;
+ uint32_t diff = _a - _b;
+
+ // Overflow can only happen if sign of a != sign of b, and then
+ // it causes sign of diff != sign of a.
+ if (((_a ^ _b) & 0x80000000) && ((_a ^ diff) & 0x80000000))
+ return fix16_overflow;
+
+ return diff;
+}
+
+/* Saturating arithmetic */
+fix16_t fix16_sadd(fix16_t a, fix16_t b)
+{
+ fix16_t result = fix16_add(a, b);
+
+ if (result == fix16_overflow)
+ return (a >= 0) ? fix16_maximum : fix16_minimum;
+
+ return result;
+}
+
+fix16_t fix16_ssub(fix16_t a, fix16_t b)
+{
+ fix16_t result = fix16_sub(a, b);
+
+ if (result == fix16_overflow)
+ return (a >= 0) ? fix16_maximum : fix16_minimum;
+
+ return result;
+}
+#endif
+
+
+
+/* 64-bit implementation for fix16_mul. Fastest version for e.g. ARM Cortex M3.
+ * Performs a 32*32 -> 64bit multiplication. The middle 32 bits are the result,
+ * bottom 16 bits are used for rounding, and upper 16 bits are used for overflow
+ * detection.
+ */
+
+#if !defined(FIXMATH_NO_64BIT) && !defined(FIXMATH_OPTIMIZE_8BIT)
+fix16_t fix16_mul(fix16_t inArg0, fix16_t inArg1)
+{
+ int64_t product = (int64_t)inArg0 * inArg1;
+
+ #ifndef FIXMATH_NO_OVERFLOW
+ // The upper 17 bits should all be the same (the sign).
+ uint32_t upper = (product >> 47);
+ #endif
+
+ if (product < 0)
+ {
+ #ifndef FIXMATH_NO_OVERFLOW
+ if (~upper)
+ return fix16_overflow;
+ #endif
+
+ #ifndef FIXMATH_NO_ROUNDING
+ // This adjustment is required in order to round -1/2 correctly
+ product--;
+ #endif
+ }
+ else
+ {
+ #ifndef FIXMATH_NO_OVERFLOW
+ if (upper)
+ return fix16_overflow;
+ #endif
+ }
+
+ #ifdef FIXMATH_NO_ROUNDING
+ return product >> 16;
+ #else
+ fix16_t result = product >> 16;
+ result += (product & 0x8000) >> 15;
+
+ return result;
+ #endif
+}
+#endif
+
+/* 32-bit implementation of fix16_mul. Potentially fast on 16-bit processors,
+ * and this is a relatively good compromise for compilers that do not support
+ * uint64_t. Uses 16*16->32bit multiplications.
+ */
+#if defined(FIXMATH_NO_64BIT) && !defined(FIXMATH_OPTIMIZE_8BIT)
+fix16_t fix16_mul(fix16_t inArg0, fix16_t inArg1)
+{
+ // Each argument is divided to 16-bit parts.
+ // AB
+ // * CD
+ // -----------
+ // BD 16 * 16 -> 32 bit products
+ // CB
+ // AD
+ // AC
+ // |----| 64 bit product
+ int32_t A = (inArg0 >> 16), C = (inArg1 >> 16);
+ uint32_t B = (inArg0 & 0xFFFF), D = (inArg1 & 0xFFFF);
+
+ int32_t AC = A*C;
+ int32_t AD_CB = A*D + C*B;
+ uint32_t BD = B*D;
+
+ int32_t product_hi = AC + (AD_CB >> 16);
+
+ // Handle carry from lower 32 bits to upper part of result.
+ uint32_t ad_cb_temp = AD_CB << 16;
+ uint32_t product_lo = BD + ad_cb_temp;
+ if (product_lo < BD)
+ product_hi++;
+
+#ifndef FIXMATH_NO_OVERFLOW
+ // The upper 17 bits should all be the same (the sign).
+ if (product_hi >> 31 != product_hi >> 15)
+ return fix16_overflow;
+#endif
+
+#ifdef FIXMATH_NO_ROUNDING
+ return (product_hi << 16) | (product_lo >> 16);
+#else
+ // Subtracting 0x8000 (= 0.5) and then using signed right shift
+ // achieves proper rounding to result-1, except in the corner
+ // case of negative numbers and lowest word = 0x8000.
+ // To handle that, we also have to subtract 1 for negative numbers.
+ uint32_t product_lo_tmp = product_lo;
+ product_lo -= 0x8000;
+ product_lo -= (uint32_t)product_hi >> 31;
+ if (product_lo > product_lo_tmp)
+ product_hi--;
+
+ // Discard the lowest 16 bits. Note that this is not exactly the same
+ // as dividing by 0x10000. For example if product = -1, result will
+ // also be -1 and not 0. This is compensated by adding +1 to the result
+ // and compensating this in turn in the rounding above.
+ fix16_t result = (product_hi << 16) | (product_lo >> 16);
+ result += 1;
+ return result;
+#endif
+}
+#endif
+
+/* 8-bit implementation of fix16_mul. Fastest on e.g. Atmel AVR.
+ * Uses 8*8->16bit multiplications, and also skips any bytes that
+ * are zero.
+ */
+#if defined(FIXMATH_OPTIMIZE_8BIT)
+fix16_t fix16_mul(fix16_t inArg0, fix16_t inArg1)
+{
+ uint32_t _a = fix_abs(inArg0);
+ uint32_t _b = fix_abs(inArg1);
+
+ uint8_t va[4] = {_a, (_a >> 8), (_a >> 16), (_a >> 24)};
+ uint8_t vb[4] = {_b, (_b >> 8), (_b >> 16), (_b >> 24)};
+
+ uint32_t low = 0;
+ uint32_t mid = 0;
+
+ // Result column i depends on va[0..i] and vb[i..0]
+
+ #ifndef FIXMATH_NO_OVERFLOW
+ // i = 6
+ if (va[3] && vb[3]) return fix16_overflow;
+ #endif
+
+ // i = 5
+ if (va[2] && vb[3]) mid += (uint16_t)va[2] * vb[3];
+ if (va[3] && vb[2]) mid += (uint16_t)va[3] * vb[2];
+ mid <<= 8;
+
+ // i = 4
+ if (va[1] && vb[3]) mid += (uint16_t)va[1] * vb[3];
+ if (va[2] && vb[2]) mid += (uint16_t)va[2] * vb[2];
+ if (va[3] && vb[1]) mid += (uint16_t)va[3] * vb[1];
+
+ #ifndef FIXMATH_NO_OVERFLOW
+ if (mid & 0xFF000000) return fix16_overflow;
+ #endif
+ mid <<= 8;
+
+ // i = 3
+ if (va[0] && vb[3]) mid += (uint16_t)va[0] * vb[3];
+ if (va[1] && vb[2]) mid += (uint16_t)va[1] * vb[2];
+ if (va[2] && vb[1]) mid += (uint16_t)va[2] * vb[1];
+ if (va[3] && vb[0]) mid += (uint16_t)va[3] * vb[0];
+
+ #ifndef FIXMATH_NO_OVERFLOW
+ if (mid & 0xFF000000) return fix16_overflow;
+ #endif
+ mid <<= 8;
+
+ // i = 2
+ if (va[0] && vb[2]) mid += (uint16_t)va[0] * vb[2];
+ if (va[1] && vb[1]) mid += (uint16_t)va[1] * vb[1];
+ if (va[2] && vb[0]) mid += (uint16_t)va[2] * vb[0];
+
+ // i = 1
+ if (va[0] && vb[1]) low += (uint16_t)va[0] * vb[1];
+ if (va[1] && vb[0]) low += (uint16_t)va[1] * vb[0];
+ low <<= 8;
+
+ // i = 0
+ if (va[0] && vb[0]) low += (uint16_t)va[0] * vb[0];
+
+ #ifndef FIXMATH_NO_ROUNDING
+ low += 0x8000;
+ #endif
+ mid += (low >> 16);
+
+ #ifndef FIXMATH_NO_OVERFLOW
+ if (mid & 0x80000000)
+ return fix16_overflow;
+ #endif
+
+ fix16_t result = mid;
+
+ /* Figure out the sign of result */
+ if ((inArg0 >= 0) != (inArg1 >= 0))
+ {
+ result = -result;
+ }
+
+ return result;
+}
+#endif
+
+#ifndef FIXMATH_NO_OVERFLOW
+/* Wrapper around fix16_mul to add saturating arithmetic. */
+fix16_t fix16_smul(fix16_t inArg0, fix16_t inArg1)
+{
+ fix16_t result = fix16_mul(inArg0, inArg1);
+
+ if (result == fix16_overflow)
+ {
+ if ((inArg0 >= 0) == (inArg1 >= 0))
+ return fix16_maximum;
+ else
+ return fix16_minimum;
+ }
+
+ return result;
+}
+#endif
+
+/* 32-bit implementation of fix16_div. Fastest version for e.g. ARM Cortex M3.
+ * Performs 32-bit divisions repeatedly to reduce the remainder. For this to
+ * be efficient, the processor has to have 32-bit hardware division.
+ */
+#if !defined(FIXMATH_OPTIMIZE_8BIT)
+#ifdef __GNUC__
+// Count leading zeros, using processor-specific instruction if available.
+#define clz(x) (__builtin_clzl(x) - (8 * sizeof(long) - 32))
+#else
+static uint8_t clz(uint32_t x)
+{
+ uint8_t result = 0;
+ if (x == 0) return 32;
+ while (!(x & 0xF0000000)) { result += 4; x <<= 4; }
+ while (!(x & 0x80000000)) { result += 1; x <<= 1; }
+ return result;
+}
+#endif
+
+fix16_t fix16_div(fix16_t a, fix16_t b)
+{
+ // This uses a hardware 32/32 bit division multiple times, until we have
+ // computed all the bits in (a<<17)/b. Usually this takes 1-3 iterations.
+
+ if (b == 0)
+ return fix16_minimum;
+
+ uint32_t remainder = fix_abs(a);
+ uint32_t divider = fix_abs(b);
+ uint64_t quotient = 0;
+ int bit_pos = 17;
+
+ // Kick-start the division a bit.
+ // This improves speed in the worst-case scenarios where N and D are large
+ // It gets a lower estimate for the result by N/(D >> 17 + 1).
+ if (divider & 0xFFF00000)
+ {
+ uint32_t shifted_div = ((divider >> 17) + 1);
+ quotient = remainder / shifted_div;
+ uint64_t tmp = ((uint64_t)quotient * (uint64_t)divider) >> 17;
+ remainder -= (uint32_t)(tmp);
+ }
+
+ // If the divider is divisible by 2^n, take advantage of it.
+ while (!(divider & 0xF) && bit_pos >= 4)
+ {
+ divider >>= 4;
+ bit_pos -= 4;
+ }
+
+ while (remainder && bit_pos >= 0)
+ {
+ // Shift remainder as much as we can without overflowing
+ int shift = clz(remainder);
+ if (shift > bit_pos) shift = bit_pos;
+ remainder <<= shift;
+ bit_pos -= shift;
+
+ uint32_t div = remainder / divider;
+ remainder = remainder % divider;
+ quotient += (uint64_t)div << bit_pos;
+
+ #ifndef FIXMATH_NO_OVERFLOW
+ if (div & ~(0xFFFFFFFF >> bit_pos))
+ return fix16_overflow;
+ #endif
+
+ remainder <<= 1;
+ bit_pos--;
+ }
+
+ #ifndef FIXMATH_NO_ROUNDING
+ // Quotient is always positive so rounding is easy
+ quotient++;
+ #endif
+
+ fix16_t result = quotient >> 1;
+
+ // Figure out the sign of the result
+ if ((a ^ b) & 0x80000000)
+ {
+ #ifndef FIXMATH_NO_OVERFLOW
+ if (result == fix16_minimum)
+ return fix16_overflow;
+ #endif
+
+ result = -result;
+ }
+
+ return result;
+}
+#endif
+
+/* Alternative 32-bit implementation of fix16_div. Fastest on e.g. Atmel AVR.
+ * This does the division manually, and is therefore good for processors that
+ * do not have hardware division.
+ */
+#if defined(FIXMATH_OPTIMIZE_8BIT)
+fix16_t fix16_div(fix16_t a, fix16_t b)
+{
+ // This uses the basic binary restoring division algorithm.
+ // It appears to be faster to do the whole division manually than
+ // trying to compose a 64-bit divide out of 32-bit divisions on
+ // platforms without hardware divide.
+
+ if (b == 0)
+ return fix16_minimum;
+
+ uint32_t remainder = fix_abs(a);
+ uint32_t divider = fix_abs(b);
+
+ uint32_t quotient = 0;
+ uint32_t bit = 0x10000;
+
+ /* The algorithm requires D >= R */
+ while (divider < remainder)
+ {
+ divider <<= 1;
+ bit <<= 1;
+ }
+
+ #ifndef FIXMATH_NO_OVERFLOW
+ if (!bit)
+ return fix16_overflow;
+ #endif
+
+ if (divider & 0x80000000)
+ {
+ // Perform one step manually to avoid overflows later.
+ // We know that divider's bottom bit is 0 here.
+ if (remainder >= divider)
+ {
+ quotient |= bit;
+ remainder -= divider;
+ }
+ divider >>= 1;
+ bit >>= 1;
+ }
+
+ /* Main division loop */
+ while (bit && remainder)
+ {
+ if (remainder >= divider)
+ {
+ quotient |= bit;
+ remainder -= divider;
+ }
+
+ remainder <<= 1;
+ bit >>= 1;
+ }
+
+ #ifndef FIXMATH_NO_ROUNDING
+ if (remainder >= divider)
+ {
+ quotient++;
+ }
+ #endif
+
+ fix16_t result = quotient;
+
+ /* Figure out the sign of result */
+ if ((a ^ b) & 0x80000000)
+ {
+ #ifndef FIXMATH_NO_OVERFLOW
+ if (result == fix16_minimum)
+ return fix16_overflow;
+ #endif
+
+ result = -result;
+ }
+
+ return result;
+}
+#endif
+
+#ifndef FIXMATH_NO_OVERFLOW
+/* Wrapper around fix16_div to add saturating arithmetic. */
+fix16_t fix16_sdiv(fix16_t inArg0, fix16_t inArg1)
+{
+ fix16_t result = fix16_div(inArg0, inArg1);
+
+ if (result == fix16_overflow)
+ {
+ if ((inArg0 >= 0) == (inArg1 >= 0))
+ return fix16_maximum;
+ else
+ return fix16_minimum;
+ }
+
+ return result;
+}
+#endif
+
+fix16_t fix16_mod(fix16_t x, fix16_t y)
+{
+ #ifdef FIXMATH_OPTIMIZE_8BIT
+ /* The reason we do this, rather than use a modulo operator
+ * is that if you don't have a hardware divider, this will result
+ * in faster operations when the angles are close to the bounds.
+ */
+ while(x >= y) x -= y;
+ while(x <= -y) x += y;
+ #else
+ /* Note that in C90, the sign of result of the modulo operation is
+ * undefined. in C99, it's the same as the dividend (aka numerator).
+ */
+ x %= y;
+ #endif
+
+ return x;
+}
+
+fix16_t fix16_lerp8(fix16_t inArg0, fix16_t inArg1, uint8_t inFract)
+{
+ int64_t tempOut = int64_mul_i32_i32(inArg0, (((int32_t)1 << 8) - inFract));
+ tempOut = int64_add(tempOut, int64_mul_i32_i32(inArg1, inFract));
+ tempOut = int64_shift(tempOut, -8);
+ return (fix16_t)int64_lo(tempOut);
+}
+
+fix16_t fix16_lerp16(fix16_t inArg0, fix16_t inArg1, uint16_t inFract)
+{
+ int64_t tempOut = int64_mul_i32_i32(inArg0, (((int32_t)1 << 16) - inFract));
+ tempOut = int64_add(tempOut, int64_mul_i32_i32(inArg1, inFract));
+ tempOut = int64_shift(tempOut, -16);
+ return (fix16_t)int64_lo(tempOut);
+}
+
+fix16_t fix16_lerp32(fix16_t inArg0, fix16_t inArg1, uint32_t inFract)
+{
+ if(inFract == 0)
+ return inArg0;
+ int64_t inFract64 = int64_const(0, inFract);
+ int64_t subbed = int64_sub(int64_const(1,0), inFract64);
+ int64_t tempOut = int64_mul_i64_i32(subbed, inArg0);
+ tempOut = int64_add(tempOut, int64_mul_i64_i32(inFract64, inArg1));
+ return int64_hi(tempOut);
+}
diff --git a/Client/ThirdParty/libfixmath/libfixmath/fix16.h b/Client/ThirdParty/libfixmath/libfixmath/fix16.h index c76993a..e378f6b 100644 --- a/Client/ThirdParty/libfixmath/libfixmath/fix16.h +++ b/Client/ThirdParty/libfixmath/libfixmath/fix16.h @@ -1,334 +1,334 @@ -#ifndef __libfixmath_fix16_h__ -#define __libfixmath_fix16_h__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -/* These options may let the optimizer to remove some calls to the functions. - * Refer to http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html - */ -#ifndef FIXMATH_FUNC_ATTRS -# ifdef __GNUC__ -# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6) -# define FIXMATH_FUNC_ATTRS __attribute__((leaf, nothrow, const)) -# else -# define FIXMATH_FUNC_ATTRS __attribute__((nothrow, const)) -# endif -# else -# define FIXMATH_FUNC_ATTRS -# endif -#endif - -#include <stdint.h> - -typedef int32_t fix16_t; - -static const fix16_t FOUR_DIV_PI = 0x145F3; /*!< Fix16 value of 4/PI */ -static const fix16_t _FOUR_DIV_PI2 = 0xFFFF9840; /*!< Fix16 value of -4/PI² */ -static const fix16_t X4_CORRECTION_COMPONENT = 0x399A; /*!< Fix16 value of 0.225 */ -static const fix16_t PI_DIV_4 = 0x0000C90F; /*!< Fix16 value of PI/4 */ -static const fix16_t THREE_PI_DIV_4 = 0x00025B2F; /*!< Fix16 value of 3PI/4 */ - -static const fix16_t fix16_maximum = 0x7FFFFFFF; /*!< the maximum value of fix16_t */ -static const fix16_t fix16_minimum = 0x80000000; /*!< the minimum value of fix16_t */ -static const fix16_t fix16_overflow = 0x80000000; /*!< the value used to indicate overflows when FIXMATH_NO_OVERFLOW is not specified */ - -static const fix16_t fix16_pi = 205887; /*!< fix16_t value of pi */ -static const fix16_t fix16_e = 178145; /*!< fix16_t value of e */ -static const fix16_t fix16_one = 0x00010000; /*!< fix16_t value of 1 */ -static const fix16_t fix16_eps = 1; /*!< fix16_t epsilon */ - -/* Conversion functions between fix16_t and float/integer. - * These are inlined to allow compiler to optimize away constant numbers - */ -static inline fix16_t fix16_from_int(int a) { return a * fix16_one; } -static inline float fix16_to_float(fix16_t a) { return (float)a / fix16_one; } -static inline double fix16_to_dbl(fix16_t a) { return (double)a / fix16_one; } - -static inline int fix16_to_int(fix16_t a) -{ -#ifdef FIXMATH_NO_ROUNDING - return (a >> 16); -#else - if (a >= 0) - return (a + (fix16_one >> 1)) / fix16_one; - return (a - (fix16_one >> 1)) / fix16_one; -#endif -} - -static inline fix16_t fix16_from_float(float a) -{ - float temp = a * fix16_one; -#ifndef FIXMATH_NO_ROUNDING - temp += (temp >= 0) ? 0.5f : -0.5f; -#endif - return (fix16_t)temp; -} - -static inline fix16_t fix16_from_dbl(double a) -{ - double temp = a * fix16_one; - /* F16() and F16C() are both rounding allways, so this should as well */ -//#ifndef FIXMATH_NO_ROUNDING - temp += (double)((temp >= 0) ? 0.5f : -0.5f); -//#endif - return (fix16_t)temp; -} - -/* Macro for defining fix16_t constant values. - The functions above can't be used from e.g. global variable initializers, - and their names are quite long also. This macro is useful for constants - springled alongside code, e.g. F16(1.234). - - Note that the argument is evaluated multiple times, and also otherwise - you should only use this for constant values. For runtime-conversions, - use the functions above. -*/ -#define F16(x) ((fix16_t)(((x) >= 0) ? ((x) * 65536.0 + 0.5) : ((x) * 65536.0 - 0.5))) - -static inline fix16_t fix16_abs(fix16_t x) - { return (fix16_t)(x < 0 ? -(uint32_t)x : (uint32_t)x); } -static inline fix16_t fix16_floor(fix16_t x) - { return (x & 0xFFFF0000UL); } -static inline fix16_t fix16_ceil(fix16_t x) - { return (x & 0xFFFF0000UL) + (x & 0x0000FFFFUL ? fix16_one : 0); } -static inline fix16_t fix16_min(fix16_t x, fix16_t y) - { return (x < y ? x : y); } -static inline fix16_t fix16_max(fix16_t x, fix16_t y) - { return (x > y ? x : y); } -static inline fix16_t fix16_clamp(fix16_t x, fix16_t lo, fix16_t hi) - { return fix16_min(fix16_max(x, lo), hi); } - -/* Subtraction and addition with (optional) overflow detection. */ -#ifdef FIXMATH_NO_OVERFLOW - -static inline fix16_t fix16_add(fix16_t inArg0, fix16_t inArg1) { return (inArg0 + inArg1); } -static inline fix16_t fix16_sub(fix16_t inArg0, fix16_t inArg1) { return (inArg0 - inArg1); } - -#else - -extern fix16_t fix16_add(fix16_t a, fix16_t b) FIXMATH_FUNC_ATTRS; -extern fix16_t fix16_sub(fix16_t a, fix16_t b) FIXMATH_FUNC_ATTRS; - -/* Saturating arithmetic */ -extern fix16_t fix16_sadd(fix16_t a, fix16_t b) FIXMATH_FUNC_ATTRS; -extern fix16_t fix16_ssub(fix16_t a, fix16_t b) FIXMATH_FUNC_ATTRS; - -#endif - -/*! Multiplies the two given fix16_t's and returns the result. -*/ -extern fix16_t fix16_mul(fix16_t inArg0, fix16_t inArg1) FIXMATH_FUNC_ATTRS; - -/*! Divides the first given fix16_t by the second and returns the result. -*/ -extern fix16_t fix16_div(fix16_t inArg0, fix16_t inArg1) FIXMATH_FUNC_ATTRS; - -#ifndef FIXMATH_NO_OVERFLOW -/*! Performs a saturated multiplication (overflow-protected) of the two given fix16_t's and returns the result. -*/ -extern fix16_t fix16_smul(fix16_t inArg0, fix16_t inArg1) FIXMATH_FUNC_ATTRS; - -/*! Performs a saturated division (overflow-protected) of the first fix16_t by the second and returns the result. -*/ -extern fix16_t fix16_sdiv(fix16_t inArg0, fix16_t inArg1) FIXMATH_FUNC_ATTRS; -#endif - -/*! Divides the first given fix16_t by the second and returns the result. -*/ -extern fix16_t fix16_mod(fix16_t x, fix16_t y) FIXMATH_FUNC_ATTRS; - - - -/*! Returns the linear interpolation: (inArg0 * (1 - inFract)) + (inArg1 * inFract) -*/ -extern fix16_t fix16_lerp8(fix16_t inArg0, fix16_t inArg1, uint8_t inFract) FIXMATH_FUNC_ATTRS; -extern fix16_t fix16_lerp16(fix16_t inArg0, fix16_t inArg1, uint16_t inFract) FIXMATH_FUNC_ATTRS; -extern fix16_t fix16_lerp32(fix16_t inArg0, fix16_t inArg1, uint32_t inFract) FIXMATH_FUNC_ATTRS; - - - -/*! Returns the sine of the given fix16_t. -*/ -extern fix16_t fix16_sin_parabola(fix16_t inAngle) FIXMATH_FUNC_ATTRS; - -/*! Returns the sine of the given fix16_t. -*/ -extern fix16_t fix16_sin(fix16_t inAngle) FIXMATH_FUNC_ATTRS; - -/*! Returns the cosine of the given fix16_t. -*/ -extern fix16_t fix16_cos(fix16_t inAngle) FIXMATH_FUNC_ATTRS; - -/*! Returns the tangent of the given fix16_t. -*/ -extern fix16_t fix16_tan(fix16_t inAngle) FIXMATH_FUNC_ATTRS; - -/*! Returns the arcsine of the given fix16_t. -*/ -extern fix16_t fix16_asin(fix16_t inValue) FIXMATH_FUNC_ATTRS; - -/*! Returns the arccosine of the given fix16_t. -*/ -extern fix16_t fix16_acos(fix16_t inValue) FIXMATH_FUNC_ATTRS; - -/*! Returns the arctangent of the given fix16_t. -*/ -extern fix16_t fix16_atan(fix16_t inValue) FIXMATH_FUNC_ATTRS; - -/*! Returns the arctangent of inY/inX. -*/ -extern fix16_t fix16_atan2(fix16_t inY, fix16_t inX) FIXMATH_FUNC_ATTRS; - -static const fix16_t fix16_rad_to_deg_mult = 3754936; -static inline fix16_t fix16_rad_to_deg(fix16_t radians) - { return fix16_mul(radians, fix16_rad_to_deg_mult); } - -static const fix16_t fix16_deg_to_rad_mult = 1144; -static inline fix16_t fix16_deg_to_rad(fix16_t degrees) - { return fix16_mul(degrees, fix16_deg_to_rad_mult); } - - - -/*! Returns the square root of the given fix16_t. -*/ -extern fix16_t fix16_sqrt(fix16_t inValue) FIXMATH_FUNC_ATTRS; - -/*! Returns the square of the given fix16_t. -*/ -static inline fix16_t fix16_sq(fix16_t x) - { return fix16_mul(x, x); } - -/*! Returns the exponent (e^) of the given fix16_t. -*/ -extern fix16_t fix16_exp(fix16_t inValue) FIXMATH_FUNC_ATTRS; - -/*! Returns the natural logarithm of the given fix16_t. - */ -extern fix16_t fix16_log(fix16_t inValue) FIXMATH_FUNC_ATTRS; - -/*! Returns the base 2 logarithm of the given fix16_t. - */ -extern fix16_t fix16_log2(fix16_t x) FIXMATH_FUNC_ATTRS; - -/*! Returns the saturated base 2 logarithm of the given fix16_t. - */ -extern fix16_t fix16_slog2(fix16_t x) FIXMATH_FUNC_ATTRS; - -/*! Convert fix16_t value to a string. - * Required buffer length for largest values is 13 bytes. - */ -extern void fix16_to_str(fix16_t value, char *buf, int decimals); - -/*! Convert string to a fix16_t value - * Ignores spaces at beginning and end. Returns fix16_overflow if - * value is too large or there were garbage characters. - */ -extern fix16_t fix16_from_str(const char *buf); - -static inline uint32_t fix_abs(fix16_t in) -{ - if(in == fix16_minimum) - { - // minimum negative number has same representation as - // its absolute value in unsigned - return 0x80000000; - } - else - { - return ((in >= 0)?(in):(-in)); - } -} - - -/** Helper macro for F16C. Replace token with its number of characters/digits. */ -#define FIXMATH_TOKLEN(token) ( sizeof( #token ) - 1 ) - -/** Helper macro for F16C. Handles pow(10, n) for n from 0 to 8. */ -#define FIXMATH_CONSTANT_POW10(times) ( \ - (times == 0) ? 1ULL \ - : (times == 1) ? 10ULL \ - : (times == 2) ? 100ULL \ - : (times == 3) ? 1000ULL \ - : (times == 4) ? 10000ULL \ - : (times == 5) ? 100000ULL \ - : (times == 6) ? 1000000ULL \ - : (times == 7) ? 10000000ULL \ - : 100000000ULL \ -) - - -/** Helper macro for F16C, the type uint64_t is only used at compile time and - * shouldn't be visible in the generated code. - * - * @note We do not use fix16_one instead of 65536ULL, because the - * "use of a const variable in a constant expression is nonstandard in C". - */ -#define FIXMATH_CONVERT_MANTISSA(m) \ -( (unsigned) \ - ( \ - ( \ - ( \ - (uint64_t)( ( ( 1 ## m ## ULL ) - FIXMATH_CONSTANT_POW10(FIXMATH_TOKLEN(m)) ) * FIXMATH_CONSTANT_POW10(5 - FIXMATH_TOKLEN(m)) ) \ - * 100000ULL * 65536ULL \ - ) \ - + 5000000000ULL /* rounding: + 0.5 */ \ - ) \ - / \ - 10000000000LL \ - ) \ -) - - -#define FIXMATH_COMBINE_I_M(i, m) \ -( \ - ( \ - ( i ) \ - << 16 \ - ) \ - | \ - ( \ - FIXMATH_CONVERT_MANTISSA(m) \ - & 0xFFFF \ - ) \ -) - - -/** Create int16_t (Q16.16) constant from separate integer and mantissa part. - * - * Only tested on 32-bit ARM Cortex-M0 / x86 Intel. - * - * This macro is needed when compiling with options like "--fpu=none", - * which forbid all and every use of float and related types and - * would thus make it impossible to have fix16_t constants. - * - * Just replace uses of F16() with F16C() like this: - * F16(123.1234) becomes F16C(123,1234) - * - * @warning Specification of any value outside the mentioned intervals - * WILL result in undefined behavior! - * - * @note Regardless of the specified minimum and maximum values for i and m below, - * the total value of the number represented by i and m MUST be in the interval - * ]-32768.00000:32767.99999[ else usage with this macro will yield undefined behavior. - * - * @param i Signed integer constant with a value in the interval ]-32768:32767[. - * @param m Positive integer constant in the interval ]0:99999[ (fractional part/mantissa). - */ -#define F16C(i, m) \ -( (fix16_t) \ - ( \ - (( #i[0] ) == '-') \ - ? -FIXMATH_COMBINE_I_M((unsigned)( ( (i) * -1) ), m) \ - : FIXMATH_COMBINE_I_M((unsigned)i, m) \ - ) \ -) - -#ifdef __cplusplus -} -#include "fix16.hpp" -#endif - -#endif +#ifndef __libfixmath_fix16_h__
+#define __libfixmath_fix16_h__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/* These options may let the optimizer to remove some calls to the functions.
+ * Refer to http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html
+ */
+#ifndef FIXMATH_FUNC_ATTRS
+# ifdef __GNUC__
+# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6)
+# define FIXMATH_FUNC_ATTRS __attribute__((leaf, nothrow, const))
+# else
+# define FIXMATH_FUNC_ATTRS __attribute__((nothrow, const))
+# endif
+# else
+# define FIXMATH_FUNC_ATTRS
+# endif
+#endif
+
+#include <stdint.h>
+
+typedef int32_t fix16_t;
+
+static const fix16_t FOUR_DIV_PI = 0x145F3; /*!< Fix16 value of 4/PI */
+static const fix16_t _FOUR_DIV_PI2 = 0xFFFF9840; /*!< Fix16 value of -4/PI² */
+static const fix16_t X4_CORRECTION_COMPONENT = 0x399A; /*!< Fix16 value of 0.225 */
+static const fix16_t PI_DIV_4 = 0x0000C90F; /*!< Fix16 value of PI/4 */
+static const fix16_t THREE_PI_DIV_4 = 0x00025B2F; /*!< Fix16 value of 3PI/4 */
+
+static const fix16_t fix16_maximum = 0x7FFFFFFF; /*!< the maximum value of fix16_t */
+static const fix16_t fix16_minimum = 0x80000000; /*!< the minimum value of fix16_t */
+static const fix16_t fix16_overflow = 0x80000000; /*!< the value used to indicate overflows when FIXMATH_NO_OVERFLOW is not specified */
+
+static const fix16_t fix16_pi = 205887; /*!< fix16_t value of pi */
+static const fix16_t fix16_e = 178145; /*!< fix16_t value of e */
+static const fix16_t fix16_one = 0x00010000; /*!< fix16_t value of 1 */
+static const fix16_t fix16_eps = 1; /*!< fix16_t epsilon */
+
+/* Conversion functions between fix16_t and float/integer.
+ * These are inlined to allow compiler to optimize away constant numbers
+ */
+static inline fix16_t fix16_from_int(int a) { return a * fix16_one; }
+static inline float fix16_to_float(fix16_t a) { return (float)a / fix16_one; }
+static inline double fix16_to_dbl(fix16_t a) { return (double)a / fix16_one; }
+
+static inline int fix16_to_int(fix16_t a)
+{
+#ifdef FIXMATH_NO_ROUNDING
+ return (a >> 16);
+#else
+ if (a >= 0)
+ return (a + (fix16_one >> 1)) / fix16_one;
+ return (a - (fix16_one >> 1)) / fix16_one;
+#endif
+}
+
+static inline fix16_t fix16_from_float(float a)
+{
+ float temp = a * fix16_one;
+#ifndef FIXMATH_NO_ROUNDING
+ temp += (temp >= 0) ? 0.5f : -0.5f;
+#endif
+ return (fix16_t)temp;
+}
+
+static inline fix16_t fix16_from_dbl(double a)
+{
+ double temp = a * fix16_one;
+ /* F16() and F16C() are both rounding allways, so this should as well */
+//#ifndef FIXMATH_NO_ROUNDING
+ temp += (double)((temp >= 0) ? 0.5f : -0.5f);
+//#endif
+ return (fix16_t)temp;
+}
+
+/* Macro for defining fix16_t constant values.
+ The functions above can't be used from e.g. global variable initializers,
+ and their names are quite long also. This macro is useful for constants
+ springled alongside code, e.g. F16(1.234).
+
+ Note that the argument is evaluated multiple times, and also otherwise
+ you should only use this for constant values. For runtime-conversions,
+ use the functions above.
+*/
+#define F16(x) ((fix16_t)(((x) >= 0) ? ((x) * 65536.0 + 0.5) : ((x) * 65536.0 - 0.5)))
+
+static inline fix16_t fix16_abs(fix16_t x)
+ { return (fix16_t)(x < 0 ? -(uint32_t)x : (uint32_t)x); }
+static inline fix16_t fix16_floor(fix16_t x)
+ { return (x & 0xFFFF0000UL); }
+static inline fix16_t fix16_ceil(fix16_t x)
+ { return (x & 0xFFFF0000UL) + (x & 0x0000FFFFUL ? fix16_one : 0); }
+static inline fix16_t fix16_min(fix16_t x, fix16_t y)
+ { return (x < y ? x : y); }
+static inline fix16_t fix16_max(fix16_t x, fix16_t y)
+ { return (x > y ? x : y); }
+static inline fix16_t fix16_clamp(fix16_t x, fix16_t lo, fix16_t hi)
+ { return fix16_min(fix16_max(x, lo), hi); }
+
+/* Subtraction and addition with (optional) overflow detection. */
+#ifdef FIXMATH_NO_OVERFLOW
+
+static inline fix16_t fix16_add(fix16_t inArg0, fix16_t inArg1) { return (inArg0 + inArg1); }
+static inline fix16_t fix16_sub(fix16_t inArg0, fix16_t inArg1) { return (inArg0 - inArg1); }
+
+#else
+
+extern fix16_t fix16_add(fix16_t a, fix16_t b) FIXMATH_FUNC_ATTRS;
+extern fix16_t fix16_sub(fix16_t a, fix16_t b) FIXMATH_FUNC_ATTRS;
+
+/* Saturating arithmetic */
+extern fix16_t fix16_sadd(fix16_t a, fix16_t b) FIXMATH_FUNC_ATTRS;
+extern fix16_t fix16_ssub(fix16_t a, fix16_t b) FIXMATH_FUNC_ATTRS;
+
+#endif
+
+/*! Multiplies the two given fix16_t's and returns the result.
+*/
+extern fix16_t fix16_mul(fix16_t inArg0, fix16_t inArg1) FIXMATH_FUNC_ATTRS;
+
+/*! Divides the first given fix16_t by the second and returns the result.
+*/
+extern fix16_t fix16_div(fix16_t inArg0, fix16_t inArg1) FIXMATH_FUNC_ATTRS;
+
+#ifndef FIXMATH_NO_OVERFLOW
+/*! Performs a saturated multiplication (overflow-protected) of the two given fix16_t's and returns the result.
+*/
+extern fix16_t fix16_smul(fix16_t inArg0, fix16_t inArg1) FIXMATH_FUNC_ATTRS;
+
+/*! Performs a saturated division (overflow-protected) of the first fix16_t by the second and returns the result.
+*/
+extern fix16_t fix16_sdiv(fix16_t inArg0, fix16_t inArg1) FIXMATH_FUNC_ATTRS;
+#endif
+
+/*! Divides the first given fix16_t by the second and returns the result.
+*/
+extern fix16_t fix16_mod(fix16_t x, fix16_t y) FIXMATH_FUNC_ATTRS;
+
+
+
+/*! Returns the linear interpolation: (inArg0 * (1 - inFract)) + (inArg1 * inFract)
+*/
+extern fix16_t fix16_lerp8(fix16_t inArg0, fix16_t inArg1, uint8_t inFract) FIXMATH_FUNC_ATTRS;
+extern fix16_t fix16_lerp16(fix16_t inArg0, fix16_t inArg1, uint16_t inFract) FIXMATH_FUNC_ATTRS;
+extern fix16_t fix16_lerp32(fix16_t inArg0, fix16_t inArg1, uint32_t inFract) FIXMATH_FUNC_ATTRS;
+
+
+
+/*! Returns the sine of the given fix16_t.
+*/
+extern fix16_t fix16_sin_parabola(fix16_t inAngle) FIXMATH_FUNC_ATTRS;
+
+/*! Returns the sine of the given fix16_t.
+*/
+extern fix16_t fix16_sin(fix16_t inAngle) FIXMATH_FUNC_ATTRS;
+
+/*! Returns the cosine of the given fix16_t.
+*/
+extern fix16_t fix16_cos(fix16_t inAngle) FIXMATH_FUNC_ATTRS;
+
+/*! Returns the tangent of the given fix16_t.
+*/
+extern fix16_t fix16_tan(fix16_t inAngle) FIXMATH_FUNC_ATTRS;
+
+/*! Returns the arcsine of the given fix16_t.
+*/
+extern fix16_t fix16_asin(fix16_t inValue) FIXMATH_FUNC_ATTRS;
+
+/*! Returns the arccosine of the given fix16_t.
+*/
+extern fix16_t fix16_acos(fix16_t inValue) FIXMATH_FUNC_ATTRS;
+
+/*! Returns the arctangent of the given fix16_t.
+*/
+extern fix16_t fix16_atan(fix16_t inValue) FIXMATH_FUNC_ATTRS;
+
+/*! Returns the arctangent of inY/inX.
+*/
+extern fix16_t fix16_atan2(fix16_t inY, fix16_t inX) FIXMATH_FUNC_ATTRS;
+
+static const fix16_t fix16_rad_to_deg_mult = 3754936;
+static inline fix16_t fix16_rad_to_deg(fix16_t radians)
+ { return fix16_mul(radians, fix16_rad_to_deg_mult); }
+
+static const fix16_t fix16_deg_to_rad_mult = 1144;
+static inline fix16_t fix16_deg_to_rad(fix16_t degrees)
+ { return fix16_mul(degrees, fix16_deg_to_rad_mult); }
+
+
+
+/*! Returns the square root of the given fix16_t.
+*/
+extern fix16_t fix16_sqrt(fix16_t inValue) FIXMATH_FUNC_ATTRS;
+
+/*! Returns the square of the given fix16_t.
+*/
+static inline fix16_t fix16_sq(fix16_t x)
+ { return fix16_mul(x, x); }
+
+/*! Returns the exponent (e^) of the given fix16_t.
+*/
+extern fix16_t fix16_exp(fix16_t inValue) FIXMATH_FUNC_ATTRS;
+
+/*! Returns the natural logarithm of the given fix16_t.
+ */
+extern fix16_t fix16_log(fix16_t inValue) FIXMATH_FUNC_ATTRS;
+
+/*! Returns the base 2 logarithm of the given fix16_t.
+ */
+extern fix16_t fix16_log2(fix16_t x) FIXMATH_FUNC_ATTRS;
+
+/*! Returns the saturated base 2 logarithm of the given fix16_t.
+ */
+extern fix16_t fix16_slog2(fix16_t x) FIXMATH_FUNC_ATTRS;
+
+/*! Convert fix16_t value to a string.
+ * Required buffer length for largest values is 13 bytes.
+ */
+extern void fix16_to_str(fix16_t value, char *buf, int decimals);
+
+/*! Convert string to a fix16_t value
+ * Ignores spaces at beginning and end. Returns fix16_overflow if
+ * value is too large or there were garbage characters.
+ */
+extern fix16_t fix16_from_str(const char *buf);
+
+static inline uint32_t fix_abs(fix16_t in)
+{
+ if(in == fix16_minimum)
+ {
+ // minimum negative number has same representation as
+ // its absolute value in unsigned
+ return 0x80000000;
+ }
+ else
+ {
+ return ((in >= 0)?(in):(-in));
+ }
+}
+
+
+/** Helper macro for F16C. Replace token with its number of characters/digits. */
+#define FIXMATH_TOKLEN(token) ( sizeof( #token ) - 1 )
+
+/** Helper macro for F16C. Handles pow(10, n) for n from 0 to 8. */
+#define FIXMATH_CONSTANT_POW10(times) ( \
+ (times == 0) ? 1ULL \
+ : (times == 1) ? 10ULL \
+ : (times == 2) ? 100ULL \
+ : (times == 3) ? 1000ULL \
+ : (times == 4) ? 10000ULL \
+ : (times == 5) ? 100000ULL \
+ : (times == 6) ? 1000000ULL \
+ : (times == 7) ? 10000000ULL \
+ : 100000000ULL \
+)
+
+
+/** Helper macro for F16C, the type uint64_t is only used at compile time and
+ * shouldn't be visible in the generated code.
+ *
+ * @note We do not use fix16_one instead of 65536ULL, because the
+ * "use of a const variable in a constant expression is nonstandard in C".
+ */
+#define FIXMATH_CONVERT_MANTISSA(m) \
+( (unsigned) \
+ ( \
+ ( \
+ ( \
+ (uint64_t)( ( ( 1 ## m ## ULL ) - FIXMATH_CONSTANT_POW10(FIXMATH_TOKLEN(m)) ) * FIXMATH_CONSTANT_POW10(5 - FIXMATH_TOKLEN(m)) ) \
+ * 100000ULL * 65536ULL \
+ ) \
+ + 5000000000ULL /* rounding: + 0.5 */ \
+ ) \
+ / \
+ 10000000000LL \
+ ) \
+)
+
+
+#define FIXMATH_COMBINE_I_M(i, m) \
+( \
+ ( \
+ ( i ) \
+ << 16 \
+ ) \
+ | \
+ ( \
+ FIXMATH_CONVERT_MANTISSA(m) \
+ & 0xFFFF \
+ ) \
+)
+
+
+/** Create int16_t (Q16.16) constant from separate integer and mantissa part.
+ *
+ * Only tested on 32-bit ARM Cortex-M0 / x86 Intel.
+ *
+ * This macro is needed when compiling with options like "--fpu=none",
+ * which forbid all and every use of float and related types and
+ * would thus make it impossible to have fix16_t constants.
+ *
+ * Just replace uses of F16() with F16C() like this:
+ * F16(123.1234) becomes F16C(123,1234)
+ *
+ * @warning Specification of any value outside the mentioned intervals
+ * WILL result in undefined behavior!
+ *
+ * @note Regardless of the specified minimum and maximum values for i and m below,
+ * the total value of the number represented by i and m MUST be in the interval
+ * ]-32768.00000:32767.99999[ else usage with this macro will yield undefined behavior.
+ *
+ * @param i Signed integer constant with a value in the interval ]-32768:32767[.
+ * @param m Positive integer constant in the interval ]0:99999[ (fractional part/mantissa).
+ */
+#define F16C(i, m) \
+( (fix16_t) \
+ ( \
+ (( #i[0] ) == '-') \
+ ? -FIXMATH_COMBINE_I_M((unsigned)( ( (i) * -1) ), m) \
+ : FIXMATH_COMBINE_I_M((unsigned)i, m) \
+ ) \
+)
+
+#ifdef __cplusplus
+}
+#include "fix16.hpp"
+#endif
+
+#endif
diff --git a/Client/ThirdParty/libfixmath/libfixmath/fix16.hpp b/Client/ThirdParty/libfixmath/libfixmath/fix16.hpp index 02470e8..eb5f7f6 100644 --- a/Client/ThirdParty/libfixmath/libfixmath/fix16.hpp +++ b/Client/ThirdParty/libfixmath/libfixmath/fix16.hpp @@ -1,157 +1,157 @@ -#ifndef __libfixmath_fix16_hpp__ -#define __libfixmath_fix16_hpp__ - -#include "fix16.h" - -class Fix16 { - public: - fix16_t value; - - inline Fix16() { value = 0; } - inline Fix16(const Fix16 &inValue) { value = inValue.value; } - inline Fix16(const float inValue) { value = fix16_from_float(inValue); } - inline Fix16(const double inValue) { value = fix16_from_dbl(inValue); } - inline Fix16(const int16_t inValue) { value = fix16_from_int(inValue); } - inline Fix16(const fix16_t inValue) { value = inValue; } - - inline operator fix16_t() const { return value; } - inline operator double() const { return fix16_to_dbl(value); } - inline operator float() const { return fix16_to_float(value); } - inline operator int16_t() const { return (int16_t)fix16_to_int(value); } - - inline Fix16 & operator=(const Fix16 &rhs) { value = rhs.value; return *this; } - inline Fix16 & operator=(const fix16_t rhs) { value = rhs; return *this; } - inline Fix16 & operator=(const double rhs) { value = fix16_from_dbl(rhs); return *this; } - inline Fix16 & operator=(const float rhs) { value = fix16_from_float(rhs); return *this; } - inline Fix16 & operator=(const int16_t rhs) { value = fix16_from_int(rhs); return *this; } - - inline Fix16 & operator+=(const Fix16 &rhs) { value += rhs.value; return *this; } - inline Fix16 & operator+=(const fix16_t rhs) { value += rhs; return *this; } - inline Fix16 & operator+=(const double rhs) { value += fix16_from_dbl(rhs); return *this; } - inline Fix16 & operator+=(const float rhs) { value += fix16_from_float(rhs); return *this; } - inline Fix16 & operator+=(const int16_t rhs) { value += fix16_from_int(rhs); return *this; } - - inline Fix16 & operator-=(const Fix16 &rhs) { value -= rhs.value; return *this; } - inline Fix16 & operator-=(const fix16_t rhs) { value -= rhs; return *this; } - inline Fix16 & operator-=(const double rhs) { value -= fix16_from_dbl(rhs); return *this; } - inline Fix16 & operator-=(const float rhs) { value -= fix16_from_float(rhs); return *this; } - inline Fix16 & operator-=(const int16_t rhs) { value -= fix16_from_int(rhs); return *this; } - - inline Fix16 & operator*=(const Fix16 &rhs) { value = fix16_mul(value, rhs.value); return *this; } - inline Fix16 & operator*=(const fix16_t rhs) { value = fix16_mul(value, rhs); return *this; } - inline Fix16 & operator*=(const double rhs) { value = fix16_mul(value, fix16_from_dbl(rhs)); return *this; } - inline Fix16 & operator*=(const float rhs) { value = fix16_mul(value, fix16_from_float(rhs)); return *this; } - inline Fix16 & operator*=(const int16_t rhs) { value *= rhs; return *this; } - - inline Fix16 & operator/=(const Fix16 &rhs) { value = fix16_div(value, rhs.value); return *this; } - inline Fix16 & operator/=(const fix16_t rhs) { value = fix16_div(value, rhs); return *this; } - inline Fix16 & operator/=(const double rhs) { value = fix16_div(value, fix16_from_dbl(rhs)); return *this; } - inline Fix16 & operator/=(const float rhs) { value = fix16_div(value, fix16_from_float(rhs)); return *this; } - inline Fix16 & operator/=(const int16_t rhs) { value /= rhs; return *this; } - - inline const Fix16 operator+(const Fix16 &other) const { Fix16 ret = *this; ret += other; return ret; } - inline const Fix16 operator+(const fix16_t other) const { Fix16 ret = *this; ret += other; return ret; } - inline const Fix16 operator+(const double other) const { Fix16 ret = *this; ret += other; return ret; } - inline const Fix16 operator+(const float other) const { Fix16 ret = *this; ret += other; return ret; } - inline const Fix16 operator+(const int16_t other) const { Fix16 ret = *this; ret += other; return ret; } - -#ifndef FIXMATH_NO_OVERFLOW - inline const Fix16 sadd(const Fix16 &other) const { Fix16 ret = fix16_sadd(value, other.value); return ret; } - inline const Fix16 sadd(const fix16_t other) const { Fix16 ret = fix16_sadd(value, other); return ret; } - inline const Fix16 sadd(const double other) const { Fix16 ret = fix16_sadd(value, fix16_from_dbl(other)); return ret; } - inline const Fix16 sadd(const float other) const { Fix16 ret = fix16_sadd(value, fix16_from_float(other)); return ret; } - inline const Fix16 sadd(const int16_t other) const { Fix16 ret = fix16_sadd(value, fix16_from_int(other)); return ret; } -#endif - - inline const Fix16 operator-(const Fix16 &other) const { Fix16 ret = *this; ret -= other; return ret; } - inline const Fix16 operator-(const fix16_t other) const { Fix16 ret = *this; ret -= other; return ret; } - inline const Fix16 operator-(const double other) const { Fix16 ret = *this; ret -= other; return ret; } - inline const Fix16 operator-(const float other) const { Fix16 ret = *this; ret -= other; return ret; } - inline const Fix16 operator-(const int16_t other) const { Fix16 ret = *this; ret -= other; return ret; } - - inline const Fix16 operator-() const { Fix16 ret = fix16_sub(0, value); return ret; } - -#ifndef FIXMATH_NO_OVERFLOW - inline const Fix16 ssub(const Fix16 &other) const { Fix16 ret = fix16_sadd(value, -other.value); return ret; } - inline const Fix16 ssub(const fix16_t other) const { Fix16 ret = fix16_sadd(value, -other); return ret; } - inline const Fix16 ssub(const double other) const { Fix16 ret = fix16_sadd(value, -fix16_from_dbl(other)); return ret; } - inline const Fix16 ssub(const float other) const { Fix16 ret = fix16_sadd(value, -fix16_from_float(other)); return ret; } - inline const Fix16 ssub(const int16_t other) const { Fix16 ret = fix16_sadd(value, -fix16_from_int(other)); return ret; } -#endif - - inline const Fix16 operator*(const Fix16 &other) const { Fix16 ret = *this; ret *= other; return ret; } - inline const Fix16 operator*(const fix16_t other) const { Fix16 ret = *this; ret *= other; return ret; } - inline const Fix16 operator*(const double other) const { Fix16 ret = *this; ret *= other; return ret; } - inline const Fix16 operator*(const float other) const { Fix16 ret = *this; ret *= other; return ret; } - inline const Fix16 operator*(const int16_t other) const { Fix16 ret = *this; ret *= other; return ret; } - -#ifndef FIXMATH_NO_OVERFLOW - inline const Fix16 smul(const Fix16 &other) const { Fix16 ret = fix16_smul(value, other.value); return ret; } - inline const Fix16 smul(const fix16_t other) const { Fix16 ret = fix16_smul(value, other); return ret; } - inline const Fix16 smul(const double other) const { Fix16 ret = fix16_smul(value, fix16_from_dbl(other)); return ret; } - inline const Fix16 smul(const float other) const { Fix16 ret = fix16_smul(value, fix16_from_float(other)); return ret; } - inline const Fix16 smul(const int16_t other) const { Fix16 ret = fix16_smul(value, fix16_from_int(other)); return ret; } -#endif - - inline const Fix16 operator/(const Fix16 &other) const { Fix16 ret = *this; ret /= other; return ret; } - inline const Fix16 operator/(const fix16_t other) const { Fix16 ret = *this; ret /= other; return ret; } - inline const Fix16 operator/(const double other) const { Fix16 ret = *this; ret /= other; return ret; } - inline const Fix16 operator/(const float other) const { Fix16 ret = *this; ret /= other; return ret; } - inline const Fix16 operator/(const int16_t other) const { Fix16 ret = *this; ret /= other; return ret; } - -#ifndef FIXMATH_NO_OVERFLOW - inline const Fix16 sdiv(const Fix16 &other) const { Fix16 ret = fix16_sdiv(value, other.value); return ret; } - inline const Fix16 sdiv(const fix16_t other) const { Fix16 ret = fix16_sdiv(value, other); return ret; } - inline const Fix16 sdiv(const double other) const { Fix16 ret = fix16_sdiv(value, fix16_from_dbl(other)); return ret; } - inline const Fix16 sdiv(const float other) const { Fix16 ret = fix16_sdiv(value, fix16_from_float(other)); return ret; } - inline const Fix16 sdiv(const int16_t other) const { Fix16 ret = fix16_sdiv(value, fix16_from_int(other)); return ret; } -#endif - - inline int operator==(const Fix16 &other) const { return (value == other.value); } - inline int operator==(const fix16_t other) const { return (value == other); } - inline int operator==(const double other) const { return (value == fix16_from_dbl(other)); } - inline int operator==(const float other) const { return (value == fix16_from_float(other)); } - inline int operator==(const int16_t other) const { return (value == fix16_from_int(other)); } - - inline int operator!=(const Fix16 &other) const { return (value != other.value); } - inline int operator!=(const fix16_t other) const { return (value != other); } - inline int operator!=(const double other) const { return (value != fix16_from_dbl(other)); } - inline int operator!=(const float other) const { return (value != fix16_from_float(other)); } - inline int operator!=(const int16_t other) const { return (value != fix16_from_int(other)); } - - inline int operator<=(const Fix16 &other) const { return (value <= other.value); } - inline int operator<=(const fix16_t other) const { return (value <= other); } - inline int operator<=(const double other) const { return (value <= fix16_from_dbl(other)); } - inline int operator<=(const float other) const { return (value <= fix16_from_float(other)); } - inline int operator<=(const int16_t other) const { return (value <= fix16_from_int(other)); } - - inline int operator>=(const Fix16 &other) const { return (value >= other.value); } - inline int operator>=(const fix16_t other) const { return (value >= other); } - inline int operator>=(const double other) const { return (value >= fix16_from_dbl(other)); } - inline int operator>=(const float other) const { return (value >= fix16_from_float(other)); } - inline int operator>=(const int16_t other) const { return (value >= fix16_from_int(other)); } - - inline int operator< (const Fix16 &other) const { return (value < other.value); } - inline int operator< (const fix16_t other) const { return (value < other); } - inline int operator< (const double other) const { return (value < fix16_from_dbl(other)); } - inline int operator< (const float other) const { return (value < fix16_from_float(other)); } - inline int operator< (const int16_t other) const { return (value < fix16_from_int(other)); } - - inline int operator> (const Fix16 &other) const { return (value > other.value); } - inline int operator> (const fix16_t other) const { return (value > other); } - inline int operator> (const double other) const { return (value > fix16_from_dbl(other)); } - inline int operator> (const float other) const { return (value > fix16_from_float(other)); } - inline int operator> (const int16_t other) const { return (value > fix16_from_int(other)); } - - inline Fix16 sin() const { return Fix16(fix16_sin(value)); } - inline Fix16 cos() const { return Fix16(fix16_cos(value)); } - inline Fix16 tan() const { return Fix16(fix16_tan(value)); } - inline Fix16 asin() const { return Fix16(fix16_asin(value)); } - inline Fix16 acos() const { return Fix16(fix16_acos(value)); } - inline Fix16 atan() const { return Fix16(fix16_atan(value)); } - inline Fix16 atan2(const Fix16 &inY) const { return Fix16(fix16_atan2(value, inY.value)); } - inline Fix16 sqrt() const { return Fix16(fix16_sqrt(value)); } - -}; - -#endif +#ifndef __libfixmath_fix16_hpp__
+#define __libfixmath_fix16_hpp__
+
+#include "fix16.h"
+
+class Fix16 {
+ public:
+ fix16_t value;
+
+ inline Fix16() { value = 0; }
+ inline Fix16(const Fix16 &inValue) { value = inValue.value; }
+ inline Fix16(const float inValue) { value = fix16_from_float(inValue); }
+ inline Fix16(const double inValue) { value = fix16_from_dbl(inValue); }
+ inline Fix16(const int16_t inValue) { value = fix16_from_int(inValue); }
+ inline Fix16(const fix16_t inValue) { value = inValue; }
+
+ inline operator fix16_t() const { return value; }
+ inline operator double() const { return fix16_to_dbl(value); }
+ inline operator float() const { return fix16_to_float(value); }
+ inline operator int16_t() const { return (int16_t)fix16_to_int(value); }
+
+ inline Fix16 & operator=(const Fix16 &rhs) { value = rhs.value; return *this; }
+ inline Fix16 & operator=(const fix16_t rhs) { value = rhs; return *this; }
+ inline Fix16 & operator=(const double rhs) { value = fix16_from_dbl(rhs); return *this; }
+ inline Fix16 & operator=(const float rhs) { value = fix16_from_float(rhs); return *this; }
+ inline Fix16 & operator=(const int16_t rhs) { value = fix16_from_int(rhs); return *this; }
+
+ inline Fix16 & operator+=(const Fix16 &rhs) { value += rhs.value; return *this; }
+ inline Fix16 & operator+=(const fix16_t rhs) { value += rhs; return *this; }
+ inline Fix16 & operator+=(const double rhs) { value += fix16_from_dbl(rhs); return *this; }
+ inline Fix16 & operator+=(const float rhs) { value += fix16_from_float(rhs); return *this; }
+ inline Fix16 & operator+=(const int16_t rhs) { value += fix16_from_int(rhs); return *this; }
+
+ inline Fix16 & operator-=(const Fix16 &rhs) { value -= rhs.value; return *this; }
+ inline Fix16 & operator-=(const fix16_t rhs) { value -= rhs; return *this; }
+ inline Fix16 & operator-=(const double rhs) { value -= fix16_from_dbl(rhs); return *this; }
+ inline Fix16 & operator-=(const float rhs) { value -= fix16_from_float(rhs); return *this; }
+ inline Fix16 & operator-=(const int16_t rhs) { value -= fix16_from_int(rhs); return *this; }
+
+ inline Fix16 & operator*=(const Fix16 &rhs) { value = fix16_mul(value, rhs.value); return *this; }
+ inline Fix16 & operator*=(const fix16_t rhs) { value = fix16_mul(value, rhs); return *this; }
+ inline Fix16 & operator*=(const double rhs) { value = fix16_mul(value, fix16_from_dbl(rhs)); return *this; }
+ inline Fix16 & operator*=(const float rhs) { value = fix16_mul(value, fix16_from_float(rhs)); return *this; }
+ inline Fix16 & operator*=(const int16_t rhs) { value *= rhs; return *this; }
+
+ inline Fix16 & operator/=(const Fix16 &rhs) { value = fix16_div(value, rhs.value); return *this; }
+ inline Fix16 & operator/=(const fix16_t rhs) { value = fix16_div(value, rhs); return *this; }
+ inline Fix16 & operator/=(const double rhs) { value = fix16_div(value, fix16_from_dbl(rhs)); return *this; }
+ inline Fix16 & operator/=(const float rhs) { value = fix16_div(value, fix16_from_float(rhs)); return *this; }
+ inline Fix16 & operator/=(const int16_t rhs) { value /= rhs; return *this; }
+
+ inline const Fix16 operator+(const Fix16 &other) const { Fix16 ret = *this; ret += other; return ret; }
+ inline const Fix16 operator+(const fix16_t other) const { Fix16 ret = *this; ret += other; return ret; }
+ inline const Fix16 operator+(const double other) const { Fix16 ret = *this; ret += other; return ret; }
+ inline const Fix16 operator+(const float other) const { Fix16 ret = *this; ret += other; return ret; }
+ inline const Fix16 operator+(const int16_t other) const { Fix16 ret = *this; ret += other; return ret; }
+
+#ifndef FIXMATH_NO_OVERFLOW
+ inline const Fix16 sadd(const Fix16 &other) const { Fix16 ret = fix16_sadd(value, other.value); return ret; }
+ inline const Fix16 sadd(const fix16_t other) const { Fix16 ret = fix16_sadd(value, other); return ret; }
+ inline const Fix16 sadd(const double other) const { Fix16 ret = fix16_sadd(value, fix16_from_dbl(other)); return ret; }
+ inline const Fix16 sadd(const float other) const { Fix16 ret = fix16_sadd(value, fix16_from_float(other)); return ret; }
+ inline const Fix16 sadd(const int16_t other) const { Fix16 ret = fix16_sadd(value, fix16_from_int(other)); return ret; }
+#endif
+
+ inline const Fix16 operator-(const Fix16 &other) const { Fix16 ret = *this; ret -= other; return ret; }
+ inline const Fix16 operator-(const fix16_t other) const { Fix16 ret = *this; ret -= other; return ret; }
+ inline const Fix16 operator-(const double other) const { Fix16 ret = *this; ret -= other; return ret; }
+ inline const Fix16 operator-(const float other) const { Fix16 ret = *this; ret -= other; return ret; }
+ inline const Fix16 operator-(const int16_t other) const { Fix16 ret = *this; ret -= other; return ret; }
+
+ inline const Fix16 operator-() const { Fix16 ret = fix16_sub(0, value); return ret; }
+
+#ifndef FIXMATH_NO_OVERFLOW
+ inline const Fix16 ssub(const Fix16 &other) const { Fix16 ret = fix16_sadd(value, -other.value); return ret; }
+ inline const Fix16 ssub(const fix16_t other) const { Fix16 ret = fix16_sadd(value, -other); return ret; }
+ inline const Fix16 ssub(const double other) const { Fix16 ret = fix16_sadd(value, -fix16_from_dbl(other)); return ret; }
+ inline const Fix16 ssub(const float other) const { Fix16 ret = fix16_sadd(value, -fix16_from_float(other)); return ret; }
+ inline const Fix16 ssub(const int16_t other) const { Fix16 ret = fix16_sadd(value, -fix16_from_int(other)); return ret; }
+#endif
+
+ inline const Fix16 operator*(const Fix16 &other) const { Fix16 ret = *this; ret *= other; return ret; }
+ inline const Fix16 operator*(const fix16_t other) const { Fix16 ret = *this; ret *= other; return ret; }
+ inline const Fix16 operator*(const double other) const { Fix16 ret = *this; ret *= other; return ret; }
+ inline const Fix16 operator*(const float other) const { Fix16 ret = *this; ret *= other; return ret; }
+ inline const Fix16 operator*(const int16_t other) const { Fix16 ret = *this; ret *= other; return ret; }
+
+#ifndef FIXMATH_NO_OVERFLOW
+ inline const Fix16 smul(const Fix16 &other) const { Fix16 ret = fix16_smul(value, other.value); return ret; }
+ inline const Fix16 smul(const fix16_t other) const { Fix16 ret = fix16_smul(value, other); return ret; }
+ inline const Fix16 smul(const double other) const { Fix16 ret = fix16_smul(value, fix16_from_dbl(other)); return ret; }
+ inline const Fix16 smul(const float other) const { Fix16 ret = fix16_smul(value, fix16_from_float(other)); return ret; }
+ inline const Fix16 smul(const int16_t other) const { Fix16 ret = fix16_smul(value, fix16_from_int(other)); return ret; }
+#endif
+
+ inline const Fix16 operator/(const Fix16 &other) const { Fix16 ret = *this; ret /= other; return ret; }
+ inline const Fix16 operator/(const fix16_t other) const { Fix16 ret = *this; ret /= other; return ret; }
+ inline const Fix16 operator/(const double other) const { Fix16 ret = *this; ret /= other; return ret; }
+ inline const Fix16 operator/(const float other) const { Fix16 ret = *this; ret /= other; return ret; }
+ inline const Fix16 operator/(const int16_t other) const { Fix16 ret = *this; ret /= other; return ret; }
+
+#ifndef FIXMATH_NO_OVERFLOW
+ inline const Fix16 sdiv(const Fix16 &other) const { Fix16 ret = fix16_sdiv(value, other.value); return ret; }
+ inline const Fix16 sdiv(const fix16_t other) const { Fix16 ret = fix16_sdiv(value, other); return ret; }
+ inline const Fix16 sdiv(const double other) const { Fix16 ret = fix16_sdiv(value, fix16_from_dbl(other)); return ret; }
+ inline const Fix16 sdiv(const float other) const { Fix16 ret = fix16_sdiv(value, fix16_from_float(other)); return ret; }
+ inline const Fix16 sdiv(const int16_t other) const { Fix16 ret = fix16_sdiv(value, fix16_from_int(other)); return ret; }
+#endif
+
+ inline int operator==(const Fix16 &other) const { return (value == other.value); }
+ inline int operator==(const fix16_t other) const { return (value == other); }
+ inline int operator==(const double other) const { return (value == fix16_from_dbl(other)); }
+ inline int operator==(const float other) const { return (value == fix16_from_float(other)); }
+ inline int operator==(const int16_t other) const { return (value == fix16_from_int(other)); }
+
+ inline int operator!=(const Fix16 &other) const { return (value != other.value); }
+ inline int operator!=(const fix16_t other) const { return (value != other); }
+ inline int operator!=(const double other) const { return (value != fix16_from_dbl(other)); }
+ inline int operator!=(const float other) const { return (value != fix16_from_float(other)); }
+ inline int operator!=(const int16_t other) const { return (value != fix16_from_int(other)); }
+
+ inline int operator<=(const Fix16 &other) const { return (value <= other.value); }
+ inline int operator<=(const fix16_t other) const { return (value <= other); }
+ inline int operator<=(const double other) const { return (value <= fix16_from_dbl(other)); }
+ inline int operator<=(const float other) const { return (value <= fix16_from_float(other)); }
+ inline int operator<=(const int16_t other) const { return (value <= fix16_from_int(other)); }
+
+ inline int operator>=(const Fix16 &other) const { return (value >= other.value); }
+ inline int operator>=(const fix16_t other) const { return (value >= other); }
+ inline int operator>=(const double other) const { return (value >= fix16_from_dbl(other)); }
+ inline int operator>=(const float other) const { return (value >= fix16_from_float(other)); }
+ inline int operator>=(const int16_t other) const { return (value >= fix16_from_int(other)); }
+
+ inline int operator< (const Fix16 &other) const { return (value < other.value); }
+ inline int operator< (const fix16_t other) const { return (value < other); }
+ inline int operator< (const double other) const { return (value < fix16_from_dbl(other)); }
+ inline int operator< (const float other) const { return (value < fix16_from_float(other)); }
+ inline int operator< (const int16_t other) const { return (value < fix16_from_int(other)); }
+
+ inline int operator> (const Fix16 &other) const { return (value > other.value); }
+ inline int operator> (const fix16_t other) const { return (value > other); }
+ inline int operator> (const double other) const { return (value > fix16_from_dbl(other)); }
+ inline int operator> (const float other) const { return (value > fix16_from_float(other)); }
+ inline int operator> (const int16_t other) const { return (value > fix16_from_int(other)); }
+
+ inline Fix16 sin() const { return Fix16(fix16_sin(value)); }
+ inline Fix16 cos() const { return Fix16(fix16_cos(value)); }
+ inline Fix16 tan() const { return Fix16(fix16_tan(value)); }
+ inline Fix16 asin() const { return Fix16(fix16_asin(value)); }
+ inline Fix16 acos() const { return Fix16(fix16_acos(value)); }
+ inline Fix16 atan() const { return Fix16(fix16_atan(value)); }
+ inline Fix16 atan2(const Fix16 &inY) const { return Fix16(fix16_atan2(value, inY.value)); }
+ inline Fix16 sqrt() const { return Fix16(fix16_sqrt(value)); }
+
+};
+
+#endif
diff --git a/Client/ThirdParty/libfixmath/libfixmath/fix16_exp.c b/Client/ThirdParty/libfixmath/libfixmath/fix16_exp.c index 7cb124e..e804da1 100644 --- a/Client/ThirdParty/libfixmath/libfixmath/fix16_exp.c +++ b/Client/ThirdParty/libfixmath/libfixmath/fix16_exp.c @@ -1,197 +1,197 @@ -#include "fix16.h" -#include <stdbool.h> - -#ifndef FIXMATH_NO_CACHE -static fix16_t _fix16_exp_cache_index[4096] = { 0 }; -static fix16_t _fix16_exp_cache_value[4096] = { 0 }; -#endif - - - -fix16_t fix16_exp(fix16_t inValue) { - if(inValue == 0 ) return fix16_one; - if(inValue == fix16_one) return fix16_e; - if(inValue >= 681391 ) return fix16_maximum; - if(inValue <= -772243 ) return 0; - - #ifndef FIXMATH_NO_CACHE - fix16_t tempIndex = (inValue ^ (inValue >> 4)) & 0x0FFF; - if(_fix16_exp_cache_index[tempIndex] == inValue) - return _fix16_exp_cache_value[tempIndex]; - #endif - - /* The algorithm is based on the power series for exp(x): - * http://en.wikipedia.org/wiki/Exponential_function#Formal_definition - * - * From term n, we get term n+1 by multiplying with x/n. - * When the sum term drops to zero, we can stop summing. - */ - - // The power-series converges much faster on positive values - // and exp(-x) = 1/exp(x). - bool neg = (inValue < 0); - if (neg) inValue = -inValue; - - fix16_t result = inValue + fix16_one; - fix16_t term = inValue; - - uint_fast8_t i; - for (i = 2; i < 30; i++) - { - term = fix16_mul(term, fix16_div(inValue, fix16_from_int(i))); - result += term; - - if ((term < 500) && ((i > 15) || (term < 20))) - break; - } - - if (neg) result = fix16_div(fix16_one, result); - - #ifndef FIXMATH_NO_CACHE - _fix16_exp_cache_index[tempIndex] = inValue; - _fix16_exp_cache_value[tempIndex] = result; - #endif - - return result; -} - - - -fix16_t fix16_log(fix16_t inValue) -{ - fix16_t guess = fix16_from_int(2); - fix16_t delta; - int scaling = 0; - int count = 0; - - if (inValue <= 0) - return fix16_minimum; - - // Bring the value to the most accurate range (1 < x < 100) - const fix16_t e_to_fourth = 3578144; - while (inValue > fix16_from_int(100)) - { - inValue = fix16_div(inValue, e_to_fourth); - scaling += 4; - } - - while (inValue < fix16_one) - { - inValue = fix16_mul(inValue, e_to_fourth); - scaling -= 4; - } - - do - { - // Solving e(x) = y using Newton's method - // f(x) = e(x) - y - // f'(x) = e(x) - fix16_t e = fix16_exp(guess); - delta = fix16_div(inValue - e, e); - - // It's unlikely that logarithm is very large, so avoid overshooting. - if (delta > fix16_from_int(3)) - delta = fix16_from_int(3); - - guess += delta; - } while ((count++ < 10) - && ((delta > 1) || (delta < -1))); - - return guess + fix16_from_int(scaling); -} - - - -static inline fix16_t fix16_rs(fix16_t x) -{ - #ifdef FIXMATH_NO_ROUNDING - return (x >> 1); - #else - fix16_t y = (x >> 1) + (x & 1); - return y; - #endif -} - -/** - * This assumes that the input value is >= 1. - * - * Note that this is only ever called with inValue >= 1 (because it has a wrapper to check. - * As such, the result is always less than the input. - */ -static fix16_t fix16__log2_inner(fix16_t x) -{ - fix16_t result = 0; - - while(x >= fix16_from_int(2)) - { - result++; - x = fix16_rs(x); - } - - if(x == 0) return (result << 16); - - uint_fast8_t i; - for(i = 16; i > 0; i--) - { - x = fix16_mul(x, x); - result <<= 1; - if(x >= fix16_from_int(2)) - { - result |= 1; - x = fix16_rs(x); - } - } - #ifndef FIXMATH_NO_ROUNDING - x = fix16_mul(x, x); - if(x >= fix16_from_int(2)) result++; - #endif - - return result; -} - - - -/** - * calculates the log base 2 of input. - * Note that negative inputs are invalid! (will return fix16_overflow, since there are no exceptions) - * - * i.e. 2 to the power output = input. - * It's equivalent to the log or ln functions, except it uses base 2 instead of base 10 or base e. - * This is useful as binary things like this are easy for binary devices, like modern microprocessros, to calculate. - * - * This can be used as a helper function to calculate powers with non-integer powers and/or bases. - */ -fix16_t fix16_log2(fix16_t x) -{ - // Note that a negative x gives a non-real result. - // If x == 0, the limit of log2(x) as x -> 0 = -infinity. - // log2(-ve) gives a complex result. - if (x <= 0) return fix16_overflow; - - // If the input is less than one, the result is -log2(1.0 / in) - if (x < fix16_one) - { - // Note that the inverse of this would overflow. - // This is the exact answer for log2(1.0 / 65536) - if (x == 1) return fix16_from_int(-16); - - fix16_t inverse = fix16_div(fix16_one, x); - return -fix16__log2_inner(inverse); - } - - // If input >= 1, just proceed as normal. - // Note that x == fix16_one is a special case, where the answer is 0. - return fix16__log2_inner(x); -} - -/** - * This is a wrapper for fix16_log2 which implements saturation arithmetic. - */ -fix16_t fix16_slog2(fix16_t x) -{ - fix16_t retval = fix16_log2(x); - // The only overflow possible is when the input is negative. - if(retval == fix16_overflow) - return fix16_minimum; - return retval; -} +#include "fix16.h"
+#include <stdbool.h>
+
+#ifndef FIXMATH_NO_CACHE
+static fix16_t _fix16_exp_cache_index[4096] = { 0 };
+static fix16_t _fix16_exp_cache_value[4096] = { 0 };
+#endif
+
+
+
+fix16_t fix16_exp(fix16_t inValue) {
+ if(inValue == 0 ) return fix16_one;
+ if(inValue == fix16_one) return fix16_e;
+ if(inValue >= 681391 ) return fix16_maximum;
+ if(inValue <= -772243 ) return 0;
+
+ #ifndef FIXMATH_NO_CACHE
+ fix16_t tempIndex = (inValue ^ (inValue >> 4)) & 0x0FFF;
+ if(_fix16_exp_cache_index[tempIndex] == inValue)
+ return _fix16_exp_cache_value[tempIndex];
+ #endif
+
+ /* The algorithm is based on the power series for exp(x):
+ * http://en.wikipedia.org/wiki/Exponential_function#Formal_definition
+ *
+ * From term n, we get term n+1 by multiplying with x/n.
+ * When the sum term drops to zero, we can stop summing.
+ */
+
+ // The power-series converges much faster on positive values
+ // and exp(-x) = 1/exp(x).
+ bool neg = (inValue < 0);
+ if (neg) inValue = -inValue;
+
+ fix16_t result = inValue + fix16_one;
+ fix16_t term = inValue;
+
+ uint_fast8_t i;
+ for (i = 2; i < 30; i++)
+ {
+ term = fix16_mul(term, fix16_div(inValue, fix16_from_int(i)));
+ result += term;
+
+ if ((term < 500) && ((i > 15) || (term < 20)))
+ break;
+ }
+
+ if (neg) result = fix16_div(fix16_one, result);
+
+ #ifndef FIXMATH_NO_CACHE
+ _fix16_exp_cache_index[tempIndex] = inValue;
+ _fix16_exp_cache_value[tempIndex] = result;
+ #endif
+
+ return result;
+}
+
+
+
+fix16_t fix16_log(fix16_t inValue)
+{
+ fix16_t guess = fix16_from_int(2);
+ fix16_t delta;
+ int scaling = 0;
+ int count = 0;
+
+ if (inValue <= 0)
+ return fix16_minimum;
+
+ // Bring the value to the most accurate range (1 < x < 100)
+ const fix16_t e_to_fourth = 3578144;
+ while (inValue > fix16_from_int(100))
+ {
+ inValue = fix16_div(inValue, e_to_fourth);
+ scaling += 4;
+ }
+
+ while (inValue < fix16_one)
+ {
+ inValue = fix16_mul(inValue, e_to_fourth);
+ scaling -= 4;
+ }
+
+ do
+ {
+ // Solving e(x) = y using Newton's method
+ // f(x) = e(x) - y
+ // f'(x) = e(x)
+ fix16_t e = fix16_exp(guess);
+ delta = fix16_div(inValue - e, e);
+
+ // It's unlikely that logarithm is very large, so avoid overshooting.
+ if (delta > fix16_from_int(3))
+ delta = fix16_from_int(3);
+
+ guess += delta;
+ } while ((count++ < 10)
+ && ((delta > 1) || (delta < -1)));
+
+ return guess + fix16_from_int(scaling);
+}
+
+
+
+static inline fix16_t fix16_rs(fix16_t x)
+{
+ #ifdef FIXMATH_NO_ROUNDING
+ return (x >> 1);
+ #else
+ fix16_t y = (x >> 1) + (x & 1);
+ return y;
+ #endif
+}
+
+/**
+ * This assumes that the input value is >= 1.
+ *
+ * Note that this is only ever called with inValue >= 1 (because it has a wrapper to check.
+ * As such, the result is always less than the input.
+ */
+static fix16_t fix16__log2_inner(fix16_t x)
+{
+ fix16_t result = 0;
+
+ while(x >= fix16_from_int(2))
+ {
+ result++;
+ x = fix16_rs(x);
+ }
+
+ if(x == 0) return (result << 16);
+
+ uint_fast8_t i;
+ for(i = 16; i > 0; i--)
+ {
+ x = fix16_mul(x, x);
+ result <<= 1;
+ if(x >= fix16_from_int(2))
+ {
+ result |= 1;
+ x = fix16_rs(x);
+ }
+ }
+ #ifndef FIXMATH_NO_ROUNDING
+ x = fix16_mul(x, x);
+ if(x >= fix16_from_int(2)) result++;
+ #endif
+
+ return result;
+}
+
+
+
+/**
+ * calculates the log base 2 of input.
+ * Note that negative inputs are invalid! (will return fix16_overflow, since there are no exceptions)
+ *
+ * i.e. 2 to the power output = input.
+ * It's equivalent to the log or ln functions, except it uses base 2 instead of base 10 or base e.
+ * This is useful as binary things like this are easy for binary devices, like modern microprocessros, to calculate.
+ *
+ * This can be used as a helper function to calculate powers with non-integer powers and/or bases.
+ */
+fix16_t fix16_log2(fix16_t x)
+{
+ // Note that a negative x gives a non-real result.
+ // If x == 0, the limit of log2(x) as x -> 0 = -infinity.
+ // log2(-ve) gives a complex result.
+ if (x <= 0) return fix16_overflow;
+
+ // If the input is less than one, the result is -log2(1.0 / in)
+ if (x < fix16_one)
+ {
+ // Note that the inverse of this would overflow.
+ // This is the exact answer for log2(1.0 / 65536)
+ if (x == 1) return fix16_from_int(-16);
+
+ fix16_t inverse = fix16_div(fix16_one, x);
+ return -fix16__log2_inner(inverse);
+ }
+
+ // If input >= 1, just proceed as normal.
+ // Note that x == fix16_one is a special case, where the answer is 0.
+ return fix16__log2_inner(x);
+}
+
+/**
+ * This is a wrapper for fix16_log2 which implements saturation arithmetic.
+ */
+fix16_t fix16_slog2(fix16_t x)
+{
+ fix16_t retval = fix16_log2(x);
+ // The only overflow possible is when the input is negative.
+ if(retval == fix16_overflow)
+ return fix16_minimum;
+ return retval;
+}
diff --git a/Client/ThirdParty/libfixmath/libfixmath/fix16_sqrt.c b/Client/ThirdParty/libfixmath/libfixmath/fix16_sqrt.c index 78984d4..f7493e7 100644 --- a/Client/ThirdParty/libfixmath/libfixmath/fix16_sqrt.c +++ b/Client/ThirdParty/libfixmath/libfixmath/fix16_sqrt.c @@ -1,85 +1,85 @@ -#include "fix16.h" - -/* The square root algorithm is quite directly from - * http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_.28base_2.29 - * An important difference is that it is split to two parts - * in order to use only 32-bit operations. - * - * Note that for negative numbers we return -sqrt(-inValue). - * Not sure if someone relies on this behaviour, but not going - * to break it for now. It doesn't slow the code much overall. - */ -fix16_t fix16_sqrt(fix16_t inValue) -{ - uint8_t neg = (inValue < 0); - uint32_t num = fix_abs(inValue); - uint32_t result = 0; - uint32_t bit; - uint8_t n; - - // Many numbers will be less than 15, so - // this gives a good balance between time spent - // in if vs. time spent in the while loop - // when searching for the starting value. - if (num & 0xFFF00000) - bit = (uint32_t)1 << 30; - else - bit = (uint32_t)1 << 18; - - while (bit > num) - bit >>= 2; - - // The main part is executed twice, in order to avoid - // using 64 bit values in computations. - for (n = 0; n < 2; n++) - { - // First we get the top 24 bits of the answer. - while (bit) - { - if (num >= result + bit) - { - num -= result + bit; - result = (result >> 1) + bit; - } - else - { - result = (result >> 1); - } - bit >>= 2; - } - - if (n == 0) - { - // Then process it again to get the lowest 8 bits. - if (num > 65535) - { - // The remainder 'num' is too large to be shifted left - // by 16, so we have to add 1 to result manually and - // adjust 'num' accordingly. - // num = a - (result + 0.5)^2 - // = num + result^2 - (result + 0.5)^2 - // = num - result - 0.5 - num -= result; - num = (num << 16) - 0x8000; - result = (result << 16) + 0x8000; - } - else - { - num <<= 16; - result <<= 16; - } - - bit = 1 << 14; - } - } - -#ifndef FIXMATH_NO_ROUNDING - // Finally, if next bit would have been 1, round the result upwards. - if (num > result) - { - result++; - } -#endif - - return (neg ? -(fix16_t)result : (fix16_t)result); -} +#include "fix16.h"
+
+/* The square root algorithm is quite directly from
+ * http://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_.28base_2.29
+ * An important difference is that it is split to two parts
+ * in order to use only 32-bit operations.
+ *
+ * Note that for negative numbers we return -sqrt(-inValue).
+ * Not sure if someone relies on this behaviour, but not going
+ * to break it for now. It doesn't slow the code much overall.
+ */
+fix16_t fix16_sqrt(fix16_t inValue)
+{
+ uint8_t neg = (inValue < 0);
+ uint32_t num = fix_abs(inValue);
+ uint32_t result = 0;
+ uint32_t bit;
+ uint8_t n;
+
+ // Many numbers will be less than 15, so
+ // this gives a good balance between time spent
+ // in if vs. time spent in the while loop
+ // when searching for the starting value.
+ if (num & 0xFFF00000)
+ bit = (uint32_t)1 << 30;
+ else
+ bit = (uint32_t)1 << 18;
+
+ while (bit > num)
+ bit >>= 2;
+
+ // The main part is executed twice, in order to avoid
+ // using 64 bit values in computations.
+ for (n = 0; n < 2; n++)
+ {
+ // First we get the top 24 bits of the answer.
+ while (bit)
+ {
+ if (num >= result + bit)
+ {
+ num -= result + bit;
+ result = (result >> 1) + bit;
+ }
+ else
+ {
+ result = (result >> 1);
+ }
+ bit >>= 2;
+ }
+
+ if (n == 0)
+ {
+ // Then process it again to get the lowest 8 bits.
+ if (num > 65535)
+ {
+ // The remainder 'num' is too large to be shifted left
+ // by 16, so we have to add 1 to result manually and
+ // adjust 'num' accordingly.
+ // num = a - (result + 0.5)^2
+ // = num + result^2 - (result + 0.5)^2
+ // = num - result - 0.5
+ num -= result;
+ num = (num << 16) - 0x8000;
+ result = (result << 16) + 0x8000;
+ }
+ else
+ {
+ num <<= 16;
+ result <<= 16;
+ }
+
+ bit = 1 << 14;
+ }
+ }
+
+#ifndef FIXMATH_NO_ROUNDING
+ // Finally, if next bit would have been 1, round the result upwards.
+ if (num > result)
+ {
+ result++;
+ }
+#endif
+
+ return (neg ? -(fix16_t)result : (fix16_t)result);
+}
diff --git a/Client/ThirdParty/libfixmath/libfixmath/fix16_trig.c b/Client/ThirdParty/libfixmath/libfixmath/fix16_trig.c index 120ad1f..09dd5d2 100644 --- a/Client/ThirdParty/libfixmath/libfixmath/fix16_trig.c +++ b/Client/ThirdParty/libfixmath/libfixmath/fix16_trig.c @@ -1,186 +1,186 @@ -#include <limits.h> -#include "fix16.h" - -#if defined(FIXMATH_SIN_LUT) -#include "fix16_trig_sin_lut.h" -#elif !defined(FIXMATH_NO_CACHE) -static fix16_t _fix16_sin_cache_index[4096] = { 0 }; -static fix16_t _fix16_sin_cache_value[4096] = { 0 }; -#endif - -#ifndef FIXMATH_NO_CACHE -static fix16_t _fix16_atan_cache_index[2][4096] = { { 0 }, { 0 } }; -static fix16_t _fix16_atan_cache_value[4096] = { 0 }; -#endif - - -fix16_t fix16_sin_parabola(fix16_t inAngle) -{ - fix16_t abs_inAngle, abs_retval, retval; - fix16_t mask; - - /* Absolute function */ - mask = (inAngle >> (sizeof(fix16_t)*CHAR_BIT-1)); - abs_inAngle = (inAngle + mask) ^ mask; - - /* On 0->PI, sin looks like x² that is : - - centered on PI/2, - - equals 1 on PI/2, - - equals 0 on 0 and PI - that means : 4/PI * x - 4/PI² * x² - Use abs(x) to handle (-PI) -> 0 zone. - */ - retval = fix16_mul(FOUR_DIV_PI, inAngle) + fix16_mul( fix16_mul(_FOUR_DIV_PI2, inAngle), abs_inAngle ); - /* At this point, retval equals sin(inAngle) on important points ( -PI, -PI/2, 0, PI/2, PI), - but is not very precise between these points - */ - #ifndef FIXMATH_FAST_SIN - /* Absolute value of retval */ - mask = (retval >> (sizeof(fix16_t)*CHAR_BIT-1)); - abs_retval = (retval + mask) ^ mask; - /* So improve its precision by adding some x^4 component to retval */ - retval += fix16_mul(X4_CORRECTION_COMPONENT, fix16_mul(retval, abs_retval) - retval ); - #endif - return retval; -} - -fix16_t fix16_sin(fix16_t inAngle) -{ - fix16_t tempAngle = inAngle % (fix16_pi << 1); - - #ifdef FIXMATH_SIN_LUT - if(tempAngle < 0) - tempAngle += (fix16_pi << 1); - - fix16_t tempOut; - if(tempAngle >= fix16_pi) { - tempAngle -= fix16_pi; - if(tempAngle >= (fix16_pi >> 1)) - tempAngle = fix16_pi - tempAngle; - tempOut = -(tempAngle >= _fix16_sin_lut_count ? fix16_one : _fix16_sin_lut[tempAngle]); - } else { - if(tempAngle >= (fix16_pi >> 1)) - tempAngle = fix16_pi - tempAngle; - tempOut = (tempAngle >= _fix16_sin_lut_count ? fix16_one : _fix16_sin_lut[tempAngle]); - } - #else - if(tempAngle > fix16_pi) - tempAngle -= (fix16_pi << 1); - 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); - - #ifndef FIXMATH_FAST_SIN // Most accurate version, accurate to ~2.1% - fix16_t tempOut = tempAngle; - tempAngle = fix16_mul(tempAngle, tempAngleSq); - tempOut -= (tempAngle / 6); - tempAngle = fix16_mul(tempAngle, tempAngleSq); - tempOut += (tempAngle / 120); - tempAngle = fix16_mul(tempAngle, tempAngleSq); - tempOut -= (tempAngle / 5040); - tempAngle = fix16_mul(tempAngle, tempAngleSq); - tempOut += (tempAngle / 362880); - tempAngle = fix16_mul(tempAngle, tempAngleSq); - tempOut -= (tempAngle / 39916800); - #else // Fast implementation, runs at 159% the speed of above 'accurate' version with an slightly lower accuracy of ~2.3% - fix16_t tempOut; - tempOut = fix16_mul(-13, tempAngleSq) + 546; - tempOut = fix16_mul(tempOut, tempAngleSq) - 10923; - tempOut = fix16_mul(tempOut, tempAngleSq) + 65536; - tempOut = fix16_mul(tempOut, tempAngle); - #endif - - #ifndef FIXMATH_NO_CACHE - _fix16_sin_cache_index[tempIndex] = inAngle; - _fix16_sin_cache_value[tempIndex] = tempOut; - #endif - #endif - - return tempOut; -} - -fix16_t fix16_cos(fix16_t inAngle) -{ - return fix16_sin(inAngle + (fix16_pi >> 1)); -} - -fix16_t fix16_tan(fix16_t inAngle) -{ - #ifndef FIXMATH_NO_OVERFLOW - return fix16_sdiv(fix16_sin(inAngle), fix16_cos(inAngle)); - #else - return fix16_div(fix16_sin(inAngle), fix16_cos(inAngle)); - #endif -} - -fix16_t fix16_asin(fix16_t x) -{ - if((x > fix16_one) - || (x < -fix16_one)) - return 0; - - fix16_t out; - out = (fix16_one - fix16_mul(x, x)); - out = fix16_div(x, fix16_sqrt(out)); - out = fix16_atan(out); - return out; -} - -fix16_t fix16_acos(fix16_t x) -{ - return ((fix16_pi >> 1) - fix16_asin(x)); -} - -fix16_t fix16_atan2(fix16_t inY , fix16_t inX) -{ - fix16_t abs_inY, mask, angle, r, r_3; - - #ifndef FIXMATH_NO_CACHE - uintptr_t hash = (inX ^ inY); - hash ^= hash >> 20; - hash &= 0x0FFF; - if((_fix16_atan_cache_index[0][hash] == inX) && (_fix16_atan_cache_index[1][hash] == inY)) - return _fix16_atan_cache_value[hash]; - #endif - - /* Absolute inY */ - mask = (inY >> (sizeof(fix16_t)*CHAR_BIT-1)); - abs_inY = (inY + mask) ^ mask; - - if (inX >= 0) - { - r = fix16_div( (inX - abs_inY), (inX + abs_inY)); - r_3 = fix16_mul(fix16_mul(r, r),r); - angle = fix16_mul(0x00003240 , r_3) - fix16_mul(0x0000FB50,r) + PI_DIV_4; - } else { - r = fix16_div( (inX + abs_inY), (abs_inY - inX)); - r_3 = fix16_mul(fix16_mul(r, r),r); - angle = fix16_mul(0x00003240 , r_3) - - fix16_mul(0x0000FB50,r) - + THREE_PI_DIV_4; - } - if (inY < 0) - { - angle = -angle; - } - - #ifndef FIXMATH_NO_CACHE - _fix16_atan_cache_index[0][hash] = inX; - _fix16_atan_cache_index[1][hash] = inY; - _fix16_atan_cache_value[hash] = angle; - #endif - - return angle; -} - -fix16_t fix16_atan(fix16_t x) -{ - return fix16_atan2(x, fix16_one); -} +#include <limits.h>
+#include "fix16.h"
+
+#if defined(FIXMATH_SIN_LUT)
+#include "fix16_trig_sin_lut.h"
+#elif !defined(FIXMATH_NO_CACHE)
+static fix16_t _fix16_sin_cache_index[4096] = { 0 };
+static fix16_t _fix16_sin_cache_value[4096] = { 0 };
+#endif
+
+#ifndef FIXMATH_NO_CACHE
+static fix16_t _fix16_atan_cache_index[2][4096] = { { 0 }, { 0 } };
+static fix16_t _fix16_atan_cache_value[4096] = { 0 };
+#endif
+
+
+fix16_t fix16_sin_parabola(fix16_t inAngle)
+{
+ fix16_t abs_inAngle, abs_retval, retval;
+ fix16_t mask;
+
+ /* Absolute function */
+ mask = (inAngle >> (sizeof(fix16_t)*CHAR_BIT-1));
+ abs_inAngle = (inAngle + mask) ^ mask;
+
+ /* On 0->PI, sin looks like x² that is :
+ - centered on PI/2,
+ - equals 1 on PI/2,
+ - equals 0 on 0 and PI
+ that means : 4/PI * x - 4/PI² * x²
+ Use abs(x) to handle (-PI) -> 0 zone.
+ */
+ retval = fix16_mul(FOUR_DIV_PI, inAngle) + fix16_mul( fix16_mul(_FOUR_DIV_PI2, inAngle), abs_inAngle );
+ /* At this point, retval equals sin(inAngle) on important points ( -PI, -PI/2, 0, PI/2, PI),
+ but is not very precise between these points
+ */
+ #ifndef FIXMATH_FAST_SIN
+ /* Absolute value of retval */
+ mask = (retval >> (sizeof(fix16_t)*CHAR_BIT-1));
+ abs_retval = (retval + mask) ^ mask;
+ /* So improve its precision by adding some x^4 component to retval */
+ retval += fix16_mul(X4_CORRECTION_COMPONENT, fix16_mul(retval, abs_retval) - retval );
+ #endif
+ return retval;
+}
+
+fix16_t fix16_sin(fix16_t inAngle)
+{
+ fix16_t tempAngle = inAngle % (fix16_pi << 1);
+
+ #ifdef FIXMATH_SIN_LUT
+ if(tempAngle < 0)
+ tempAngle += (fix16_pi << 1);
+
+ fix16_t tempOut;
+ if(tempAngle >= fix16_pi) {
+ tempAngle -= fix16_pi;
+ if(tempAngle >= (fix16_pi >> 1))
+ tempAngle = fix16_pi - tempAngle;
+ tempOut = -(tempAngle >= _fix16_sin_lut_count ? fix16_one : _fix16_sin_lut[tempAngle]);
+ } else {
+ if(tempAngle >= (fix16_pi >> 1))
+ tempAngle = fix16_pi - tempAngle;
+ tempOut = (tempAngle >= _fix16_sin_lut_count ? fix16_one : _fix16_sin_lut[tempAngle]);
+ }
+ #else
+ if(tempAngle > fix16_pi)
+ tempAngle -= (fix16_pi << 1);
+ 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);
+
+ #ifndef FIXMATH_FAST_SIN // Most accurate version, accurate to ~2.1%
+ fix16_t tempOut = tempAngle;
+ tempAngle = fix16_mul(tempAngle, tempAngleSq);
+ tempOut -= (tempAngle / 6);
+ tempAngle = fix16_mul(tempAngle, tempAngleSq);
+ tempOut += (tempAngle / 120);
+ tempAngle = fix16_mul(tempAngle, tempAngleSq);
+ tempOut -= (tempAngle / 5040);
+ tempAngle = fix16_mul(tempAngle, tempAngleSq);
+ tempOut += (tempAngle / 362880);
+ tempAngle = fix16_mul(tempAngle, tempAngleSq);
+ tempOut -= (tempAngle / 39916800);
+ #else // Fast implementation, runs at 159% the speed of above 'accurate' version with an slightly lower accuracy of ~2.3%
+ fix16_t tempOut;
+ tempOut = fix16_mul(-13, tempAngleSq) + 546;
+ tempOut = fix16_mul(tempOut, tempAngleSq) - 10923;
+ tempOut = fix16_mul(tempOut, tempAngleSq) + 65536;
+ tempOut = fix16_mul(tempOut, tempAngle);
+ #endif
+
+ #ifndef FIXMATH_NO_CACHE
+ _fix16_sin_cache_index[tempIndex] = inAngle;
+ _fix16_sin_cache_value[tempIndex] = tempOut;
+ #endif
+ #endif
+
+ return tempOut;
+}
+
+fix16_t fix16_cos(fix16_t inAngle)
+{
+ return fix16_sin(inAngle + (fix16_pi >> 1));
+}
+
+fix16_t fix16_tan(fix16_t inAngle)
+{
+ #ifndef FIXMATH_NO_OVERFLOW
+ return fix16_sdiv(fix16_sin(inAngle), fix16_cos(inAngle));
+ #else
+ return fix16_div(fix16_sin(inAngle), fix16_cos(inAngle));
+ #endif
+}
+
+fix16_t fix16_asin(fix16_t x)
+{
+ if((x > fix16_one)
+ || (x < -fix16_one))
+ return 0;
+
+ fix16_t out;
+ out = (fix16_one - fix16_mul(x, x));
+ out = fix16_div(x, fix16_sqrt(out));
+ out = fix16_atan(out);
+ return out;
+}
+
+fix16_t fix16_acos(fix16_t x)
+{
+ return ((fix16_pi >> 1) - fix16_asin(x));
+}
+
+fix16_t fix16_atan2(fix16_t inY , fix16_t inX)
+{
+ fix16_t abs_inY, mask, angle, r, r_3;
+
+ #ifndef FIXMATH_NO_CACHE
+ uintptr_t hash = (inX ^ inY);
+ hash ^= hash >> 20;
+ hash &= 0x0FFF;
+ if((_fix16_atan_cache_index[0][hash] == inX) && (_fix16_atan_cache_index[1][hash] == inY))
+ return _fix16_atan_cache_value[hash];
+ #endif
+
+ /* Absolute inY */
+ mask = (inY >> (sizeof(fix16_t)*CHAR_BIT-1));
+ abs_inY = (inY + mask) ^ mask;
+
+ if (inX >= 0)
+ {
+ r = fix16_div( (inX - abs_inY), (inX + abs_inY));
+ r_3 = fix16_mul(fix16_mul(r, r),r);
+ angle = fix16_mul(0x00003240 , r_3) - fix16_mul(0x0000FB50,r) + PI_DIV_4;
+ } else {
+ r = fix16_div( (inX + abs_inY), (abs_inY - inX));
+ r_3 = fix16_mul(fix16_mul(r, r),r);
+ angle = fix16_mul(0x00003240 , r_3)
+ - fix16_mul(0x0000FB50,r)
+ + THREE_PI_DIV_4;
+ }
+ if (inY < 0)
+ {
+ angle = -angle;
+ }
+
+ #ifndef FIXMATH_NO_CACHE
+ _fix16_atan_cache_index[0][hash] = inX;
+ _fix16_atan_cache_index[1][hash] = inY;
+ _fix16_atan_cache_value[hash] = angle;
+ #endif
+
+ return angle;
+}
+
+fix16_t fix16_atan(fix16_t x)
+{
+ return fix16_atan2(x, fix16_one);
+}
diff --git a/Client/ThirdParty/libfixmath/libfixmath/fixmath.h b/Client/ThirdParty/libfixmath/libfixmath/fixmath.h index 36e87b0..cd0d20a 100644 --- a/Client/ThirdParty/libfixmath/libfixmath/fixmath.h +++ b/Client/ThirdParty/libfixmath/libfixmath/fixmath.h @@ -1,23 +1,23 @@ -#ifndef __libfixmath_fixmath_h__ -#define __libfixmath_fixmath_h__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -/*! - \file fixmath.h - \brief Functions to perform fast accurate fixed-point math operations. -*/ - -#include "uint32.h" -#include "int64.h" -#include "fract32.h" -#include "fix16.h" - -#ifdef __cplusplus -} -#endif - -#endif +#ifndef __libfixmath_fixmath_h__
+#define __libfixmath_fixmath_h__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/*!
+ \file fixmath.h
+ \brief Functions to perform fast accurate fixed-point math operations.
+*/
+
+#include "uint32.h"
+#include "int64.h"
+#include "fract32.h"
+#include "fix16.h"
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Client/ThirdParty/libfixmath/libfixmath/fract32.c b/Client/ThirdParty/libfixmath/libfixmath/fract32.c index a69d63c..cca94a7 100644 --- a/Client/ThirdParty/libfixmath/libfixmath/fract32.c +++ b/Client/ThirdParty/libfixmath/libfixmath/fract32.c @@ -1,27 +1,27 @@ -#include "fract32.h" - - - -fract32_t fract32_create(uint32_t inNumerator, uint32_t inDenominator) { - if(inDenominator <= inNumerator) - return 0xFFFFFFFF; - uint32_t tempMod = (inNumerator % inDenominator); - uint32_t tempDiv = (0xFFFFFFFF / (inDenominator - 1)); - return (tempMod * tempDiv); -} - -fract32_t fract32_invert(fract32_t inFract) { - return (0xFFFFFFFF - inFract); -} - -#ifndef FIXMATH_NO_64BIT -uint32_t fract32_usmul(uint32_t inVal, fract32_t inFract) { - return (uint32_t)(((uint64_t)inVal * (uint64_t)inFract) >> 32); -} - -int32_t fract32_smul(int32_t inVal, fract32_t inFract) { - if(inVal < 0) - return -(int32_t)fract32_usmul(-inVal, inFract); - return fract32_usmul(inVal, inFract); -} -#endif +#include "fract32.h"
+
+
+
+fract32_t fract32_create(uint32_t inNumerator, uint32_t inDenominator) {
+ if(inDenominator <= inNumerator)
+ return 0xFFFFFFFF;
+ uint32_t tempMod = (inNumerator % inDenominator);
+ uint32_t tempDiv = (0xFFFFFFFF / (inDenominator - 1));
+ return (tempMod * tempDiv);
+}
+
+fract32_t fract32_invert(fract32_t inFract) {
+ return (0xFFFFFFFF - inFract);
+}
+
+#ifndef FIXMATH_NO_64BIT
+uint32_t fract32_usmul(uint32_t inVal, fract32_t inFract) {
+ return (uint32_t)(((uint64_t)inVal * (uint64_t)inFract) >> 32);
+}
+
+int32_t fract32_smul(int32_t inVal, fract32_t inFract) {
+ if(inVal < 0)
+ return -(int32_t)fract32_usmul(-inVal, inFract);
+ return fract32_usmul(inVal, inFract);
+}
+#endif
diff --git a/Client/ThirdParty/libfixmath/libfixmath/fract32.h b/Client/ThirdParty/libfixmath/libfixmath/fract32.h index 2620b5a..ee1f1c6 100644 --- a/Client/ThirdParty/libfixmath/libfixmath/fract32.h +++ b/Client/ThirdParty/libfixmath/libfixmath/fract32.h @@ -1,38 +1,38 @@ -#ifndef __libfixmath_fract32_h__ -#define __libfixmath_fract32_h__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include <stdint.h> - -typedef uint32_t fract32_t; - -/*! Creates a fraction using unsigned integers. - \param inNumerator the unsigned integer numerator - \param inDenominator the unsigned integer denominator - \return a fraction using the given numerator and denominator -*/ -extern fract32_t fract32_create(uint32_t inNumerator, uint32_t inDenominator); - -/*! Inverts the given fraction, swapping the numerator and the denominator. -*/ -extern fract32_t fract32_invert(fract32_t inFract); - -#ifndef FIXMATH_NO_64BIT -/*! Performs unsigned saturated (overflow-protected) multiplication with the two given fractions and returns the result as an unsigned integer. -*/ -extern uint32_t fract32_usmul(uint32_t inVal, fract32_t inFract); - -/*! Performs saturated (overflow-protected) multiplication with the two given fractions and returns the result as a signed integer. -*/ -extern int32_t fract32_smul(int32_t inVal, fract32_t inFract); -#endif - -#ifdef __cplusplus -} -#endif - -#endif +#ifndef __libfixmath_fract32_h__
+#define __libfixmath_fract32_h__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+typedef uint32_t fract32_t;
+
+/*! Creates a fraction using unsigned integers.
+ \param inNumerator the unsigned integer numerator
+ \param inDenominator the unsigned integer denominator
+ \return a fraction using the given numerator and denominator
+*/
+extern fract32_t fract32_create(uint32_t inNumerator, uint32_t inDenominator);
+
+/*! Inverts the given fraction, swapping the numerator and the denominator.
+*/
+extern fract32_t fract32_invert(fract32_t inFract);
+
+#ifndef FIXMATH_NO_64BIT
+/*! Performs unsigned saturated (overflow-protected) multiplication with the two given fractions and returns the result as an unsigned integer.
+*/
+extern uint32_t fract32_usmul(uint32_t inVal, fract32_t inFract);
+
+/*! Performs saturated (overflow-protected) multiplication with the two given fractions and returns the result as a signed integer.
+*/
+extern int32_t fract32_smul(int32_t inVal, fract32_t inFract);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Client/ThirdParty/libfixmath/libfixmath/int64.h b/Client/ThirdParty/libfixmath/libfixmath/int64.h index f229edf..8a3d26a 100644 --- a/Client/ThirdParty/libfixmath/libfixmath/int64.h +++ b/Client/ThirdParty/libfixmath/libfixmath/int64.h @@ -1,177 +1,177 @@ -#ifndef __libfixmath_int64_h__ -#define __libfixmath_int64_h__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include <stdint.h> - -#ifndef FIXMATH_NO_64BIT -static inline int64_t int64_const(int32_t hi, uint32_t lo) { return (((int64_t)hi << 32) | lo); } -static inline int64_t int64_from_int32(int32_t x) { return (int64_t)x; } -static inline int32_t int64_hi(int64_t x) { return (x >> 32); } -static inline uint32_t int64_lo(int64_t x) { return (x & ((1ULL << 32) - 1)); } - -static inline int64_t int64_add(int64_t x, int64_t y) { return (x + y); } -static inline int64_t int64_neg(int64_t x) { return (-x); } -static inline int64_t int64_sub(int64_t x, int64_t y) { return (x - y); } -static inline int64_t int64_shift(int64_t x, int8_t y) { return (y < 0 ? (x >> -y) : (x << y)); } - -static inline int64_t int64_mul_i32_i32(int32_t x, int32_t y) { return ((int64_t)x * y); } -static inline int64_t int64_mul_i64_i32(int64_t x, int32_t y) { return (x * y); } - -static inline int64_t int64_div_i64_i32(int64_t x, int32_t y) { return (x / y); } - -static inline int int64_cmp_eq(int64_t x, int64_t y) { return (x == y); } -static inline int int64_cmp_ne(int64_t x, int64_t y) { return (x != y); } -static inline int int64_cmp_gt(int64_t x, int64_t y) { return (x > y); } -static inline int int64_cmp_ge(int64_t x, int64_t y) { return (x >= y); } -static inline int int64_cmp_lt(int64_t x, int64_t y) { return (x < y); } -static inline int int64_cmp_le(int64_t x, int64_t y) { return (x <= y); } -#else - -typedef struct { - int32_t hi; - uint32_t lo; -} _int64_t; - -static inline _int64_t int64_const(int32_t hi, uint32_t lo) { return (_int64_t){ hi, lo }; } -static inline _int64_t int64_from_int32(int32_t x) { return (_int64_t){ (x < 0 ? -1 : 0), x }; } -static inline int32_t int64_hi(_int64_t x) { return x.hi; } -static inline uint32_t int64_lo(_int64_t x) { return x.lo; } - -static inline int int64_cmp_eq(_int64_t x, _int64_t y) { return ((x.hi == y.hi) && (x.lo == y.lo)); } -static inline int int64_cmp_ne(_int64_t x, _int64_t y) { return ((x.hi != y.hi) || (x.lo != y.lo)); } -static inline int int64_cmp_gt(_int64_t x, _int64_t y) { return ((x.hi > y.hi) || ((x.hi == y.hi) && (x.lo > y.lo))); } -static inline int int64_cmp_ge(_int64_t x, _int64_t y) { return ((x.hi > y.hi) || ((x.hi == y.hi) && (x.lo >= y.lo))); } -static inline int int64_cmp_lt(_int64_t x, _int64_t y) { return ((x.hi < y.hi) || ((x.hi == y.hi) && (x.lo < y.lo))); } -static inline int int64_cmp_le(_int64_t x, _int64_t y) { return ((x.hi < y.hi) || ((x.hi == y.hi) && (x.lo <= y.lo))); } - -static inline _int64_t int64_add(_int64_t x, _int64_t y) { - _int64_t ret; - ret.hi = x.hi + y.hi; - ret.lo = x.lo + y.lo; - if((ret.lo < x.lo) || (ret.lo < y.lo)) - ret.hi++; - return ret; -} - -static inline _int64_t int64_neg(_int64_t x) { - _int64_t ret; - ret.hi = ~x.hi; - ret.lo = ~x.lo + 1; - if(ret.lo == 0) - ret.hi++; - return ret; -} - -static inline _int64_t int64_sub(_int64_t x, _int64_t y) { - return int64_add(x, int64_neg(y)); -} - -static inline _int64_t int64_shift(_int64_t x, int8_t y) { - _int64_t ret = {0,0}; - if(y >= 64 || y <= -64) - return (_int64_t){ 0, 0 }; - if(y >= 32) { - ret.hi = (x.lo << (y - 32)); - } - else if(y > 0) { - ret.hi = (x.hi << y) | (x.lo >> (32 - y)); - ret.lo = (x.lo << y); - } - else { - y = -y; - if(y >= 32){ - ret.lo = (x.hi >> (y - 32)); - ret.hi = (x.hi < 0) ? -1 : 0; - } else { - ret.lo = (x.lo >> y) | (x.hi << (32 - y)); - ret.hi = (x.hi >> y); - } - } - return ret; -} - -static inline _int64_t int64_mul_i32_i32(int32_t x, int32_t y) { - int16_t hi[2] = { (x >> 16), (y >> 16) }; - uint16_t lo[2] = { (x & 0xFFFF), (y & 0xFFFF) }; - - int32_t r_hi = hi[0] * hi[1]; - int32_t r_md = (hi[0] * lo[1]) + (hi[1] * lo[0]); - uint32_t r_lo = lo[0] * lo[1]; - - _int64_t r_hilo64 = (_int64_t){ r_hi, r_lo }; - _int64_t r_md64 = int64_shift(int64_from_int32(r_md), 16); - - return int64_add(r_hilo64, r_md64); -} - -static inline _int64_t int64_mul_i64_i32(_int64_t x, int32_t y) { - int neg = ((x.hi ^ y) < 0); - if(x.hi < 0) - x = int64_neg(x); - uint32_t ypos = (y < 0)? (-y) : (y); - - uint32_t _x[4] = { (x.lo & 0xFFFF), (x.lo >> 16), (x.hi & 0xFFFF), (x.hi >> 16) }; - uint32_t _y[2] = { (ypos & 0xFFFF), (ypos >> 16) }; - - uint32_t r[4]; - r[0] = (_x[0] * _y[0]); - r[1] = (_x[1] * _y[0]); - uint32_t temp_r1 = r[1]; - r[1] += (_x[0] * _y[1]); - r[2] = (_x[2] * _y[0]) + (_x[1] * _y[1]); - r[3] = (_x[3] * _y[0]) + (_x[2] * _y[1]); - // Detect carry bit in r[1]. r[0] can't carry, and r[2]/r[3] don't matter. - if(r[1] < temp_r1) - r[3] ++; - - _int64_t middle = int64_shift(int64_const(0, r[1]), 16); - _int64_t ret; - ret.lo = r[0]; - ret.hi = (r[3] << 16) + r[2]; - ret = int64_add(ret, middle); - return (neg ? int64_neg(ret) : ret); -} - -static inline _int64_t int64_div_i64_i32(_int64_t x, int32_t y) { - int neg = ((x.hi ^ y) < 0); - if(x.hi < 0) - x = int64_neg(x); - if(y < 0) - y = -y; - - _int64_t ret = { (x.hi / y) , (x.lo / y) }; - x.hi = x.hi % y; - x.lo = x.lo % y; - - _int64_t _y = int64_from_int32(y); - - _int64_t i; - for(i = int64_from_int32(1); int64_cmp_lt(_y, x); _y = int64_shift(_y, 1), i = int64_shift(i, 1)); - - while(x.hi) { - _y = int64_shift(_y, -1); - i = int64_shift(i, -1); - if(int64_cmp_ge(x, _y)) { - x = int64_sub(x, _y); - ret = int64_add(ret, i); - } - } - - ret = int64_add(ret, int64_from_int32(x.lo / y)); - return (neg ? int64_neg(ret) : ret); -} - -#define int64_t _int64_t - -#endif - -#ifdef __cplusplus -} -#endif - -#endif +#ifndef __libfixmath_int64_h__
+#define __libfixmath_int64_h__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+#ifndef FIXMATH_NO_64BIT
+static inline int64_t int64_const(int32_t hi, uint32_t lo) { return (((int64_t)hi << 32) | lo); }
+static inline int64_t int64_from_int32(int32_t x) { return (int64_t)x; }
+static inline int32_t int64_hi(int64_t x) { return (x >> 32); }
+static inline uint32_t int64_lo(int64_t x) { return (x & ((1ULL << 32) - 1)); }
+
+static inline int64_t int64_add(int64_t x, int64_t y) { return (x + y); }
+static inline int64_t int64_neg(int64_t x) { return (-x); }
+static inline int64_t int64_sub(int64_t x, int64_t y) { return (x - y); }
+static inline int64_t int64_shift(int64_t x, int8_t y) { return (y < 0 ? (x >> -y) : (x << y)); }
+
+static inline int64_t int64_mul_i32_i32(int32_t x, int32_t y) { return ((int64_t)x * y); }
+static inline int64_t int64_mul_i64_i32(int64_t x, int32_t y) { return (x * y); }
+
+static inline int64_t int64_div_i64_i32(int64_t x, int32_t y) { return (x / y); }
+
+static inline int int64_cmp_eq(int64_t x, int64_t y) { return (x == y); }
+static inline int int64_cmp_ne(int64_t x, int64_t y) { return (x != y); }
+static inline int int64_cmp_gt(int64_t x, int64_t y) { return (x > y); }
+static inline int int64_cmp_ge(int64_t x, int64_t y) { return (x >= y); }
+static inline int int64_cmp_lt(int64_t x, int64_t y) { return (x < y); }
+static inline int int64_cmp_le(int64_t x, int64_t y) { return (x <= y); }
+#else
+
+typedef struct {
+ int32_t hi;
+ uint32_t lo;
+} _int64_t;
+
+static inline _int64_t int64_const(int32_t hi, uint32_t lo) { return (_int64_t){ hi, lo }; }
+static inline _int64_t int64_from_int32(int32_t x) { return (_int64_t){ (x < 0 ? -1 : 0), x }; }
+static inline int32_t int64_hi(_int64_t x) { return x.hi; }
+static inline uint32_t int64_lo(_int64_t x) { return x.lo; }
+
+static inline int int64_cmp_eq(_int64_t x, _int64_t y) { return ((x.hi == y.hi) && (x.lo == y.lo)); }
+static inline int int64_cmp_ne(_int64_t x, _int64_t y) { return ((x.hi != y.hi) || (x.lo != y.lo)); }
+static inline int int64_cmp_gt(_int64_t x, _int64_t y) { return ((x.hi > y.hi) || ((x.hi == y.hi) && (x.lo > y.lo))); }
+static inline int int64_cmp_ge(_int64_t x, _int64_t y) { return ((x.hi > y.hi) || ((x.hi == y.hi) && (x.lo >= y.lo))); }
+static inline int int64_cmp_lt(_int64_t x, _int64_t y) { return ((x.hi < y.hi) || ((x.hi == y.hi) && (x.lo < y.lo))); }
+static inline int int64_cmp_le(_int64_t x, _int64_t y) { return ((x.hi < y.hi) || ((x.hi == y.hi) && (x.lo <= y.lo))); }
+
+static inline _int64_t int64_add(_int64_t x, _int64_t y) {
+ _int64_t ret;
+ ret.hi = x.hi + y.hi;
+ ret.lo = x.lo + y.lo;
+ if((ret.lo < x.lo) || (ret.lo < y.lo))
+ ret.hi++;
+ return ret;
+}
+
+static inline _int64_t int64_neg(_int64_t x) {
+ _int64_t ret;
+ ret.hi = ~x.hi;
+ ret.lo = ~x.lo + 1;
+ if(ret.lo == 0)
+ ret.hi++;
+ return ret;
+}
+
+static inline _int64_t int64_sub(_int64_t x, _int64_t y) {
+ return int64_add(x, int64_neg(y));
+}
+
+static inline _int64_t int64_shift(_int64_t x, int8_t y) {
+ _int64_t ret = {0,0};
+ if(y >= 64 || y <= -64)
+ return (_int64_t){ 0, 0 };
+ if(y >= 32) {
+ ret.hi = (x.lo << (y - 32));
+ }
+ else if(y > 0) {
+ ret.hi = (x.hi << y) | (x.lo >> (32 - y));
+ ret.lo = (x.lo << y);
+ }
+ else {
+ y = -y;
+ if(y >= 32){
+ ret.lo = (x.hi >> (y - 32));
+ ret.hi = (x.hi < 0) ? -1 : 0;
+ } else {
+ ret.lo = (x.lo >> y) | (x.hi << (32 - y));
+ ret.hi = (x.hi >> y);
+ }
+ }
+ return ret;
+}
+
+static inline _int64_t int64_mul_i32_i32(int32_t x, int32_t y) {
+ int16_t hi[2] = { (x >> 16), (y >> 16) };
+ uint16_t lo[2] = { (x & 0xFFFF), (y & 0xFFFF) };
+
+ int32_t r_hi = hi[0] * hi[1];
+ int32_t r_md = (hi[0] * lo[1]) + (hi[1] * lo[0]);
+ uint32_t r_lo = lo[0] * lo[1];
+
+ _int64_t r_hilo64 = (_int64_t){ r_hi, r_lo };
+ _int64_t r_md64 = int64_shift(int64_from_int32(r_md), 16);
+
+ return int64_add(r_hilo64, r_md64);
+}
+
+static inline _int64_t int64_mul_i64_i32(_int64_t x, int32_t y) {
+ int neg = ((x.hi ^ y) < 0);
+ if(x.hi < 0)
+ x = int64_neg(x);
+ uint32_t ypos = (y < 0)? (-y) : (y);
+
+ uint32_t _x[4] = { (x.lo & 0xFFFF), (x.lo >> 16), (x.hi & 0xFFFF), (x.hi >> 16) };
+ uint32_t _y[2] = { (ypos & 0xFFFF), (ypos >> 16) };
+
+ uint32_t r[4];
+ r[0] = (_x[0] * _y[0]);
+ r[1] = (_x[1] * _y[0]);
+ uint32_t temp_r1 = r[1];
+ r[1] += (_x[0] * _y[1]);
+ r[2] = (_x[2] * _y[0]) + (_x[1] * _y[1]);
+ r[3] = (_x[3] * _y[0]) + (_x[2] * _y[1]);
+ // Detect carry bit in r[1]. r[0] can't carry, and r[2]/r[3] don't matter.
+ if(r[1] < temp_r1)
+ r[3] ++;
+
+ _int64_t middle = int64_shift(int64_const(0, r[1]), 16);
+ _int64_t ret;
+ ret.lo = r[0];
+ ret.hi = (r[3] << 16) + r[2];
+ ret = int64_add(ret, middle);
+ return (neg ? int64_neg(ret) : ret);
+}
+
+static inline _int64_t int64_div_i64_i32(_int64_t x, int32_t y) {
+ int neg = ((x.hi ^ y) < 0);
+ if(x.hi < 0)
+ x = int64_neg(x);
+ if(y < 0)
+ y = -y;
+
+ _int64_t ret = { (x.hi / y) , (x.lo / y) };
+ x.hi = x.hi % y;
+ x.lo = x.lo % y;
+
+ _int64_t _y = int64_from_int32(y);
+
+ _int64_t i;
+ for(i = int64_from_int32(1); int64_cmp_lt(_y, x); _y = int64_shift(_y, 1), i = int64_shift(i, 1));
+
+ while(x.hi) {
+ _y = int64_shift(_y, -1);
+ i = int64_shift(i, -1);
+ if(int64_cmp_ge(x, _y)) {
+ x = int64_sub(x, _y);
+ ret = int64_add(ret, i);
+ }
+ }
+
+ ret = int64_add(ret, int64_from_int32(x.lo / y));
+ return (neg ? int64_neg(ret) : ret);
+}
+
+#define int64_t _int64_t
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/Client/ThirdParty/libfixmath/libfixmath/uint32.c b/Client/ThirdParty/libfixmath/libfixmath/uint32.c index 5f6fc2a..2980ab9 100644 --- a/Client/ThirdParty/libfixmath/libfixmath/uint32.c +++ b/Client/ThirdParty/libfixmath/libfixmath/uint32.c @@ -1,15 +1,15 @@ -#include "uint32.h" - - - -uint32_t uint32_log2(uint32_t inVal) { - if(inVal == 0) - return 0; - uint32_t tempOut = 0; - if(inVal >= (1 << 16)) { inVal >>= 16; tempOut += 16; } - if(inVal >= (1 << 8)) { inVal >>= 8; tempOut += 8; } - if(inVal >= (1 << 4)) { inVal >>= 4; tempOut += 4; } - if(inVal >= (1 << 2)) { inVal >>= 2; tempOut += 2; } - if(inVal >= (1 << 1)) { tempOut += 1; } - return tempOut; -} +#include "uint32.h"
+
+
+
+uint32_t uint32_log2(uint32_t inVal) {
+ if(inVal == 0)
+ return 0;
+ uint32_t tempOut = 0;
+ if(inVal >= (1 << 16)) { inVal >>= 16; tempOut += 16; }
+ if(inVal >= (1 << 8)) { inVal >>= 8; tempOut += 8; }
+ if(inVal >= (1 << 4)) { inVal >>= 4; tempOut += 4; }
+ if(inVal >= (1 << 2)) { inVal >>= 2; tempOut += 2; }
+ if(inVal >= (1 << 1)) { tempOut += 1; }
+ return tempOut;
+}
diff --git a/Client/ThirdParty/libfixmath/libfixmath/uint32.h b/Client/ThirdParty/libfixmath/libfixmath/uint32.h index 1cb4eec..1303338 100644 --- a/Client/ThirdParty/libfixmath/libfixmath/uint32.h +++ b/Client/ThirdParty/libfixmath/libfixmath/uint32.h @@ -1,19 +1,19 @@ -#ifndef __libfixmath_uint32_h__ -#define __libfixmath_uint32_h__ - -#ifdef __cplusplus -extern "C" -{ -#endif - -#include <stdint.h> - -/*! Performs an unsigned log-base2 on the specified unsigned integer and returns the result. -*/ -extern uint32_t uint32_log2(uint32_t inVal); - -#ifdef __cplusplus -} -#endif - -#endif +#ifndef __libfixmath_uint32_h__
+#define __libfixmath_uint32_h__
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <stdint.h>
+
+/*! Performs an unsigned log-base2 on the specified unsigned integer and returns the result.
+*/
+extern uint32_t uint32_log2(uint32_t inVal);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
|