|
|
|
@@ -2,21 +2,21 @@ |
|
|
|
#define CORE_H |
|
|
|
|
|
|
|
// cstdlib includes |
|
|
|
#include <cwchar> |
|
|
|
#include <math.h> |
|
|
|
#include <stdint.h> // necessary for int type sizes |
|
|
|
#include <stdio.h> |
|
|
|
#include <time.h> // TODO(djledda): try not to depend on this one |
|
|
|
#include "math.h" |
|
|
|
#include "stdbool.h" |
|
|
|
#include "stdint.h" // necessary for int type sizes |
|
|
|
#include "stdio.h" |
|
|
|
#include "time.h" // TODO(djledda): try not to depend on this one |
|
|
|
|
|
|
|
// ### Misc macros ### |
|
|
|
// ### Misc macros ### |
|
|
|
#if ENABLE_ASSERT |
|
|
|
#define Assert(expression) if (!(expression)) {*(volatile int *)0 = 0;} |
|
|
|
#else |
|
|
|
#define Assert(expression) |
|
|
|
#define Assert(expression) |
|
|
|
#endif |
|
|
|
|
|
|
|
#define function static |
|
|
|
#define global static |
|
|
|
#define global static |
|
|
|
#define local_persist static |
|
|
|
|
|
|
|
// ### Types ### |
|
|
|
@@ -45,18 +45,20 @@ typedef struct string string; |
|
|
|
#define Billion(n) ((n)*1000000000LL) |
|
|
|
|
|
|
|
#define ArrayCount(arr) (sizeof(arr) / sizeof((arr)[0])) |
|
|
|
#define MemberSize(type, memberName) (sizeof(((type*)0)->data)) |
|
|
|
#define MemberSizeUnderlying(type, memberName) (sizeof(*((type*)0)->data)) |
|
|
|
|
|
|
|
// ### Arenas ### |
|
|
|
struct Arena { |
|
|
|
typedef struct { |
|
|
|
void *memory; |
|
|
|
size_t capacity; |
|
|
|
size_t head; |
|
|
|
}; |
|
|
|
} Arena; |
|
|
|
|
|
|
|
struct Scratch { |
|
|
|
typedef struct { |
|
|
|
Arena *arena; |
|
|
|
size_t start; |
|
|
|
}; |
|
|
|
} Scratch; |
|
|
|
|
|
|
|
void *pushSize(Arena *arena, size_t bytes); |
|
|
|
void *pushSizeFill(Arena *arena, size_t bytes, byte fill); |
|
|
|
@@ -67,8 +69,8 @@ void arenaPopTo(Arena *arena, void *pos); |
|
|
|
|
|
|
|
void initialiseDjStdCore(); |
|
|
|
|
|
|
|
Scratch scratchStart(Arena **conflicts, size_t conflictCount); |
|
|
|
void scratchEnd(Scratch scratch); |
|
|
|
Scratch scratchStart(Arena **conflicts, size_t conflictCount); |
|
|
|
void scratchEnd(Scratch scratch); |
|
|
|
|
|
|
|
#define PushArray(arena, type, size) (type *)pushSize(arena, sizeof(type) * (size)) |
|
|
|
#define PushArrayZero(arena, type, size) (type *)pushSizeFill(arena, sizeof(type) * (size), 0) |
|
|
|
@@ -76,13 +78,13 @@ void scratchEnd(Scratch scratch); |
|
|
|
#define PushStructZero(arena, type) (type *)pushSizeFill(arena, sizeof(type), 0) |
|
|
|
|
|
|
|
// ### Vectors ### |
|
|
|
union Vec2 { |
|
|
|
typedef union { |
|
|
|
struct { |
|
|
|
real32 x; |
|
|
|
real32 y; |
|
|
|
}; |
|
|
|
real32 vec[2]; |
|
|
|
}; |
|
|
|
} Vec2; |
|
|
|
inline function Vec2 vec2(real32 x, real32 y) { |
|
|
|
Vec2 result = {0}; |
|
|
|
result.x = x; |
|
|
|
@@ -90,14 +92,14 @@ inline function Vec2 vec2(real32 x, real32 y) { |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
union Vec3 { |
|
|
|
typedef union { |
|
|
|
struct { |
|
|
|
real32 x; |
|
|
|
real32 y; |
|
|
|
real32 z; |
|
|
|
}; |
|
|
|
real32 vec[3]; |
|
|
|
}; |
|
|
|
} Vec3; |
|
|
|
inline function Vec3 vec3(real32 x, real32 y, real32 z) { |
|
|
|
Vec3 result = {0}; |
|
|
|
result.x = x; |
|
|
|
@@ -106,7 +108,7 @@ inline function Vec3 vec3(real32 x, real32 y, real32 z) { |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
union Vec4 { |
|
|
|
typedef union { |
|
|
|
struct { |
|
|
|
real32 r; |
|
|
|
real32 g; |
|
|
|
@@ -120,7 +122,7 @@ union Vec4 { |
|
|
|
real32 w; |
|
|
|
}; |
|
|
|
real32 vec[4]; |
|
|
|
}; |
|
|
|
} Vec4; |
|
|
|
inline function Vec4 vec4(real32 x, real32 y, real32 z, real32 w) { |
|
|
|
Vec4 result = {0}; |
|
|
|
result.x = x; |
|
|
|
@@ -140,11 +142,11 @@ inline function Vec4 vec4(real32 x, real32 y, real32 z, real32 w) { |
|
|
|
|
|
|
|
DefineList(string, String); |
|
|
|
|
|
|
|
#define PushList(arena, type, size) ((type){ PushArray(arena, type, size), size, 0 }) |
|
|
|
#define PushList(arena, type, size) ((type){ pushSize(arena, MemberSizeUnderlying(type, data)), size, 0 }) |
|
|
|
#define EmptyList(type) ((type){ NULL, 0, 0 }) |
|
|
|
#define PushListZero(arena, type, size) ((type){ PushArrayZero(arena, type, size), size, 0 }) |
|
|
|
#define PushFullList(arena, type, size) ((type){ PushArray(arena, type, size), size, size }) |
|
|
|
#define PushFullListZero(arena, type, size) ((type){ PushArrayZero(arena, type, size), size, size }) |
|
|
|
#define PushListZero(arena, type, size) ((type){ pushSizeFill(arena, MemberSizeUnderlying(type, data), 0), size, 0 }) |
|
|
|
#define PushFullList(arena, type, size) ((type){ pushSize(arena, MemberSizeUnderlying(type, data)), size, size }) |
|
|
|
#define PushFullListZero(arena, type, size) ((type){ pushSizeFill(arena, MemberSizeUnderlying(type, data), 0), size, size }) |
|
|
|
#define ArrayAsList(type, array) ((type){ array, ArrayCount(array), ArrayCount(array) }) |
|
|
|
|
|
|
|
#define AppendList(type, list, element) \ |
|
|
|
@@ -163,58 +165,58 @@ struct string { |
|
|
|
#define STB_SPRINTF_DECORATE(name) stb_##name // define this before including if you want to change the names |
|
|
|
#include "vendor/stb_sprintf.h" |
|
|
|
|
|
|
|
#define s(lit) (string{(char *)(lit), sizeof(lit) - 1}) |
|
|
|
#define PushString(arena, length) (string{ (char *)pushSize(arena, length), (length) }) |
|
|
|
#define PushStringFill(arena, length, characterByte) (string{ (char *)pushSizeFill(arena, length, characterByte), (length) }) |
|
|
|
#define s(lit) ((string){(char *)(lit), sizeof(lit) - 1}) |
|
|
|
#define PushString(arena, length) ((string){ (char *)pushSize(arena, length), (length) }) |
|
|
|
#define PushStringFill(arena, length, characterByte) ((string){ (char *)pushSizeFill(arena, length, characterByte), (length) }) |
|
|
|
|
|
|
|
// C Strings |
|
|
|
DefineList(char, Char); |
|
|
|
const char *cstringFromCharList(Arena *arena, CharList buf); |
|
|
|
const char *cstring(Arena *arena, string str); |
|
|
|
size_t calcStringLen(const char *str); |
|
|
|
string strFromCString(Arena *arena, const char *str); |
|
|
|
const char *cstringFromCharList(Arena *arena, CharList buf); |
|
|
|
const char *cstring(Arena *arena, string str); |
|
|
|
size_t calcStringLen(const char *str); |
|
|
|
string strFromCString(Arena *arena, const char *str); |
|
|
|
|
|
|
|
bool strEql(string s1, string s2); |
|
|
|
bool strEql(string s1, string s2); |
|
|
|
bool strStartsWith(string str, string testStr); |
|
|
|
bool stringContains(string str, char c); |
|
|
|
bool stringContains(string str, char c); |
|
|
|
|
|
|
|
string strReverse(Arena *arena, string str); |
|
|
|
string strSlice(string str, size_t start, size_t stop = 0); |
|
|
|
string strSlice(char *data, size_t start, size_t stop = 0); |
|
|
|
StringList strSplit(Arena *arena, string splitStr, string inputStr); |
|
|
|
string strReverse(Arena *arena, string str); |
|
|
|
string strSlice(string str, size_t start, size_t stop); |
|
|
|
string strSliceCStr(char *data, size_t start, size_t stop); |
|
|
|
StringList strSplit(Arena *arena, string splitStr, string inputStr); |
|
|
|
string strPrintfv(Arena *arena, const char *fmt, va_list args); |
|
|
|
string strPrintf(Arena *arena, const char *fmt, ...); |
|
|
|
|
|
|
|
struct ParsePositiveIntResult { uint8 result; bool valid; }; |
|
|
|
ParsePositiveIntResult parsePositiveInt(string str, size_t *lengthPointer); |
|
|
|
struct ParsePositiveReal32Result { real32 result; bool valid; }; |
|
|
|
ParsePositiveReal32Result parsePositiveReal32(Arena *arena, string str, size_t *lengthPointer); |
|
|
|
typedef struct { uint8 result; bool valid; } ParsePositiveIntResult; |
|
|
|
ParsePositiveIntResult parsePositiveInt(string str, size_t *lengthPointer); |
|
|
|
typedef struct { real32 result; bool valid; } ParsePositiveReal32Result; |
|
|
|
ParsePositiveReal32Result parsePositiveReal32(string str, size_t *lengthPointer); |
|
|
|
|
|
|
|
inline function bool isNumeric(char c); |
|
|
|
inline function bool isNumeric(char c); |
|
|
|
|
|
|
|
// ### Cmdline ### |
|
|
|
StringList getArgs(Arena *arena, int argc, char **argv); |
|
|
|
StringList getArgs(Arena *arena, int argc, char **argv); |
|
|
|
|
|
|
|
// ### Time ### |
|
|
|
typedef uint64 UnixTimestamp; |
|
|
|
typedef tm Timestamp; |
|
|
|
typedef struct tm Timestamp; |
|
|
|
|
|
|
|
UnixTimestamp getSystemUnixTime(); |
|
|
|
Timestamp timestampFromUnixTime(UnixTimestamp *unixTimestamp); |
|
|
|
string formatTimeHms(Arena *arena, UnixTimestamp time); |
|
|
|
string formatTimeHms(Arena *arena, Timestamp *time); |
|
|
|
string formatTimeYmd(Arena *arena, UnixTimestamp time); |
|
|
|
string formatTimeYmd(Arena *arena, Timestamp *time); |
|
|
|
UnixTimestamp getSystemUnixTime(); |
|
|
|
Timestamp timestampFromUnixTime(UnixTimestamp *unixTimestamp); |
|
|
|
string formatTimeHmsUnix(Arena *arena, UnixTimestamp time); |
|
|
|
string formatTimeHms(Arena *arena, Timestamp *time); |
|
|
|
string formatTimeYmdUnix(Arena *arena, UnixTimestamp time); |
|
|
|
string formatTimeYmd(Arena *arena, Timestamp *time); |
|
|
|
|
|
|
|
// ### Linked Lists ### |
|
|
|
// TODO(djledda): implement basic linked lists (based on arenas?) |
|
|
|
|
|
|
|
// ### Logging ### |
|
|
|
enum StdStream { |
|
|
|
typedef enum { |
|
|
|
StdStream_stdout, |
|
|
|
StdStream_stdin, |
|
|
|
StdStream_stderr, |
|
|
|
}; |
|
|
|
} StdStream; |
|
|
|
|
|
|
|
#define ANSI_INSTRUCTION_FROM_ENUM(ansiCodeEnum) ANSI_INSTRUCTION(ansiCodeEnum) |
|
|
|
#define ANSI_INSTRUCTION(ansiCode) "\u001b[" #ansiCode "m" |
|
|
|
@@ -262,9 +264,10 @@ enum StdStream { |
|
|
|
#define COLOR_TEXT_FG_BG(text, foregroundcolor, backgroundcolor) ANSI_INSTRUCTION_FROM_ENUM(foregroundcolor) ANSI_INSTRUCTION_FROM_ENUM(backgroundcolor) text ANSI_RESET |
|
|
|
#define COLOR_TEXT_RGB(text, red, green, blue) ANSI_INSTRUCTION_STR("38;2;" #red ";" #green ";" #blue) text ANSI_RESET |
|
|
|
|
|
|
|
#define SetStdErr() DeferLoop |
|
|
|
DefineList(int, Int); |
|
|
|
void printIntList(IntList l, StdStream target = StdStream_stdout); |
|
|
|
void printStrList(StringList l, StdStream target = StdStream_stdout); |
|
|
|
void printIntListErr(IntList l); |
|
|
|
void printStrListErr(StringList l); |
|
|
|
void print(const char *fmt, ...); |
|
|
|
void printErr(const char *fmt, ...); |
|
|
|
|
|
|
|
@@ -274,6 +277,6 @@ void printErr(const char *fmt, ...); |
|
|
|
#define EachInArray(arr, it) size_t it = 0; it < ArrayCount(arr); ++it |
|
|
|
|
|
|
|
// ### Misc ### |
|
|
|
int intCompare(const void *a, const void *b); |
|
|
|
int intCompare(const void *a, const void *b); |
|
|
|
|
|
|
|
#endif |