2023-06-21 16:59:36 +00:00
|
|
|
/* date = June 19th 2023 7:27 pm */
|
|
|
|
|
|
|
|
#ifndef CORE_H
|
|
|
|
#define CORE_H
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <intrin.h>
|
|
|
|
#include <stdarg.h>
|
2023-08-06 10:35:09 +00:00
|
|
|
#include <stdlib.h>
|
2023-06-21 16:59:36 +00:00
|
|
|
|
|
|
|
//- sixten: Base types
|
|
|
|
|
|
|
|
typedef uint8_t u8;
|
|
|
|
typedef uint16_t u16;
|
|
|
|
typedef uint32_t u32;
|
|
|
|
typedef uint64_t u64;
|
|
|
|
typedef int8_t s8;
|
|
|
|
typedef int16_t s16;
|
|
|
|
typedef int32_t s32;
|
|
|
|
typedef int64_t s64;
|
|
|
|
typedef float r32;
|
|
|
|
typedef double r64;
|
|
|
|
typedef u8 b8;
|
|
|
|
typedef u16 b16;
|
|
|
|
typedef u32 b32;
|
|
|
|
typedef uintptr_t umm;
|
|
|
|
typedef intptr_t smm;
|
|
|
|
|
|
|
|
//- sixten: Base type limits
|
|
|
|
|
|
|
|
#define U8_Min 0x00
|
|
|
|
#define U8_Max 0xFF
|
|
|
|
#define U16_Min 0x0000
|
|
|
|
#define U16_Max 0xFFFF
|
|
|
|
#define U32_Min 0x00000000
|
|
|
|
#define U32_Max 0xFFFFFFFF
|
|
|
|
#define U64_Min 0x0000000000000000
|
|
|
|
#define U64_Max 0xFFFFFFFFFFFFFFFF
|
|
|
|
#define S8_Min 0x80
|
|
|
|
#define S8_Max 0x7F
|
|
|
|
#define S16_Min 0x8000
|
|
|
|
#define S16_Max 0x7FFF
|
|
|
|
#define S32_Min 0x80000000
|
|
|
|
#define S32_Max 0x7FFFFFFF
|
|
|
|
#define S64_Min 0x8000000000000000
|
|
|
|
#define S64_Max 0x7FFFFFFFFFFFFFFF
|
|
|
|
|
|
|
|
//- sixten: Keywords
|
2023-06-17 17:00:55 +00:00
|
|
|
|
|
|
|
#define global static
|
|
|
|
#define persist static
|
|
|
|
|
|
|
|
#pragma section(".roglob", read)
|
|
|
|
#define read_only __declspec(allocate(".roglob"))
|
|
|
|
|
2023-06-21 16:59:36 +00:00
|
|
|
#define per_thread __declspec(thread)
|
|
|
|
|
2023-06-17 17:00:55 +00:00
|
|
|
#define fallthrough
|
|
|
|
|
2023-06-21 16:59:36 +00:00
|
|
|
//- sixten: Assertions & debugging
|
|
|
|
|
2023-06-17 17:00:55 +00:00
|
|
|
#if VN_SLOW
|
|
|
|
#define Assert(Statement) if(!(Statement)) { *(int *)0 = 0; }
|
|
|
|
#else
|
|
|
|
#define Assert(Statement)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#define CTAssert(Statement) static_assert(Statement)
|
|
|
|
|
2023-06-21 16:59:36 +00:00
|
|
|
#define InvokeDebugger __debugbreak()
|
2023-06-17 17:00:55 +00:00
|
|
|
#define UnimplementedCodepath Assert(!"Unimplemented codepath")
|
|
|
|
|
|
|
|
#define InvalidCodepath Assert(!"Invalid codepath")
|
|
|
|
#define InvalidDefaultCase default: { Assert(!"Invalid codepath"); } break
|
|
|
|
|
2023-08-06 10:35:09 +00:00
|
|
|
//- sixten: Compiler warning helpers
|
|
|
|
|
|
|
|
#define UnusedVariable(Var) ((void)(Var))
|
|
|
|
|
2023-06-21 16:59:36 +00:00
|
|
|
//- sixten: Array & pointer manipulation
|
|
|
|
|
2023-06-17 17:00:55 +00:00
|
|
|
#define ArrayCount(Array) (sizeof(Array)/sizeof((Array)[0]))
|
|
|
|
#define OffsetOf(type, Member) (umm) &(((type *)0)->Member)
|
|
|
|
|
2023-06-21 16:59:36 +00:00
|
|
|
#define PointerToU64(x) ((u64)(void *)x)
|
|
|
|
#define U64ToPointer(x) ((void *)(u64)x)
|
|
|
|
|
2023-06-23 12:38:15 +00:00
|
|
|
#define FindIndexOfElement(Index, Array, Default, ToFind)\
|
|
|
|
Index = Default;\
|
|
|
|
for(s64 ___ = 0; ___ < ArrayCount(Array); ++___)\
|
|
|
|
{\
|
|
|
|
if(Array[___] == ToFind)\
|
|
|
|
{\
|
|
|
|
Index = ___; break;\
|
|
|
|
}\
|
|
|
|
}\
|
|
|
|
|
2023-07-19 15:09:41 +00:00
|
|
|
#define Bytes(n) (n)
|
|
|
|
#define Kilobytes(n) (n << 10)
|
|
|
|
#define Megabytes(n) (n << 20)
|
|
|
|
#define Gigabytes(n) (((u64)n) << 30)
|
|
|
|
#define Terabytes(n) (((u64)n) << 40)
|
|
|
|
|
2023-06-21 16:59:36 +00:00
|
|
|
//- sixten: Min, max & clamp
|
|
|
|
|
2023-06-17 17:00:55 +00:00
|
|
|
#define Minimum(A, B) (((A)<(B))?(A):(B))
|
|
|
|
#define Maximum(A, B) (((A)>(B))?(A):(B))
|
|
|
|
|
|
|
|
#define Clamp(Value, Min, Max) Minimum(Maximum(Value, Min), Max)
|
|
|
|
#define Clamp01(Value) Clamp(Value, 0, 1)
|
|
|
|
|
2023-06-21 16:59:36 +00:00
|
|
|
//- sixten: Linked list helpers
|
2023-06-17 17:00:55 +00:00
|
|
|
|
|
|
|
#define IsNull(x) ((x) == 0)
|
|
|
|
#define SetNull(x) ((x) = 0)
|
|
|
|
|
2023-07-19 15:09:41 +00:00
|
|
|
#define QueuePush_N(f,l,n,next) (IsNull(f)?\
|
|
|
|
(((f)=(l)=(n)), SetNull((n)->next)):\
|
|
|
|
((l)->next=(n),(l)=(n),SetNull((n)->next)))
|
|
|
|
#define QueuePushFront_N(f,l,n,next) (IsNull(f) ? (((f) = (l) = (n)), SetNull((n)->next)) :\
|
|
|
|
((n)->next = (f)), ((f) = (n)))
|
|
|
|
#define QueuePop_N(f,l,next) ((f)==(l)?\
|
|
|
|
(SetNull(f),SetNull(l)):\
|
|
|
|
((f)=(f)->next))
|
|
|
|
#define StackPush_N(f,n,next) ((n)->next=(f),(f)=(n))
|
|
|
|
#define StackPop_N(f,next) (IsNull(f)?0:((f)=(f)->next))
|
|
|
|
|
|
|
|
#define QueuePush(f,l,n) QueuePush_N(f,l,n,Next)
|
|
|
|
#define QueuePushFront(f,l,n) QueuePushFront_N(f,l,n,Next)
|
|
|
|
#define QueuePop(f,l) QueuePop_N(f,l,Next)
|
|
|
|
#define StackPush(f,n) StackPush_N(f,n,Next)
|
|
|
|
#define StackPop(f) StackPop_N(f,Next)
|
|
|
|
|
2023-06-17 17:00:55 +00:00
|
|
|
#define DLLInsert_NP(f,l,p,n,next,prev) \
|
|
|
|
(IsNull(f) ? (((f) = (l) = (n)), SetNull((n)->next), SetNull((n)->prev)) :\
|
|
|
|
IsNull(p) ? (SetNull((n)->prev), (n)->next = (f), (IsNull(f) ? (0) : ((f)->prev = (n))), (f) = (n)) :\
|
|
|
|
((IsNull((p)->next) ? (0) : (((p)->next->prev) = (n))), (n)->next = (p)->next, (n)->prev = (p), (p)->next = (n),\
|
|
|
|
((p) == (l) ? (l) = (n) : (0))))
|
|
|
|
|
|
|
|
#define DLLInsertLast_NP(f,l,n,next,prev) DLLInsert_NP(f,l,l,n,next,prev)
|
|
|
|
#define DLLInsertFirst_NP(f,l,n,next,prev) DLLInsert_NP(l,f,f,n,prev,next)
|
|
|
|
|
|
|
|
#define DLLRemove_NP(f,l,n,next,prev)\
|
|
|
|
(((f)==(n))?\
|
|
|
|
((f)=(f)->next, (IsNull(f) ? (SetNull(l)) : SetNull((f)->prev))):\
|
|
|
|
((l)==(n))?\
|
|
|
|
((l)=(l)->prev, (IsNull(l) ? (SetNull(f)) : SetNull((l)->next))):\
|
|
|
|
((IsNull((n)->next) ? (0) : ((n)->next->prev=(n)->prev)),\
|
|
|
|
(IsNull((n)->prev) ? (0) : ((n)->prev->next=(n)->next))))
|
|
|
|
|
|
|
|
#define DLLInsertFirst(First, Last, Element) DLLInsertFirst_NP(First, Last, Element, Next, Prev)
|
|
|
|
#define DLLInsertLast(First, Last, Element) DLLInsertLast_NP(First, Last, Element, Next, Prev)
|
|
|
|
#define DLLRemove(First, Last, Element) DLLRemove_NP(First, Last, Element, Next, Prev)
|
|
|
|
#define DLLIsEmpty(First) ((First) == 0)
|
|
|
|
|
2023-07-24 13:50:57 +00:00
|
|
|
#define SenDLLInit(Sentinel)\
|
|
|
|
(Sentinel)->Next = (Sentinel);\
|
|
|
|
(Sentinel)->Prev = (Sentinel);
|
|
|
|
|
|
|
|
#define SenDLLInsertFirst(Sentinel, Element)\
|
|
|
|
(Element)->Next = (Sentinel)->Next;\
|
|
|
|
(Element)->Prev = (Sentinel);\
|
|
|
|
(Element)->Next->Prev = (Element);\
|
|
|
|
(Element)->Prev->Next = (Element);
|
|
|
|
|
|
|
|
#define SenDLLInsertLast(Sentinel, Element)\
|
|
|
|
(Element)->Next = (Sentinel);\
|
|
|
|
(Element)->Prev = (Sentinel)->Prev;\
|
|
|
|
(Element)->Next->Prev = (Element);\
|
|
|
|
(Element)->Prev->Next = (Element);
|
|
|
|
|
|
|
|
#define SenDLLRemove(Element)\
|
|
|
|
auto __Temp = (Element)->Next->Prev;\
|
|
|
|
(Element)->Next->Prev = (Element)->Prev->Next;\
|
|
|
|
(Element)->Prev->Next = __Temp;
|
|
|
|
|
2023-08-06 10:35:09 +00:00
|
|
|
#define SenDLLIsEmpty(Sentinel)\
|
|
|
|
((Sentinel)->Next==(Sentinel))
|
|
|
|
|
2023-06-21 16:59:36 +00:00
|
|
|
//- sixten: Stringify
|
2023-06-17 17:00:55 +00:00
|
|
|
|
2023-06-21 16:59:36 +00:00
|
|
|
#define _Stringify(x) #x
|
|
|
|
#define Stringify(x) _Stringify(x)
|
2023-06-17 17:00:55 +00:00
|
|
|
|
2023-06-21 16:59:36 +00:00
|
|
|
//- sixten: Defer loop
|
2023-06-17 17:00:55 +00:00
|
|
|
|
2023-06-21 16:59:36 +00:00
|
|
|
#define DeferLoop(Start, End) for(s32 ___ = ((Start), 0); ___ == 0; ++___, (End))
|
2023-06-17 17:00:55 +00:00
|
|
|
|
2023-06-21 16:59:36 +00:00
|
|
|
//- sixten: Atomics
|
2023-06-17 17:00:55 +00:00
|
|
|
|
|
|
|
inline u64 AtomicExchangeU64(u64 volatile *Value, u64 New)
|
|
|
|
{
|
|
|
|
u64 Result = _InterlockedExchange64((__int64 volatile *)Value, New);
|
|
|
|
return(Result);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline u64 AtomicAddU64(u64 volatile *Value, u64 Addend)
|
|
|
|
{
|
|
|
|
u64 Result = _InterlockedExchangeAdd64((__int64 volatile *)Value, Addend);
|
|
|
|
return(Result);
|
|
|
|
}
|
|
|
|
|
2023-06-21 16:59:36 +00:00
|
|
|
// sixten: Memory mutexes
|
|
|
|
|
|
|
|
struct ticket_mutex
|
|
|
|
{
|
|
|
|
u64 volatile Ticket;
|
|
|
|
u64 volatile Serving;
|
|
|
|
};
|
|
|
|
|
2023-06-17 17:00:55 +00:00
|
|
|
inline void BeginTicketMutex(ticket_mutex *Mutex)
|
|
|
|
{
|
|
|
|
u64 Ticket = AtomicAddU64(&Mutex->Ticket, 1);
|
|
|
|
while(Ticket != Mutex->Serving) { _mm_pause(); }
|
|
|
|
}
|
|
|
|
|
|
|
|
inline void EndTicketMutex(ticket_mutex *Mutex)
|
|
|
|
{
|
|
|
|
AtomicAddU64(&Mutex->Serving, 1);
|
|
|
|
}
|
|
|
|
|
2023-06-21 16:59:36 +00:00
|
|
|
//- sixten: Axes
|
|
|
|
enum axis2
|
2023-06-19 17:12:26 +00:00
|
|
|
{
|
2023-06-21 16:59:36 +00:00
|
|
|
Axis2_X,
|
|
|
|
Axis2_Y,
|
|
|
|
Axis2_Count
|
|
|
|
};
|
2023-06-19 17:12:26 +00:00
|
|
|
|
2023-06-21 16:59:36 +00:00
|
|
|
inline axis2 Opposite(axis2 Axis) { axis2 Result = (axis2)(!(u32)Axis); return(Result); }
|
2023-06-17 17:00:55 +00:00
|
|
|
|
2023-07-19 15:09:41 +00:00
|
|
|
////////////////////////////////
|
|
|
|
//- sixten: Corners
|
|
|
|
enum corner
|
|
|
|
{
|
|
|
|
Corner_00 = 0,
|
|
|
|
Corner_10 = (1 << Axis2_X),
|
|
|
|
Corner_01 = (1 << Axis2_Y),
|
|
|
|
Corner_11 = (1 << Axis2_X)|(1 << Axis2_Y),
|
|
|
|
Corner_Count,
|
|
|
|
};
|
|
|
|
|
2023-06-21 16:59:36 +00:00
|
|
|
#endif //CORE_H
|