aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorbonmas14 <bonmas14@gmail.com>2025-08-23 01:28:41 +0300
committerbonmas14 <bonmas14@gmail.com>2025-08-23 01:28:41 +0300
commit8ebdc95621bc61fdf3c98cd7ae4ddca67398df23 (patch)
tree205413ed09ac001e37267889d429a363c37008f2 /src
parentc96c355b360f18f982459e1a866dcbf5864efdb8 (diff)
downloadungrateful-8ebdc95621bc61fdf3c98cd7ae4ddca67398df23.tar.gz
ungrateful-8ebdc95621bc61fdf3c98cd7ae4ddca67398df23.zip
Ungrateful changes, added more stuffHEADmain
Diffstat (limited to 'src')
-rw-r--r--src/un_list.c39
-rw-r--r--src/un_math.c220
-rw-r--r--src/un_mem_linux_x64.c16
-rw-r--r--src/un_mem_std.c14
-rw-r--r--src/un_mem_win_x64.c18
-rw-r--r--src/un_memory.c90
-rw-r--r--src/un_splines.c93
-rw-r--r--src/un_vecr.c353
-rw-r--r--src/un_wstrings.c66
-rw-r--r--src/ungrateful.c9
-rw-r--r--src/ungrateful.h497
11 files changed, 712 insertions, 703 deletions
diff --git a/src/un_list.c b/src/un_list.c
index 133dc12..9d6a5ce 100644
--- a/src/un_list.c
+++ b/src/un_list.c
@@ -8,12 +8,16 @@ List un_list_create(u64 start_capacity, u64 element_size, Allocator alloc) {
list.data = un_memory_alloc(list.capacity * list.element_size, alloc);
- assert(list.data != NULL);
+ if (list.data == NULL) {
+ list.alloc = un_allocator_get_temporary();
+ list.data = un_memory_alloc(list.capacity * list.element_size, list.alloc);
+ }
+
return list;
}
-void un_list_destroy(List *list) {
- un_memory_destroy(&list->alloc);
+void un_list_destroy(List *list, b32 delete_allocator) {
+ if (delete_allocator) { un_memory_destroy(&list->alloc); }
UN_CLEAR(*list);
}
@@ -25,6 +29,11 @@ List un_list_clone(List *list, Allocator alloc) {
result.data = un_memory_alloc(result.capacity * result.element_size, alloc);
assert(result.data != NULL);
+ if (result.data == NULL) {
+ result.alloc = un_allocator_get_temporary();
+ result.data = un_memory_alloc(result.capacity * result.element_size, result.alloc);
+ }
+
un_memory_copy(result.data, list->data, result.count * result.element_size);
return result;
@@ -34,12 +43,15 @@ static b32 list_grow_if_needed(List *list) {
if ((list->count + 1) <= list->capacity) {
return true;
} else {
- void *mem = un_memory_realloc(list->data, list->element_size * list->capacity * 2, list->alloc);
+ void *mem = un_memory_alloc(list->element_size * list->capacity * 2, list->alloc);
if (!mem) {
return false;
}
+ un_memory_copy(mem, list->data, list->element_size * list->capacity);
+ un_memory_free(list->data, list->alloc);
+
list->data = mem;
list->capacity *= 2;
}
@@ -47,7 +59,22 @@ static b32 list_grow_if_needed(List *list) {
return true;
}
+static void un_list_create_if_needed(List *list) {
+ assert(list != NULL);
+
+ if (list->data != NULL) return;
+
+ assert(list->capacity == 0);
+ assert(list->element_size != 0);
+
+ if (!list->data) {
+ Allocator alloc = list->alloc.proc == NULL ? un_allocator_get_standard() : list->alloc;
+ *list = un_list_create(UN_LIST_STANDARD_CAPACITY, list->element_size, alloc);
+ }
+}
+
b32 un_list_append(List *list, void *data) {
+ un_list_create_if_needed(list);
void *addr;
if (list_grow_if_needed(list)) {
@@ -63,6 +90,8 @@ b32 un_list_append(List *list, void *data) {
void *un_list_get(List *list, u64 index) {
if (index >= list->count) return NULL;
+ assert(list->data != NULL);
+
return (u8*)list->data + index * list->element_size;
}
@@ -72,8 +101,8 @@ void un_list_remove(List *list, u64 index) {
if (index >= list->count) return;
+ assert(list->data != NULL);
addr = (u8*)list->data + index * list->element_size;
-
move_elements = list->count - (index + 1);
if (move_elements) {
diff --git a/src/un_math.c b/src/un_math.c
index 42a1c4b..a2ff65e 100644
--- a/src/un_math.c
+++ b/src/un_math.c
@@ -1,50 +1,13 @@
-/* reals */
-
-real un_m_lerpr(real a, real b, real t) {
+/* lerps */
+f32 un_m_lerpf(f32 a, f32 b, f32 t) {
return (1.0 - t) * a + b * t;
}
-real un_m_ease_isiner(real t) {
-#if defined(UN_DOUBLE_PRECISION)
- return 1.0 - cos((t * PI_D) / 2.0);
-#else
- return 1.0 - cosf((t * PI) / 2.0);
-#endif
-}
-
-real un_m_ease_iosiner(real t) {
-#if defined(UN_DOUBLE_PRECISION)
- return sin((t * PI_D) / 2.0f);
-#else
- return sinf((t * PI) / 2.0f);
-#endif
-}
-
-real un_m_ease_osiner(real t) {
-#if defined(UN_DOUBLE_PRECISION)
- return -(cos(t * PI_D) - 1.0) / 2.0;
-#else
- return -(cosf(t * PI) - 1.0) / 2.0;
-#endif
-}
-
-real un_m_ease_iquadr(real t) {
- return t * t;
-}
-
-real un_m_ease_ioquadr(real t) {
- return 1.0 - (1.0 - t) * (1.0 - t);
-}
-
-real un_m_ease_oquadr(real t) {
- return t < 0.5 ? 2.0 * t * t : 1.0 - ((-2.0 * t + 2.0) * (-2.0 * t + 2.0)) / 2.0;
-}
-
-/* floats */
-f32 un_m_lerpf(f32 a, f32 b, f32 t) {
+f64 un_m_lerpd(f64 a, f64 b, f64 t) {
return (1.0 - t) * a + b * t;
}
+/* easing */
f32 un_m_ease_isinef(f32 t) {
return 1.0 - cosf((t * PI) / 2.0);
}
@@ -69,11 +32,6 @@ f32 un_m_ease_oquadf(f32 t) {
return t < 0.5 ? 2.0 * t * t : 1.0 - ((-2.0 * t + 2.0) * (-2.0 * t + 2.0)) / 2.0;
}
-/* doubles */
-f64 un_m_lerpd(f64 a, f64 b, f64 t) {
- return (1.0 - t) * a + b * t;
-}
-
f64 un_m_ease_isined(f64 t) {
return 1.0 - cos((t * PI) / 2.0);
}
@@ -97,3 +55,173 @@ f64 un_m_ease_ioquadd(f64 t) {
f64 un_m_ease_oquadd(f64 t) {
return t < 0.5 ? 2.0 * t * t : 1.0 - ((-2.0 * t + 2.0) * (-2.0 * t + 2.0)) / 2.0;
}
+
+/* complex */
+
+void un_m_complex_divf(f32 *v, f32 *a, f32 *b) {
+ f32 divisor;
+
+ // un_m_complex_mulf(v, a, conjugated_b)
+ v[0] = a[0] * b[0] - a[1] * -b[1];
+ v[1] = a[0] * -b[1] + a[1] * b[0];
+
+ divisor = b[0] * b[0] + b[1] * b[1];
+
+ v[0] /= divisor;
+ v[1] /= divisor;
+}
+
+void un_m_complex_mulf(f32 *v, f32 *a, f32 *b) {
+ v[0] = a[0] * b[0] - a[1] * b[1];
+ v[1] = a[0] * b[1] + a[1] * b[0];
+}
+
+
+void un_m_complex_divd(f64 *v, f64 *a, f64 *b) {
+ f64 divisor;
+
+ // un_m_complex_muld(v, a, conjugated_b)
+ v[0] = a[0] * b[0] - a[1] * -b[1];
+ v[1] = a[0] * -b[1] + a[1] * b[0];
+
+ divisor = b[0] * b[0] + b[1] * b[1];
+
+ v[0] /= divisor;
+ v[1] /= divisor;
+}
+
+void un_m_complex_muld(f64 *v, f64 *a, f64 *b) {
+ v[0] = a[0] * b[0] - a[1] * b[1];
+ v[1] = a[0] * b[1] + a[1] * b[0];
+}
+
+/* splines */
+
+void un_m_bezierf(f32 *v, f32 a, f32 q0, f32 q1, f32 b, f32 t) {
+ f32 i0, i1, i2, p0, p1, ti;
+
+ ti = 1.0 - t;
+
+ i0 = ti * a + q0 * t;
+ i1 = ti * q0 + q1 * t;
+ i2 = ti * q1 + b * t;
+
+ p0 = ti * i0 + i1 * t;
+ p1 = ti * i1 + i2 * t;
+
+ *v = ti * p0 + p1 * t;
+}
+
+void un_m_bezierd(f64 *v, f64 a, f64 q0, f64 q1, f64 b, f64 t) {
+ f64 i0, i1, i2, p0, p1, ti;
+
+ ti = 1.0 - t;
+
+ i0 = ti * a + q0 * t;
+ i1 = ti * q0 + q1 * t;
+ i2 = ti * q1 + b * t;
+
+ p0 = ti * i0 + i1 * t;
+ p1 = ti * i1 + i2 * t;
+
+ *v = ti * p0 + p1 * t;
+}
+
+void un_m_bezier2f(f32 *v, f32 *a, f32 *q0, f32 *q1, f32 *b, f32 t) {
+ un_m_bezierf(v + 0, a[0], q0[0], q1[0], b[0], t);
+ un_m_bezierf(v + 1, a[1], q0[1], q1[1], b[1], t);
+}
+
+void un_m_bezier3f(f32 *v, f32 *a, f32 *q0, f32 *q1, f32 *b, f32 t) {
+ un_m_bezierf(v + 0, a[0], q0[0], q1[0], b[0], t);
+ un_m_bezierf(v + 1, a[1], q0[1], q1[1], b[1], t);
+ un_m_bezierf(v + 2, a[2], q0[2], q1[2], b[2], t);
+}
+
+void un_m_bezier4f(f32 *v, f32 *a, f32 *q0, f32 *q1, f32 *b, f32 t) {
+ un_m_bezierf(v + 0, a[0], q0[0], q1[0], b[0], t);
+ un_m_bezierf(v + 1, a[1], q0[1], q1[1], b[1], t);
+ un_m_bezierf(v + 2, a[2], q0[2], q1[2], b[2], t);
+ un_m_bezierf(v + 3, a[3], q0[3], q1[3], b[3], t);
+}
+
+
+void un_m_bezier2d(f64 *v, f64 *a, f64 *q0, f64 *q1, f64 *b, f64 t) {
+ un_m_bezierd(v + 0, a[0], q0[0], q1[0], b[0], t);
+ un_m_bezierd(v + 1, a[1], q0[1], q1[1], b[1], t);
+}
+
+void un_m_bezier3d(f64 *v, f64 *a, f64 *q0, f64 *q1, f64 *b, f64 t) {
+ un_m_bezierd(v + 0, a[0], q0[0], q1[0], b[0], t);
+ un_m_bezierd(v + 1, a[1], q0[1], q1[1], b[1], t);
+ un_m_bezierd(v + 2, a[2], q0[2], q1[2], b[2], t);
+}
+
+void un_m_bezier4d(f64 *v, f64 *a, f64 *q0, f64 *q1, f64 *b, f64 t) {
+ un_m_bezierd(v + 0, a[0], q0[0], q1[0], b[0], t);
+ un_m_bezierd(v + 1, a[1], q0[1], q1[1], b[1], t);
+ un_m_bezierd(v + 2, a[2], q0[2], q1[2], b[2], t);
+ un_m_bezierd(v + 3, a[3], q0[3], q1[3], b[3], t);
+}
+
+
+
+/* matrix and quaternions */
+
+/* convention of matrix is: Column-major
+ *
+ * stored in memory as x0 y0 z0 w0 x1 y1 z1 w1 ...
+ *
+ * transform
+ * inverse transform
+ * multiply
+ * reverse
+ * rotate
+ * quaternion -> matrix
+ * matrix -> quaternion
+ * matrix to components: un_mat_disassemble(f32 *pos3, f32 *scale3, f32 *quat4)
+ * un_mat_assemble(f32 *v, f32 *pos3, f32 *scale3, f32 *quat4)
+ * assembe_inverse
+ *
+ * */
+
+
+
+void un_m_mat_identityf(f32 *v) {
+ un_memory_set((void*)v, 0, sizeof(*v) * UN_MATRIX_SIZE);
+
+ v[0 + 0 * UN_MATRIX_STRIPE] = 1.0f;
+ v[1 + 1 * UN_MATRIX_STRIPE] = 1.0f;
+ v[2 + 2 * UN_MATRIX_STRIPE] = 1.0f;
+ v[3 + 3 * UN_MATRIX_STRIPE] = 1.0f;
+}
+
+void un_m_mat_mulf(f32 *v, f32 *left, f32 *right) {
+ u64 row, col, i;
+ un_memory_set((void*)v, 0, sizeof(*v) * UN_MATRIX_SIZE);
+
+ for (col = 0; col < 4; col++) {
+ for (row = 0; row < 4; row++) {
+ for (i = 0; i < 4; i++) {
+ v[row + col * UN_MATRIX_STRIPE] += left[row + i * UN_MATRIX_STRIPE] * right[i + col * UN_MATRIX_STRIPE];
+ }
+ }
+ }
+}
+
+void un_mat_xformf(f32 *v, f32 *xform) {
+ un_m_mat_identityf(v);
+
+ v[3 + 0 * UN_MATRIX_STRIPE] += xform[0];
+ v[3 + 1 * UN_MATRIX_STRIPE] += xform[1];
+ v[3 + 2 * UN_MATRIX_STRIPE] += xform[2];
+}
+
+void un_mat_scalef(f32 *v, f32 *scale) {
+ un_m_mat_identityf(v);
+
+ v[0 + 0 * UN_MATRIX_STRIPE] = scale[0];
+ v[1 + 1 * UN_MATRIX_STRIPE] = scale[1];
+ v[2 + 2 * UN_MATRIX_STRIPE] = scale[2];
+}
+
diff --git a/src/un_mem_linux_x64.c b/src/un_mem_linux_x64.c
new file mode 100644
index 0000000..3d498bc
--- /dev/null
+++ b/src/un_mem_linux_x64.c
@@ -0,0 +1,16 @@
+// @todo: mmap
+
+static ALLOCATOR_PROC_SIGNATURE(un_std_alloc_proc) {
+ UNUSED(data);
+
+ switch (message) {
+ case UN_ALLOC_MSG_ALLOCATE:
+ return calloc(1, size);
+ case UN_ALLOC_MSG_FREE:
+ free(p);
+ break;
+ case UN_ALLOC_MSG_SELF_DELETE: break;
+ }
+
+ return NULL;
+}
diff --git a/src/un_mem_std.c b/src/un_mem_std.c
new file mode 100644
index 0000000..0d5d288
--- /dev/null
+++ b/src/un_mem_std.c
@@ -0,0 +1,14 @@
+static ALLOCATOR_PROC_SIGNATURE(un_std_alloc_proc) {
+ UNUSED(data);
+
+ switch (message) {
+ case UN_ALLOC_MSG_ALLOCATE:
+ return calloc(1, size);
+ case UN_ALLOC_MSG_FREE:
+ free(p);
+ break;
+ case UN_ALLOC_MSG_SELF_DELETE: break;
+ }
+
+ return NULL;
+}
diff --git a/src/un_mem_win_x64.c b/src/un_mem_win_x64.c
new file mode 100644
index 0000000..91f838f
--- /dev/null
+++ b/src/un_mem_win_x64.c
@@ -0,0 +1,18 @@
+#include <windows.h>
+
+static ALLOCATOR_PROC_SIGNATURE(un_std_alloc_proc) {
+ UNUSED(data);
+
+ switch (message) {
+ case UN_ALLOC_MSG_ALLOCATE:
+ return VirtualAlloc(NULL, (SIZE_T)size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
+ case UN_ALLOC_MSG_FREE:
+ if (!VirtualFree(p, 0, MEM_RELEASE)) {
+ assert(false);
+ }
+ break;
+ case UN_ALLOC_MSG_SELF_DELETE: break;
+ }
+
+ return NULL;
+}
diff --git a/src/un_memory.c b/src/un_memory.c
index b092196..178fcbc 100644
--- a/src/un_memory.c
+++ b/src/un_memory.c
@@ -56,14 +56,9 @@ void *un_memory_alloc(u64 size, Allocator alloc) {
return alloc.proc(NULL, size, UN_ALLOC_MSG_ALLOCATE, alloc.data);
}
-void *un_memory_realloc(void *ptr, u64 size, Allocator alloc) {
+void un_memory_free(void *ptr, Allocator alloc) {
assert(alloc.proc != NULL);
- return alloc.proc(ptr, size, UN_ALLOC_MSG_REALLOCATE, alloc.data);
-}
-
-void *un_memory_free(void *ptr, Allocator alloc) {
- assert(alloc.proc != NULL);
- return alloc.proc(ptr, 0, UN_ALLOC_MSG_FREE, alloc.data);
+ alloc.proc(ptr, 0, UN_ALLOC_MSG_FREE, alloc.data);
}
void un_memory_destroy(Allocator *alloc) {
@@ -77,22 +72,16 @@ void un_memory_destroy(Allocator *alloc) {
/// -------- Stdlib allocator
-static ALLOCATOR_PROC_SIGNATURE(un_std_alloc_proc) {
- UNUSED(data);
+#if defined(OS_WINDOWS)
+#include "un_mem_win_x64.c"
- switch (message) {
- case UN_ALLOC_MSG_ALLOCATE:
- return calloc(1, size);
- case UN_ALLOC_MSG_REALLOCATE:
- return realloc(p, size);
- case UN_ALLOC_MSG_FREE:
- free(p);
- break;
- case UN_ALLOC_MSG_SELF_DELETE: break;
- }
+#elif defined(OS_LINUX)
+#include "un_mem_linux_x64.c"
- return NULL;
-}
+#else
+#include "un_mem_std.c"
+
+#endif
Allocator un_allocator_get_standard(void) {
return CLITERAL(Allocator) { .proc = un_std_alloc_proc };
@@ -134,7 +123,6 @@ static ALLOCATOR_PROC_SIGNATURE(un_temp_alloc_proc) {
switch (message) {
case UN_ALLOC_MSG_ALLOCATE:
return temp_alloc(size);
- case UN_ALLOC_MSG_REALLOCATE:
case UN_ALLOC_MSG_FREE:
break;
case UN_ALLOC_MSG_SELF_DELETE: break;
@@ -204,8 +192,6 @@ static ALLOCATOR_PROC_SIGNATURE(un_arena_alloc_proc) {
switch (message) {
case UN_ALLOC_MSG_ALLOCATE:
return arena_allocate(size, (Arena*)data);
- case UN_ALLOC_MSG_REALLOCATE:
- break;
case UN_ALLOC_MSG_FREE:
break;
case UN_ALLOC_MSG_SELF_DELETE:
@@ -224,3 +210,59 @@ Allocator un_allocator_create_arena(u64 size) {
return alloc;
}
+
+/// Wrapping allocator
+
+
+typedef struct Allocation_Info {
+ void *p;
+ u64 size;
+} Allocation_Info;
+
+typedef struct Wrapper {
+ // we need to create hashmap and add all allocations in here
+ // List allocations;
+ Allocator target;
+} Wrapper;
+
+static Wrapper *wrapper_create(Allocator target) {
+ Wrapper *wrapper = (Wrapper *)un_memory_alloc(sizeof(Wrapper), un_allocator_get_standard());
+
+ un_memory_set((void*)wrapper, 0, sizeof(Wrapper));
+ wrapper->target = target;
+
+ return wrapper;
+}
+
+static void wrapper_destroy(Wrapper *wrapper) {
+ assert(wrapper != NULL);
+
+ un_memory_free(wrapper, un_allocator_get_standard());
+}
+
+static ALLOCATOR_PROC_SIGNATURE(un_wrapper_alloc_proc) {
+ assert(data != NULL);
+
+ switch (message) {
+ case UN_ALLOC_MSG_ALLOCATE:
+ return un_memory_alloc(size, ((Wrapper*)data)->target);
+ case UN_ALLOC_MSG_FREE:
+ un_memory_free(p, ((Wrapper*)data)->target);
+ break;
+ case UN_ALLOC_MSG_SELF_DELETE:
+ un_memory_destroy(&((Wrapper*)data)->target);
+ wrapper_destroy((Wrapper*)data);
+ break;
+ }
+
+ return NULL;
+}
+
+Allocator un_allocator_create_wrapper(Allocator target) {
+ Allocator alloc = { 0 };
+
+ alloc.proc = un_wrapper_alloc_proc;
+ alloc.data = wrapper_create(target);
+
+ return alloc;
+}
diff --git a/src/un_splines.c b/src/un_splines.c
deleted file mode 100644
index c6d2844..0000000
--- a/src/un_splines.c
+++ /dev/null
@@ -1,93 +0,0 @@
-void un_m_bezierr(real *v, real a, real q0, real q1, real b, real t) {
- real i0, i1, i2, p0, p1;
-
- i0 = un_m_lerpr(a, q0, t);
- i1 = un_m_lerpr(q0, q1, t);
- i2 = un_m_lerpr(q1, b, t);
-
- p0 = un_m_lerpr(i0, i1, t);
- p1 = un_m_lerpr(i1, i2, t);
-
- *v = un_m_lerpr(p0, p1, t);
-}
-
-void un_m_bezierf(f32 *v, f32 a, f32 q0, f32 q1, f32 b, f32 t) {
- f32 i0, i1, i2, p0, p1;
-
- i0 = un_m_lerpf(a, q0, t);
- i1 = un_m_lerpf(q0, q1, t);
- i2 = un_m_lerpf(q1, b, t);
-
- p0 = un_m_lerpf(i0, i1, t);
- p1 = un_m_lerpf(i1, i2, t);
-
- *v = un_m_lerpf(p0, p1, t);
-}
-
-void un_m_bezierd(f64 *v, f64 a, f64 q0, f64 q1, f64 b, f64 t) {
- f64 i0, i1, i2, p0, p1;
-
- i0 = un_m_lerpd(a, q0, t);
- i1 = un_m_lerpd(q0, q1, t);
- i2 = un_m_lerpd(q1, b, t);
-
- p0 = un_m_lerpd(i0, i1, t);
- p1 = un_m_lerpd(i1, i2, t);
-
- *v = un_m_lerpd(p0, p1, t);
-}
-
-void un_m_bezier2r(real *v, real *a, real *q0, real *q1, real *b, real t) {
- un_m_bezierr(v + 0, a[0], q0[0], q1[0], b[0], t);
- un_m_bezierr(v + 1, a[1], q0[1], q1[1], b[1], t);
-}
-
-void un_m_bezier3r(real *v, real *a, real *q0, real *q1, real *b, real t) {
- un_m_bezierr(v + 0, a[0], q0[0], q1[0], b[0], t);
- un_m_bezierr(v + 1, a[1], q0[1], q1[1], b[1], t);
- un_m_bezierr(v + 2, a[2], q0[2], q1[2], b[2], t);
-}
-
-void un_m_bezier4r(real *v, real *a, real *q0, real *q1, real *b, real t) {
- un_m_bezierr(v + 0, a[0], q0[0], q1[0], b[0], t);
- un_m_bezierr(v + 1, a[1], q0[1], q1[1], b[1], t);
- un_m_bezierr(v + 2, a[2], q0[2], q1[2], b[2], t);
- un_m_bezierr(v + 3, a[3], q0[3], q1[3], b[3], t);
-}
-
-void un_m_bezier2f(f32 *v, f32 *a, f32 *q0, f32 *q1, f32 *b, f32 t) {
- un_m_bezierf(v + 0, a[0], q0[0], q1[0], b[0], t);
- un_m_bezierf(v + 1, a[1], q0[1], q1[1], b[1], t);
-}
-
-void un_m_bezier3f(f32 *v, f32 *a, f32 *q0, f32 *q1, f32 *b, f32 t) {
- un_m_bezierf(v + 0, a[0], q0[0], q1[0], b[0], t);
- un_m_bezierf(v + 1, a[1], q0[1], q1[1], b[1], t);
- un_m_bezierf(v + 2, a[2], q0[2], q1[2], b[2], t);
-}
-
-void un_m_bezier4f(f32 *v, f32 *a, f32 *q0, f32 *q1, f32 *b, f32 t) {
- un_m_bezierf(v + 0, a[0], q0[0], q1[0], b[0], t);
- un_m_bezierf(v + 1, a[1], q0[1], q1[1], b[1], t);
- un_m_bezierf(v + 2, a[2], q0[2], q1[2], b[2], t);
- un_m_bezierf(v + 3, a[3], q0[3], q1[3], b[3], t);
-}
-
-
-void un_m_bezier2d(f64 *v, f64 *a, f64 *q0, f64 *q1, f64 *b, f64 t) {
- un_m_bezierd(v + 0, a[0], q0[0], q1[0], b[0], t);
- un_m_bezierd(v + 1, a[1], q0[1], q1[1], b[1], t);
-}
-
-void un_m_bezier3d(f64 *v, f64 *a, f64 *q0, f64 *q1, f64 *b, f64 t) {
- un_m_bezierd(v + 0, a[0], q0[0], q1[0], b[0], t);
- un_m_bezierd(v + 1, a[1], q0[1], q1[1], b[1], t);
- un_m_bezierd(v + 2, a[2], q0[2], q1[2], b[2], t);
-}
-
-void un_m_bezier4d(f64 *v, f64 *a, f64 *q0, f64 *q1, f64 *b, f64 t) {
- un_m_bezierd(v + 0, a[0], q0[0], q1[0], b[0], t);
- un_m_bezierd(v + 1, a[1], q0[1], q1[1], b[1], t);
- un_m_bezierd(v + 2, a[2], q0[2], q1[2], b[2], t);
- un_m_bezierd(v + 3, a[3], q0[3], q1[3], b[3], t);
-}
diff --git a/src/un_vecr.c b/src/un_vecr.c
deleted file mode 100644
index 0fcf672..0000000
--- a/src/un_vecr.c
+++ /dev/null
@@ -1,353 +0,0 @@
-void un_m_add2r(real *v, real *a, real *b) {
- v[0] = a[0] + b[0];
- v[1] = a[1] + b[1];
-}
-
-void un_m_add3r(real *v, real *a, real *b) {
- v[0] = a[0] + b[0];
- v[1] = a[1] + b[1];
- v[2] = a[2] + b[2];
-}
-
-void un_m_add4r(real *v, real *a, real *b) {
- v[0] = a[0] + b[0];
- v[1] = a[1] + b[1];
- v[2] = a[2] + b[2];
- v[3] = a[3] + b[3];
-}
-
-void un_m_sub2r(real *v, real *a, real *b) {
- v[0] = a[0] - b[0];
- v[1] = a[1] - b[1];
-}
-
-void un_m_sub3r(real *v, real *a, real *b) {
- v[0] = a[0] - b[0];
- v[1] = a[1] - b[1];
- v[2] = a[2] - b[2];
-}
-
-void un_m_sub4r(real *v, real *a, real *b) {
- v[0] = a[0] - b[0];
- v[1] = a[1] - b[1];
- v[2] = a[2] - b[2];
- v[3] = a[3] - b[3];
-}
-
-void un_m_add_scalar2r(real *v, real *a, real scalar) {
- v[0] = a[0] + scalar;
- v[1] = a[1] + scalar;
-}
-
-void un_m_add_scalar3r(real *v, real *a, real scalar) {
- v[0] = a[0] + scalar;
- v[1] = a[1] + scalar;
- v[2] = a[2] + scalar;
-}
-
-void un_m_add_scalar4r(real *v, real *a, real scalar) {
- v[0] = a[0] + scalar;
- v[1] = a[1] + scalar;
- v[2] = a[2] + scalar;
- v[3] = a[3] + scalar;
-}
-
-void un_m_sub_scalar2r(real *v, real *a, real scalar) {
- v[0] = a[0] - scalar;
- v[1] = a[1] - scalar;
-}
-
-void un_m_sub_scalar3r(real *v, real *a, real scalar) {
- v[0] = a[0] - scalar;
- v[1] = a[1] - scalar;
- v[2] = a[2] - scalar;
-}
-
-void un_m_sub_scalar4r(real *v, real *a, real scalar) {
- v[0] = a[0] - scalar;
- v[1] = a[1] - scalar;
- v[2] = a[2] - scalar;
- v[3] = a[3] - scalar;
-}
-
-void un_m_mul_scalar2r(real *v, real *a, real scalar) {
- v[0] = a[0] * scalar;
- v[1] = a[1] * scalar;
-}
-
-void un_m_mul_scalar3r(real *v, real *a, real scalar) {
- v[0] = a[0] * scalar;
- v[1] = a[1] * scalar;
- v[2] = a[2] * scalar;
-}
-
-void un_m_mul_scalar4r(real *v, real *a, real scalar) {
- v[0] = a[0] * scalar;
- v[1] = a[1] * scalar;
- v[2] = a[2] * scalar;
- v[3] = a[3] * scalar;
-}
-
-void un_m_div_scalar2r(real *v, real *a, real scalar) {
- v[0] = a[0] / scalar;
- v[1] = a[1] / scalar;
-}
-
-void un_m_div_scalar3r(real *v, real *a, real scalar) {
- v[0] = a[0] / scalar;
- v[1] = a[1] / scalar;
- v[2] = a[2] / scalar;
-}
-
-void un_m_div_scalar4r(real *v, real *a, real scalar) {
- v[0] = a[0] / scalar;
- v[1] = a[1] / scalar;
- v[2] = a[2] / scalar;
- v[3] = a[3] / scalar;
-}
-
-void un_m_dot2r(real *v, real *a, real *b) {
- *v = a[0] * b[0] + a[1] * b[1];
-}
-
-void un_m_dot3r(real *v, real *a, real *b) {
- *v = a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
-}
-
-void un_m_dot4r(real *v, real *a, real *b) {
- *v = a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
-}
-
-void un_m_hadamard2r(real *v, real *a, real *b) {
- v[0] = a[0] * b[0];
- v[1] = a[1] * b[1];
-}
-
-void un_m_hadamard3r(real *v, real *a, real *b) {
- v[0] = a[0] * b[0];
- v[1] = a[1] * b[1];
- v[2] = a[2] * b[2];
-}
-
-void un_m_hadamard4r(real *v, real *a, real *b) {
- v[0] = a[0] * b[0];
- v[1] = a[1] * b[1];
- v[2] = a[2] * b[2];
- v[3] = a[3] * b[3];
-}
-
-void un_m_cross2r(real *v, real *a) {
- v[0] = a[1];
- v[1] =-a[0];
-}
-
-void un_m_cross3r(real *v, real *a, real *b) {
- v[0] = a[1] * b[2] - a[2] * b[1];
- v[1] = a[2] * b[0] - a[0] * b[2];
- v[2] = a[0] * b[1] - a[1] * b[0];
-}
-
-void un_m_magnitude2r(real *v, real *a) {
-#if defined(UN_DOUBLE_PRECISION)
- *v = sqrt(a[0] * a[0] + a[1] * a[1]);
-#else
- *v = sqrtf(a[0] * a[0] + a[1] * a[1]);
-#endif
-}
-
-void un_m_magnitude3r(real *v, real *a) {
-#if defined(UN_DOUBLE_PRECISION)
- *v = sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
-#else
- *v = sqrtf(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
-#endif
-}
-
-void un_m_magnitude4r(real *v, real *a) {
-#if defined(UN_DOUBLE_PRECISION)
- *v = sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3]);
-#else
- *v = sqrtf(a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3]);
-#endif
-}
-
-void un_m_magnitude_sqr2r(real *v, real *a) {
- *v = a[0] * a[0] + a[1] * a[1];
-}
-
-void un_m_magnitude_sqr3r(real *v, real *a) {
- *v = a[0] * a[0] + a[1] * a[1] + a[2] * a[2];
-}
-
-void un_m_magnitude_sqr4r(real *v, real *a) {
- *v = a[0] * a[0] + a[1] * a[1] + a[2] * a[2] + a[3] * a[3];
-}
-
-void un_m_distance2r(real *v, real *a, real *b) {
- real f[2];
- un_m_sub2r(f, b, a);
-#if defined(UN_DOUBLE_PRECISION)
- *v = sqrt(f[0] * f[0] + f[1] * f[1]);
-#else
- *v = sqrtf(f[0] * f[0] + f[1] * f[1]);
-#endif
-}
-
-void un_m_distance3r(real *v, real *a, real *b) {
- real f[3];
- un_m_sub3r(f, b, a);
-#if defined(UN_DOUBLE_PRECISION)
- *v = sqrt(f[0] * f[0] + f[1] * f[1] + f[2] * f[2]);
-#else
- *v = sqrtf(f[0] * f[0] + f[1] * f[1] + f[2] * f[2]);
-#endif
-}
-
-void un_m_distance4r(real *v, real *a, real *b) {
- real f[4];
- un_m_sub4r(f, b, a);
-#if defined(UN_DOUBLE_PRECISION)
- *v = sqrt(f[0] * f[0] + f[1] * f[1] + f[2] * f[2] + f[3] * f[3]);
-#else
- *v = sqrtf(f[0] * f[0] + f[1] * f[1] + f[2] * f[2] + f[3] * f[3]);
-#endif
-}
-
-void un_m_distance_sqr2r(real *v, real *a, real *b) {
- real f[2];
- un_m_sub2r(f, b, a);
- *v = f[0] * f[0] + f[1] * f[1];
-}
-
-void un_m_distance_sqr3r(real *v, real *a, real *b) {
- real f[3];
- un_m_sub3r(f, b, a);
- *v = f[0] * f[0] + f[1] * f[1] + f[2] * f[2];
-}
-
-void un_m_distance_sqr4r(real *v, real *a, real *b) {
- real f[4];
- un_m_sub4r(f, b, a);
- *v = f[0] * f[0] + f[1] * f[1] + f[2] * f[2] + f[3] * f[3];
-}
-
-void un_m_normalize2r(real *v, real *a) {
- real f;
- un_m_magnitude2r(&f, a);
- v[0] = a[0] / f;
- v[1] = a[1] / f;
-}
-
-void un_m_normalize3r(real *v, real *a) {
- real f;
- un_m_magnitude3r(&f, a);
- v[0] = a[0] / f;
- v[1] = a[1] / f;
- v[2] = a[2] / f;
-}
-
-void un_m_normalize4r(real *v, real *a) {
- real f;
- un_m_magnitude4r(&f, a);
- v[0] = a[0] / f;
- v[1] = a[1] / f;
- v[2] = a[2] / f;
- v[3] = a[3] / f;
-}
-
-void un_m_project2r(real *v, real *a, real *onto) {
- real dot, magn, scale;
-
- un_m_dot2r(&dot, a, onto);
- un_m_magnitude_sqr2r(&magn, onto);
-
-
-#if defined(UN_DOUBLE_PRECISION)
- if (magn < EPSILON_D) {
- un_memory_set((void*)v, 0, sizeof(*v) * 2);
- return;
- }
-#else
- if (magn < EPSILON) {
- un_memory_set((void*)v, 0, sizeof(*v) * 2);
- return;
- }
-#endif
-
- scale = dot / magn;
- v[0] = onto[0] * scale;
- v[1] = onto[1] * scale;
-}
-
-void un_m_project3r(real *v, real *a, real *onto) {
- real dot, magn, scale;
-
- un_m_dot3r(&dot, a, onto);
- un_m_magnitude_sqr3r(&magn, onto);
-
-#if defined(UN_DOUBLE_PRECISION)
- if (magn < EPSILON_D) {
- un_memory_set((void*)v, 0, sizeof(*v) * 3);
- return;
- }
-#else
- if (magn < EPSILON) {
- un_memory_set((void*)v, 0, sizeof(*v) * 3);
- return;
- }
-#endif
-
- scale = dot / magn;
- v[0] = onto[0] * scale;
- v[1] = onto[1] * scale;
- v[2] = onto[2] * scale;
-}
-
-void un_m_project4r(real *v, real *a, real *onto) {
- real dot, magn, scale;
-
- un_m_dot4r(&dot, a, onto);
- un_m_magnitude_sqr4r(&magn, onto);
-
-#if defined(UN_DOUBLE_PRECISION)
- if (magn < EPSILON_D) {
- un_memory_set((void*)v, 0, sizeof(*v) * 4);
- return;
- }
-#else
- if (magn < EPSILON) {
- un_memory_set((void*)v, 0, sizeof(*v) * 4);
- return;
- }
-#endif
-
- scale = dot / magn;
- v[0] = onto[0] * scale;
- v[1] = onto[1] * scale;
- v[2] = onto[2] * scale;
- v[3] = onto[3] * scale;
-}
-
-void un_m_reflect2r(real *v, real *a, real *normal) {
- real dot;
-
- un_m_dot2r(&dot, a, normal);
- un_m_mul_scalar2r(v, normal, 2.0 * dot);
- un_m_sub2r(v, v, a);
-}
-
-void un_m_reflect3r(real *v, real *a, real *normal) {
- real dot;
-
- un_m_dot3r(&dot, a, normal);
- un_m_mul_scalar3r(v, normal, 2.0 * dot);
- un_m_sub3r(v, v, a);
-}
-
-void un_m_reflect4r(real *v, real *a, real *normal) {
- real dot;
-
- un_m_dot4r(&dot, a, normal);
- un_m_mul_scalar4r(v, normal, 2.0 * dot);
- un_m_sub4r(v, v, a);
-}
diff --git a/src/un_wstrings.c b/src/un_wstrings.c
new file mode 100644
index 0000000..601c809
--- /dev/null
+++ b/src/un_wstrings.c
@@ -0,0 +1,66 @@
+#if defined(OS_WINDOWS)
+wchar* un_wstring_from_string(String utf8_string, Allocator alloc) {
+ return un_wstring_from_cstring(un_string_to_cstring(utf8_string, un_allocator_get_temporary()), alloc);
+}
+
+wchar* un_wstring_from_cstring(u8 *utf8_string, Allocator alloc) {
+ u32 error_code, buffer_size, wrote_chars;
+ wchar *string_buffer;
+ assert(utf8_string != NULL);
+
+ buffer_size = MultiByteToWideChar(
+ CP_UTF8,
+ 0, // or MB_PRECOMPOSED
+ (LPCCH)utf8_string,
+ -1,
+ NULL,
+ 0
+ );
+
+ if (!buffer_size) {
+ error_code = GetLastError();
+
+ switch (error_code) {
+ case ERROR_NO_UNICODE_TRANSLATION: return NULL; break;
+ default:
+ assert(false);
+ break;
+ }
+
+ return NULL;
+ }
+
+ string_buffer = un_memory_alloc(sizeof(wchar) * buffer_size, alloc);
+
+ if (string_buffer == NULL) {
+ return NULL;
+ }
+
+ wrote_chars = MultiByteToWideChar(
+ CP_UTF8,
+ 0, // or MB_PRECOMPOSED
+ (LPCCH)utf8_string,
+ -1,
+ (LPWSTR)string_buffer,
+ buffer_size
+ );
+
+ assert(wrote_chars == buffer_size);
+
+ return string_buffer;
+}
+#else
+
+wchar* un_wstring_from_string(String utf8_string, Allocator alloc) {
+ UNUSED(utf8_string);
+ UNUSED(alloc);
+ __TRAP();
+}
+
+wchar* un_wstring_from_cstring(u8 *utf8_string, Allocator alloc) {
+ UNUSED(utf8_string);
+ UNUSED(alloc);
+ __TRAP();
+}
+
+#endif
diff --git a/src/ungrateful.c b/src/ungrateful.c
index 61d8185..5031a45 100644
--- a/src/ungrateful.c
+++ b/src/ungrateful.c
@@ -1,13 +1,16 @@
#include "ungrateful.h"
+#if defined(OS_WINDOWS)
+#include <windows.h>
+#elif defined(OS_LINUX)
+#endif
+
#include "un_memory.c"
#include "un_strings.c"
+#include "un_wstrings.c"
#include "un_list.c"
#include "un_math.c"
#include "un_vec.c"
#include "un_vecd.c"
-#include "un_vecr.c"
-
-#include "un_splines.c"
diff --git a/src/ungrateful.h b/src/ungrateful.h
index bbbea47..82152fa 100644
--- a/src/ungrateful.h
+++ b/src/ungrateful.h
@@ -61,6 +61,7 @@
#include <limits.h>
#include <assert.h>
#include <math.h>
+#include <wchar.h>
#define UNUSED(x) (void)(x)
@@ -71,6 +72,7 @@
#define UN_MAX(a, b) (a) > (b) ? (a) : (b)
#define UN_MIN(a, b) (a) < (b) ? (a) : (b)
+#define UN_TODO(msg) assert((msg, false))
#define UN_CSTR (u8*)
#define UN_STR(cstr) un_string_from_cstring(UN_CSTR cstr)
#define CSTR (char*)
@@ -97,19 +99,21 @@ typedef int8_t b8;
typedef float f32;
typedef double f64;
-#ifndef PI
+typedef wchar_t wchar;
+
+#if !defined(PI)
# define PI 3.14159265358979323846f
#endif
-#ifndef EPSILON
+#if !defined(EPSILON)
# define EPSILON 0.000001f
#endif
-#ifndef DEG2RAD
+#if !defined(DEG2RAD)
# define DEG2RAD (PI/180.0f)
#endif
-#ifndef RAD2DEG
+#if !defined(RAD2DEG)
# define RAD2DEG (180.0f/PI)
#endif
@@ -119,18 +123,18 @@ typedef double f64;
typedef float real;
#endif // UN_DOUBLE_PRECISION
-#ifndef PI_D
+#if !defined(PI_D)
# define PI_D 3.14159265358979323846
#endif
-#ifndef EPSILON_D
+#if !defined(EPSILON_D)
# define EPSILON_D 0.000000000000001
#endif
-#ifndef DEG2RAD_D
+#if !defined(DEG2RAD_D)
# define DEG2RAD_D (PI/180.0)
#endif
-#ifndef RAD2DEG_D
+#if !defined(RAD2DEG_D)
# define RAD2DEG_D (180.0/PI)
#endif
@@ -143,7 +147,6 @@ typedef double f64;
typedef enum {
UN_ALLOC_MSG_ALLOCATE,
- UN_ALLOC_MSG_REALLOCATE,
UN_ALLOC_MSG_FREE,
UN_ALLOC_MSG_SELF_DELETE,
} Allocator_Message;
@@ -158,15 +161,15 @@ typedef struct {
void *data;
} Allocator;
-// extern Allocator un_allocator_create_heap(s64 chunk_size); /* ... for large things */
-extern Allocator un_allocator_create_arena(u64 initial_size); /* Grouping allocator, that will recursively grow */
+// extern Allocator un_allocator_create_heap(s64 chunk_size); /* ... for large things. */
+extern Allocator un_allocator_create_arena(u64 initial_size); /* Grouping allocator, that will recursively grow. */
+extern Allocator un_allocator_create_wrapper(Allocator target); /* Allocator for debug purposes. */
extern Allocator un_allocator_get_standard(void);
extern Allocator un_allocator_get_temporary(void);
extern void *un_memory_alloc(u64 size, Allocator alloc);
-extern void *un_memory_realloc(void *ptr, u64 size, Allocator alloc);
-extern void *un_memory_free(void *ptr, Allocator alloc);
+extern void un_memory_free(void *ptr, Allocator alloc);
extern void un_memory_destroy(Allocator *alloc);
extern void un_memory_set(u8 *dest, u8 value, u64 size);
@@ -176,6 +179,8 @@ extern s32 un_memory_compare(u8 *left, u8 *right, u64 size); /* checks for ever
/* ---- Generic list structure ---- */
+#define UN_LIST_STANDARD_CAPACITY UN_KB(1)
+
typedef struct {
u64 count;
u64 capacity;
@@ -185,7 +190,7 @@ typedef struct {
} List;
extern List un_list_create(u64 start_capacity, u64 element_size, Allocator alloc);
-extern void un_list_destroy(List *list);
+extern void un_list_destroy(List *list, b32 delete_allocator);
extern List un_list_clone(List *list, Allocator alloc);
extern b32 un_list_append(List *list, void *data); /* Returns true if succeed. */
@@ -228,202 +233,304 @@ extern s64 un_string_index_of_last(String input, u8 value);
extern String un_string_format(Allocator alloc, String buffer, ...);
extern String un_string_vformat(Allocator alloc, String buffer, va_list args);
+/* ---- wide strings API ---- */
+
+extern wchar* un_wstring_from_string(String utf8_string, Allocator alloc);
+extern wchar* un_wstring_from_cstring(u8 *utf8_string, Allocator alloc);
+
/* ---- math, and vecmath ---- */
-real un_m_lerpr(real a, real b, real t);
+#if defined(UN_DOUBLE_PRECISION)
+#define un_m_lerpr un_m_lerpd
+#else
+#define un_m_lerpr un_m_lerpf
+#endif
+
f32 un_m_lerpf(f32 a, f32 b, f32 t);
f64 un_m_lerpd(f64 a, f64 b, f64 t);
/* 2d f32 */
-void un_m_add2f(f32 *v, f32 *a, f32 *b);
-void un_m_sub2f(f32 *v, f32 *a, f32 *b);
-void un_m_add_scalar2f(f32 *v, f32 *a, f32 scalar);
-void un_m_sub_scalar2f(f32 *v, f32 *a, f32 scalar);
-void un_m_mul_scalar2f(f32 *v, f32 *a, f32 scalar);
-void un_m_div_scalar2f(f32 *v, f32 *a, f32 scalar);
+extern void un_m_add2f(f32 *v, f32 *a, f32 *b);
+extern void un_m_sub2f(f32 *v, f32 *a, f32 *b);
+extern void un_m_add_scalar2f(f32 *v, f32 *a, f32 scalar);
+extern void un_m_sub_scalar2f(f32 *v, f32 *a, f32 scalar);
+extern void un_m_mul_scalar2f(f32 *v, f32 *a, f32 scalar);
+extern void un_m_div_scalar2f(f32 *v, f32 *a, f32 scalar);
-void un_m_dot2f(f32 *v, f32 *a, f32 *b);
-void un_m_hadamard2f(f32 *v, f32 *a, f32 *b);
-void un_m_project2f(f32 *v, f32 *a, f32 *onto);
-void un_m_reflect2f(f32 *v, f32 *a, f32 *normal);
-void un_m_cross2f(f32 *v, f32 *a);
+extern void un_m_dot2f(f32 *v, f32 *a, f32 *b);
+extern void un_m_hadamard2f(f32 *v, f32 *a, f32 *b);
+extern void un_m_project2f(f32 *v, f32 *a, f32 *onto);
+extern void un_m_reflect2f(f32 *v, f32 *a, f32 *normal);
+extern void un_m_cross2f(f32 *v, f32 *a);
-void un_m_normalize2f(f32 *v, f32 *a);
-void un_m_magnitude2f(f32 *v, f32 *a);
-void un_m_magnitude_sqr2f(f32 *v, f32 *a);
-void un_m_distance2f(f32 *v, f32 *a, f32 *b);
-void un_m_distance_sqr2f(f32 *v, f32 *a, f32 *b);
+extern void un_m_normalize2f(f32 *v, f32 *a);
+extern void un_m_magnitude2f(f32 *v, f32 *a);
+extern void un_m_magnitude_sqr2f(f32 *v, f32 *a);
+extern void un_m_distance2f(f32 *v, f32 *a, f32 *b);
+extern void un_m_distance_sqr2f(f32 *v, f32 *a, f32 *b);
/* 3d f32 */
-void un_m_add3f(f32 *v, f32 *a, f32 *b);
-void un_m_sub3f(f32 *v, f32 *a, f32 *b);
-void un_m_add_scalar3f(f32 *v, f32 *a, f32 scalar);
-void un_m_sub_scalar3f(f32 *v, f32 *a, f32 scalar);
-void un_m_mul_scalar3f(f32 *v, f32 *a, f32 scalar);
-void un_m_div_scalar3f(f32 *v, f32 *a, f32 scalar);
+extern void un_m_add3f(f32 *v, f32 *a, f32 *b);
+extern void un_m_sub3f(f32 *v, f32 *a, f32 *b);
+extern void un_m_add_scalar3f(f32 *v, f32 *a, f32 scalar);
+extern void un_m_sub_scalar3f(f32 *v, f32 *a, f32 scalar);
+extern void un_m_mul_scalar3f(f32 *v, f32 *a, f32 scalar);
+extern void un_m_div_scalar3f(f32 *v, f32 *a, f32 scalar);
-void un_m_dot3f(f32 *v, f32 *a, f32 *b);
-void un_m_hadamard3f(f32 *v, f32 *a, f32 *b);
-void un_m_project3f(f32 *v, f32 *a, f32 *onto);
-void un_m_reflect3f(f32 *v, f32 *a, f32 *normal);
-void un_m_cross3f(f32 *v, f32 *a, f32 *b);
+extern void un_m_dot3f(f32 *v, f32 *a, f32 *b);
+extern void un_m_hadamard3f(f32 *v, f32 *a, f32 *b);
+extern void un_m_project3f(f32 *v, f32 *a, f32 *onto);
+extern void un_m_reflect3f(f32 *v, f32 *a, f32 *normal);
+extern void un_m_cross3f(f32 *v, f32 *a, f32 *b);
-void un_m_normalize3f(f32 *v, f32 *a);
-void un_m_magnitude3f(f32 *v, f32 *a);
-void un_m_magnitude_sqr3f(f32 *v, f32 *a);
-void un_m_distance3f(f32 *v, f32 *a, f32 *b);
-void un_m_distance_sqr3f(f32 *v, f32 *a, f32 *b);
+extern void un_m_normalize3f(f32 *v, f32 *a);
+extern void un_m_magnitude3f(f32 *v, f32 *a);
+extern void un_m_magnitude_sqr3f(f32 *v, f32 *a);
+extern void un_m_distance3f(f32 *v, f32 *a, f32 *b);
+extern void un_m_distance_sqr3f(f32 *v, f32 *a, f32 *b);
/* 4d f32 */
-void un_m_add4f(f32 *v, f32 *a, f32 *b);
-void un_m_sub4f(f32 *v, f32 *a, f32 *b);
-void un_m_add_scalar4f(f32 *v, f32 *a, f32 scalar);
-void un_m_sub_scalar4f(f32 *v, f32 *a, f32 scalar);
-void un_m_mul_scalar4f(f32 *v, f32 *a, f32 scalar);
-void un_m_div_scalar4f(f32 *v, f32 *a, f32 scalar);
+extern void un_m_add4f(f32 *v, f32 *a, f32 *b);
+extern void un_m_sub4f(f32 *v, f32 *a, f32 *b);
+extern void un_m_add_scalar4f(f32 *v, f32 *a, f32 scalar);
+extern void un_m_sub_scalar4f(f32 *v, f32 *a, f32 scalar);
+extern void un_m_mul_scalar4f(f32 *v, f32 *a, f32 scalar);
+extern void un_m_div_scalar4f(f32 *v, f32 *a, f32 scalar);
-void un_m_dot4f(f32 *v, f32 *a, f32 *b);
-void un_m_hadamard4f(f32 *v, f32 *a, f32 *b);
-void un_m_project4f(f32 *v, f32 *a, f32 *onto);
-void un_m_reflect4f(f32 *v, f32 *a, f32 *normal);
+extern void un_m_dot4f(f32 *v, f32 *a, f32 *b);
+extern void un_m_hadamard4f(f32 *v, f32 *a, f32 *b);
+extern void un_m_project4f(f32 *v, f32 *a, f32 *onto);
+extern void un_m_reflect4f(f32 *v, f32 *a, f32 *normal);
-void un_m_normalize4f(f32 *v, f32 *a);
-void un_m_magnitude4f(f32 *v, f32 *a);
-void un_m_magnitude_sqr4f(f32 *v, f32 *a);
-void un_m_distance4f(f32 *v, f32 *a, f32 *b);
-void un_m_distance_sqr4f(f32 *v, f32 *a, f32 *b);
+extern void un_m_normalize4f(f32 *v, f32 *a);
+extern void un_m_magnitude4f(f32 *v, f32 *a);
+extern void un_m_magnitude_sqr4f(f32 *v, f32 *a);
+extern void un_m_distance4f(f32 *v, f32 *a, f32 *b);
+extern void un_m_distance_sqr4f(f32 *v, f32 *a, f32 *b);
/* 2d f64 */
-void un_m_add2d(f64 *v, f64 *a, f64 *b);
-void un_m_sub2d(f64 *v, f64 *a, f64 *b);
+extern void un_m_add2d(f64 *v, f64 *a, f64 *b);
+extern void un_m_sub2d(f64 *v, f64 *a, f64 *b);
-void un_m_add_scalar2d(f64 *v, f64 *a, f64 scalar);
-void un_m_sub_scalar2d(f64 *v, f64 *a, f64 scalar);
-void un_m_mul_scalar2d(f64 *v, f64 *a, f64 scalar);
-void un_m_div_scalar2d(f64 *v, f64 *a, f64 scalar);
+extern void un_m_add_scalar2d(f64 *v, f64 *a, f64 scalar);
+extern void un_m_sub_scalar2d(f64 *v, f64 *a, f64 scalar);
+extern void un_m_mul_scalar2d(f64 *v, f64 *a, f64 scalar);
+extern void un_m_div_scalar2d(f64 *v, f64 *a, f64 scalar);
-void un_m_dot2d(f64 *v, f64 *a, f64 *b);
-void un_m_hadamard2d(f64 *v, f64 *a, f64 *b);
-void un_m_project2d(f64 *v, f64 *a, f64 *onto);
-void un_m_reflect2d(f64 *v, f64 *a, f64 *normal);
-void un_m_cross2d(f64 *v, f64 *a);
+extern void un_m_dot2d(f64 *v, f64 *a, f64 *b);
+extern void un_m_hadamard2d(f64 *v, f64 *a, f64 *b);
+extern void un_m_project2d(f64 *v, f64 *a, f64 *onto);
+extern void un_m_reflect2d(f64 *v, f64 *a, f64 *normal);
+extern void un_m_cross2d(f64 *v, f64 *a);
-void un_m_normalize2d(f64 *v, f64 *a);
-void un_m_magnitude2d(f64 *v, f64 *a);
-void un_m_magnitude_sqr2d(f64 *v, f64 *a);
-void un_m_distance2d(f64 *v, f64 *a, f64 *b);
-void un_m_distance_sqr2d(f64 *v, f64 *a, f64 *b);
+extern void un_m_normalize2d(f64 *v, f64 *a);
+extern void un_m_magnitude2d(f64 *v, f64 *a);
+extern void un_m_magnitude_sqr2d(f64 *v, f64 *a);
+extern void un_m_distance2d(f64 *v, f64 *a, f64 *b);
+extern void un_m_distance_sqr2d(f64 *v, f64 *a, f64 *b);
/* 3d f64 */
-void un_m_add3d(f64 *v, f64 *a, f64 *b);
-void un_m_sub3d(f64 *v, f64 *a, f64 *b);
+extern void un_m_add3d(f64 *v, f64 *a, f64 *b);
+extern void un_m_sub3d(f64 *v, f64 *a, f64 *b);
-void un_m_add_scalar3d(f64 *v, f64 *a, f64 scalar);
-void un_m_sub_scalar3d(f64 *v, f64 *a, f64 scalar);
-void un_m_mul_scalar3d(f64 *v, f64 *a, f64 scalar);
-void un_m_div_scalar3d(f64 *v, f64 *a, f64 scalar);
+extern void un_m_add_scalar3d(f64 *v, f64 *a, f64 scalar);
+extern void un_m_sub_scalar3d(f64 *v, f64 *a, f64 scalar);
+extern void un_m_mul_scalar3d(f64 *v, f64 *a, f64 scalar);
+extern void un_m_div_scalar3d(f64 *v, f64 *a, f64 scalar);
-void un_m_dot3d(f64 *v, f64 *a, f64 *b);
-void un_m_hadamard3d(f64 *v, f64 *a, f64 *b);
-void un_m_project3d(f64 *v, f64 *a, f64 *onto);
-void un_m_reflect3d(f64 *v, f64 *a, f64 *normal);
-void un_m_cross3d(f64 *v, f64 *a, f64 *b);
+extern void un_m_dot3d(f64 *v, f64 *a, f64 *b);
+extern void un_m_hadamard3d(f64 *v, f64 *a, f64 *b);
+extern void un_m_project3d(f64 *v, f64 *a, f64 *onto);
+extern void un_m_reflect3d(f64 *v, f64 *a, f64 *normal);
+extern void un_m_cross3d(f64 *v, f64 *a, f64 *b);
-void un_m_normalize3d(f64 *v, f64 *a);
-void un_m_magnitude3d(f64 *v, f64 *a);
-void un_m_magnitude_sqr3d(f64 *v, f64 *a);
-void un_m_distance3d(f64 *v, f64 *a, f64 *b);
-void un_m_distance_sqr3d(f64 *v, f64 *a, f64 *b);
+extern void un_m_normalize3d(f64 *v, f64 *a);
+extern void un_m_magnitude3d(f64 *v, f64 *a);
+extern void un_m_magnitude_sqr3d(f64 *v, f64 *a);
+extern void un_m_distance3d(f64 *v, f64 *a, f64 *b);
+extern void un_m_distance_sqr3d(f64 *v, f64 *a, f64 *b);
/* 4d f64 */
-void un_m_add4d(f64 *v, f64 *a, f64 *b);
-void un_m_sub4d(f64 *v, f64 *a, f64 *b);
+extern void un_m_add4d(f64 *v, f64 *a, f64 *b);
+extern void un_m_sub4d(f64 *v, f64 *a, f64 *b);
+
+extern void un_m_add_scalar4d(f64 *v, f64 *a, f64 scalar);
+extern void un_m_sub_scalar4d(f64 *v, f64 *a, f64 scalar);
+extern void un_m_mul_scalar4d(f64 *v, f64 *a, f64 scalar);
+extern void un_m_div_scalar4d(f64 *v, f64 *a, f64 scalar);
-void un_m_add_scalar4d(f64 *v, f64 *a, f64 scalar);
-void un_m_sub_scalar4d(f64 *v, f64 *a, f64 scalar);
-void un_m_mul_scalar4d(f64 *v, f64 *a, f64 scalar);
-void un_m_div_scalar4d(f64 *v, f64 *a, f64 scalar);
+extern void un_m_dot4d(f64 *v, f64 *a, f64 *b);
+extern void un_m_hadamard4d(f64 *v, f64 *a, f64 *b);
+extern void un_m_project4d(f64 *v, f64 *a, f64 *onto);
+extern void un_m_reflect4d(f64 *v, f64 *a, f64 *normal);
-void un_m_dot4d(f64 *v, f64 *a, f64 *b);
-void un_m_hadamard4d(f64 *v, f64 *a, f64 *b);
-void un_m_project4d(f64 *v, f64 *a, f64 *onto);
-void un_m_reflect4d(f64 *v, f64 *a, f64 *normal);
+extern void un_m_normalize4d(f64 *v, f64 *a);
+extern void un_m_magnitude4d(f64 *v, f64 *a);
+extern void un_m_magnitude_sqr4d(f64 *v, f64 *a);
+extern void un_m_distance4d(f64 *v, f64 *a, f64 *b);
+extern void un_m_distance_sqr4d(f64 *v, f64 *a, f64 *b);
-void un_m_normalize4d(f64 *v, f64 *a);
-void un_m_magnitude4d(f64 *v, f64 *a);
-void un_m_magnitude_sqr4d(f64 *v, f64 *a);
-void un_m_distance4d(f64 *v, f64 *a, f64 *b);
-void un_m_distance_sqr4d(f64 *v, f64 *a, f64 *b);
+#if defined(UN_DOUBLE_PRECISION)
/* 2d real */
-void un_m_add2r(real *v, real *a, real *b);
-void un_m_sub2r(real *v, real *a, real *b);
+#define un_m_add2r un_m_add2d
+#define un_m_sub2r un_m_sub2d
-void un_m_add_scalar2r(real *v, real *a, real scalar);
-void un_m_sub_scalar2r(real *v, real *a, real scalar);
-void un_m_mul_scalar2r(real *v, real *a, real scalar);
-void un_m_div_scalar2r(real *v, real *a, real scalar);
+#define un_m_add_scalar2r un_m_add_scalar2d
+#define un_m_sub_scalar2r un_m_sub_scalar2d
+#define un_m_mul_scalar2r un_m_mul_scalar2d
+#define un_m_div_scalar2r un_m_div_scalar2d
-void un_m_dot2r(real *v, real *a, real *b);
-void un_m_hadamard2r(real *v, real *a, real *b);
-void un_m_project2r(real *v, real *a, real *onto);
-void un_m_reflect2r(real *v, real *a, real *normal);
-void un_m_cross2r(real *v, real *a);
+#define un_m_dot2r un_m_dot2d
+#define un_m_hadamard2r un_m_hadamard2d
+#define un_m_project2r un_m_project2d
+#define un_m_reflect2r un_m_reflect2d
+#define un_m_cross2r un_m_cross2d
-void un_m_normalize2r(real *v, real *a);
-void un_m_magnitude2r(real *v, real *a);
-void un_m_magnitude_sqr2r(real *v, real *a);
-void un_m_distance2r(real *v, real *a, real *b);
-void un_m_distance_sqr2r(real *v, real *a, real *b);
+#define un_m_normalize2r un_m_normalize2d
+#define un_m_magnitude2r un_m_magnitude2d
+#define un_m_magnitude_sqr2r un_m_magnitude_sqr2d
+#define un_m_distance2r un_m_distance2d
+#define un_m_distance_sqr2r un_m_distance_sqr2d
/* 3d real */
-void un_m_add3r(real *v, real *a, real *b);
-void un_m_sub3r(real *v, real *a, real *b);
+#define un_m_add3r un_m_add3d
+#define un_m_sub3r un_m_sub3d
-void un_m_add_scalar3r(real *v, real *a, real scalar);
-void un_m_sub_scalar3r(real *v, real *a, real scalar);
-void un_m_mul_scalar3r(real *v, real *a, real scalar);
-void un_m_div_scalar3r(real *v, real *a, real scalar);
+#define un_m_add_scalar3r un_m_add_scalar3d
+#define un_m_sub_scalar3r un_m_sub_scalar3d
+#define un_m_mul_scalar3r un_m_mul_scalar3d
+#define un_m_div_scalar3r un_m_div_scalar3d
-void un_m_dot3r(real *v, real *a, real *b);
-void un_m_hadamard3r(real *v, real *a, real *b);
-void un_m_project3r(real *v, real *a, real *onto);
-void un_m_reflect3r(real *v, real *a, real *normal);
-void un_m_cross3r(real *v, real *a, real *b);
+#define un_m_dot3r un_m_dot3d
+#define un_m_hadamard3r un_m_hadamard3d
+#define un_m_project3r un_m_project3d
+#define un_m_reflect3r un_m_reflect3d
+#define un_m_cross3r un_m_cross3d
-void un_m_normalize3r(real *v, real *a);
-void un_m_magnitude3r(real *v, real *a);
-void un_m_magnitude_sqr3r(real *v, real *a);
-void un_m_distance3r(real *v, real *a, real *b);
-void un_m_distance_sqr3r(real *v, real *a, real *b);
+#define un_m_normalize3r un_m_normalize3d
+#define un_m_magnitude3r un_m_magnitude3d
+#define un_m_magnitude_sqr3r un_m_magnitude_sqr3d
+#define un_m_distance3r un_m_distance3d
+#define un_m_distance_sqr3r un_m_distance_sqr3d
/* 4d real */
-void un_m_add4r(real *v, real *a, real *b);
-void un_m_sub4r(real *v, real *a, real *b);
+#define un_m_add4r un_m_add4d
+#define un_m_sub4r un_m_sub4d
-void un_m_add_scalar4r(real *v, real *a, real scalar);
-void un_m_sub_scalar4r(real *v, real *a, real scalar);
-void un_m_mul_scalar4r(real *v, real *a, real scalar);
-void un_m_div_scalar4r(real *v, real *a, real scalar);
+#define un_m_add_scalar4r un_m_add_scalar4d
+#define un_m_sub_scalar4r un_m_sub_scalar4d
+#define un_m_mul_scalar4r un_m_mul_scalar4d
+#define un_m_div_scalar4r un_m_div_scalar4d
-void un_m_dot4r(real *v, real *a, real *b);
-void un_m_hadamard4r(real *v, real *a, real *b);
-void un_m_project4r(real *v, real *a, real *onto);
-void un_m_reflect4r(real *v, real *a, real *normal);
+#define un_m_dot4r un_m_dot4d
+#define un_m_hadamard4r un_m_hadamard4d
+#define un_m_project4r un_m_project4d
+#define un_m_reflect4r un_m_reflect4d
-void un_m_normalize4r(real *v, real *a);
-void un_m_magnitude4r(real *v, real *a);
-void un_m_magnitude_sqr4r(real *v, real *a);
-void un_m_distance4r(real *v, real *a, real *b);
-void un_m_distance_sqr4r(real *v, real *a, real *b);
+#define un_m_normalize4r un_m_normalize4d
+#define un_m_magnitude4r un_m_magnitude4d
+#define un_m_magnitude_sqr4r un_m_magnitude_sqr4d
+#define un_m_distance4r un_m_distance4d
+#define un_m_distance_sqr4r un_m_distance_sqr4d
-/* ---- splines ---- */
+#else
+
+/* 2d real */
+#define un_m_add2r un_m_add2f
+#define un_m_sub2r un_m_sub2f
+
+#define un_m_add_scalar2r un_m_add_scalar2f
+#define un_m_sub_scalar2r un_m_sub_scalar2f
+#define un_m_mul_scalar2r un_m_mul_scalar2f
+#define un_m_div_scalar2r un_m_div_scalar2f
+
+#define un_m_dot2r un_m_dot2f
+#define un_m_hadamard2r un_m_hadamard2f
+#define un_m_project2r un_m_project2f
+#define un_m_reflect2r un_m_reflect2f
+#define un_m_cross2r un_m_cross2f
+
+#define un_m_normalize2r un_m_normalize2f
+#define un_m_magnitude2r un_m_magnitude2f
+#define un_m_magnitude_sqr2r un_m_magnitude_sqr2f
+#define un_m_distance2r un_m_distance2f
+#define un_m_distance_sqr2r un_m_distance_sqr2f
+
+/* 3d real */
+#define un_m_add3r un_m_add3f
+#define un_m_sub3r un_m_sub3f
+
+#define un_m_add_scalar3r un_m_add_scalar3f
+#define un_m_sub_scalar3r un_m_sub_scalar3f
+#define un_m_mul_scalar3r un_m_mul_scalar3f
+#define un_m_div_scalar3r un_m_div_scalar3f
+
+#define un_m_dot3r un_m_dot3f
+#define un_m_hadamard3r un_m_hadamard3f
+#define un_m_project3r un_m_project3f
+#define un_m_reflect3r un_m_reflect3f
+#define un_m_cross3r un_m_cross3f
+
+#define un_m_normalize3r un_m_normalize3f
+#define un_m_magnitude3r un_m_magnitude3f
+#define un_m_magnitude_sqr3r un_m_magnitude_sqr3f
+#define un_m_distance3r un_m_distance3f
+#define un_m_distance_sqr3r un_m_distance_sqr3f
+
+/* 4d real */
+#define un_m_add4r un_m_add4f
+#define un_m_sub4r un_m_sub4f
+
+#define un_m_add_scalar4r un_m_add_scalar4f
+#define un_m_sub_scalar4r un_m_sub_scalar4f
+#define un_m_mul_scalar4r un_m_mul_scalar4f
+#define un_m_div_scalar4r un_m_div_scalar4f
-void un_m_bezierr(real *v, real a, real q0, real q1, real b, real t);
-void un_m_bezier2r(real *v, real *a, real *q0, real *q1, real *b, real t);
-void un_m_bezier3r(real *v, real *a, real *q0, real *q1, real *b, real t);
-void un_m_bezier4r(real *v, real *a, real *q0, real *q1, real *b, real t);
+#define un_m_dot4r un_m_dot4f
+#define un_m_hadamard4r un_m_hadamard4f
+#define un_m_project4r un_m_project4f
+#define un_m_reflect4r un_m_reflect4f
+
+#define un_m_normalize4r un_m_normalize4f
+#define un_m_magnitude4r un_m_magnitude4f
+#define un_m_magnitude_sqr4r un_m_magnitude_sqr4f
+#define un_m_distance4r un_m_distance4f
+#define un_m_distance_sqr4r un_m_distance_sqr4f
+
+#endif // UN_DOUBLE_PRECISION
+
+/* ---- complex ---- */
+
+#define un_m_complex_addf un_m_add2f
+#define un_m_complex_subf un_m_sub2f
+extern void un_m_complex_divf(f32 *v, f32 *a, f32 *b);
+extern void un_m_complex_mulf(f32 *v, f32 *a, f32 *b);
+
+#define un_m_complex_addd un_m_add2d
+#define un_m_complex_subd un_m_sub2d
+extern void un_m_complex_divd(f64 *v, f64 *a, f64 *b);
+extern void un_m_complex_muld(f64 *v, f64 *a, f64 *b);
+
+#define un_m_complex_magnitudef un_m_magnitude2f
+#define un_m_complex_magnituded un_m_magnitude2d
+
+#if defined(UN_DOUBLE_PRECISION)
+#define un_m_complex_addr un_m_complex_addd
+#define un_m_complex_subr un_m_complex_subd
+#define un_m_complex_divr un_m_complex_divd
+#define un_m_complex_mulr un_m_complex_muld
+#define un_m_complex_magnituder un_m_complex_magnituded
+#else
+#define un_m_complex_addr un_m_complex_addf
+#define un_m_complex_subr un_m_complex_subf
+#define un_m_complex_divr un_m_complex_divf
+#define un_m_complex_mulr un_m_complex_mulf
+#define un_m_complex_magnituder un_m_complex_magnitudef
+#endif // UN_DOUBLE_PRECISION
+
+/* ---- splines ---- */
void un_m_bezierf(f32 *v, f32 a, f32 q0, f32 q1, f32 b, f32 t);
void un_m_bezier2f(f32 *v, f32 *a, f32 *q0, f32 *q1, f32 *b, f32 t);
@@ -435,28 +542,60 @@ void un_m_bezier2d(f64 *v, f64 *a, f64 *q0, f64 *q1, f64 *b, f64 t);
void un_m_bezier3d(f64 *v, f64 *a, f64 *q0, f64 *q1, f64 *b, f64 t);
void un_m_bezier4d(f64 *v, f64 *a, f64 *q0, f64 *q1, f64 *b, f64 t);
+#if defined(UN_DOUBLE_PRECISION)
+#define un_m_bezierr un_m_bezierd
+#define un_m_bezier2r un_m_bezier2d
+#define un_m_bezier3r un_m_bezier3d
+#define un_m_bezier4r un_m_bezier4d
+#else
+#define un_m_bezierr un_m_bezierf
+#define un_m_bezier2r un_m_bezier2f
+#define un_m_bezier3r un_m_bezier3f
+#define un_m_bezier4r un_m_bezier4f
+#endif // UN_DOUBLE_PRECISION
+
/* ---- easing ---- */
-real un_m_ease_isiner(real t);
-real un_m_ease_iosiner(real t);
-real un_m_ease_osiner(real t);
-real un_m_ease_iquadr(real t);
-real un_m_ease_ioquadr(real t);
-real un_m_ease_oquadr(real t);
+extern f32 un_m_ease_isinef(f32 t);
+extern f32 un_m_ease_iosinef(f32 t);
+extern f32 un_m_ease_osinef(f32 t);
+extern f32 un_m_ease_iquadf(f32 t);
+extern f32 un_m_ease_ioquadf(f32 t);
+extern f32 un_m_ease_oquadf(f32 t);
+
+extern f64 un_m_ease_isined(f64 t);
+extern f64 un_m_ease_iosined(f64 t);
+extern f64 un_m_ease_osined(f64 t);
+extern f64 un_m_ease_iquadd(f64 t);
+extern f64 un_m_ease_ioquadd(f64 t);
+extern f64 un_m_ease_oquadd(f64 t);
+
+#if defined(UN_DOUBLE_PRECISION)
+#define un_m_ease_isiner un_m_ease_isined
+#define un_m_ease_iosiner un_m_ease_iosined
+#define un_m_ease_osiner un_m_ease_osined
+#define un_m_ease_iquadr un_m_ease_iquadd
+#define un_m_ease_ioquadr un_m_ease_ioquadd
+#define un_m_ease_oquadr un_m_ease_oquadd
+#else
+#define un_m_ease_isiner un_m_ease_isinef
+#define un_m_ease_iosiner un_m_ease_iosinef
+#define un_m_ease_osiner un_m_ease_osinef
+#define un_m_ease_iquadr un_m_ease_iquadf
+#define un_m_ease_ioquadr un_m_ease_ioquadf
+#define un_m_ease_oquadr un_m_ease_oquadf
+#endif // UN_DOUBLE_PRECISION
+
+/* --- matrix ----
+ * Convention of matrices!
+ * column-major matrices and all matrices are 4x4.
+ */
-f32 un_m_ease_isinef(f32 t);
-f32 un_m_ease_iosinef(f32 t);
-f32 un_m_ease_osinef(f32 t);
-f32 un_m_ease_iquadf(f32 t);
-f32 un_m_ease_ioquadf(f32 t);
-f32 un_m_ease_oquadf(f32 t);
+#define UN_MATRIX_SIZE (16)
+#define UN_MATRIX_STRIPE (4)
-f64 un_m_ease_isined(f64 t);
-f64 un_m_ease_iosined(f64 t);
-f64 un_m_ease_osined(f64 t);
-f64 un_m_ease_iquadd(f64 t);
-f64 un_m_ease_ioquadd(f64 t);
-f64 un_m_ease_oquadd(f64 t);
+extern void un_m_mat_mulf(f32 *v, f32 *left, f32 *right);
+extern void un_m_mat_identityf(f32 *v);
#if defined(__cplusplus)
}