System info & network
This commit is contained in:
12
code/lib/all.h
Normal file
12
code/lib/all.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef _PIUMA_LIB_ALL_H_
|
||||
#define _PIUMA_LIB_ALL_H_
|
||||
|
||||
#include "types.h"
|
||||
#include "ds.h"
|
||||
#include "queue.h"
|
||||
#include "math.h"
|
||||
#include "geometry.h"
|
||||
#include "color.h"
|
||||
#include "text.h"
|
||||
|
||||
#endif
|
||||
26
code/lib/bits.h
Normal file
26
code/lib/bits.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef _PIUMA_LIB_BITS_H_
|
||||
#define _PIUMA_LIB_BITS_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
inline u32 bits_endian_swap(u32 x)
|
||||
{
|
||||
return
|
||||
(x << 24 ) |
|
||||
(x << 8 & 0x00FF0000) |
|
||||
(x >> 8 & 0x0000FF00) |
|
||||
(x >> 24 );
|
||||
}
|
||||
|
||||
inline u32 bits_reverse(u32 x)
|
||||
{
|
||||
u32 result = 0;
|
||||
for(int i = 0; i < 32; i++)
|
||||
{
|
||||
result = result << 1 | (x & 1);
|
||||
x = x >> 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
25
code/lib/color.h
Normal file
25
code/lib/color.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#ifndef _PIUMA_LIB_COLOR_H_
|
||||
#define _PIUMA_LIB_COLOR_H_
|
||||
|
||||
#include "math.h"
|
||||
#include "types.h"
|
||||
|
||||
inline u32 convert_color_to_ABGR_u32(v4 color)
|
||||
{
|
||||
u32 r = 0xFF * color.r;
|
||||
u32 g = 0xFF * color.g;
|
||||
u32 b = 0xFF * color.b;
|
||||
u32 a = 0xFF * color.a;
|
||||
return (a << 24) | (b << 16) | (g << 8) | (r);
|
||||
}
|
||||
|
||||
inline v4 convert_ABGR_u32_to_color(u32 color)
|
||||
{
|
||||
f32 r = (f32)((color >> 0) & 0xFF) / (f32)(0xFF);
|
||||
f32 g = (f32)((color >> 8) & 0xFF) / (f32)(0xFF);
|
||||
f32 b = (f32)((color >> 16) & 0xFF) / (f32)(0xFF);
|
||||
f32 a = (f32)((color >> 24) & 0xFF) / (f32)(0xFF);
|
||||
return v4{r, g, b, a};
|
||||
}
|
||||
|
||||
#endif
|
||||
87
code/lib/ds.cpp
Normal file
87
code/lib/ds.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#include "ds.h"
|
||||
#include <string.h>
|
||||
|
||||
int char_cmp(const void *a, const void *b)
|
||||
{
|
||||
char _a = *(char*)a;
|
||||
char _b = *(char*)b;
|
||||
if(_a < _b) return -1;
|
||||
if(_a > _b) return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int u8_cmp (const void *a, const void *b)
|
||||
{
|
||||
u8 _a = *(u8*)a;
|
||||
u8 _b = *(u8*)b;
|
||||
if(_a < _b) return -1;
|
||||
if(_a > _b) return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int u32_cmp(const void *a, const void *b)
|
||||
{
|
||||
u32 _a = *(u32*)a;
|
||||
u32 _b = *(u32*)b;
|
||||
if(_a < _b) return -1;
|
||||
if(_a > _b) return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int u64_cmp(const void *a, const void *b)
|
||||
{
|
||||
u64 _a = *(u64*)a;
|
||||
u64 _b = *(u64*)b;
|
||||
if(_a < _b) return -1;
|
||||
if(_a > _b) return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int s32_cmp(const void *a, const void *b)
|
||||
{
|
||||
s32 _a = *(s32*)a;
|
||||
s32 _b = *(s32*)b;
|
||||
if(_a < _b) return -1;
|
||||
if(_a > _b) return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int s64_cmp(const void *a, const void *b)
|
||||
{
|
||||
s64 _a = *(s64*)a;
|
||||
s64 _b = *(s64*)b;
|
||||
if(_a < _b) return -1;
|
||||
if(_a > _b) return +1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
u64 make_unique(void *array, u64 count, u64 element_size, compare_fn *cmp)
|
||||
{
|
||||
qsort(array, count, element_size, cmp);
|
||||
|
||||
// Remove duplicates
|
||||
u8 *start = (u8*)array;
|
||||
u8 *end = start + element_size * count;
|
||||
|
||||
u64 deleted = 0;
|
||||
|
||||
u8 *prev = start;
|
||||
u8 *curr = start + element_size;
|
||||
while(curr < end)
|
||||
{
|
||||
if(cmp(prev, curr) == 0)
|
||||
{
|
||||
deleted++;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev += element_size;
|
||||
memcpy(prev, curr, element_size);
|
||||
}
|
||||
curr += element_size;
|
||||
}
|
||||
|
||||
return count - deleted;
|
||||
}
|
||||
29
code/lib/ds.h
Normal file
29
code/lib/ds.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef _PIUMA_LIB_DS_H_
|
||||
#define _PIUMA_LIB_DS_H_
|
||||
|
||||
#include "types.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
typedef int compare_fn(const void *, const void *);
|
||||
|
||||
// Basic compare functions
|
||||
int char_cmp(const void *a, const void *b);
|
||||
int u8_cmp (const void *a, const void *b);
|
||||
int u32_cmp(const void *a, const void *b);
|
||||
int u64_cmp(const void *a, const void *b);
|
||||
int s32_cmp(const void *a, const void *b);
|
||||
int s64_cmp(const void *a, const void *b);
|
||||
|
||||
// Modifies "array" and returns the number of unique things
|
||||
u64 make_unique(void *array, u64 count, u64 element_size, compare_fn *cmp);
|
||||
|
||||
// @Cleanup: put this in the right place
|
||||
template<typename T>
|
||||
void swap(T &a, T &b)
|
||||
{
|
||||
T tmp = a;
|
||||
a = b;
|
||||
b = tmp;
|
||||
}
|
||||
|
||||
#endif
|
||||
220
code/lib/event.h
Normal file
220
code/lib/event.h
Normal file
@@ -0,0 +1,220 @@
|
||||
#ifndef _PIUMA_LIB_EVENT_H_
|
||||
#define _PIUMA_LIB_EVENT_H_
|
||||
|
||||
#include "types.h"
|
||||
#include "math.h"
|
||||
|
||||
// Mouse events
|
||||
// Keyboard events
|
||||
// Window events (resize, hide, focus)
|
||||
// Quit
|
||||
// Other OS events (signals?)
|
||||
|
||||
|
||||
enum Event_Type
|
||||
{
|
||||
EVENT_NONE,
|
||||
|
||||
EVENT_QUIT,
|
||||
|
||||
EVENT_MOUSE_MOVE,
|
||||
EVENT_KEY,
|
||||
|
||||
EVENT_RESIZE,
|
||||
EVENT_FOCUS,
|
||||
EVENT_UNFOCUS,
|
||||
|
||||
EVENT_TEXT,
|
||||
|
||||
EVENT_COUNT
|
||||
};
|
||||
|
||||
|
||||
|
||||
// @Performance: a lot of this codes are sequential in Linux. Check with other OSs if that's the case. If it is, we can have faster mapping by subtracting and adding an offset.
|
||||
enum Key_Code
|
||||
{
|
||||
KEY_UNKNOWN = 0,
|
||||
|
||||
// @Correctness: check all ascii characters that are on a keyboard
|
||||
KEY_ENTER = '\r',
|
||||
KEY_ESCAPE = '\e',
|
||||
KEY_BACKSPACE = '\b',
|
||||
KEY_TAB = '\t',
|
||||
KEY_SPACE = ' ',
|
||||
KEY_EXCLAMATION = '!',
|
||||
KEY_DOUBLE_QUOTE = '"',
|
||||
KEY_HASH = '#',
|
||||
KEY_PERCENT = '%',
|
||||
KEY_DOLLAR = '$',
|
||||
KEY_AMPERSAND = '&',
|
||||
KEY_SINGLE_QUOTE = '\'',
|
||||
KEY_LEFT_PARENTHESIS = '(',
|
||||
KEY_RIGHT_PARENTHESIS = ')',
|
||||
KEY_ASTERISK = '*',
|
||||
KEY_PLUS = '+',
|
||||
KEY_COMMA = ',',
|
||||
KEY_MINUS = '-',
|
||||
KEY_PERIOD = '.',
|
||||
KEY_SLASH = '/',
|
||||
KEY_0 = '0',
|
||||
KEY_1 = '1',
|
||||
KEY_2 = '2',
|
||||
KEY_3 = '3',
|
||||
KEY_4 = '4',
|
||||
KEY_5 = '5',
|
||||
KEY_6 = '6',
|
||||
KEY_7 = '7',
|
||||
KEY_8 = '8',
|
||||
KEY_9 = '9',
|
||||
KEY_COLON = ':',
|
||||
KEY_SEMICOLON = ';',
|
||||
KEY_LESS = '<',
|
||||
KEY_EQUALS = '=',
|
||||
KEY_GREATER = '>',
|
||||
KEY_QUESTION = '?',
|
||||
KEY_AT = '@',
|
||||
KEY_LEFT_BRACKET = '[',
|
||||
KEY_RIGHT_BRACKET = ']',
|
||||
KEY_BACKSLASH = '\\',
|
||||
KEY_CARET = '^',
|
||||
KEY_UNDERSCORE = '_',
|
||||
KEY_BACKQUOTE = '`',
|
||||
KEY_A = 'A',
|
||||
KEY_B = 'B',
|
||||
KEY_C = 'C',
|
||||
KEY_D = 'D',
|
||||
KEY_E = 'E',
|
||||
KEY_F = 'F',
|
||||
KEY_G = 'G',
|
||||
KEY_H = 'H',
|
||||
KEY_I = 'I',
|
||||
KEY_J = 'J',
|
||||
KEY_K = 'K',
|
||||
KEY_L = 'L',
|
||||
KEY_M = 'M',
|
||||
KEY_N = 'N',
|
||||
KEY_O = 'O',
|
||||
KEY_P = 'P',
|
||||
KEY_Q = 'Q',
|
||||
KEY_R = 'R',
|
||||
KEY_S = 'S',
|
||||
KEY_T = 'T',
|
||||
KEY_U = 'U',
|
||||
KEY_V = 'V',
|
||||
KEY_W = 'W',
|
||||
KEY_X = 'X',
|
||||
KEY_Y = 'Y',
|
||||
KEY_Z = 'Z',
|
||||
|
||||
KEY_CAPSLOCK = 1000,
|
||||
KEY_F1,
|
||||
KEY_F2,
|
||||
KEY_F3,
|
||||
KEY_F4,
|
||||
KEY_F5,
|
||||
KEY_F6,
|
||||
KEY_F7,
|
||||
KEY_F8,
|
||||
KEY_F9,
|
||||
KEY_F10,
|
||||
KEY_F11,
|
||||
KEY_F12,
|
||||
|
||||
KEY_PRINTSCREEN,
|
||||
KEY_SCROLLLOCK,
|
||||
KEY_PAUSE,
|
||||
KEY_INSERT,
|
||||
KEY_DELETE,
|
||||
|
||||
KEY_HOME,
|
||||
KEY_END,
|
||||
KEY_PAGEUP,
|
||||
KEY_PAGEDOWN,
|
||||
|
||||
KEY_ARROW_UP,
|
||||
KEY_ARROW_DOWN,
|
||||
KEY_ARROW_LEFT,
|
||||
KEY_ARROW_RIGHT,
|
||||
|
||||
KEY_NUMLOCK,
|
||||
KEY_PAD_DIVIDE,
|
||||
KEY_PAD_MULTIPLY,
|
||||
KEY_PAD_MINUS,
|
||||
KEY_PAD_PLUS,
|
||||
KEY_PAD_ENTER,
|
||||
KEY_PAD_1,
|
||||
KEY_PAD_2,
|
||||
KEY_PAD_3,
|
||||
KEY_PAD_4,
|
||||
KEY_PAD_5,
|
||||
KEY_PAD_6,
|
||||
KEY_PAD_7,
|
||||
KEY_PAD_8,
|
||||
KEY_PAD_9,
|
||||
KEY_PAD_0,
|
||||
KEY_PAD_PERIOD,
|
||||
|
||||
KEY_LEFT_CTRL,
|
||||
KEY_RIGHT_CTRL,
|
||||
KEY_LEFT_SHIFT,
|
||||
KEY_RIGHT_SHIFT,
|
||||
KEY_LEFT_ALT,
|
||||
KEY_RIGHT_ALT,
|
||||
|
||||
KEY_MOUSE_LEFT,
|
||||
KEY_MOUSE_MIDDLE,
|
||||
KEY_MOUSE_RIGHT,
|
||||
KEY_MOUSE_WHEEL_UP,
|
||||
KEY_MOUSE_WHEEL_DOWN,
|
||||
KEY_MOUSE_4,
|
||||
KEY_MOUSE_5,
|
||||
|
||||
// @Correctness: check for more keys in: USB spec, linux libinput/x11/wayland/whatever, windows win32
|
||||
};
|
||||
|
||||
struct Event_Key
|
||||
{
|
||||
bool pressed;
|
||||
Key_Code key_code;
|
||||
};
|
||||
|
||||
|
||||
struct Event_Mouse_Move
|
||||
{
|
||||
bool relative;
|
||||
union
|
||||
{
|
||||
v2 position;
|
||||
v2 delta;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
struct Event_Resize
|
||||
{
|
||||
s32 width, height;
|
||||
};
|
||||
|
||||
|
||||
struct Event_Text
|
||||
{
|
||||
char data[16]; // @Correctness: We have a bug if the os sends text that is longer
|
||||
};
|
||||
|
||||
|
||||
struct Event
|
||||
{
|
||||
Event_Type type;
|
||||
|
||||
union
|
||||
{
|
||||
Event_Key key;
|
||||
Event_Mouse_Move mouse_move;
|
||||
Event_Resize resize;
|
||||
Event_Text text;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
319
code/lib/geometry.h
Normal file
319
code/lib/geometry.h
Normal file
@@ -0,0 +1,319 @@
|
||||
#ifndef _PIUMA_LIB_GEOMETRY_H_
|
||||
#define _PIUMA_LIB_GEOMETRY_H_
|
||||
|
||||
#include "types.h"
|
||||
#include "math.h"
|
||||
|
||||
// Rect
|
||||
union Rect
|
||||
{
|
||||
struct
|
||||
{
|
||||
f32 x, y;
|
||||
f32 w, h;
|
||||
};
|
||||
struct
|
||||
{
|
||||
v2 position; // Usually, the top-left corner of the rectangle
|
||||
v2 size;
|
||||
};
|
||||
};
|
||||
|
||||
inline bool is_inside(Rect rect, v2 p)
|
||||
{
|
||||
bool in_range_x = rect.x <= p.x && p.x <= (rect.x + rect.w);
|
||||
bool in_range_y = rect.y <= p.y && p.y <= (rect.y + rect.h);
|
||||
return in_range_x && in_range_y;
|
||||
}
|
||||
|
||||
// @Feature: add Cube/Parallelepiped? Unlike Box, it has rotations
|
||||
// Box
|
||||
struct Box
|
||||
{
|
||||
v3 min;
|
||||
v3 max;
|
||||
};
|
||||
|
||||
inline bool is_inside(Box b, v3 p)
|
||||
{
|
||||
return
|
||||
(p.x < b.min.x || p.x > b.max.x) ||
|
||||
(p.y < b.min.y || p.y > b.max.y) ||
|
||||
(p.z < b.min.z || p.z > b.max.z);
|
||||
}
|
||||
|
||||
inline bool overlaps(Box a, Box b)
|
||||
{
|
||||
if(a.min.x > b.max.x) // no overlap
|
||||
return false;
|
||||
if(a.max.x < b.min.x) // no overlap
|
||||
return false;
|
||||
if(a.min.y > b.max.y) // no overlap
|
||||
return false;
|
||||
if(a.max.y < b.min.y) // no overlap
|
||||
return false;
|
||||
if(a.min.z > b.max.z) // no overlap
|
||||
return false;
|
||||
if(a.max.z < b.min.z) // no overlap
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline Box box_from_point_cloud(v3 *points, u32 count)
|
||||
{
|
||||
if(count == 0)
|
||||
return Box{.min = {0,0,0}, .max = {0,0,0}};
|
||||
|
||||
Box box;
|
||||
box.min = points[0];
|
||||
box.max = points[0];
|
||||
for(u32 i = 0; i < count; i++)
|
||||
{
|
||||
v3 p = points[i];
|
||||
box.min.x = minimum(box.min.x, p.x);
|
||||
box.min.y = minimum(box.min.y, p.y);
|
||||
box.min.z = minimum(box.min.z, p.z);
|
||||
box.max.x = maximum(box.max.x, p.x);
|
||||
box.max.y = maximum(box.max.y, p.y);
|
||||
box.max.z = maximum(box.max.z, p.z);
|
||||
}
|
||||
return box;
|
||||
}
|
||||
|
||||
inline v3 box_closest_point(Box b, v3 point);
|
||||
inline f32 box_SDF(Box b, v3 point, v3* res_closest = NULL)
|
||||
{
|
||||
v3 closest = box_closest_point(b, point);
|
||||
f32 sign = -1 * is_inside(b, point);
|
||||
|
||||
if(res_closest)
|
||||
*res_closest = closest;
|
||||
return sign * distance(closest, point);
|
||||
}
|
||||
|
||||
|
||||
// Ray
|
||||
struct Ray
|
||||
{
|
||||
v3 position;
|
||||
v3 direction;
|
||||
};
|
||||
|
||||
|
||||
// Circle
|
||||
// @Cleanup: Should Circle be merged with Sphere?
|
||||
struct Circle
|
||||
{
|
||||
v2 center;
|
||||
f32 radius;
|
||||
};
|
||||
|
||||
inline bool is_inside(Circle c, v2 p)
|
||||
{
|
||||
v2 v = p - c.center;
|
||||
return dot(v, v) <= square(c.radius);
|
||||
}
|
||||
|
||||
// Sphere
|
||||
struct Sphere
|
||||
{
|
||||
v3 center;
|
||||
f32 radius;
|
||||
};
|
||||
|
||||
inline bool is_inside(Sphere s, v3 p)
|
||||
{
|
||||
v3 v = p - s.center;
|
||||
return dot(v, v) <= square(s.radius); // distance² <= radius²
|
||||
}
|
||||
|
||||
inline f32 sphere_SDF(Sphere s, v3 point)
|
||||
{
|
||||
return distance(s.center, point) - s.radius;
|
||||
}
|
||||
|
||||
|
||||
// Segment
|
||||
struct Segment
|
||||
{
|
||||
v3 a;
|
||||
v3 b;
|
||||
};
|
||||
|
||||
|
||||
// Plane
|
||||
struct Plane
|
||||
{
|
||||
v3 normal;
|
||||
f32 offset;
|
||||
};
|
||||
|
||||
inline f32 plane_SDF(Plane plane, v3 point)
|
||||
{
|
||||
f32 projected = dot(point, plane.normal);
|
||||
return plane.offset - projected;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Projections
|
||||
inline f32 project_point_on_vector(v3 vector, v3 point)
|
||||
{
|
||||
return dot(vector, point);
|
||||
}
|
||||
|
||||
inline v3 project_point_on_plane(Plane plane, v3 point)
|
||||
{
|
||||
f32 distance = plane_SDF(plane, point);
|
||||
return point - plane.normal * distance;
|
||||
}
|
||||
|
||||
|
||||
// Closest point
|
||||
inline v3 segment_closest_point(Segment seg, v3 point)
|
||||
{
|
||||
v3 ab = seg.b - seg.a;
|
||||
v3 ap = point - seg.a;
|
||||
f32 u = dot(ab, ap);
|
||||
return seg.a + ab * clamp(0.0, 1.0, u);
|
||||
}
|
||||
|
||||
inline v3 box_closest_point(Box b, v3 point)
|
||||
{
|
||||
v3 closest;
|
||||
// Closest point on the box is the one with coords closer to the ones of the point,
|
||||
// so for each axis we can clamp to the nearest point of the border.
|
||||
|
||||
f32 dx1 = abs(b.min.x - point.x);
|
||||
f32 dx2 = abs(b.max.x - point.x);
|
||||
closest.x = (dx1 < dx2) ? b.min.x : b.max.x;
|
||||
f32 dy1 = abs(b.min.y - point.y);
|
||||
f32 dy2 = abs(b.max.y - point.y);
|
||||
closest.y = (dy1 < dy2) ? b.min.y : b.max.y;
|
||||
f32 dz1 = abs(b.min.z - point.z);
|
||||
f32 dz2 = abs(b.max.z - point.z);
|
||||
closest.z = (dz1 < dz2) ? b.min.z : b.max.z;
|
||||
|
||||
return closest;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Triangles functions
|
||||
inline v3 triangle_normal(v3 a, v3 b, v3 c)
|
||||
{
|
||||
v3 ba = b - a;
|
||||
v3 ca = c - a;
|
||||
v3 orthogonal = cross(ba, ca);
|
||||
return normalize(orthogonal);
|
||||
}
|
||||
|
||||
|
||||
// Transformations (all angles in radians)
|
||||
inline m4 rotation_x(f32 angle)
|
||||
{
|
||||
f32 c = cos(angle);
|
||||
f32 s = sin(angle);
|
||||
|
||||
m4 result = m4_identity;
|
||||
result.E[1][1] = c;
|
||||
result.E[1][2] = -s;
|
||||
result.E[2][1] = s;
|
||||
result.E[2][2] = c;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline m4 rotation_y(f32 angle)
|
||||
{
|
||||
f32 c = cos(angle);
|
||||
f32 s = sin(angle);
|
||||
|
||||
m4 result = m4_identity;
|
||||
result.E[0][0] = c;
|
||||
result.E[0][2] = s;
|
||||
result.E[2][0] = -s;
|
||||
result.E[2][2] = c;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline m4 rotation_z(f32 angle)
|
||||
{
|
||||
f32 c = cos(angle);
|
||||
f32 s = sin(angle);
|
||||
|
||||
m4 result = m4_identity;
|
||||
result.E[0][0] = c;
|
||||
result.E[0][1] = -s;
|
||||
result.E[1][0] = s;
|
||||
result.E[1][1] = c;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline m4 rotation(f32 x, f32 y, f32 z)
|
||||
{
|
||||
return rotation_z(z) * rotation_y(y) * rotation_x(x);
|
||||
}
|
||||
|
||||
inline m4 rotation_v3(v3 angle)
|
||||
{
|
||||
return rotation(angle.x, angle.y, angle.z);
|
||||
}
|
||||
|
||||
|
||||
inline m4 translation(f32 x, f32 y, f32 z)
|
||||
{
|
||||
m4 result = m4_identity;
|
||||
|
||||
result.E[0][3] = x;
|
||||
result.E[1][3] = y;
|
||||
result.E[2][3] = z;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline m4 translation_v3(v3 t)
|
||||
{
|
||||
return translation(t.x, t.y, t.z);
|
||||
}
|
||||
|
||||
inline m4 scale(f32 x, f32 y, f32 z)
|
||||
{
|
||||
m4 result = m4_zero;
|
||||
|
||||
result.E[0][0] = x;
|
||||
result.E[1][1] = y;
|
||||
result.E[2][2] = z;
|
||||
result.E[3][3] = 1.0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline m4 scale_v3(v3 factor)
|
||||
{
|
||||
return scale(factor.x, factor.y, factor.z);
|
||||
}
|
||||
|
||||
inline m4 scale(f32 factor)
|
||||
{
|
||||
return scale(factor, factor, factor);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Primitives
|
||||
// Pass array of 8 elements to fill with coordinates
|
||||
inline void build_cube_vertices(v3 *vertices)
|
||||
{
|
||||
for(int x = 0; x < 2; x++)
|
||||
for(int y = 0; y < 2; y++)
|
||||
for(int z = 0; z < 2; z++)
|
||||
vertices[x*2*2 + y*2 + z] = v3{.x = x - 0.5f, .y = y - 0.5f, .z = z - 0.5f};
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
97
code/lib/hashing.h
Normal file
97
code/lib/hashing.h
Normal file
@@ -0,0 +1,97 @@
|
||||
#ifndef _PIUMA_LIB_HASHING_H_
|
||||
#define _PIUMA_LIB_HASHING_H_
|
||||
|
||||
//#include "bits.h"
|
||||
|
||||
static const u32 hash_crc32_table[256] = {
|
||||
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
|
||||
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
|
||||
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
|
||||
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
|
||||
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
|
||||
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
|
||||
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
|
||||
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
|
||||
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
|
||||
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
|
||||
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
|
||||
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
|
||||
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
|
||||
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
|
||||
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
|
||||
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
|
||||
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
|
||||
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
|
||||
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
|
||||
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
|
||||
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
|
||||
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
|
||||
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
|
||||
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
|
||||
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
|
||||
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
|
||||
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
|
||||
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
|
||||
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
|
||||
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
|
||||
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
|
||||
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
|
||||
};
|
||||
|
||||
/*
|
||||
// Code to compute the lookup table for CRC32
|
||||
// table needs 256 spaces
|
||||
static const u32 hash_crc32_polynomial = 0x04C11DB7;
|
||||
inline void hash_crc32_make_table(u32 *table)
|
||||
{
|
||||
u32 polynomial = bits_reverse(hash_crc32_polynomial);
|
||||
for(u32 byte = 0; byte <= 0xFF; byte++)
|
||||
{
|
||||
u32 crc = byte;
|
||||
for(u8 bit = 0; bit < 8; bit++)
|
||||
{
|
||||
if(crc & 1)
|
||||
crc = (crc >> 1) ^ polynomial;
|
||||
else
|
||||
crc = (crc >> 1);
|
||||
}
|
||||
table[byte] = crc;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
inline u32 hash_crc32(const void *data, u64 size, u32 seed = 0xFFFFFFFF)
|
||||
{
|
||||
u32 crc = seed;
|
||||
u8 *d = (u8*)data;
|
||||
while(size--)
|
||||
{
|
||||
crc = hash_crc32_table[(crc & 0xFF) ^ *d] ^ (crc >> 8);
|
||||
d++;
|
||||
}
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
/*
|
||||
// Simpler code to compute CRC32, one bit at a time.
|
||||
// The version with the lookup table computes 8 bit at a time.
|
||||
inline u32 hash_crc32(const void *data, u64 size, u32 seed = 0xFFFFFFFF)
|
||||
{
|
||||
u8 *d = (u8*)data;
|
||||
u32 crc = seed;
|
||||
while(size--)
|
||||
{
|
||||
crc = crc ^ (*d++ << 24);
|
||||
for(int i = 0; i < 8; i++)
|
||||
{
|
||||
if(crc & (1L<<31))
|
||||
crc = (crc << 1) ^ hash_crc32_polynomial;
|
||||
else
|
||||
crc = (crc << 1);
|
||||
}
|
||||
}
|
||||
return bits_endian_swap(~crc);
|
||||
}
|
||||
*/
|
||||
|
||||
#endif
|
||||
1432
code/lib/math.h
Normal file
1432
code/lib/math.h
Normal file
File diff suppressed because it is too large
Load Diff
10
code/lib/memory.h
Normal file
10
code/lib/memory.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef _PIUMA_LIB_MEMORY_H_
|
||||
#define _PIUMA_LIB_MEMORY_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
typedef void *(*alloc_t)(size_t size);
|
||||
typedef void *(*realloc_t)(void *ptr, size_t size);
|
||||
typedef void (*free_t)(void *ptr);
|
||||
|
||||
#endif
|
||||
93
code/lib/queue.h
Normal file
93
code/lib/queue.h
Normal file
@@ -0,0 +1,93 @@
|
||||
#ifndef _PIUMA_LIB_QUEUE_H_
|
||||
#define _PIUMA_LIB_QUEUE_H_
|
||||
|
||||
#include "types.h"
|
||||
#include <assert.h>
|
||||
|
||||
struct queue_header
|
||||
{
|
||||
u64 start;
|
||||
u64 size;
|
||||
|
||||
u64 capacity;
|
||||
};
|
||||
|
||||
|
||||
#define QUEUE_HEADER_PTR(queue) ((queue_header *)(((u8*)queue) - sizeof(queue_header)))
|
||||
|
||||
#define QUEUE_TYPE(type) type *
|
||||
#define Queue_Alloc(alloc_func, type, capacity) ((type*) _queue_alloc(alloc_func, sizeof(type), capacity))
|
||||
#define Queue_Free(free_func, queue) free_func(QUEUE_HEADER_PTR(queue))
|
||||
|
||||
#define Queue_Pop(queue) (queue[_queue_pop_index((u8*)queue)])
|
||||
#define Queue_Push(queue, element) { queue[_queue_at_index((u8*)queue, QUEUE_HEADER_PTR(queue)->size)] = element; _queue_push_fix_indices((u8*)queue); }
|
||||
#define Queue_At(queue, index) (queue[_queue_at_index((u8*)queue, index)])
|
||||
#define Queue_Size(queue) _queue_size((u8*)queue)
|
||||
#define Queue_Capacity(queue) _queue_capacity((u8*)queue)
|
||||
|
||||
|
||||
|
||||
typedef void * (*alloc_func_t)(u64);
|
||||
typedef void (*free_func_t)(void *);
|
||||
|
||||
inline u8 * _queue_alloc(alloc_func_t alloc_func, u64 sizeof_type, u64 capacity)
|
||||
{
|
||||
u8 *data;
|
||||
queue_header *header;
|
||||
|
||||
data = (u8 *)alloc_func(sizeof(queue_header) + sizeof_type * capacity);
|
||||
header = (queue_header *)data;
|
||||
|
||||
header->capacity = capacity;
|
||||
header->start = 0;
|
||||
header->size = 0;
|
||||
|
||||
return data + sizeof(queue_header);
|
||||
}
|
||||
|
||||
inline u64 _queue_pop_index(u8 *queue)
|
||||
{
|
||||
queue_header *header = QUEUE_HEADER_PTR(queue);
|
||||
assert(header->size > 0);
|
||||
|
||||
u64 element_index = header->start;
|
||||
header->start = (header->start + 1) % header->capacity;
|
||||
header->size--;
|
||||
|
||||
return element_index;
|
||||
}
|
||||
|
||||
inline void _queue_push_fix_indices(u8 *queue)
|
||||
{
|
||||
queue_header *header = QUEUE_HEADER_PTR(queue);
|
||||
|
||||
header->size++;
|
||||
if(header->size > header->capacity)
|
||||
{
|
||||
// Queue is full. Remove oldest element
|
||||
header->start = (header->start + 1) % header->capacity;
|
||||
header->size = header->capacity;
|
||||
}
|
||||
}
|
||||
|
||||
inline u64 _queue_at_index(u8 *queue, u64 index)
|
||||
{
|
||||
queue_header *header = QUEUE_HEADER_PTR(queue);
|
||||
|
||||
return (header->start + index) % header->capacity;
|
||||
}
|
||||
|
||||
inline u64 _queue_size(u8 *queue)
|
||||
{
|
||||
queue_header *header = QUEUE_HEADER_PTR(queue);
|
||||
return header->size;
|
||||
}
|
||||
|
||||
inline u64 _queue_capacity(u8 *queue)
|
||||
{
|
||||
queue_header *header = QUEUE_HEADER_PTR(queue);
|
||||
return header->capacity;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
196
code/lib/text.cpp
Normal file
196
code/lib/text.cpp
Normal file
@@ -0,0 +1,196 @@
|
||||
#include "text.h"
|
||||
|
||||
u64 utf8_codepoint_count(const char *s)
|
||||
{
|
||||
u64 count = 0;
|
||||
while(*s)
|
||||
{
|
||||
if(utf8_is_codepoint_start(s))
|
||||
count++;
|
||||
s++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
bool utf8_is_codepoint_start(const char *s)
|
||||
{
|
||||
return (*s & 0b11000000) != 0b10000000;
|
||||
}
|
||||
|
||||
u32 utf8_codepoint_bytes(const char *s)
|
||||
{
|
||||
if(!utf8_is_codepoint_start(s))
|
||||
return 0; // Error: This byte belongs to a previous codepoint
|
||||
|
||||
if((*s & 0b10000000) == 0b00000000) //1 byte codepoint
|
||||
return 1;
|
||||
else if((*s & 0b11100000) == 0b11000000) //2 bytes codepoint
|
||||
return 2;
|
||||
else if((*s & 0b11110000) == 0b11100000) //3 bytes codepoint
|
||||
return 3;
|
||||
else if((*s & 0b11111000) == 0b11110000) //4 bytes codepoint
|
||||
return 4;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If bytes_read returns 0, we either reached the end of the string or there was a decoding error */
|
||||
utf8_codepoint utf8_extract_codepoint(const char *s, u64 current_index, u32 *bytes_read)
|
||||
{
|
||||
s += current_index;
|
||||
// UTF8:
|
||||
// First byte: (0xxxxxxx = 1 byte, 110xxxxx = 2 byte, 1110xxxx = 3 byte, 11110xxx = 4 byte)
|
||||
// Next bytes: 10xxxxxx
|
||||
// To get a Codepoint: concatenate all the xxxx
|
||||
utf8_codepoint codepoint = 0;
|
||||
*bytes_read = 0;
|
||||
u8 next_bytes = 0;
|
||||
|
||||
if(!utf8_is_codepoint_start(s))
|
||||
{
|
||||
// Error: This byte belongs to a previous codepoint
|
||||
return 0;
|
||||
}
|
||||
|
||||
if((*s & 0b10000000) == 0b00000000) //1 byte codepoint
|
||||
{
|
||||
codepoint = *s;
|
||||
next_bytes = 0;
|
||||
}
|
||||
else if((*s & 0b11100000) == 0b11000000) //2 bytes codepoint
|
||||
{
|
||||
codepoint = (*s & 0b00011111);
|
||||
next_bytes = 1;
|
||||
}
|
||||
else if((*s & 0b11110000) == 0b11100000) //3 bytes codepoint
|
||||
{
|
||||
codepoint = (*s & 0b00001111);
|
||||
next_bytes = 2;
|
||||
}
|
||||
else if((*s & 0b11111000) == 0b11110000) //4 bytes codepoint
|
||||
{
|
||||
codepoint = (*s & 0b00000111);
|
||||
next_bytes = 3;
|
||||
}
|
||||
|
||||
for(u8 i = 0; i < next_bytes; i++)
|
||||
{
|
||||
s++;
|
||||
if(*s == 0)
|
||||
{
|
||||
// Error: End of string reached before completing codepoint
|
||||
return 0;
|
||||
}
|
||||
if((*s & 0b11000000) != 0b10000000)
|
||||
{
|
||||
// Error: Byte prefix does not match with the expected one. Broken codepoint
|
||||
return 0;
|
||||
}
|
||||
codepoint = codepoint << 6;
|
||||
codepoint |= (*s & 0b00111111);
|
||||
}
|
||||
*bytes_read = next_bytes + 1;
|
||||
|
||||
return codepoint;
|
||||
}
|
||||
|
||||
u32 utf8_bytes_to_next_valid_codepoint(const char *s, u64 current_index)
|
||||
{
|
||||
s += current_index;
|
||||
u64 bytes = 1;
|
||||
while(*(s + bytes))
|
||||
{
|
||||
if(utf8_is_codepoint_start(s + bytes))
|
||||
break;
|
||||
bytes++;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
u32 utf8_bytes_to_prev_valid_codepoint(const char *s, u64 current_index)
|
||||
{
|
||||
s += current_index;
|
||||
u64 bytes = 0;
|
||||
while(bytes < current_index)
|
||||
{
|
||||
bytes++;
|
||||
if(utf8_is_codepoint_start(s - bytes))
|
||||
break;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
u64 utf8_from_string(const char *s, u64 *bytes_read, utf8_codepoint *result, u64 result_size)
|
||||
{
|
||||
u64 decoded = 0;
|
||||
bytes_read = 0;
|
||||
while(*s && decoded < result_size)
|
||||
{
|
||||
u32 read = 0;
|
||||
result[decoded] = utf8_extract_codepoint(s, 0, &read);
|
||||
if(read == 0)
|
||||
{
|
||||
bytes_read = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
s += read;
|
||||
bytes_read += read;
|
||||
decoded++;
|
||||
}
|
||||
|
||||
return decoded;
|
||||
}
|
||||
|
||||
u64 utf8_to_string(utf8_codepoint *codepoints, u64 count, char *result, u64 result_size)
|
||||
{
|
||||
result_size--; // Reserve space for zero-terminator
|
||||
u64 i = 0;
|
||||
u64 result_i = 0;
|
||||
for(i = 0; i < count; i++)
|
||||
{
|
||||
utf8_codepoint cp = codepoints[i];
|
||||
if((cp & 0xFFFFFF80) == 0) // 1 byte
|
||||
{
|
||||
if(result_i + 1 >= result_size) // Not enought space left
|
||||
break;
|
||||
|
||||
result[result_i++] = cp & 0b01111111;
|
||||
}
|
||||
else if((cp & 0xFFFFF800) == 0) // 2 bytes
|
||||
{
|
||||
if(result_i + 2 >= result_size) // Not enought space left
|
||||
break;
|
||||
|
||||
result[result_i++] = 0b11000000 | ((cp >> 6) & 0b00011111);
|
||||
result[result_i++] = 0b10000000 | ((cp ) & 0b00111111);
|
||||
}
|
||||
else if((cp & 0xFFFF0000) == 0) // 3 bytes
|
||||
{
|
||||
if(result_i + 3 >= result_size) // Not enought space left
|
||||
break;
|
||||
|
||||
result[result_i++] = 0b11100000 | ((cp >> 12) & 0b00001111);
|
||||
result[result_i++] = 0b10000000 | ((cp >> 6) & 0b00111111);
|
||||
result[result_i++] = 0b10000000 | ((cp ) & 0b00111111);
|
||||
}
|
||||
else if((cp & 0xFFE00000) == 0) // 4 bytes
|
||||
{
|
||||
if(result_i + 4 >= result_size) // Not enought space left
|
||||
break;
|
||||
|
||||
result[result_i++] = 0b11110000 | ((cp >> 18) & 0b00000111);
|
||||
result[result_i++] = 0b10000000 | ((cp >> 12) & 0b00111111);
|
||||
result[result_i++] = 0b10000000 | ((cp >> 6) & 0b00111111);
|
||||
result[result_i++] = 0b10000000 | ((cp ) & 0b00111111);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Invalid codepoint
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
result[result_i] = 0;
|
||||
return i;
|
||||
}
|
||||
22
code/lib/text.h
Normal file
22
code/lib/text.h
Normal file
@@ -0,0 +1,22 @@
|
||||
#ifndef _PIUMA_LIB_TEXT_H_
|
||||
#define _PIUMA_LIB_TEXT_H_
|
||||
|
||||
#include "types.h"
|
||||
|
||||
typedef u32 utf8_codepoint;
|
||||
|
||||
u64 utf8_codepoint_count(const char *s);
|
||||
bool utf8_is_codepoint_start(const char *s);
|
||||
u32 utf8_codepoint_bytes(const char *s);
|
||||
/* If bytes_read returns 0, we either reached the end of the string or there was a decoding error */
|
||||
utf8_codepoint utf8_extract_codepoint(const char *s, u64 current_index, u32 *bytes_read);
|
||||
u32 utf8_bytes_to_next_valid_codepoint(const char *s, u64 current_index);
|
||||
u32 utf8_bytes_to_prev_valid_codepoint(const char *s, u64 current_index);
|
||||
|
||||
|
||||
/* Returns the number of codepoints read. If bytes_read returns 0, there was a decoding error */
|
||||
u64 utf8_from_string(const char *s, u64 *bytes_read, utf8_codepoint *result, u64 result_size);
|
||||
/* Returns the number of codepoints written. */
|
||||
u64 utf8_to_string(utf8_codepoint *codepoints, u64 count, char *result, u64 result_size);
|
||||
|
||||
#endif
|
||||
42
code/lib/types.h
Normal file
42
code/lib/types.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef _PIUMA_LIB_TYPES_H_
|
||||
#define _PIUMA_LIB_TYPES_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
|
||||
// Integers
|
||||
typedef int8_t s8;
|
||||
typedef int16_t s16;
|
||||
typedef int32_t s32;
|
||||
typedef int64_t s64;
|
||||
|
||||
typedef uint8_t u8;
|
||||
typedef uint16_t u16;
|
||||
typedef uint32_t u32;
|
||||
typedef uint64_t u64;
|
||||
|
||||
// Real numbers
|
||||
typedef float f32;
|
||||
typedef double f64;
|
||||
|
||||
// Binary
|
||||
typedef u8 b8;
|
||||
typedef u16 b16;
|
||||
typedef u32 b32;
|
||||
typedef u64 b64;
|
||||
|
||||
|
||||
// Buffer
|
||||
struct Buffer
|
||||
{
|
||||
u64 size;
|
||||
u8 *data;
|
||||
};
|
||||
|
||||
struct String
|
||||
{
|
||||
u64 size;
|
||||
u8 *text;
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user