summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Gunger <kgunger12@gmail.com>2024-05-02 03:58:29 -0400
committerKyle Gunger <kgunger12@gmail.com>2024-05-02 03:58:29 -0400
commit50871e715812060a8dfb515fe2b432b1778583d6 (patch)
treeca3df41b8817c760022aa885dfafc93e5621001e
parent65e52cd2a11f4d0433e3ef60b6719ea490b3f6c8 (diff)
Working on bitwise ops for float conversion
-rw-r--r--include/osm/device.h37
-rw-r--r--include/osm/types.h109
-rw-r--r--src/types.c116
3 files changed, 262 insertions, 0 deletions
diff --git a/include/osm/device.h b/include/osm/device.h
index edf9c12..f774179 100644
--- a/include/osm/device.h
+++ b/include/osm/device.h
@@ -1,6 +1,8 @@
#ifndef OSM_DEVICE_H
#define OSM_DEVICE_H
+#include <stdint.h>
+
#include <osm/utils.h>
/*
@@ -19,4 +21,39 @@ typedef struct {
Vector inputs, outputs;
} OSMDevice;
+// Device datapoint
+
+/// Raw data (rarely used)
+#define OSM_TYPE_RAW 0 ///< Raw data that a script or extrnal program could process
+
+#define OSM_TYPE_BOOL 1 ///< Boolean type
+#define OSM_TYPE_INT 2 ///< Integer type
+#define OSM_TYPE_FLOAT 3 ///< Floating point type
+#define OSM_TYPE_COLOR 4 ///< Color type
+#define OSM_TYPE_SELECT 5 ///< Selection type
+#define OSM_TYPE_TIME 6 ///< Time type (duration)
+#define OSM_TYPE_DATE 7 ///< Date type (exact date/time)
+
+#define OSM_DDF_INPUT 0b0001 ///< This datapoint can be read
+#define OSM_DDF_OUTPUT 0b0010 ///< This datapoint can be written
+#define OSM_DDF_RANGE 0b0100 ///< This datapoint can be interpreted as two values which create a range
+#define OSM_DDF_RANGED 0b1000 ///< This datapoint must be between a certain range
+
+/// The device datapoint
+typedef struct {
+ uint64_t id; /// Unique id of the datapoint
+ uint8_t *name; /// Name of the datapoint in UTF-8
+ uint8_t type; /// Datatype of datapoint
+ uint8_t flags; /// Datapoint flags
+} OSMDatapoint;
+
+/// Attempt to read a datapoint from a device
+/// returns nonzero error code on failure
+int osm_read_datapoint(OSMDevice *dev, OSMDatapoint *dat, void *in);
+
+/// Attempt to write a datapoint to a device
+/// returns nonzero error code on failure
+int osm_write_datapoint(OSMDevice *dev, OSMDatapoint *dat, void *out);
+
+
#endif
diff --git a/include/osm/types.h b/include/osm/types.h
new file mode 100644
index 0000000..5120098
--- /dev/null
+++ b/include/osm/types.h
@@ -0,0 +1,109 @@
+#ifndef OSM_TYPES_H
+#define OSM_TYPES_H
+
+#include <stdint.h>
+#include <stdbool.h>
+
+/*
+ * Defines all types which can be transfered reliably across
+ * a device connection
+ */
+
+// Raw data
+typedef struct {
+ uint32_t length;
+} OSMRaw;
+
+
+
+// Bools
+
+#define OSMTrue 1
+#define OSMFalse 0
+
+/// Represents a bool
+typedef uint8_t OSMBool;
+
+
+
+// Numeric
+
+/// Represents an integer
+typedef int64_t OSMInteger;
+/// Represents a floating point (IEEE 754 64 bit)
+typedef uint64_t OSMFloat;
+
+/// Represents the broken down floating point number
+typedef struct {
+ uint8_t sign;
+ uint16_t mantissa;
+ uint64_t fraction;
+} OSMFloatBreakdown;
+
+/// Break a OSMFloat into it's constituant parts
+OSMFloatBreakdown osm_break_float(OSMFloat f);
+/// Break a native float into constituant parts
+OSMFloatBreakdown osm_break_native_float(double d);
+
+/// Convert an osm float to a native one
+double osm_float_to_native(OSMFloat f);
+/// Convert a native float to an osm one
+OSMFloat osm_native_to_float(double d);
+
+/// Check whether a float is NaN
+bool osm_is_nan(OSMFloat f);
+
+/// Check whether a float is infinity
+/// if positive infinity, returns 1
+/// if negative infinity, returns -1
+/// otherwise returns 0
+uint8_t osm_is_infinity(OSMFloat f);
+
+
+
+// Color
+
+/// Color struct with support for extra channels (up to 255)
+/// each channel has a range from 0-255
+typedef struct {
+ uint8_t
+ r,
+ g,
+ b;
+
+ uint8_t extra;
+ uint8_t *ex;
+ uint8_t **ex_names; /// Extra channel names encoded in UTF-8
+} OSMColor;
+
+/// Output rgb from a color struct
+uint32_t osm_to_rgb(OSMColor color);
+
+/// Output color struct from 24-bit RGB
+OSMColor osm_rgb_to_color(uint8_t r, uint8_t g, uint8_t b);
+
+/// Parse a 32-bit integer as a 24-bit color.
+/// Assumes r, g, and b channels are stores in
+/// the lower 24 bits of the number.
+OSMColor osm_int_to_color(uint32_t c);
+
+/// Deep copy a color struct
+OSMColor osm_color_copy(OSMColor color);
+
+/// Free a color struct
+void osm_color_free(OSMColor color);
+
+
+
+// Selection
+
+typedef struct {
+ /// TODO: Should getting selection options be an async operation?
+} OSMSelect;
+
+
+
+// TODO: Time, others
+
+
+#endif
diff --git a/src/types.c b/src/types.c
new file mode 100644
index 0000000..c9482c1
--- /dev/null
+++ b/src/types.c
@@ -0,0 +1,116 @@
+#include <math.h>
+
+#include "osm/types.h"
+
+OSMFloatBreakdown osm_float_to_break(OSMFloat f)
+{
+ OSMFloatBreakdown out;
+
+ out.sign = f >> 63;
+ out.mantissa = (f >> 52) & 0x7ff;
+ out.fraction = f & 0xfffffffffffff;
+
+ return out;
+}
+
+/*
+ * WARNING: This code assumes that the compiler
+ * supports IEEE 754 floating point numbers.
+ *
+ * Should probably be updated with more formats if I was
+ * feeling frisky.
+ *
+ * Supports half, single, and double precision IEEE 754
+ */
+OSMFloatBreakdown osm_native_float_to_break(double d)
+{
+ OSMFloatBreakdown out = {0};
+
+ switch(sizeof(double))
+ {
+ case 2: {
+ uint16_t bits = *(uint16_t *) &d;
+ out.sign = bits >> 15;
+ } break;
+
+ case 4: {
+ uint32_t bits = * (uint32_t *) &d;
+ out.sign = bits >> 31;
+ } break;
+
+ case 8: {
+ uint64_t bits = * (uint64_t *) &d;
+ out = osm_float_to_break(bits);
+ } break;
+
+ default:
+ break;
+ }
+
+ return out;
+}
+
+OSMFloat osm_break_to_float(OSMFloatBreakdown b)
+{
+ OSMFloat out;
+
+ if (b.sign)
+ out = 1;
+ out = out << 63;
+
+ out |= (OSMFloat)(b.mantissa & 0x7ff) << 52;
+
+ out |= b.fraction & 0xfffffffffffff;
+
+ return out;
+}
+
+/*
+ * WARNING: This code assumes that the compiler
+ * supports IEEE 754 floating point numbers.
+ *
+ * Should probably be updated with more formats if I was
+ * feeling frisky.
+ */
+double osm_break_to_native_float(OSMFloatBreakdown b)
+{
+ double out = 0;
+
+ switch(sizeof(double))
+ {
+ case 2: {
+ } break;
+
+ case 4: {
+ } break;
+
+ case 8: {
+ OSMFloat f = osm_break_to_float(b);
+ out = * (double *) &f;
+ } break;
+
+ default:
+ break;
+ }
+
+ if (b.sign)
+ out = -out;
+
+ return out;
+}
+
+double osm_float_to_native(OSMFloat f)
+{
+ return
+ osm_break_to_native_float(
+ osm_float_to_break(f)
+ );
+}
+
+OSMFloat osm_native_to_float(double d)
+{
+ return
+ osm_break_to_float(
+ osm_native_float_to_break(d)
+ );
+}