]> Shamusworld >> Repos - rmac/blobdiff - fltpoint.c
Version bump for last commit. :-)
[rmac] / fltpoint.c
index fa1eb41ad9c78af887a63b444f099a4ecf184d95..ffde55edc1ef6ea159663cde60440b7754bf813b 100644 (file)
@@ -2,7 +2,7 @@
 // Floating point to IEEE-754 conversion routines
 //
 // by James Hammons
-// (C) 2018 Underground Software
+// (C) 2019 Underground Software
 //
 // Since there are no guarantees vis-a-vis floating point numbers in C, we have
 // to utilize routines like the following in order to guarantee that the thing
@@ -14,6 +14,8 @@
 #include "fltpoint.h"
 #include <float.h>
 #include <math.h>
+#include <stdio.h>
+#include "error.h"
 
 //
 // Check for IEEE-754 conformance (C99 compilers should be OK here)
@@ -169,3 +171,47 @@ void DoubleToExtended(double d, uint8_t out[])
        out[11] = intMant & 0xFF;
 }
 
+
+//
+// Convert a double to a DSP56001 style fixed point float.
+// Seems to be 23 bits of float value with 1 bit (MSB) for the sign.
+//
+uint32_t DoubleToDSPFloat(double d)
+{
+       if (d >= 1)
+       {
+               warn("DSP value clamped to +1.");
+               return 0x7FFFFF;
+       }
+       else if (d <= -1)
+       {
+               warn("DSP value clamped to -1.");
+               return 0x800000;
+       }
+
+       // The casts are here because some compilers do weird shit.  See bug #149.
+       return (uint32_t)((int32_t)trunc(round(ldexp(d, 23))));
+}
+
+
+//
+// Convert a host native floating point number to a fixed point number.
+//
+uint64_t DoubleToFixedPoint(double d, int intBits, int fracBits)
+{
+       uint8_t signBit = (signbit(d) ? 1 : 0);
+
+       // Ensure what we're working on is positive...
+       if (d < 0)
+               d *= -1;
+
+       double scaleFactor = (double)(1 << fracBits);
+       uint64_t result = (uint64_t)(d * scaleFactor);
+
+       // Invert the result, if necessary
+       if (signBit == 1)
+               result = (result ^ 0xFFFFFFFFFFFFFFFFLL) + 1;
+
+       return result;
+}
+