Added a proper "core" to the codebase.
parent
cab0dac728
commit
15bb3ef384
|
@ -1,6 +1,6 @@
|
||||||
@echo off
|
@echo off
|
||||||
|
|
||||||
set CommonCompilerOptions=/Zi /FC /nologo /DVN_INTERNAL=1 /DVN_SLOW=1 /Oi /W4 /WL /WX /wd4996 /wd4201 /wd4305 /wd4244 /wd4100 /wd4505 /std:c++17
|
set CommonCompilerOptions=/Zi /FC /nologo /DVN_INTERNAL=1 /DVN_SLOW=1 /Oi /W4 /WX /wd4996 /wd4201 /wd4305 /wd4244 /wd4100 /wd4505 /std:c++17
|
||||||
|
|
||||||
if not exist "../build" mkdir "../build"
|
if not exist "../build" mkdir "../build"
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,50 @@
|
||||||
/* date = April 26th 2023 8:58 pm */
|
/* date = June 19th 2023 7:27 pm */
|
||||||
|
|
||||||
#ifndef VN_CORE_H
|
#ifndef CORE_H
|
||||||
#define VN_CORE_H
|
#define CORE_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <intrin.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
//- 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
|
||||||
|
|
||||||
#define global static
|
#define global static
|
||||||
#define persist static
|
#define persist static
|
||||||
|
@ -9,8 +52,12 @@
|
||||||
#pragma section(".roglob", read)
|
#pragma section(".roglob", read)
|
||||||
#define read_only __declspec(allocate(".roglob"))
|
#define read_only __declspec(allocate(".roglob"))
|
||||||
|
|
||||||
|
#define per_thread __declspec(thread)
|
||||||
|
|
||||||
#define fallthrough
|
#define fallthrough
|
||||||
|
|
||||||
|
//- sixten: Assertions & debugging
|
||||||
|
|
||||||
#if VN_SLOW
|
#if VN_SLOW
|
||||||
#define Assert(Statement) if(!(Statement)) { *(int *)0 = 0; }
|
#define Assert(Statement) if(!(Statement)) { *(int *)0 = 0; }
|
||||||
#else
|
#else
|
||||||
|
@ -25,19 +72,23 @@
|
||||||
#define InvalidCodepath Assert(!"Invalid codepath")
|
#define InvalidCodepath Assert(!"Invalid codepath")
|
||||||
#define InvalidDefaultCase default: { Assert(!"Invalid codepath"); } break
|
#define InvalidDefaultCase default: { Assert(!"Invalid codepath"); } break
|
||||||
|
|
||||||
|
//- sixten: Array & pointer manipulation
|
||||||
|
|
||||||
#define ArrayCount(Array) (sizeof(Array)/sizeof((Array)[0]))
|
#define ArrayCount(Array) (sizeof(Array)/sizeof((Array)[0]))
|
||||||
#define OffsetOf(type, Member) (umm) &(((type *)0)->Member)
|
#define OffsetOf(type, Member) (umm) &(((type *)0)->Member)
|
||||||
|
|
||||||
|
#define PointerToU64(x) ((u64)(void *)x)
|
||||||
|
#define U64ToPointer(x) ((void *)(u64)x)
|
||||||
|
|
||||||
|
//- sixten: Min, max & clamp
|
||||||
|
|
||||||
#define Minimum(A, B) (((A)<(B))?(A):(B))
|
#define Minimum(A, B) (((A)<(B))?(A):(B))
|
||||||
#define Maximum(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 Clamp(Value, Min, Max) Minimum(Maximum(Value, Min), Max)
|
||||||
#define Clamp01(Value) Clamp(Value, 0, 1)
|
#define Clamp01(Value) Clamp(Value, 0, 1)
|
||||||
|
|
||||||
#define DeferLoop(Start, End) for(s32 ___ = ((Start), 0); ___ == 0; ++___, (End))
|
//- sixten: Linked list helpers
|
||||||
|
|
||||||
#define _Stringify(x) #x
|
|
||||||
#define Stringify(x) _Stringify(x)
|
|
||||||
|
|
||||||
#define IsNull(x) ((x) == 0)
|
#define IsNull(x) ((x) == 0)
|
||||||
#define SetNull(x) ((x) = 0)
|
#define SetNull(x) ((x) = 0)
|
||||||
|
@ -64,45 +115,16 @@ IsNull(p) ? (SetNull((n)->prev), (n)->next = (f), (IsNull(f) ? (0) : ((f)->prev
|
||||||
#define DLLRemove(First, Last, Element) DLLRemove_NP(First, Last, Element, Next, Prev)
|
#define DLLRemove(First, Last, Element) DLLRemove_NP(First, Last, Element, Next, Prev)
|
||||||
#define DLLIsEmpty(First) ((First) == 0)
|
#define DLLIsEmpty(First) ((First) == 0)
|
||||||
|
|
||||||
#include "vn_types.h"
|
//- sixten: Stringify
|
||||||
#include "vn_math.h"
|
|
||||||
|
|
||||||
// sixten(TODO): Scuffed AF. Need to make a proper "core" of the codebase.
|
#define _Stringify(x) #x
|
||||||
static s64 UTF8FromCodepoint(u8 *Out, u32 Codepoint);
|
#define Stringify(x) _Stringify(x)
|
||||||
#define STB_SPRINTF_IMPLEMENTATION
|
|
||||||
#include "third_party/stb_sprintf.h"
|
|
||||||
|
|
||||||
inline void Copy(void *Dest_, void *Source_, umm Count)
|
//- sixten: Defer loop
|
||||||
{
|
|
||||||
u8 *Dest = (u8 *)Dest_;
|
|
||||||
u8 *Source = (u8 *)Source_;
|
|
||||||
|
|
||||||
while(Count--)
|
#define DeferLoop(Start, End) for(s32 ___ = ((Start), 0); ___ == 0; ++___, (End))
|
||||||
{
|
|
||||||
*Dest++ = *Source++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void ZeroSize(void *Dest_, umm Count)
|
//- sixten: Atomics
|
||||||
{
|
|
||||||
u8 *Dest = (u8 *)Dest_;
|
|
||||||
while(Count--)
|
|
||||||
{
|
|
||||||
*Dest++ = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void *U64ToPointer(u64 Value)
|
|
||||||
{
|
|
||||||
void *Result = (void *)Value;
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline u64 PointerToU64(void *Value)
|
|
||||||
{
|
|
||||||
u64 Result = (u64)Value;
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline u64 AtomicExchangeU64(u64 volatile *Value, u64 New)
|
inline u64 AtomicExchangeU64(u64 volatile *Value, u64 New)
|
||||||
{
|
{
|
||||||
|
@ -116,6 +138,14 @@ inline u64 AtomicAddU64(u64 volatile *Value, u64 Addend)
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sixten: Memory mutexes
|
||||||
|
|
||||||
|
struct ticket_mutex
|
||||||
|
{
|
||||||
|
u64 volatile Ticket;
|
||||||
|
u64 volatile Serving;
|
||||||
|
};
|
||||||
|
|
||||||
inline void BeginTicketMutex(ticket_mutex *Mutex)
|
inline void BeginTicketMutex(ticket_mutex *Mutex)
|
||||||
{
|
{
|
||||||
u64 Ticket = AtomicAddU64(&Mutex->Ticket, 1);
|
u64 Ticket = AtomicAddU64(&Mutex->Ticket, 1);
|
||||||
|
@ -127,49 +157,15 @@ inline void EndTicketMutex(ticket_mutex *Mutex)
|
||||||
AtomicAddU64(&Mutex->Serving, 1);
|
AtomicAddU64(&Mutex->Serving, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline b32 InRange(range_s64 Range, s64 P)
|
//- sixten: Axes
|
||||||
{
|
|
||||||
b32 Result = ((P >= Range.Min) && (P < Range.Max));
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline b32 InRange(range2_r32 Range, v2 P)
|
enum axis2
|
||||||
{
|
{
|
||||||
b32 Result = ((P.x >= Range.Min.x) &&
|
Axis2_X,
|
||||||
(P.y >= Range.Min.y) &&
|
Axis2_Y,
|
||||||
(P.x < Range.Max.x) &&
|
Axis2_Count
|
||||||
(P.y < Range.Max.y));
|
};
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline range_s64 RangeS64(s64 A, s64 B)
|
inline axis2 Opposite(axis2 Axis) { axis2 Result = (axis2)(!(u32)Axis); return(Result); }
|
||||||
{
|
|
||||||
range_s64 Result = {Minimum(A, B), Maximum(A, B)};
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline range_r32 RangeR32(r32 A, r32 B)
|
#endif //CORE_H
|
||||||
{
|
|
||||||
range_r32 Result = {Minimum(A, B), Maximum(A, B)};
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline range2_r32 Range2R32(v2 A, v2 B)
|
|
||||||
{
|
|
||||||
range2_r32 Result = { Min(A, B), Max(A, B) };
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline s64 DimOfRange(range_s64 Range)
|
|
||||||
{
|
|
||||||
s64 Dim = Range.Max - Range.Min;
|
|
||||||
return(Dim);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline v2 DimOfRange(range2_r32 Range)
|
|
||||||
{
|
|
||||||
v2 Dim = Range.Max - Range.Min;
|
|
||||||
return(Dim);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //VN_CORE_H
|
|
|
@ -0,0 +1,601 @@
|
||||||
|
//- sixten: V2 R32
|
||||||
|
|
||||||
|
inline v2_r32 V2R32(r32 x, r32 y)
|
||||||
|
{
|
||||||
|
v2_r32 Result = {x, y};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v2_r32 operator+(v2_r32 A, v2_r32 B)
|
||||||
|
{
|
||||||
|
v2_r32 Result = {A.x + B.x, A.y + B.y};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v2_r32 operator-(v2_r32 A, v2_r32 B)
|
||||||
|
{
|
||||||
|
v2_r32 Result = {A.x - B.x, A.y - B.y};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v2_r32 operator*(v2_r32 A, v2_r32 B)
|
||||||
|
{
|
||||||
|
v2_r32 Result = {A.x * B.x, A.y * B.y};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v2_r32 operator/(v2_r32 A, v2_r32 B)
|
||||||
|
{
|
||||||
|
v2_r32 Result = {A.x / B.x, A.y / B.y};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v2_r32 operator*(v2_r32 A, r32 B)
|
||||||
|
{
|
||||||
|
v2_r32 Result = {A.x * B, A.y * B};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v2_r32 operator+=(v2_r32 &A, v2_r32 B) { return A = A + B; }
|
||||||
|
inline v2_r32 operator-=(v2_r32 &A, v2_r32 B) { return A = A - B; }
|
||||||
|
inline v2_r32 operator*=(v2_r32 &A, v2_r32 B) { return A = A * B; }
|
||||||
|
inline v2_r32 operator/=(v2_r32 &A, v2_r32 B) { return A = A / B; }
|
||||||
|
inline v2_r32 operator*=(v2_r32 &A, r32 B) { return A = A * B; }
|
||||||
|
|
||||||
|
inline r32 Inner(v2_r32 A, v2_r32 B)
|
||||||
|
{
|
||||||
|
r32 Result = A.x*B.x + A.y*B.y;
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline r32 LengthSquared(v2_r32 V)
|
||||||
|
{
|
||||||
|
r32 Result = Inner(V, V);
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline r32 Length(v2_r32 V)
|
||||||
|
{
|
||||||
|
r32 Result = SquareRoot(LengthSquared(V));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v2_r32 NOZ(v2_r32 V)
|
||||||
|
{
|
||||||
|
v2_r32 Result = {};
|
||||||
|
|
||||||
|
r32 Len = Length(V);
|
||||||
|
if(Len != 0)
|
||||||
|
{
|
||||||
|
Result = V / V2R32(Len, Len);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v2_r32 LinearBlend(v2_r32 A, v2_r32 B, r32 x)
|
||||||
|
{
|
||||||
|
v2_r32 Result = A+(B-A)*x;
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v2_r32 Min(v2_r32 A, v2_r32 B)
|
||||||
|
{
|
||||||
|
v2_r32 Result = V2R32(Min(A.x, B.x), Min(A.y, B.y));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v2_r32 Max(v2_r32 A, v2_r32 B)
|
||||||
|
{
|
||||||
|
v2_r32 Result = V2R32(Max(A.x, B.x), Max(A.y, B.y));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- sixten: V2 S32
|
||||||
|
|
||||||
|
inline v2_s32 V2S32(s32 x, s32 y)
|
||||||
|
{
|
||||||
|
v2_s32 Result = {x, y};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v2_s32 operator+(v2_s32 A, v2_s32 B)
|
||||||
|
{
|
||||||
|
v2_s32 Result = {A.x + B.x, A.y + B.y};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v2_s32 operator-(v2_s32 A, v2_s32 B)
|
||||||
|
{
|
||||||
|
v2_s32 Result = {A.x - B.x, A.y - B.y};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v2_s32 operator+=(v2_s32 &A, v2_s32 B) { return A = A + B; }
|
||||||
|
inline v2_s32 operator-=(v2_s32 &A, v2_s32 B) { return A = A - B; }
|
||||||
|
|
||||||
|
inline v2_s32 Min(v2_s32 A, v2_s32 B)
|
||||||
|
{
|
||||||
|
v2_s32 Result = V2S32(Min(A.x, B.x), Min(A.y, B.y));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v2_s32 Max(v2_s32 A, v2_s32 B)
|
||||||
|
{
|
||||||
|
v2_s32 Result = V2S32(Max(A.x, B.x), Max(A.y, B.y));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- sixten: V2 S64
|
||||||
|
|
||||||
|
inline v2_s64 V2S64(s64 x, s64 y)
|
||||||
|
{
|
||||||
|
v2_s64 Result = {x, y};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v2_s64 operator+(v2_s64 A, v2_s64 B)
|
||||||
|
{
|
||||||
|
v2_s64 Result = {A.x + B.x, A.y + B.y};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v2_s64 operator-(v2_s64 A, v2_s64 B)
|
||||||
|
{
|
||||||
|
v2_s64 Result = {A.x - B.x, A.y - B.y};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v2_s64 operator+=(v2_s64 &A, v2_s64 B) { return A = A + B; }
|
||||||
|
inline v2_s64 operator-=(v2_s64 &A, v2_s64 B) { return A = A - B; }
|
||||||
|
|
||||||
|
inline v2_s64 Min(v2_s64 A, v2_s64 B)
|
||||||
|
{
|
||||||
|
v2_s64 Result = V2S64(Min(A.x, B.x), Min(A.y, B.y));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v2_s64 Max(v2_s64 A, v2_s64 B)
|
||||||
|
{
|
||||||
|
v2_s64 Result = V2S64(Max(A.x, B.x), Max(A.y, B.y));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- sixten: V3 R32
|
||||||
|
|
||||||
|
inline v3_r32 V3R32(r32 x, r32 y, r32 z)
|
||||||
|
{
|
||||||
|
v3_r32 Result = {x, y, z};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v3_r32 operator+(v3_r32 A, v3_r32 B)
|
||||||
|
{
|
||||||
|
v3_r32 Result = {A.x + B.x, A.y + B.y, A.z + B.z};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v3_r32 operator-(v3_r32 A, v3_r32 B)
|
||||||
|
{
|
||||||
|
v3_r32 Result = {A.x - B.x, A.y - B.y, A.z - B.z};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v3_r32 operator*(v3_r32 A, v3_r32 B)
|
||||||
|
{
|
||||||
|
v3_r32 Result = {A.x * B.x, A.y * B.y, A.z * B.z};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v3_r32 operator/(v3_r32 A, v3_r32 B)
|
||||||
|
{
|
||||||
|
v3_r32 Result = {A.x / B.x, A.y / B.y, A.z / B.z};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v3_r32 operator*(v3_r32 A, r32 B)
|
||||||
|
{
|
||||||
|
v3_r32 Result = {A.x * B, A.y * B, A.z * B};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v3_r32 operator+=(v3_r32 &A, v3_r32 B) { return A = A + B; }
|
||||||
|
inline v3_r32 operator-=(v3_r32 &A, v3_r32 B) { return A = A - B; }
|
||||||
|
inline v3_r32 operator*=(v3_r32 &A, v3_r32 B) { return A = A * B; }
|
||||||
|
inline v3_r32 operator/=(v3_r32 &A, v3_r32 B) { return A = A / B; }
|
||||||
|
inline v3_r32 operator*=(v3_r32 &A, r32 B) { return A = A * B; }
|
||||||
|
|
||||||
|
inline r32 Inner(v3_r32 A, v3_r32 B)
|
||||||
|
{
|
||||||
|
r32 Result = A.x*B.x + A.y*B.y + A.z*B.z;
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline r32 LengthSquared(v3_r32 V)
|
||||||
|
{
|
||||||
|
r32 Result = Inner(V, V);
|
||||||
|
return(Result);;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline r32 Length(v3_r32 V)
|
||||||
|
{
|
||||||
|
r32 Result = SquareRoot(LengthSquared(V));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v3_r32 NOZ(v3_r32 V)
|
||||||
|
{
|
||||||
|
v3_r32 Result = {};
|
||||||
|
|
||||||
|
r32 Len = Length(V);
|
||||||
|
if(Len != 0)
|
||||||
|
{
|
||||||
|
Result = V / V3R32(Len, Len, Len);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v3_r32 LinearBlend(v3_r32 A, v3_r32 B, r32 x)
|
||||||
|
{
|
||||||
|
v3_r32 Result = A+(B-A)*x;
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v3_r32 Min(v3_r32 A, v3_r32 B)
|
||||||
|
{
|
||||||
|
v3_r32 Result = V3R32(Min(A.x, B.x), Min(A.y, B.y), Min(A.z, B.z));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v3_r32 Max(v3_r32 A, v3_r32 B)
|
||||||
|
{
|
||||||
|
v3_r32 Result = V3R32(Max(A.x, B.x), Max(A.y, B.y), Max(A.z, B.z));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- sixten: V3 S32
|
||||||
|
|
||||||
|
inline v3_s32 V3S32(s32 x, s32 y, s32 z)
|
||||||
|
{
|
||||||
|
v3_s32 Result = {x, y, z};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v3_s32 operator+(v3_s32 A, v3_s32 B)
|
||||||
|
{
|
||||||
|
v3_s32 Result = {A.x + B.x, A.y + B.y, A.z + B.z};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v3_s32 operator-(v3_s32 A, v3_s32 B)
|
||||||
|
{
|
||||||
|
v3_s32 Result = {A.x - B.x, A.y - B.y, A.z - B.z};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v3_s32 operator+=(v3_s32 &A, v3_s32 B) { return A = A + B; }
|
||||||
|
inline v3_s32 operator-=(v3_s32 &A, v3_s32 B) { return A = A - B; }
|
||||||
|
|
||||||
|
inline v3_s32 Min(v3_s32 A, v3_s32 B)
|
||||||
|
{
|
||||||
|
v3_s32 Result = V3S32(Min(A.x, B.x), Min(A.y, B.y), Min(A.z, B.z));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v3_s32 Max(v3_s32 A, v3_s32 B)
|
||||||
|
{
|
||||||
|
v3_s32 Result = V3S32(Max(A.x, B.x), Max(A.y, B.y), Max(A.z, B.z));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- sixten: V3 S64
|
||||||
|
|
||||||
|
inline v3_s64 V4S64(s64 x, s64 y, s64 z)
|
||||||
|
{
|
||||||
|
v3_s64 Result = {x, y, z};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v3_s64 operator+(v3_s64 A, v3_s64 B)
|
||||||
|
{
|
||||||
|
v3_s64 Result = {A.x + B.x, A.y + B.y, A.z + B.z};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v3_s64 operator-(v3_s64 A, v3_s64 B)
|
||||||
|
{
|
||||||
|
v3_s64 Result = {A.x - B.x, A.y - B.y, A.z - B.z};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v3_s64 operator+=(v3_s64 &A, v3_s64 B) { return A = A + B; }
|
||||||
|
inline v3_s64 operator-=(v3_s64 &A, v3_s64 B) { return A = A - B; }
|
||||||
|
|
||||||
|
inline v3_s64 Min(v3_s64 A, v3_s64 B)
|
||||||
|
{
|
||||||
|
v3_s64 Result = V4S64(Min(A.x, B.x), Min(A.y, B.y), Min(A.z, B.z));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v3_s64 Max(v3_s64 A, v3_s64 B)
|
||||||
|
{
|
||||||
|
v3_s64 Result = V4S64(Max(A.x, B.x), Max(A.y, B.y), Max(A.z, B.z));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- sixten: V4 R32
|
||||||
|
|
||||||
|
inline v4_r32 V4R32(r32 x, r32 y, r32 z, r32 w)
|
||||||
|
{
|
||||||
|
v4_r32 Result = {x, y, z, w};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v4_r32 operator+(v4_r32 A, v4_r32 B)
|
||||||
|
{
|
||||||
|
v4_r32 Result = {A.x + B.x, A.y + B.y, A.z + B.z, A.w + B.w};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v4_r32 operator-(v4_r32 A, v4_r32 B)
|
||||||
|
{
|
||||||
|
v4_r32 Result = {A.x - B.x, A.y - B.y, A.z - B.z, A.w - B.w};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v4_r32 operator*(v4_r32 A, v4_r32 B)
|
||||||
|
{
|
||||||
|
v4_r32 Result = {A.x * B.x, A.y * B.y, A.z * B.z, A.w * B.w};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v4_r32 operator/(v4_r32 A, v4_r32 B)
|
||||||
|
{
|
||||||
|
v4_r32 Result = {A.x / B.x, A.y / B.y, A.z / B.z, A.w / B.w};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v4_r32 operator*(v4_r32 A, r32 B)
|
||||||
|
{
|
||||||
|
v4_r32 Result = {A.x * B, A.y * B, A.z * B, A.w * B};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v4_r32 operator+=(v4_r32 &A, v4_r32 B) { return A = A + B; }
|
||||||
|
inline v4_r32 operator-=(v4_r32 &A, v4_r32 B) { return A = A - B; }
|
||||||
|
inline v4_r32 operator*=(v4_r32 &A, v4_r32 B) { return A = A * B; }
|
||||||
|
inline v4_r32 operator/=(v4_r32 &A, v4_r32 B) { return A = A / B; }
|
||||||
|
inline v4_r32 operator*=(v4_r32 &A, r32 B) { return A = A * B; }
|
||||||
|
|
||||||
|
inline r32 Inner(v4_r32 A, v4_r32 B)
|
||||||
|
{
|
||||||
|
r32 Result = A.x*B.x + A.y*B.y + A.z*B.z + A.w*B.w;
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline r32 LengthSquared(v4_r32 V)
|
||||||
|
{
|
||||||
|
r32 Result = Inner(V, V);
|
||||||
|
return(Result);;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline r32 Length(v4_r32 V)
|
||||||
|
{
|
||||||
|
r32 Result = SquareRoot(LengthSquared(V));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v4_r32 NOZ(v4_r32 V)
|
||||||
|
{
|
||||||
|
v4_r32 Result = {};
|
||||||
|
|
||||||
|
r32 Len = Length(V);
|
||||||
|
if(Len != 0)
|
||||||
|
{
|
||||||
|
Result = V / V4R32(Len, Len, Len, Len);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v4_r32 LinearBlend(v4_r32 A, v4_r32 B, r32 x)
|
||||||
|
{
|
||||||
|
v4_r32 Result = A+(B-A)*x;
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v4_r32 Min(v4_r32 A, v4_r32 B)
|
||||||
|
{
|
||||||
|
v4_r32 Result = V4R32(Min(A.x, B.x), Min(A.y, B.y), Min(A.z, B.z), Min(A.w, B.w));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v4_r32 Max(v4_r32 A, v4_r32 B)
|
||||||
|
{
|
||||||
|
v4_r32 Result = V4R32(Max(A.x, B.x), Max(A.y, B.y), Max(A.z, B.z), Max(A.w, B.w));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- sixten: V4 S32
|
||||||
|
|
||||||
|
inline v4_s32 V4S32(s32 x, s32 y, s32 z, s32 w)
|
||||||
|
{
|
||||||
|
v4_s32 Result = {x, y, z, w};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v4_s32 operator+(v4_s32 A, v4_s32 B)
|
||||||
|
{
|
||||||
|
v4_s32 Result = {A.x + B.x, A.y + B.y, A.z + B.z, A.w + B.w};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v4_s32 operator-(v4_s32 A, v4_s32 B)
|
||||||
|
{
|
||||||
|
v4_s32 Result = {A.x - B.x, A.y - B.y, A.z - B.z, A.w - B.w};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v4_s32 operator+=(v4_s32 &A, v4_s32 B) { return A = A + B; }
|
||||||
|
inline v4_s32 operator-=(v4_s32 &A, v4_s32 B) { return A = A - B; }
|
||||||
|
|
||||||
|
inline v4_s32 Min(v4_s32 A, v4_s32 B)
|
||||||
|
{
|
||||||
|
v4_s32 Result = V4S32(Min(A.x, B.x), Min(A.y, B.y), Min(A.z, B.z), Min(A.w, B.w));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v4_s32 Max(v4_s32 A, v4_s32 B)
|
||||||
|
{
|
||||||
|
v4_s32 Result = V4S32(Max(A.x, B.x), Max(A.y, B.y), Max(A.z, B.z), Max(A.w, B.w));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- sixten: V4 S64
|
||||||
|
|
||||||
|
inline v4_s64 V4S64(s64 x, s64 y, s64 z, s64 w)
|
||||||
|
{
|
||||||
|
v4_s64 Result = {x, y, z, w};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v4_s64 operator+(v4_s64 A, v4_s64 B)
|
||||||
|
{
|
||||||
|
v4_s64 Result = {A.x + B.x, A.y + B.y, A.z + B.z, A.w + B.w};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v4_s64 operator-(v4_s64 A, v4_s64 B)
|
||||||
|
{
|
||||||
|
v4_s64 Result = {A.x - B.x, A.y - B.y, A.z - B.z, A.w - B.w};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v4_s64 operator+=(v4_s64 &A, v4_s64 B) { return A = A + B; }
|
||||||
|
inline v4_s64 operator-=(v4_s64 &A, v4_s64 B) { return A = A - B; }
|
||||||
|
|
||||||
|
inline v4_s64 Min(v4_s64 A, v4_s64 B)
|
||||||
|
{
|
||||||
|
v4_s64 Result = V4S64(Min(A.x, B.x), Min(A.y, B.y), Min(A.z, B.z), Min(A.w, B.w));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v4_s64 Max(v4_s64 A, v4_s64 B)
|
||||||
|
{
|
||||||
|
v4_s64 Result = V4S64(Max(A.x, B.x), Max(A.y, B.y), Max(A.z, B.z), Max(A.w, B.w));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- sixten: Range functions
|
||||||
|
|
||||||
|
inline range1_r32 Range1R32(r32 Min, r32 Max)
|
||||||
|
{
|
||||||
|
range1_r32 Result = {Min, Max};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline b32 InRange(range1_r32 Range, r32 Value)
|
||||||
|
{
|
||||||
|
b32 Result = (Value >= Range.Min) && (Value < Range.Max);
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline r32 DimOfRange(range1_r32 Range)
|
||||||
|
{
|
||||||
|
r32 Result = Range.Max - Range.Min;
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline range1_s32 Range1S32(s32 Min, s32 Max)
|
||||||
|
{
|
||||||
|
range1_s32 Result = {Min, Max};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline b32 InRange(range1_s32 Range, s32 Value)
|
||||||
|
{
|
||||||
|
b32 Result = (Value >= Range.Min) && (Value < Range.Max);
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline s32 DimOfRange(range1_s32 Range)
|
||||||
|
{
|
||||||
|
s32 Result = Range.Max - Range.Min;
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline range1_s64 Range1S64(s64 Min, s64 Max)
|
||||||
|
{
|
||||||
|
range1_s64 Result = {Min, Max};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline b32 InRange(range1_s64 Range, s64 Value)
|
||||||
|
{
|
||||||
|
b32 Result = (Value >= Range.Min) && (Value < Range.Max);
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline s64 DimOfRange(range1_s64 Range)
|
||||||
|
{
|
||||||
|
s64 Result = Range.Max - Range.Min;
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline range2_r32 Range2R32(v2_r32 Min, v2_r32 Max)
|
||||||
|
{
|
||||||
|
range2_r32 Result = {Min, Max};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline b32 InRange(range2_r32 Range, v2_r32 Value)
|
||||||
|
{
|
||||||
|
b32 Result = ((Value.x >= Range.Min.x) && (Value.y >= Range.Min.y) &&
|
||||||
|
(Value.x < Range.Max.x) && (Value.y < Range.Max.y));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v2_r32 DimOfRange(range2_r32 Range)
|
||||||
|
{
|
||||||
|
v2_r32 Result = Range.Max - Range.Min;
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline range2_s32 Range2S32(v2_s32 Min, v2_s32 Max)
|
||||||
|
{
|
||||||
|
range2_s32 Result = {Min, Max};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline b32 InRange(range2_s32 Range, v2_s32 Value)
|
||||||
|
{
|
||||||
|
b32 Result = ((Value.x >= Range.Min.x) && (Value.y >= Range.Min.y) &&
|
||||||
|
(Value.x < Range.Max.x) && (Value.y < Range.Max.y));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v2_s32 DimOfRange(range2_s32 Range)
|
||||||
|
{
|
||||||
|
v2_s32 Result = Range.Max - Range.Min;
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline range2_s64 Range2S64(v2_s64 Min, v2_s64 Max)
|
||||||
|
{
|
||||||
|
range2_s64 Result = {Min, Max};
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline b32 InRange(range2_s64 Range, v2_s64 Value)
|
||||||
|
{
|
||||||
|
b32 Result = ((Value.x >= Range.Min.x) && (Value.y >= Range.Min.y) &&
|
||||||
|
(Value.x < Range.Max.x) && (Value.y < Range.Max.y));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline v2_s64 DimOfRange(range2_s64 Range)
|
||||||
|
{
|
||||||
|
v2_s64 Result = Range.Max - Range.Min;
|
||||||
|
return(Result);
|
||||||
|
}
|
|
@ -0,0 +1,356 @@
|
||||||
|
/* date = June 19th 2023 10:28 pm */
|
||||||
|
|
||||||
|
#ifndef CORE_MATH_H
|
||||||
|
#define CORE_MATH_H
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
//- sixten: Constants
|
||||||
|
|
||||||
|
read_only global r32 InfinityR32 = INFINITY;
|
||||||
|
read_only global r32 PiR32 = 3.1415926535897f;
|
||||||
|
read_only global r32 EulersNumberR32 = 2.7182818284590452353602874713527f;
|
||||||
|
|
||||||
|
//- sixten: Vector types
|
||||||
|
|
||||||
|
union v2_r32
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
r32 x, y;
|
||||||
|
};
|
||||||
|
|
||||||
|
r32 E[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
union v2_s32
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
s32 x, y;
|
||||||
|
};
|
||||||
|
|
||||||
|
s32 E[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
union v2_s64
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
s64 x, y;
|
||||||
|
};
|
||||||
|
|
||||||
|
s64 E[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
union v3_r32
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
r32 x, y, z;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
r32 r, g, b;
|
||||||
|
};
|
||||||
|
|
||||||
|
r32 E[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
union v3_s32
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
s32 x, y, z;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
s32 r, g, b;
|
||||||
|
};
|
||||||
|
|
||||||
|
s32 E[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
union v3_s64
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
s64 x, y, z;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
s64 r, g, b;
|
||||||
|
};
|
||||||
|
|
||||||
|
s64 E[3];
|
||||||
|
};
|
||||||
|
|
||||||
|
union v4_r32
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
r32 x, y, z, w;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
r32 r, g, b, a;
|
||||||
|
};
|
||||||
|
|
||||||
|
r32 E[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
union v4_s32
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
s32 x, y, z, w;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
s32 r, g, b, a;
|
||||||
|
};
|
||||||
|
|
||||||
|
s32 E[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
union v4_s64
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
s64 x, y, z, w;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
s64 r, g, b, a;
|
||||||
|
};
|
||||||
|
|
||||||
|
s64 E[4];
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ConvertV2ToR32(V) V2R32((r32)(V).x, (r32)(V).y)
|
||||||
|
#define ConvertV2ToS32(V) V2S32((s32)(V).x, (s32)(V).y)
|
||||||
|
#define ConvertV2ToS64(V) V2S64((s64)(V).x, (s64)(V).y)
|
||||||
|
#define ConvertV3ToR32(V) V3R32((r32)(V).x, (r32)(V).y, (r32)(V).z)
|
||||||
|
#define ConvertV3ToS32(V) V3S32((s32)(V).x, (s32)(V).y, (s32)(V).z)
|
||||||
|
#define ConvertV3ToS64(V) V3S64((s64)(V).x, (s64)(V).y, (s64)(V).z)
|
||||||
|
#define ConvertV4ToR32(V) V4R32((r32)(V).x, (r32)(V).y, (r32)(V).z, (r32)(V).w)
|
||||||
|
#define ConvertV4ToS32(V) V4S32((s32)(V).x, (s32)(V).y, (s32)(V).z, (s32)(V).w)
|
||||||
|
#define ConvertV4ToS64(V) V4S64((s64)(V).x, (s64)(V).y, (s64)(V).z, (s64)(V).w)
|
||||||
|
|
||||||
|
//- sixten: Matrix types
|
||||||
|
|
||||||
|
// sixten(NOTE): Matrices are treated as column-major.
|
||||||
|
|
||||||
|
struct m3x3
|
||||||
|
{
|
||||||
|
r32 E[3][3];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct m4x4
|
||||||
|
{
|
||||||
|
r32 E[4][4];
|
||||||
|
};
|
||||||
|
|
||||||
|
//- sixten: Range types
|
||||||
|
|
||||||
|
struct range1_r32
|
||||||
|
{
|
||||||
|
r32 Min, Max;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct range1_s32
|
||||||
|
{
|
||||||
|
s32 Min, Max;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct range1_s64
|
||||||
|
{
|
||||||
|
s64 Min, Max;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct range2_r32
|
||||||
|
{
|
||||||
|
v2_r32 Min, Max;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct range2_s32
|
||||||
|
{
|
||||||
|
v2_s32 Min, Max;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct range2_s64
|
||||||
|
{
|
||||||
|
v2_s64 Min, Max;
|
||||||
|
};
|
||||||
|
|
||||||
|
//- sixten: Scalar functions
|
||||||
|
|
||||||
|
inline r32 Floor(r32 x) { r32 Result = floorf(x); return(Result); }
|
||||||
|
inline r32 Ceil(r32 x) { r32 Result = ceilf(x); return(Result); }
|
||||||
|
inline r32 Round(r32 x) { r32 Result = roundf(x); return(Result); }
|
||||||
|
inline r32 Mod(r32 x, r32 y) { r32 Result = fmodf(x, y); return(Result); }
|
||||||
|
inline r32 SquareRoot(r32 x) { r32 Result = sqrtf(x); return(Result); }
|
||||||
|
inline r32 AbsoluteValue(r32 x) { r32 Result = fabsf(x); return(Result); }
|
||||||
|
inline r32 Sin(r32 x) { r32 Result = sinf(x); return(Result); }
|
||||||
|
inline r32 Cos(r32 x) { r32 Result = cosf(x); return(Result); }
|
||||||
|
inline r32 Tan(r32 x) { r32 Result = tanf(x); return(Result); }
|
||||||
|
inline r32 Pow(r32 Base, r32 Exponent) { r32 Result = powf(Base, Exponent); return(Result); }
|
||||||
|
inline r32 Log10(r32 x) { r32 Result = log10f(x); return(Result); }
|
||||||
|
inline r32 Log(r32 x) { r32 Result = logf(x); return(Result); }
|
||||||
|
|
||||||
|
inline r32 LinearBlend(r32 a, r32 b, r32 x) { r32 Result = a + (b-a)*x; return(Result); }
|
||||||
|
|
||||||
|
inline r32 Min(r32 A, r32 B) { r32 Result = Minimum(A, B); return(Result); }
|
||||||
|
inline r32 Max(r32 A, r32 B) { r32 Result = Maximum(A, B); return(Result); }
|
||||||
|
|
||||||
|
//- sixten: Vector functions
|
||||||
|
|
||||||
|
inline v2_r32 V2R32(r32 x, r32 y);
|
||||||
|
inline v2_r32 operator+(v2_r32 A, v2_r32 B);
|
||||||
|
inline v2_r32 operator-(v2_r32 A, v2_r32 B);
|
||||||
|
inline v2_r32 operator*(v2_r32 A, v2_r32 B);
|
||||||
|
inline v2_r32 operator/(v2_r32 A, v2_r32 B);
|
||||||
|
inline v2_r32 operator*(v2_r32 A, r32 B);
|
||||||
|
inline v2_r32 operator+=(v2_r32 &A, v2_r32 B);
|
||||||
|
inline v2_r32 operator-=(v2_r32 &A, v2_r32 B);
|
||||||
|
inline v2_r32 operator*=(v2_r32 &A, v2_r32 B);
|
||||||
|
inline v2_r32 operator/=(v2_r32 &A, v2_r32 B);
|
||||||
|
inline v2_r32 operator*=(v2_r32 &A, r32 B);
|
||||||
|
inline r32 Inner(v2_r32 A, v2_r32 B);
|
||||||
|
inline r32 LengthSquared(v2_r32 V);
|
||||||
|
inline r32 Length(v2_r32 V);
|
||||||
|
inline v2_r32 NOZ(v2_r32 V);
|
||||||
|
inline v2_r32 LinearBlend(v2_r32 A, v2_r32 B, r32 x);
|
||||||
|
inline v2_r32 Min(v2_r32 A, v2_r32 B);
|
||||||
|
inline v2_r32 Max(v2_r32 A, v2_r32 B);
|
||||||
|
|
||||||
|
inline v2_s32 V2S32(s32 x, s32 y);
|
||||||
|
inline v2_s32 operator+(v2_s32 A, v2_s32 B);
|
||||||
|
inline v2_s32 operator-(v2_s32 A, v2_s32 B);
|
||||||
|
inline v2_s32 operator+=(v2_s32 &A, v2_s32 B);
|
||||||
|
inline v2_s32 operator-=(v2_s32 &A, v2_s32 B);
|
||||||
|
inline v2_s32 Min(v2_s32 A, v2_s32 B);
|
||||||
|
inline v2_s32 Max(v2_s32 A, v2_s32 B);
|
||||||
|
|
||||||
|
inline v2_s64 V2S64(s64 x, s64 y);
|
||||||
|
inline v2_s64 operator+(v2_s64 A, v2_s64 B);
|
||||||
|
inline v2_s64 operator-(v2_s64 A, v2_s64 B);
|
||||||
|
inline v2_s64 operator+=(v2_s64 &A, v2_s64 B);
|
||||||
|
inline v2_s64 operator-=(v2_s64 &A, v2_s64 B);
|
||||||
|
inline v2_s64 Min(v2_s64 A, v2_s64 B);
|
||||||
|
inline v2_s64 Max(v2_s64 A, v2_s64 B);
|
||||||
|
|
||||||
|
inline v3_r32 V3R32(r32 x, r32 y, r32 z);
|
||||||
|
inline v3_r32 operator+(v3_r32 A, v3_r32 B);
|
||||||
|
inline v3_r32 operator-(v3_r32 A, v3_r32 B);
|
||||||
|
inline v3_r32 operator*(v3_r32 A, v3_r32 B);
|
||||||
|
inline v3_r32 operator/(v3_r32 A, v3_r32 B);
|
||||||
|
inline v3_r32 operator*(v3_r32 A, r32 B);
|
||||||
|
inline v3_r32 operator+=(v3_r32 &A, v3_r32 B);
|
||||||
|
inline v3_r32 operator-=(v3_r32 &A, v3_r32 B);
|
||||||
|
inline v3_r32 operator*=(v3_r32 &A, v3_r32 B);
|
||||||
|
inline v3_r32 operator/=(v3_r32 &A, v3_r32 B);
|
||||||
|
inline v3_r32 operator*=(v3_r32 &A, r32 B);
|
||||||
|
inline r32 Inner(v3_r32 A, v3_r32 B);
|
||||||
|
inline r32 LengthSquared(v3_r32 V);
|
||||||
|
inline r32 Length(v3_r32 V);
|
||||||
|
inline v3_r32 NOZ(v3_r32 V);
|
||||||
|
inline v3_r32 LinearBlend(v3_r32 A, v3_r32 B, r32 x);
|
||||||
|
inline v3_r32 Cross(v3_r32 A, v3_r32 B);
|
||||||
|
inline v3_r32 Min(v3_r32 A, v3_r32 B);
|
||||||
|
inline v3_r32 Max(v3_r32 A, v3_r32 B);
|
||||||
|
|
||||||
|
inline v3_s32 V3S32(s32 x, s32 y, s32 z);
|
||||||
|
inline v3_s32 operator+(v3_s32 A, v3_s32 B);
|
||||||
|
inline v3_s32 operator-(v3_s32 A, v3_s32 B);
|
||||||
|
inline v3_s32 operator+=(v3_s32 &A, v3_s32 B);
|
||||||
|
inline v3_s32 operator-=(v3_s32 &A, v3_s32 B);
|
||||||
|
inline v3_s32 Min(v3_s32 A, v3_s32 B);
|
||||||
|
inline v3_s32 Max(v3_s32 A, v3_s32 B);
|
||||||
|
|
||||||
|
inline v3_s64 V3S64(s64 x, s64 y, s64 z);
|
||||||
|
inline v3_s64 operator+(v3_s64 A, v3_s64 B);
|
||||||
|
inline v3_s64 operator-(v3_s64 A, v3_s64 B);
|
||||||
|
inline v3_s64 operator+=(v3_s64 &A, v3_s64 B);
|
||||||
|
inline v3_s64 operator-=(v3_s64 &A, v3_s64 B);
|
||||||
|
inline v3_s64 Min(v3_s64 A, v3_s64 B);
|
||||||
|
inline v3_s64 Max(v3_s64 A, v3_s64 B);
|
||||||
|
|
||||||
|
inline v4_r32 V4R32(r32 x, r32 y, r32 z, r32 w);
|
||||||
|
inline v4_r32 operator+(v4_r32 A, v4_r32 B);
|
||||||
|
inline v4_r32 operator-(v4_r32 A, v4_r32 B);
|
||||||
|
inline v4_r32 operator*(v4_r32 A, v4_r32 B);
|
||||||
|
inline v4_r32 operator/(v4_r32 A, v4_r32 B);
|
||||||
|
inline v4_r32 operator*(v4_r32 A, r32 B);
|
||||||
|
inline v4_r32 operator+=(v4_r32 &A, v4_r32 B);
|
||||||
|
inline v4_r32 operator-=(v4_r32 &A, v4_r32 B);
|
||||||
|
inline v4_r32 operator*=(v4_r32 &A, v4_r32 B);
|
||||||
|
inline v4_r32 operator/=(v4_r32 &A, v4_r32 B);
|
||||||
|
inline v4_r32 operator*=(v4_r32 &A, r32 B);
|
||||||
|
inline r32 Inner(v4_r32 A, v4_r32 B);
|
||||||
|
inline r32 LengthSquared(v4_r32 V);
|
||||||
|
inline r32 Length(v4_r32 V);
|
||||||
|
inline v4_r32 NOZ(v4_r32 V);
|
||||||
|
inline v4_r32 LinearBlend(v4_r32 A, v4_r32 B, r32 x);
|
||||||
|
inline v4_r32 Min(v4_r32 A, v4_r32 B);
|
||||||
|
inline v4_r32 Max(v4_r32 A, v4_r32 B);
|
||||||
|
|
||||||
|
inline v4_s32 V4S32(s32 x, s32 y, s32 z, s32 w);
|
||||||
|
inline v4_s32 operator+(v4_s32 A, v4_s32 B);
|
||||||
|
inline v4_s32 operator-(v4_s32 A, v4_s32 B);
|
||||||
|
inline v4_s32 operator+=(v4_s32 &A, v4_s32 B);
|
||||||
|
inline v4_s32 operator-=(v4_s32 &A, v4_s32 B);
|
||||||
|
inline v4_s32 Min(v4_s32 A, v4_s32 B);
|
||||||
|
inline v4_s32 Max(v4_s32 A, v4_s32 B);
|
||||||
|
|
||||||
|
inline v4_s64 V4S64(s64 x, s64 y, s64 z, s64 w);
|
||||||
|
inline v4_s64 operator+(v4_s64 A, v4_s64 B);
|
||||||
|
inline v4_s64 operator-(v4_s64 A, v4_s64 B);
|
||||||
|
inline v4_s64 operator+=(v4_s64 &A, v4_s64 B);
|
||||||
|
inline v4_s64 operator-=(v4_s64 &A, v4_s64 B);
|
||||||
|
inline v4_s64 Min(v4_s64 A, v4_s64 B);
|
||||||
|
inline v4_s64 Max(v4_s64 A, v4_s64 B);
|
||||||
|
|
||||||
|
//- sixten: Range functions
|
||||||
|
|
||||||
|
inline range1_r32 Range1R32(r32 Min, r32 Max);
|
||||||
|
inline b32 InRange(range1_r32 Range, r32 Value);
|
||||||
|
inline r32 DimOfRange(range1_r32 Range);
|
||||||
|
|
||||||
|
inline range1_s32 Range1S32(s32 Min, s32 Max);
|
||||||
|
inline b32 InRange(range1_s32 Range, s32 Value);
|
||||||
|
inline s32 DimOfRange(range1_s32 Range);
|
||||||
|
|
||||||
|
inline range1_s64 Range1S64(s64 Min, s64 Max);
|
||||||
|
inline b32 InRange(range1_s64 Range, s64 Value);
|
||||||
|
inline s64 DimOfRange(range1_s64 Range);
|
||||||
|
|
||||||
|
inline range2_r32 Range2R32(v2_r32 Min, v2_r32 Max);
|
||||||
|
inline b32 InRange(range2_r32 Range, v2_r32 Value);
|
||||||
|
inline v2_r32 DimOfRange(range2_r32 Range);
|
||||||
|
|
||||||
|
inline range2_s32 Range2S32(v2_s32 Min, v2_s32 Max);
|
||||||
|
inline b32 InRange(range2_s32 Range, v2_s32 Value);
|
||||||
|
inline v2_s32 DimOfRange(range2_s32 Range);
|
||||||
|
|
||||||
|
inline range2_s64 Range2S64(v2_s64 Min, v2_s64 Max);
|
||||||
|
inline b32 InRange(range2_s64 Range, v2_s64 Value);
|
||||||
|
inline v2_s64 DimOfRange(range2_s64 Range);
|
||||||
|
|
||||||
|
//- sixten: Shorthand base types
|
||||||
|
|
||||||
|
typedef v2_r32 v2;
|
||||||
|
typedef v3_r32 v3;
|
||||||
|
typedef v4_r32 v4;
|
||||||
|
|
||||||
|
#define V2(...) V2R32(__VA_ARGS__)
|
||||||
|
#define V3(...) V3R32(__VA_ARGS__)
|
||||||
|
#define V4(...) V4R32(__VA_ARGS__)
|
||||||
|
|
||||||
|
#endif //CORE_MATH_H
|
|
@ -1,60 +1,34 @@
|
||||||
/* date = April 26th 2023 10:11 pm */
|
//- sixten: Common memory functions
|
||||||
|
|
||||||
#ifndef VN_MEMORY_H
|
static void Copy(void *Dest, void *Source, umm Count)
|
||||||
#define VN_MEMORY_H
|
|
||||||
|
|
||||||
struct memory_arena
|
|
||||||
{
|
{
|
||||||
platform_memory_block *CurrentBlock;
|
u8 *Dest8 = (u8 *)Dest;
|
||||||
umm MinimumBlockSize;
|
u8 *Source8 = (u8 *)Source;
|
||||||
s32 TemporaryMemoryCount;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct temporary_memory
|
while(Count--)
|
||||||
{
|
{
|
||||||
memory_arena *Arena;
|
*Dest8++ = *Source8++;
|
||||||
platform_memory_block *Block;
|
}
|
||||||
umm Used;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline temporary_memory BeginTemporaryMemory(memory_arena *Arena)
|
|
||||||
{
|
|
||||||
temporary_memory Result;
|
|
||||||
Result.Arena = Arena;
|
|
||||||
Result.Block = Arena->CurrentBlock;
|
|
||||||
Result.Used = Arena->CurrentBlock ? Arena->CurrentBlock->Used : 0;
|
|
||||||
|
|
||||||
++Arena->TemporaryMemoryCount;
|
|
||||||
|
|
||||||
return(Result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void EndTemporaryMemory(temporary_memory Temp)
|
static void Fill(void *Dest, u8 Value, umm Count)
|
||||||
{
|
{
|
||||||
memory_arena *Arena = Temp.Arena;
|
u8 *Dest8 = (u8 *)Dest;
|
||||||
while(Arena->CurrentBlock != Temp.Block)
|
|
||||||
{
|
|
||||||
platform_memory_block *MemoryBlock = Arena->CurrentBlock;
|
|
||||||
Arena->CurrentBlock = MemoryBlock->ArenaPrev;
|
|
||||||
Platform.DeallocateMemory(MemoryBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Arena->CurrentBlock)
|
while(Count--)
|
||||||
{
|
{
|
||||||
Assert(Arena->CurrentBlock->Used >= Temp.Used);
|
*Dest8++ = Value;
|
||||||
Arena->CurrentBlock->Used = Temp.Used;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert(Arena->TemporaryMemoryCount > 0);
|
|
||||||
--Arena->TemporaryMemoryCount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//- sixten: Memory arena functions
|
||||||
|
|
||||||
static void Release(memory_arena *Arena)
|
static void Release(memory_arena *Arena)
|
||||||
{
|
{
|
||||||
while(Arena->CurrentBlock != 0)
|
while(Arena->CurrentBlock != 0)
|
||||||
{
|
{
|
||||||
platform_memory_block *MemoryBlock = Arena->CurrentBlock;
|
platform_memory_block *MemoryBlock = Arena->CurrentBlock;
|
||||||
b32 IsLastBlock = MemoryBlock->ArenaPrev == 0;
|
b32 IsLastBlock = (MemoryBlock->ArenaPrev == 0);
|
||||||
Arena->CurrentBlock = MemoryBlock->ArenaPrev;
|
Arena->CurrentBlock = MemoryBlock->ArenaPrev;
|
||||||
Platform.DeallocateMemory(MemoryBlock);
|
Platform.DeallocateMemory(MemoryBlock);
|
||||||
|
|
||||||
|
@ -65,32 +39,6 @@ static void Release(memory_arena *Arena)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum arena_push_flag
|
|
||||||
{
|
|
||||||
ArenaFlag_ClearToZero = 0x1,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct arena_push_params
|
|
||||||
{
|
|
||||||
u32 Flags;
|
|
||||||
u32 Alignment;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline arena_push_params DefaultArenaParams(void)
|
|
||||||
{
|
|
||||||
arena_push_params Params = {};
|
|
||||||
Params.Flags = ArenaFlag_ClearToZero;
|
|
||||||
Params.Alignment = 4;
|
|
||||||
return(Params);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline arena_push_params NoClear(void)
|
|
||||||
{
|
|
||||||
arena_push_params Params = DefaultArenaParams();
|
|
||||||
Params.Flags &= ~ArenaFlag_ClearToZero;
|
|
||||||
return(Params);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline umm GetAlignmentOffset(memory_arena *Arena, umm Alignment)
|
inline umm GetAlignmentOffset(memory_arena *Arena, umm Alignment)
|
||||||
{
|
{
|
||||||
umm AlignmentOffset = 0;
|
umm AlignmentOffset = 0;
|
||||||
|
@ -115,11 +63,7 @@ inline umm GetEffectiveSizeFor(memory_arena *Arena, umm InitialSize, arena_push_
|
||||||
return(Size);
|
return(Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PushSize(Arena, InitialSize, ...) PushSize_(Arena, InitialSize, __VA_ARGS__)
|
static void *PushSize_(memory_arena *Arena, umm InitialSize, arena_push_params Params)
|
||||||
#define PushStruct(Arena, type, ...) (type *)PushSize_(Arena, sizeof(type), __VA_ARGS__)
|
|
||||||
#define PushArray(Arena, type, Count, ...) (type *)PushSize_(Arena, sizeof(type)*Count, __VA_ARGS__)
|
|
||||||
|
|
||||||
inline void *PushSize_(memory_arena *Arena, umm InitialSize, arena_push_params Params = DefaultArenaParams())
|
|
||||||
{
|
{
|
||||||
void *Result = 0;
|
void *Result = 0;
|
||||||
|
|
||||||
|
@ -157,12 +101,14 @@ inline void *PushSize_(memory_arena *Arena, umm InitialSize, arena_push_params P
|
||||||
|
|
||||||
if(Params.Flags & ArenaFlag_ClearToZero)
|
if(Params.Flags & ArenaFlag_ClearToZero)
|
||||||
{
|
{
|
||||||
ZeroSize(Result, InitialSize);
|
Fill(Result, 0, InitialSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//- sixten: Bootsrapping helpers
|
||||||
|
|
||||||
static void *BootstrapPushSize(umm Size, umm OffsetToArena)
|
static void *BootstrapPushSize(umm Size, umm OffsetToArena)
|
||||||
{
|
{
|
||||||
memory_arena Arena = {};
|
memory_arena Arena = {};
|
||||||
|
@ -172,54 +118,36 @@ static void *BootstrapPushSize(umm Size, umm OffsetToArena)
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BootstrapPushStruct(type, Member) (type *)BootstrapPushSize(sizeof(type), OffsetOf(type, Member))
|
//- sixten: Temporary memory functions
|
||||||
|
|
||||||
static string PushString(memory_arena *Arena, string String)
|
static temporary_memory BeginTemporaryMemory(memory_arena *Arena)
|
||||||
{
|
{
|
||||||
string Result = MakeString(PushArray(Arena, char, String.Count + 1), String.Count);
|
temporary_memory Result;
|
||||||
Copy(Result.Data, String.Data, String.Count);
|
Result.Arena = Arena;
|
||||||
|
Result.Block = Arena->CurrentBlock;
|
||||||
|
Result.Used = Arena->CurrentBlock ? Arena->CurrentBlock->Used : 0;
|
||||||
|
|
||||||
Result.Data[Result.Count] = 0;
|
++Arena->TemporaryMemoryCount;
|
||||||
|
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static string PushFormatVariadic(memory_arena *Arena, char *Format, va_list Arguments)
|
static void EndTemporaryMemory(temporary_memory Temp)
|
||||||
{
|
{
|
||||||
va_list ArgumentsCopy;
|
memory_arena *Arena = Temp.Arena;
|
||||||
va_copy(ArgumentsCopy, Arguments);
|
while(Arena->CurrentBlock != Temp.Block)
|
||||||
|
{
|
||||||
|
platform_memory_block *MemoryBlock = Arena->CurrentBlock;
|
||||||
|
Arena->CurrentBlock = MemoryBlock->ArenaPrev;
|
||||||
|
Platform.DeallocateMemory(MemoryBlock);
|
||||||
|
}
|
||||||
|
|
||||||
string Result;
|
if(Arena->CurrentBlock)
|
||||||
Result.Count = stbsp_vsnprintf(0, 0, Format, ArgumentsCopy);
|
{
|
||||||
Result.Data = (u8 *)PushSize(Arena, Result.Count + 1, NoClear());
|
Assert(Arena->CurrentBlock->Used >= Temp.Used);
|
||||||
Result.Data[Result.Count] = 0;
|
Arena->CurrentBlock->Used = Temp.Used;
|
||||||
|
}
|
||||||
|
|
||||||
stbsp_vsnprintf((char *)Result.Data, (s32)Result.Count + 1, Format, Arguments);
|
Assert(Arena->TemporaryMemoryCount > 0);
|
||||||
|
--Arena->TemporaryMemoryCount;
|
||||||
return(Result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline string PushFormat(memory_arena *Arena, char *Format, ...)
|
|
||||||
{
|
|
||||||
va_list Arguments;
|
|
||||||
va_start(Arguments, Format);
|
|
||||||
string Result = PushFormatVariadic(Arena, Format, Arguments);
|
|
||||||
va_end(Arguments);
|
|
||||||
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
// sixten(TODO): Scuffed AF. Need to make a proper "core" of the codebase.
|
|
||||||
inline s64 StringLength(char *String);
|
|
||||||
|
|
||||||
inline string PushCString(memory_arena *Arena, char *CString)
|
|
||||||
{
|
|
||||||
string Result;
|
|
||||||
Result.Count = StringLength(CString);
|
|
||||||
Result.Data = PushArray(Arena, u8, Result.Count);
|
|
||||||
Copy(Result.Data, CString, Result.Count);
|
|
||||||
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //VN_MEMORY_H
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
/* date = June 19th 2023 10:07 pm */
|
||||||
|
|
||||||
|
#ifndef CORE_MEMORY_H
|
||||||
|
#define CORE_MEMORY_H
|
||||||
|
|
||||||
|
//- sixten: Common memory functions
|
||||||
|
|
||||||
|
static void Copy(void *Dest, void *Source, umm Count);
|
||||||
|
static void Fill(void *Dest, u8 Value, umm Count);
|
||||||
|
|
||||||
|
//- sixten: Memory arena types
|
||||||
|
|
||||||
|
struct platform_memory_block;
|
||||||
|
|
||||||
|
struct memory_arena
|
||||||
|
{
|
||||||
|
platform_memory_block *CurrentBlock;
|
||||||
|
umm MinimumBlockSize;
|
||||||
|
s32 TemporaryMemoryCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct temporary_memory
|
||||||
|
{
|
||||||
|
memory_arena *Arena;
|
||||||
|
platform_memory_block *Block;
|
||||||
|
umm Used;
|
||||||
|
};
|
||||||
|
|
||||||
|
//- sixten: Arena push flags
|
||||||
|
|
||||||
|
enum arena_push_flag
|
||||||
|
{
|
||||||
|
ArenaFlag_ClearToZero = 0x1,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct arena_push_params
|
||||||
|
{
|
||||||
|
u32 Flags;
|
||||||
|
u32 Alignment;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline arena_push_params DefaultArenaParams(void)
|
||||||
|
{
|
||||||
|
arena_push_params Params = {};
|
||||||
|
Params.Flags = ArenaFlag_ClearToZero;
|
||||||
|
Params.Alignment = 4;
|
||||||
|
return(Params);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline arena_push_params NoClear(void)
|
||||||
|
{
|
||||||
|
arena_push_params Params = DefaultArenaParams();
|
||||||
|
Params.Flags &= ~ArenaFlag_ClearToZero;
|
||||||
|
return(Params);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- sixten: Memory arena functions
|
||||||
|
|
||||||
|
static void Release(memory_arena *Arena);
|
||||||
|
|
||||||
|
#define PushSize(Arena, InitialSize, ...) PushSize_(Arena, InitialSize, __VA_ARGS__)
|
||||||
|
#define PushStruct(Arena, type, ...) (type *)PushSize_(Arena, sizeof(type), __VA_ARGS__)
|
||||||
|
#define PushArray(Arena, type, Count, ...) (type *)PushSize_(Arena, sizeof(type)*Count, __VA_ARGS__)
|
||||||
|
static void *PushSize_(memory_arena *Arena, umm InitialSize, arena_push_params Params = DefaultArenaParams());
|
||||||
|
|
||||||
|
//- sixten: Bootstrapping helpers
|
||||||
|
|
||||||
|
#define BootstrapPushStruct(type, Member) (type *)BootstrapPushSize(sizeof(type), OffsetOf(type, Member))
|
||||||
|
static void *BootstrapPushSize(umm Size, umm OffsetToArena);
|
||||||
|
|
||||||
|
//- sixten: Temporary memory functions
|
||||||
|
|
||||||
|
static temporary_memory BeginTemporaryMemory(memory_arena *Arena);
|
||||||
|
static void EndTemporaryMemory(temporary_memory Temp);
|
||||||
|
|
||||||
|
#endif //CORE_MEMORY_H
|
|
@ -1,7 +1,7 @@
|
||||||
/* date = May 7th 2023 9:01 pm */
|
#define STB_SPRINTF_IMPLEMENTATION
|
||||||
|
#include "third_party/stb_sprintf.h"
|
||||||
|
|
||||||
#ifndef VN_STRING_H
|
//~ sixten: Char funcitons
|
||||||
#define VN_STRING_H
|
|
||||||
|
|
||||||
inline b32 IsWhitespace(char C)
|
inline b32 IsWhitespace(char C)
|
||||||
{
|
{
|
||||||
|
@ -24,39 +24,26 @@ inline b32 IsLetter(char C)
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline s64 StringLength(char *String)
|
|
||||||
|
//~ sixten: String functions
|
||||||
|
|
||||||
|
//- sixten: Basic constructors
|
||||||
|
|
||||||
|
inline string MakeString(u8 *Data, s64 Count)
|
||||||
{
|
{
|
||||||
s64 Result = 0;
|
string Result = {Count, Data};
|
||||||
while(*String++)
|
|
||||||
{
|
|
||||||
++Result;
|
|
||||||
}
|
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline string MakeStringFromCString(char *Data)
|
inline string MakeString(char *CString)
|
||||||
{
|
{
|
||||||
string Result = {StringLength(Data), (u8 *)Data};
|
string Result = {StringLength(CString), (u8 *)CString};
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline u64 HashString(string String)
|
//- sixten: Equality
|
||||||
{
|
|
||||||
u64 Result = 5731;
|
|
||||||
for(s64 Index = 0;
|
|
||||||
Index < String.Count;
|
|
||||||
++Index)
|
|
||||||
{
|
|
||||||
Result += String.Data[Index];
|
|
||||||
Result ^= Result << 13;
|
|
||||||
Result ^= Result >> 7;
|
|
||||||
Result ^= Result << 17;
|
|
||||||
}
|
|
||||||
|
|
||||||
return(Result);
|
static b32 AreEqual(string A, string B)
|
||||||
}
|
|
||||||
|
|
||||||
inline b32 AreEqual(string A, string B)
|
|
||||||
{
|
{
|
||||||
b32 Result = false;
|
b32 Result = false;
|
||||||
if(A.Count == B.Count)
|
if(A.Count == B.Count)
|
||||||
|
@ -78,7 +65,49 @@ inline b32 AreEqual(string A, string B)
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline s64 FirstIndexOf(string String, char Char)
|
//- sixten: Substring
|
||||||
|
|
||||||
|
static string Substring(string String, range1_s64 Range)
|
||||||
|
{
|
||||||
|
string Result = MakeString(String.Data + Range.Min, DimOfRange(Range));
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static string Prefix(string String, s64 Count)
|
||||||
|
{
|
||||||
|
range1_s64 Range = Range1S64(0, Count);
|
||||||
|
string Result = Substring(String, Range);
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static string Suffix(string String, s64 Count)
|
||||||
|
{
|
||||||
|
range1_s64 Range = Range1S64(String.Count - Count, String.Count);
|
||||||
|
string Result = Substring(String, Range);
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- sixten: Hashing
|
||||||
|
|
||||||
|
static u64 HashString(string String)
|
||||||
|
{
|
||||||
|
u64 Result = 5731;
|
||||||
|
for(s64 Index = 0;
|
||||||
|
Index < String.Count;
|
||||||
|
++Index)
|
||||||
|
{
|
||||||
|
Result += String.Data[Index];
|
||||||
|
Result ^= Result << 13;
|
||||||
|
Result ^= Result >> 7;
|
||||||
|
Result ^= Result << 17;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- sixten: Searching
|
||||||
|
|
||||||
|
static s64 FirstIndexOf(string String, char Char)
|
||||||
{
|
{
|
||||||
s64 Result = -1;
|
s64 Result = -1;
|
||||||
for(s64 Index = 0;
|
for(s64 Index = 0;
|
||||||
|
@ -94,7 +123,7 @@ inline s64 FirstIndexOf(string String, char Char)
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline s64 LastIndexOf(string String, char Char)
|
static s64 LastIndexOf(string String, char Char)
|
||||||
{
|
{
|
||||||
s64 Result = -1;
|
s64 Result = -1;
|
||||||
for(s64 Index = String.Count-1;
|
for(s64 Index = String.Count-1;
|
||||||
|
@ -110,26 +139,94 @@ inline s64 LastIndexOf(string String, char Char)
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline s64 LastIndexOf(string String, string Substring)
|
static s64 FirstIndexOf(string String, string Sub)
|
||||||
{
|
{
|
||||||
s64 Result = -1;
|
s64 Result = -1;
|
||||||
if(String.Count >= Substring.Count)
|
if(String.Count >= Sub.Count)
|
||||||
{
|
{
|
||||||
for(s64 Index = String.Count-Substring.Count;
|
for(s64 Index = 0;
|
||||||
Index >= 0;
|
Index < String.Count - Sub.Count;
|
||||||
--Index)
|
++Index)
|
||||||
{
|
{
|
||||||
string ToCheck = MakeString((char *)String.Data + Index, Substring.Count);
|
string ToCheck = Substring(String, Range1S64(Index, Index + Sub.Count));
|
||||||
if(AreEqual(ToCheck, Substring))
|
if(AreEqual(ToCheck, Sub))
|
||||||
{
|
{
|
||||||
Result = Index;
|
Result = Index;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static s64 LastIndexOf(string String, string Sub)
|
||||||
|
{
|
||||||
|
s64 Result = -1;
|
||||||
|
if(String.Count >= Sub.Count)
|
||||||
|
{
|
||||||
|
for(s64 Index = String.Count - Sub.Count - 1;
|
||||||
|
Index >= 0;
|
||||||
|
--Index)
|
||||||
|
{
|
||||||
|
string ToCheck = Substring(String, Range1S64(Index, Index + Sub.Count));
|
||||||
|
if(AreEqual(ToCheck, Sub))
|
||||||
|
{
|
||||||
|
Result = Index;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- sixten: Allocation
|
||||||
|
|
||||||
|
static string PushString(memory_arena *Arena, string String)
|
||||||
|
{
|
||||||
|
string Result;
|
||||||
|
Result.Data = PushArray(Arena, u8, String.Count, NoClear());
|
||||||
|
Result.Count = String.Count;
|
||||||
|
Copy(Result.Data, String.Data, String.Count);
|
||||||
|
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static string PushFormatVariadic(memory_arena *Arena, char *Format, va_list Arguments)
|
||||||
|
{
|
||||||
|
va_list ArgumentsCopy;
|
||||||
|
va_copy(ArgumentsCopy, Arguments);
|
||||||
|
|
||||||
|
string Result;
|
||||||
|
Result.Count = stbsp_vsnprintf(0, 0, Format, ArgumentsCopy);
|
||||||
|
Result.Data = PushArray(Arena, u8, Result.Count + 1, NoClear());
|
||||||
|
Result.Data[Result.Count] = 0;
|
||||||
|
|
||||||
|
stbsp_vsnprintf((char *)Result.Data, (s32)Result.Count + 1, Format, Arguments);
|
||||||
|
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static string PushFormat(memory_arena *Arena, char *Format, ...)
|
||||||
|
{
|
||||||
|
va_list Arguments;
|
||||||
|
va_start(Arguments, Format);
|
||||||
|
string Result = PushFormatVariadic(Arena, Format, Arguments);
|
||||||
|
va_end(Arguments);
|
||||||
|
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static string PushCString(memory_arena *Arena, char *CString)
|
||||||
|
{
|
||||||
|
string String = MakeString(CString);
|
||||||
|
string Result = PushString(Arena, String);
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- sixten: Conversion
|
||||||
|
|
||||||
static s64 ConvertStringToS64(string String)
|
static s64 ConvertStringToS64(string String)
|
||||||
{
|
{
|
||||||
s64 Result = 0;
|
s64 Result = 0;
|
||||||
|
@ -151,13 +248,13 @@ static s64 ConvertStringToS64(string String)
|
||||||
|
|
||||||
if(IsNegative)
|
if(IsNegative)
|
||||||
{
|
{
|
||||||
Result = -Result;
|
Result = -Result;;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static string ConvertS64ToString(s64 Value, memory_arena *Arena)
|
static string ConvertS64ToString(memory_arena *Arena, s64 Value)
|
||||||
{
|
{
|
||||||
b32 IsNegative = (Value < 0);
|
b32 IsNegative = (Value < 0);
|
||||||
if(IsNegative)
|
if(IsNegative)
|
||||||
|
@ -188,25 +285,113 @@ static string ConvertS64ToString(s64 Value, memory_arena *Arena)
|
||||||
return(String);
|
return(String);
|
||||||
}
|
}
|
||||||
|
|
||||||
static string Substring(string String, range_s64 Range)
|
static string StringFromCodepoint(memory_arena *Arena, u32 Codepoint)
|
||||||
{
|
{
|
||||||
string Result = MakeString((char *)String.Data + Range.Min, DimOfRange(Range));
|
char Buffer[5] = {};
|
||||||
|
UTF8FromCodepoint((u8 *)Buffer, Codepoint);
|
||||||
|
|
||||||
|
string Result = PushCString(Arena, Buffer);
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static string Prefix(string String, s64 Count)
|
//- sixten: "C Style" strings
|
||||||
{
|
|
||||||
range_s64 Range = RangeS64(0, Count);
|
static s64 StringLength(char *String)
|
||||||
|
{
|
||||||
|
s64 Result = 0;
|
||||||
|
while(*String++)
|
||||||
|
{
|
||||||
|
++Result;
|
||||||
|
}
|
||||||
|
|
||||||
string Result = Substring(String, Range);
|
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static string Suffix(string String, s64 Count)
|
|
||||||
{
|
|
||||||
range_s64 Range = RangeS64(String.Count - Count, String.Count);
|
|
||||||
|
|
||||||
string Result = Substring(String, Range);
|
//~ sixten: String list
|
||||||
|
|
||||||
|
static void AppendString(string_list *List, string String, memory_arena *Arena)
|
||||||
|
{
|
||||||
|
string_node *Node = PushStruct(Arena, string_node);
|
||||||
|
Node->String = String;
|
||||||
|
|
||||||
|
List->TotalCount += String.Count;
|
||||||
|
|
||||||
|
DLLInsertLast(List->First, List->Last, Node);
|
||||||
|
}
|
||||||
|
|
||||||
|
static string JoinStringList(string_list *List, memory_arena *Arena)
|
||||||
|
{
|
||||||
|
u8 *Buffer = PushArray(Arena, u8, List->TotalCount + 1);
|
||||||
|
Buffer[List->TotalCount] = 0;
|
||||||
|
|
||||||
|
s64 GlobalIndex = 0;
|
||||||
|
|
||||||
|
for(string_node *Node = List->First;
|
||||||
|
Node != 0;
|
||||||
|
Node = Node->Next)
|
||||||
|
{
|
||||||
|
string String = Node->String;
|
||||||
|
for(s64 Index = 0;
|
||||||
|
Index < String.Count;
|
||||||
|
++Index)
|
||||||
|
{
|
||||||
|
Buffer[GlobalIndex++] = String.Data[Index];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string Result = MakeString(Buffer, List->TotalCount);
|
||||||
|
return(Result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//~ sixten: Unicode
|
||||||
|
|
||||||
|
static utf8_iterator IterateUTF8String(string String)
|
||||||
|
{
|
||||||
|
utf8_iterator Iter = {};
|
||||||
|
Iter.Data = String;
|
||||||
|
Advance(&Iter);
|
||||||
|
|
||||||
|
return(Iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Advance(utf8_iterator *Iter)
|
||||||
|
{
|
||||||
|
u8 *At = Iter->Data.Data + Iter->Index;
|
||||||
|
|
||||||
|
if(Iter->Index < Iter->Data.Count)
|
||||||
|
{
|
||||||
|
if((At[0] & 0x80) == 0x00)
|
||||||
|
{
|
||||||
|
Iter->Codepoint = (At[0] & 0x7F);
|
||||||
|
Iter->Index += 1;
|
||||||
|
}
|
||||||
|
else if((At[0] & 0xE0) == 0xC0)
|
||||||
|
{
|
||||||
|
Iter->Codepoint = ((At[0] & 0x1F) << 6)|(At[1] & 0x3F);
|
||||||
|
Iter->Index += 2;
|
||||||
|
}
|
||||||
|
else if((At[0] & 0xF0) == 0xE0)
|
||||||
|
{
|
||||||
|
Iter->Codepoint = ((At[0] & 0x0F) << 12)|((At[1] & 0x3F) << 6)|(At[2] & 0x3F);
|
||||||
|
Iter->Index += 3;
|
||||||
|
}
|
||||||
|
else if((Iter->Data.Data[Iter->Index] & 0xF8) == 0xF0)
|
||||||
|
{
|
||||||
|
Iter->Codepoint = ((At[0] & 0x0F) << 18)|((At[1] & 0x3F) << 12)|((At[2] & 0x3F) << 6)|(At[3] & 0x3F);
|
||||||
|
Iter->Index += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Iter->Codepoint = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static b32 IsValid(utf8_iterator *Iter)
|
||||||
|
{
|
||||||
|
b32 Result = (Iter->Codepoint != 0);
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,127 +432,3 @@ static s64 UTF8FromCodepoint(u8 *Out, u32 Codepoint)
|
||||||
|
|
||||||
return(Length);
|
return(Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline s64 GetCodepointSize(u32 Codepoint)
|
|
||||||
{
|
|
||||||
s64 Result = 0;
|
|
||||||
if(Codepoint <= 0x7F)
|
|
||||||
{
|
|
||||||
Result = 1;
|
|
||||||
}
|
|
||||||
else if(Codepoint <= 0x7FF)
|
|
||||||
{
|
|
||||||
Result = 2;
|
|
||||||
}
|
|
||||||
else if(Codepoint <= 0xFFFF)
|
|
||||||
{
|
|
||||||
Result = 3;
|
|
||||||
}
|
|
||||||
else if(Codepoint <= 0x10FFFF)
|
|
||||||
{
|
|
||||||
Result = 4;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Result = 1;
|
|
||||||
}
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
// sixten(TODO): Remove this forward decl.
|
|
||||||
inline string PushCString(struct memory_arena *Arena, char *CString);
|
|
||||||
|
|
||||||
inline string StringFromCodepoint(struct memory_arena *Arena, u32 Codepoint)
|
|
||||||
{
|
|
||||||
char Buffer[5] = {};
|
|
||||||
UTF8FromCodepoint((u8 *)Buffer, Codepoint);
|
|
||||||
|
|
||||||
string Result = PushCString(Arena, Buffer);
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct utf8_iterator
|
|
||||||
{
|
|
||||||
string Data;
|
|
||||||
s64 Index;
|
|
||||||
|
|
||||||
u32 Codepoint;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline void Advance(utf8_iterator *Iter)
|
|
||||||
{
|
|
||||||
u8 *At = Iter->Data.Data + Iter->Index;
|
|
||||||
|
|
||||||
if(Iter->Index < Iter->Data.Count)
|
|
||||||
{
|
|
||||||
if((At[0] & 0x80) == 0x00)
|
|
||||||
{
|
|
||||||
Iter->Codepoint = (At[0] & 0x7F);
|
|
||||||
Iter->Index += 1;
|
|
||||||
}
|
|
||||||
else if((At[0] & 0xE0) == 0xC0)
|
|
||||||
{
|
|
||||||
Iter->Codepoint = ((At[0] & 0x1F) << 6)|(At[1] & 0x3F);
|
|
||||||
Iter->Index += 2;
|
|
||||||
}
|
|
||||||
else if((At[0] & 0xF0) == 0xE0)
|
|
||||||
{
|
|
||||||
Iter->Codepoint = ((At[0] & 0x0F) << 12)|((At[1] & 0x3F) << 6)|(At[2] & 0x3F);
|
|
||||||
Iter->Index += 3;
|
|
||||||
}
|
|
||||||
else if((Iter->Data.Data[Iter->Index] & 0xF8) == 0xF0)
|
|
||||||
{
|
|
||||||
Iter->Codepoint = ((At[0] & 0x0F) << 18)|((At[1] & 0x3F) << 12)|((At[2] & 0x3F) << 6)|(At[3] & 0x3F);
|
|
||||||
Iter->Index += 4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Iter->Codepoint = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline utf8_iterator IterateUTF8String(string String)
|
|
||||||
{
|
|
||||||
utf8_iterator Iter = {};
|
|
||||||
Iter.Data = String;
|
|
||||||
Advance(&Iter);
|
|
||||||
|
|
||||||
return(Iter);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void AppendString(string_list *List, string String, memory_arena *Arena)
|
|
||||||
{
|
|
||||||
string_node *Node = PushStruct(Arena, string_node);
|
|
||||||
Node->String = String;
|
|
||||||
|
|
||||||
List->TotalCount += String.Count;
|
|
||||||
|
|
||||||
DLLInsertLast(List->First, List->Last, Node);
|
|
||||||
}
|
|
||||||
|
|
||||||
static string JoinStringList(string_list *List, memory_arena *Arena)
|
|
||||||
{
|
|
||||||
u8 *Buffer = PushArray(Arena, u8, List->TotalCount + 1);
|
|
||||||
Buffer[List->TotalCount] = 0;
|
|
||||||
|
|
||||||
s64 GlobalIndex = 0;
|
|
||||||
|
|
||||||
for(string_node *Node = List->First;
|
|
||||||
Node != 0;
|
|
||||||
Node = Node->Next)
|
|
||||||
{
|
|
||||||
string String = Node->String;
|
|
||||||
for(s64 Index = 0;
|
|
||||||
Index < String.Count;
|
|
||||||
++Index)
|
|
||||||
{
|
|
||||||
Buffer[GlobalIndex++] = String.Data[Index];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
string Result = MakeString((char *)Buffer, List->TotalCount);
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //VN_STRING_H
|
|
|
@ -0,0 +1,111 @@
|
||||||
|
/* date = June 19th 2023 9:15 pm */
|
||||||
|
|
||||||
|
#ifndef CORE_STRING_H
|
||||||
|
#define CORE_STRING_H
|
||||||
|
|
||||||
|
/////////////////////////////////////
|
||||||
|
//~ sixten: String types
|
||||||
|
|
||||||
|
struct string
|
||||||
|
{
|
||||||
|
s64 Count;
|
||||||
|
u8 *Data;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef string buffer;
|
||||||
|
|
||||||
|
struct string_node
|
||||||
|
{
|
||||||
|
string String;
|
||||||
|
string_node *Next;
|
||||||
|
string_node *Prev;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct string_list
|
||||||
|
{
|
||||||
|
string_node *First;
|
||||||
|
string_node *Last;
|
||||||
|
|
||||||
|
s64 TotalCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//~ sixten: Char funcitons
|
||||||
|
|
||||||
|
inline b32 IsWhitespace(char C);
|
||||||
|
inline b32 IsDigit(char C);
|
||||||
|
inline b32 IsLetter(char C);
|
||||||
|
|
||||||
|
|
||||||
|
//~ sixten: String functions
|
||||||
|
|
||||||
|
//- sixten: Basic constructors
|
||||||
|
|
||||||
|
inline string MakeString(u8 *Data, s64 Count);
|
||||||
|
inline string MakeString(char *CString);
|
||||||
|
#define StrLit(String) MakeString((u8 *)String, ArrayCount(String) - 1)
|
||||||
|
|
||||||
|
//- sixten: Equality
|
||||||
|
|
||||||
|
static b32 AreEqual(string A, string B);
|
||||||
|
|
||||||
|
//- sixten: Substring
|
||||||
|
|
||||||
|
static string Substring(string String, range1_s64 Range);
|
||||||
|
static string Prefix(string String, s64 Count);
|
||||||
|
static string Suffix(string String, s64 Count);
|
||||||
|
|
||||||
|
//- sixten: Hashing
|
||||||
|
|
||||||
|
static u64 HashString(string String);
|
||||||
|
|
||||||
|
//- sixten: Searching
|
||||||
|
|
||||||
|
static s64 FirstIndexOf(string String, char Char);
|
||||||
|
static s64 LastIndexOf(string String, char Char);
|
||||||
|
static s64 FirstIndexOf(string String, string Sub);
|
||||||
|
static s64 LastIndexOf(string String, string Sub);
|
||||||
|
|
||||||
|
//- sixten: Allocation
|
||||||
|
|
||||||
|
static string PushString(memory_arena *Arena, string String);
|
||||||
|
static string PushFormatVariadic(memory_arena *Arena, char *Format, va_list Arguments);
|
||||||
|
static string PushFormat(memory_arena *Arena, char *Format, ...);
|
||||||
|
static string PushCString(memory_arena *Arena, char *String);
|
||||||
|
|
||||||
|
//- sixten: Conversion
|
||||||
|
|
||||||
|
static s64 ConvertStringToS64(string String);
|
||||||
|
static string ConvertS64ToString(memory_arena *Arena, s64 Value);
|
||||||
|
static string StringFromCodepoint(memory_arena *Arena, u32 Codepoint);
|
||||||
|
|
||||||
|
//- sixten: "C Style" strings
|
||||||
|
|
||||||
|
static s64 StringLength(char *String);
|
||||||
|
|
||||||
|
|
||||||
|
//~ sixten: String list
|
||||||
|
|
||||||
|
static void AppendString(string_list *List, string String, memory_arena *Arena);
|
||||||
|
static string JoinStringList(string_list *List, memory_arena *Arena);
|
||||||
|
|
||||||
|
|
||||||
|
//~ sixten: Unicode
|
||||||
|
|
||||||
|
struct utf8_iterator
|
||||||
|
{
|
||||||
|
// sixten: Input
|
||||||
|
string Data;
|
||||||
|
s64 Index;
|
||||||
|
|
||||||
|
// sixten: Output
|
||||||
|
u32 Codepoint;
|
||||||
|
};
|
||||||
|
|
||||||
|
static utf8_iterator IterateUTF8String(string String);
|
||||||
|
static void Advance(utf8_iterator *Iter);
|
||||||
|
static b32 IsValid(utf8_iterator *Iter);
|
||||||
|
|
||||||
|
static s64 UTF8FromCodepoint(u8 *Out, u32 Codepoint);
|
||||||
|
|
||||||
|
#endif //CORE_STRING_H
|
|
@ -0,0 +1,45 @@
|
||||||
|
per_thread thread_context *ThreadLocal_ThreadContext = 0;
|
||||||
|
|
||||||
|
static void SetThreadContext(thread_context *Context)
|
||||||
|
{
|
||||||
|
ThreadLocal_ThreadContext = Context;
|
||||||
|
}
|
||||||
|
|
||||||
|
static thread_context *GetThreadContext(void)
|
||||||
|
{
|
||||||
|
return(ThreadLocal_ThreadContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
static temporary_memory GetScratch(memory_arena **Conflicts, u64 ConflictCount)
|
||||||
|
{
|
||||||
|
temporary_memory Scratch = {};
|
||||||
|
thread_context *Context = GetThreadContext();
|
||||||
|
|
||||||
|
for(u64 ArenaIndex = 0;
|
||||||
|
ArenaIndex < ArrayCount(Context->Arenas);
|
||||||
|
++ArenaIndex)
|
||||||
|
{
|
||||||
|
b32 FoundConflict = false;
|
||||||
|
for(u64 ConflictIndex = 0;
|
||||||
|
ConflictIndex < ConflictCount;
|
||||||
|
++ConflictIndex)
|
||||||
|
{
|
||||||
|
memory_arena *Conflict = Conflicts[ConflictIndex];
|
||||||
|
if(Conflict == Context->Arenas + ArenaIndex)
|
||||||
|
{
|
||||||
|
FoundConflict = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!FoundConflict)
|
||||||
|
{
|
||||||
|
Scratch = BeginTemporaryMemory(Context->Arenas + ArenaIndex);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Assert(Scratch.Arena);
|
||||||
|
|
||||||
|
return(Scratch);
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
/* date = June 21st 2023 6:51 pm */
|
||||||
|
|
||||||
|
#ifndef CORE_THREAD_CONTEXT_H
|
||||||
|
#define CORE_THREAD_CONTEXT_H
|
||||||
|
|
||||||
|
struct thread_context
|
||||||
|
{
|
||||||
|
memory_arena Arenas[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
//- sixten: Thread state management
|
||||||
|
static void SetThreadContext(thread_context *Context);
|
||||||
|
static thread_context *GetThreadContext(void);
|
||||||
|
|
||||||
|
//- sixten: Scratch
|
||||||
|
static temporary_memory GetScratch(memory_arena **Conflicts = 0, u64 ConflictCount = 0);
|
||||||
|
#define ReleaseScratch(Scratch) EndTemporaryMemory(Scratch)
|
||||||
|
|
||||||
|
#endif //CORE_THREAD_CONTEXT_H
|
|
@ -430,7 +430,7 @@ static opengl_context OpenGL_SetupContext(vn_render_commands *RenderCommands, um
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
u32 WhiteData = 0xFFFFFFFF;
|
u32 WhiteData = 0xFFFFFFFF;
|
||||||
RenderCommands->WhiteTexture = OpenGL_AllocateTexture(V2S(1, 1), Render_TextureFormat_RGBA8, &WhiteData);
|
RenderCommands->WhiteTexture = OpenGL_AllocateTexture(V2S32(1, 1), Render_TextureFormat_RGBA8, &WhiteData);
|
||||||
|
|
||||||
RenderCommands->AllocateTexture = OpenGL_AllocateTexture;
|
RenderCommands->AllocateTexture = OpenGL_AllocateTexture;
|
||||||
RenderCommands->FillRegion = OpenGL_FillRegion;
|
RenderCommands->FillRegion = OpenGL_FillRegion;
|
||||||
|
|
|
@ -10,7 +10,7 @@ struct opengl_texture
|
||||||
{
|
{
|
||||||
u32 ID;
|
u32 ID;
|
||||||
render_texture_format Format;
|
render_texture_format Format;
|
||||||
v2s Dim;
|
v2_s32 Dim;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct quad_program
|
struct quad_program
|
||||||
|
|
|
@ -253,7 +253,7 @@ static void Config_WriteFile(config *Config)
|
||||||
IntegerValue = *(s64 *)Entry->Target;
|
IntegerValue = *(s64 *)Entry->Target;
|
||||||
}
|
}
|
||||||
|
|
||||||
string Value = ConvertS64ToString(IntegerValue, Scratch.Arena);
|
string Value = ConvertS64ToString(Scratch.Arena, IntegerValue);
|
||||||
AppendString(&Out, Value, Scratch.Arena);
|
AppendString(&Out, Value, Scratch.Arena);
|
||||||
}
|
}
|
||||||
else if(Entry->Type == Config_Entry_B32)
|
else if(Entry->Type == Config_Entry_B32)
|
||||||
|
|
269
code/vn_font.cpp
269
code/vn_font.cpp
|
@ -2,223 +2,224 @@
|
||||||
|
|
||||||
inline s32 GetSubpixelSegmentAtP(r32 Value)
|
inline s32 GetSubpixelSegmentAtP(r32 Value)
|
||||||
{
|
{
|
||||||
s32 Result = (s32)(Value - Floor(Value))*GLYPH_SUBPIXEL_SEGMENTS;
|
s32 Result = (s32)(Value - Floor(Value))*GLYPH_SUBPIXEL_SEGMENTS;
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void RasterizeGlyph(glyph_atlas *Atlas, font_id Font, glyph *Glyph, u32 Codepoint, r32 Size, s32 Subpixel)
|
static void RasterizeGlyph(glyph_atlas *Atlas, font_id Font, glyph *Glyph, u32 Codepoint, r32 Size, s32 Subpixel)
|
||||||
{
|
{
|
||||||
Glyph->Font = Font;
|
Glyph->Font = Font;
|
||||||
Glyph->Codepoint = Codepoint;
|
Glyph->Codepoint = Codepoint;
|
||||||
Glyph->Size = Size;
|
Glyph->Size = Size;
|
||||||
Glyph->Subpixel = Subpixel;
|
Glyph->Subpixel = Subpixel;
|
||||||
|
|
||||||
Assert(Subpixel < GLYPH_SUBPIXEL_SEGMENTS);
|
Assert(Subpixel < GLYPH_SUBPIXEL_SEGMENTS);
|
||||||
|
|
||||||
loaded_font *LoadedFont = Atlas->Fonts + Font;
|
loaded_font *LoadedFont = Atlas->Fonts + Font;
|
||||||
stbtt_fontinfo *Info = &LoadedFont->Info;
|
stbtt_fontinfo *Info = &LoadedFont->Info;
|
||||||
|
|
||||||
r32 Scale = stbtt_ScaleForMappingEmToPixels(Info, Size);
|
r32 Scale = stbtt_ScaleForMappingEmToPixels(Info, Size);
|
||||||
|
|
||||||
s32 InternalIndex = (s32)(Glyph - Atlas->Glyphs);
|
s32 InternalIndex = (s32)(Glyph - Atlas->Glyphs);
|
||||||
s32 GlyphsPerRow = Atlas->BitmapSize / Atlas->GlyphSize;
|
s32 GlyphsPerRow = Atlas->BitmapSize / Atlas->GlyphSize;
|
||||||
|
|
||||||
v2s BaseTextureOffset = V2S((InternalIndex % GlyphsPerRow)*Atlas->GlyphSize,
|
v2_s32 BaseTextureOffset = V2S32((InternalIndex % GlyphsPerRow)*Atlas->GlyphSize,
|
||||||
(InternalIndex / GlyphsPerRow)*Atlas->GlyphSize);
|
(InternalIndex / GlyphsPerRow)*Atlas->GlyphSize);
|
||||||
|
|
||||||
int GlyphIndex = stbtt_FindGlyphIndex(Info, Codepoint);
|
int GlyphIndex = stbtt_FindGlyphIndex(Info, Codepoint);
|
||||||
|
|
||||||
stbtt_GetGlyphBitmapBoxSubpixel(Info, GlyphIndex, Scale, Scale,
|
stbtt_GetGlyphBitmapBoxSubpixel(Info, GlyphIndex, Scale, Scale,
|
||||||
|
(r32)Subpixel/GLYPH_SUBPIXEL_SEGMENTS, 0,
|
||||||
|
&Glyph->P0.x, &Glyph->P0.y, &Glyph->P1.x, &Glyph->P1.y);
|
||||||
|
|
||||||
|
Fill(Atlas->BitmapBuffer, 0, Atlas->GlyphSize*Atlas->GlyphSize);
|
||||||
|
stbtt_MakeGlyphBitmapSubpixel(Info, Atlas->BitmapBuffer,
|
||||||
|
Atlas->GlyphSize, Atlas->GlyphSize, Atlas->GlyphSize,
|
||||||
|
Scale, Scale,
|
||||||
(r32)Subpixel/GLYPH_SUBPIXEL_SEGMENTS, 0,
|
(r32)Subpixel/GLYPH_SUBPIXEL_SEGMENTS, 0,
|
||||||
&Glyph->P0.x, &Glyph->P0.y, &Glyph->P1.x, &Glyph->P1.y);
|
GlyphIndex);
|
||||||
|
|
||||||
ZeroSize(Atlas->BitmapBuffer, Atlas->GlyphSize*Atlas->GlyphSize);
|
s32 Advance, LeftSideBearing;
|
||||||
stbtt_MakeGlyphBitmapSubpixel(Info, Atlas->BitmapBuffer,
|
stbtt_GetGlyphHMetrics(Info, GlyphIndex, &Advance, &LeftSideBearing);
|
||||||
Atlas->GlyphSize, Atlas->GlyphSize, Atlas->GlyphSize,
|
Glyph->Advance = Advance*Scale;
|
||||||
Scale, Scale,
|
Glyph->Offset.x = LeftSideBearing*Scale;
|
||||||
(r32)Subpixel/GLYPH_SUBPIXEL_SEGMENTS, 0,
|
|
||||||
GlyphIndex);
|
|
||||||
|
|
||||||
s32 Advance, LeftSideBearing;
|
Glyph->Offset.y = Glyph->P0.y + (LoadedFont->Ascent + LoadedFont->LineGap)*Scale;
|
||||||
stbtt_GetGlyphHMetrics(Info, GlyphIndex, &Advance, &LeftSideBearing);
|
|
||||||
Glyph->Advance = Advance*Scale;
|
|
||||||
Glyph->Offset.x = LeftSideBearing*Scale;
|
|
||||||
|
|
||||||
Glyph->Offset.y = Glyph->P0.y + (LoadedFont->Ascent + LoadedFont->LineGap)*Scale;
|
v2_s32 Dim = Glyph->P1 - Glyph->P0;
|
||||||
|
|
||||||
v2s Dim = Glyph->P1 - Glyph->P0;
|
Glyph->P0 = BaseTextureOffset;
|
||||||
|
Glyph->P1 = BaseTextureOffset + Dim + V2S32(2, 2);
|
||||||
|
|
||||||
Glyph->P0 = BaseTextureOffset;
|
Atlas->RenderCommands->FillRegion(Atlas->Texture,
|
||||||
Glyph->P1 = BaseTextureOffset + Dim + V2S(2, 2);
|
BaseTextureOffset, V2S32(Atlas->GlyphSize, Atlas->GlyphSize),
|
||||||
|
Atlas->BitmapBuffer);
|
||||||
Atlas->RenderCommands->FillRegion(Atlas->Texture,
|
|
||||||
BaseTextureOffset, V2S(Atlas->GlyphSize, Atlas->GlyphSize),
|
|
||||||
Atlas->BitmapBuffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static glyph *GetGlyph(glyph_atlas *Atlas, font_id Font, u32 Codepoint, r32 Size, s32 Subpixel)
|
static glyph *GetGlyph(glyph_atlas *Atlas, font_id Font, u32 Codepoint, r32 Size, s32 Subpixel)
|
||||||
{
|
{
|
||||||
glyph *Glyph = 0;
|
glyph *Glyph = 0;
|
||||||
|
|
||||||
for(s32 GlyphIndex = 0;
|
for(s32 GlyphIndex = 0;
|
||||||
GlyphIndex < Atlas->GlyphsUsed;
|
GlyphIndex < Atlas->GlyphsUsed;
|
||||||
++GlyphIndex)
|
++GlyphIndex)
|
||||||
{
|
|
||||||
glyph *At = Atlas->Glyphs + GlyphIndex;
|
|
||||||
if((At->Font == Font) && (At->Codepoint == Codepoint) && (At->Size == Size) && (At->Subpixel == Subpixel))
|
|
||||||
{
|
{
|
||||||
Glyph = At;
|
glyph *At = Atlas->Glyphs + GlyphIndex;
|
||||||
break;
|
if((At->Font == Font) && (At->Codepoint == Codepoint) && (At->Size == Size) && (At->Subpixel == Subpixel))
|
||||||
|
{
|
||||||
|
Glyph = At;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if(Glyph)
|
if(Glyph)
|
||||||
{
|
|
||||||
DLLRemove_NP(Atlas->LRUFirst, Atlas->LRULast, Glyph, LRUNext, LRUPrev);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(Atlas->GlyphsUsed < Atlas->MaxGlyphCount)
|
|
||||||
{
|
{
|
||||||
Glyph = Atlas->Glyphs + Atlas->GlyphsUsed++;
|
DLLRemove_NP(Atlas->LRUFirst, Atlas->LRULast, Glyph, LRUNext, LRUPrev);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Glyph = Atlas->LRUFirst;
|
if(Atlas->GlyphsUsed < Atlas->MaxGlyphCount)
|
||||||
Assert(Glyph);
|
{
|
||||||
|
Glyph = Atlas->Glyphs + Atlas->GlyphsUsed++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Glyph = Atlas->LRUFirst;
|
||||||
|
Assert(Glyph);
|
||||||
|
|
||||||
DLLRemove_NP(Atlas->LRUFirst, Atlas->LRULast, Glyph, LRUNext, LRUPrev);
|
DLLRemove_NP(Atlas->LRUFirst, Atlas->LRULast, Glyph, LRUNext, LRUPrev);
|
||||||
|
}
|
||||||
|
|
||||||
|
RasterizeGlyph(Atlas, Font, Glyph, Codepoint, Size, Subpixel);
|
||||||
}
|
}
|
||||||
|
|
||||||
RasterizeGlyph(Atlas, Font, Glyph, Codepoint, Size, Subpixel);
|
DLLInsertLast_NP(Atlas->LRUFirst, Atlas->LRULast, Glyph, LRUNext, LRUPrev);
|
||||||
}
|
|
||||||
|
|
||||||
DLLInsertLast_NP(Atlas->LRUFirst, Atlas->LRULast, Glyph, LRUNext, LRUPrev);
|
return(Glyph);
|
||||||
|
|
||||||
return(Glyph);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static glyph_atlas *CreateGlyphAtlas(vn_render_commands *RenderCommands,
|
static glyph_atlas *CreateGlyphAtlas(vn_render_commands *RenderCommands,
|
||||||
s32 BitmapSize = DEFAULT_GLYPH_ATLAS_DIM,
|
s32 BitmapSize = DEFAULT_GLYPH_ATLAS_DIM,
|
||||||
s32 GlyphSize = MAX_GLYPH_SIZE)
|
s32 GlyphSize = MAX_GLYPH_SIZE)
|
||||||
{
|
{
|
||||||
glyph_atlas *Atlas = BootstrapPushStruct(glyph_atlas, Arena);
|
glyph_atlas *Atlas = BootstrapPushStruct(glyph_atlas, Arena);
|
||||||
|
|
||||||
Atlas->BitmapSize = BitmapSize;
|
Atlas->BitmapSize = BitmapSize;
|
||||||
Atlas->GlyphSize = GlyphSize;
|
Atlas->GlyphSize = GlyphSize;
|
||||||
|
|
||||||
Atlas->MaxGlyphCount = (DEFAULT_GLYPH_ATLAS_DIM / MAX_GLYPH_SIZE)*(DEFAULT_GLYPH_ATLAS_DIM / MAX_GLYPH_SIZE);
|
Atlas->MaxGlyphCount = (DEFAULT_GLYPH_ATLAS_DIM / MAX_GLYPH_SIZE)*(DEFAULT_GLYPH_ATLAS_DIM / MAX_GLYPH_SIZE);
|
||||||
Atlas->Glyphs = PushArray(&Atlas->Arena, glyph, Atlas->MaxGlyphCount);
|
Atlas->Glyphs = PushArray(&Atlas->Arena, glyph, Atlas->MaxGlyphCount);
|
||||||
|
|
||||||
Atlas->RenderCommands = RenderCommands;
|
Atlas->RenderCommands = RenderCommands;
|
||||||
Atlas->Texture = RenderCommands->AllocateTexture(V2S(BitmapSize, BitmapSize), Render_TextureFormat_R8, 0);
|
Atlas->Texture = RenderCommands->AllocateTexture(V2S32(BitmapSize, BitmapSize), Render_TextureFormat_R8, 0);
|
||||||
|
|
||||||
Atlas->Fonts[Font_Regular].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("fonts/Roboto-Regular.ttf"));
|
Atlas->Fonts[Font_Regular].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("fonts/Roboto-Regular.ttf"));
|
||||||
Atlas->Fonts[Font_Bold].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("fonts/Roboto-Bold.ttf"));
|
Atlas->Fonts[Font_Bold].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("fonts/Roboto-Bold.ttf"));
|
||||||
Atlas->Fonts[Font_Monospace].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("fonts/Liberation-Mono.ttf"));
|
Atlas->Fonts[Font_Monospace].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("fonts/Liberation-Mono.ttf"));
|
||||||
Atlas->Fonts[Font_Icons].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("fonts/icons.ttf"));
|
Atlas->Fonts[Font_Icons].Data = Platform_ReadEntireFile(&Atlas->Arena, StrLit("fonts/icons.ttf"));
|
||||||
|
|
||||||
for(s32 FontIndex = 0;
|
for(s32 FontIndex = 0;
|
||||||
FontIndex < Font_Count;
|
FontIndex < Font_Count;
|
||||||
++FontIndex)
|
++FontIndex)
|
||||||
{
|
{
|
||||||
loaded_font *Font = Atlas->Fonts + FontIndex;
|
loaded_font *Font = Atlas->Fonts + FontIndex;
|
||||||
stbtt_InitFont(&Font->Info,
|
stbtt_InitFont(&Font->Info,
|
||||||
Font->Data.Data,
|
Font->Data.Data,
|
||||||
stbtt_GetFontOffsetForIndex(Font->Data.Data, 0));
|
stbtt_GetFontOffsetForIndex(Font->Data.Data, 0));
|
||||||
|
|
||||||
stbtt_GetFontVMetrics(&Font->Info, &Font->Ascent, &Font->Descent, &Font->LineGap);
|
stbtt_GetFontVMetrics(&Font->Info, &Font->Ascent, &Font->Descent, &Font->LineGap);
|
||||||
}
|
}
|
||||||
|
|
||||||
Atlas->BitmapBuffer = PushArray(&Atlas->Arena, u8, GlyphSize*GlyphSize);
|
Atlas->BitmapBuffer = PushArray(&Atlas->Arena, u8, GlyphSize*GlyphSize);
|
||||||
|
|
||||||
return(Atlas);
|
return(Atlas);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PushText(render_group *Group, glyph_atlas *Atlas, font_id Font,
|
static void PushText(render_group *Group, glyph_atlas *Atlas, font_id Font,
|
||||||
v2 P, r32 Size, v4 Color,
|
v2 P, r32 Size, v4 Color,
|
||||||
string Text)
|
string Text)
|
||||||
{
|
{
|
||||||
r32 Oversample = 2;
|
r32 Oversample = 2;
|
||||||
|
|
||||||
for(utf8_iterator Iter = IterateUTF8String(Text);
|
for(utf8_iterator Iter = IterateUTF8String(Text);
|
||||||
Iter.Codepoint != 0;
|
IsValid(&Iter);
|
||||||
Advance(&Iter))
|
Advance(&Iter))
|
||||||
{
|
{
|
||||||
u32 Codepoint = Iter.Codepoint;
|
u32 Codepoint = Iter.Codepoint;
|
||||||
|
|
||||||
glyph *Glyph = GetGlyph(Atlas, Font, Codepoint, Size*Oversample, GetSubpixelSegmentAtP(P.x*Oversample));
|
glyph *Glyph = GetGlyph(Atlas, Font, Codepoint, Size*Oversample, GetSubpixelSegmentAtP(P.x*Oversample));
|
||||||
Assert(Glyph);
|
Assert(Glyph);
|
||||||
|
|
||||||
v2 GlyphP = P;
|
v2 GlyphP = P;
|
||||||
GlyphP.x += Glyph->Offset.x/Oversample;
|
GlyphP.x += Glyph->Offset.x/Oversample;
|
||||||
GlyphP.y += Glyph->Offset.y/Oversample;
|
GlyphP.y += Glyph->Offset.y/Oversample;
|
||||||
|
|
||||||
v2 RenderDim = V2(Glyph->P1 - Glyph->P0);
|
v2 RenderDim = ConvertV2ToR32(Glyph->P1 - Glyph->P0);
|
||||||
v2 Dim = RenderDim;
|
v2 Dim = RenderDim;
|
||||||
Dim.x /= Oversample;
|
Dim.x /= Oversample;
|
||||||
Dim.y /= Oversample;
|
Dim.y /= Oversample;
|
||||||
|
|
||||||
PushTexturedQuad(Group, GlyphP, Dim, V2(Glyph->P0), RenderDim, Color, Color, Color, Color, 0, 0, 0, Atlas->Texture);
|
PushTexturedQuad(Group, GlyphP, Dim, ConvertV2ToR32(Glyph->P0), RenderDim,
|
||||||
|
Color, Color, Color, Color, 0, 0, 0, Atlas->Texture);
|
||||||
|
|
||||||
P.x += Glyph->Advance/Oversample;
|
P.x += Glyph->Advance/Oversample;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PushTextF(render_group *Group, glyph_atlas *Atlas, font_id Font,
|
static void PushTextF(render_group *Group, glyph_atlas *Atlas, font_id Font,
|
||||||
v2 P, r32 Size, v4 Color,
|
v2 P, r32 Size, v4 Color,
|
||||||
char *Format, ...)
|
char *Format, ...)
|
||||||
{
|
{
|
||||||
temporary_memory Scratch = GetScratch(0, 0);
|
temporary_memory Scratch = GetScratch(0, 0);
|
||||||
|
|
||||||
va_list Arguments;
|
va_list Arguments;
|
||||||
va_start(Arguments, Format);
|
va_start(Arguments, Format);
|
||||||
string String = PushFormatVariadic(Scratch.Arena, Format, Arguments);
|
string String = PushFormatVariadic(Scratch.Arena, Format, Arguments);
|
||||||
va_end(Arguments);
|
va_end(Arguments);
|
||||||
|
|
||||||
PushText(Group, Atlas, Font, P, Size, Color, String);
|
PushText(Group, Atlas, Font, P, Size, Color, String);
|
||||||
|
|
||||||
ReleaseScratch(Scratch);
|
ReleaseScratch(Scratch);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline r32 CalculateRasterizedTextWidth(glyph_atlas *Atlas, font_id Font, r32 Size, string Text)
|
inline r32 CalculateRasterizedTextWidth(glyph_atlas *Atlas, font_id Font, r32 Size, string Text)
|
||||||
{
|
{
|
||||||
r32 Oversample = 2;
|
r32 Oversample = 2;
|
||||||
|
|
||||||
r32 X = 0;
|
r32 X = 0;
|
||||||
|
|
||||||
for(utf8_iterator Iter = IterateUTF8String(Text);
|
for(utf8_iterator Iter = IterateUTF8String(Text);
|
||||||
Iter.Codepoint != 0;
|
Iter.Codepoint != 0;
|
||||||
Advance(&Iter))
|
Advance(&Iter))
|
||||||
{
|
{
|
||||||
u32 Codepoint = Iter.Codepoint;
|
u32 Codepoint = Iter.Codepoint;
|
||||||
|
|
||||||
glyph *Glyph = GetGlyph(Atlas, Font, Codepoint, Size*Oversample, GetSubpixelSegmentAtP(X*Oversample));
|
glyph *Glyph = GetGlyph(Atlas, Font, Codepoint, Size*Oversample, GetSubpixelSegmentAtP(X*Oversample));
|
||||||
Assert(Glyph);
|
Assert(Glyph);
|
||||||
|
|
||||||
X += Glyph->Advance/Oversample;
|
X += Glyph->Advance/Oversample;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(X);
|
return(X);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline r32 CalculateRasterizedTextHeight(glyph_atlas *Atlas, font_id Font, r32 Size, string Text)
|
inline r32 CalculateRasterizedTextHeight(glyph_atlas *Atlas, font_id Font, r32 Size, string Text)
|
||||||
{
|
{
|
||||||
r32 Scale = stbtt_ScaleForMappingEmToPixels(&Atlas->Fonts[Font].Info, Size)/
|
r32 Scale = stbtt_ScaleForMappingEmToPixels(&Atlas->Fonts[Font].Info, Size)/
|
||||||
stbtt_ScaleForPixelHeight(&Atlas->Fonts[Font].Info, Size);
|
stbtt_ScaleForPixelHeight(&Atlas->Fonts[Font].Info, Size);
|
||||||
|
|
||||||
r32 Y = Size*Scale;
|
r32 Y = Size*Scale;
|
||||||
|
|
||||||
for(utf8_iterator Iter = IterateUTF8String(Text);
|
for(utf8_iterator Iter = IterateUTF8String(Text);
|
||||||
Iter.Codepoint != 0;
|
Iter.Codepoint != 0;
|
||||||
Advance(&Iter))
|
Advance(&Iter))
|
||||||
{
|
|
||||||
u32 Codepoint = Iter.Codepoint;
|
|
||||||
|
|
||||||
if(Codepoint == '\n')
|
|
||||||
{
|
{
|
||||||
Y += Size*Scale;
|
u32 Codepoint = Iter.Codepoint;
|
||||||
|
|
||||||
|
if(Codepoint == '\n')
|
||||||
|
{
|
||||||
|
Y += Size*Scale;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
return(Y);
|
||||||
return(Y);
|
|
||||||
}
|
}
|
|
@ -64,8 +64,8 @@ struct glyph
|
||||||
r32 Size;
|
r32 Size;
|
||||||
s32 Subpixel;
|
s32 Subpixel;
|
||||||
|
|
||||||
v2s P0;
|
v2_s32 P0;
|
||||||
v2s P1;
|
v2_s32 P1;
|
||||||
v2 Offset;
|
v2 Offset;
|
||||||
r32 Advance;
|
r32 Advance;
|
||||||
};
|
};
|
||||||
|
|
144
code/vn_math.h
144
code/vn_math.h
|
@ -1,144 +0,0 @@
|
||||||
/* date = April 29th 2023 3:06 pm */
|
|
||||||
|
|
||||||
#ifndef VN_MATH_H
|
|
||||||
#define VN_MATH_H
|
|
||||||
|
|
||||||
#include "math.h"
|
|
||||||
|
|
||||||
inline r32 Round(r32 Value)
|
|
||||||
{
|
|
||||||
r32 Result = roundf(Value);
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline r32 Floor(r32 Value)
|
|
||||||
{
|
|
||||||
r32 Result = floorf(Value);
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline r32 Ceil(r32 Value)
|
|
||||||
{
|
|
||||||
r32 Result = ceilf(Value);
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline r32 Log(r32 Value)
|
|
||||||
{
|
|
||||||
r32 Result = logf(Value);
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline r32 Pow(r32 Base, r32 Exponent)
|
|
||||||
{
|
|
||||||
r32 Result = powf(Base, Exponent);
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline r32 AbsoluteValue(r32 Value)
|
|
||||||
{
|
|
||||||
r32 Result = fabsf(Value);
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline b32 AreAlmostEqual(r32 A, r32 B)
|
|
||||||
{
|
|
||||||
b32 Result = false;
|
|
||||||
|
|
||||||
r32 Epsilon = 0.001;
|
|
||||||
if(AbsoluteValue(A - B) < Epsilon)
|
|
||||||
{
|
|
||||||
Result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline s64 Min(s64 A, s64 B)
|
|
||||||
{
|
|
||||||
s64 Result = Minimum(A, B);
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline s64 Max(s64 A, s64 B)
|
|
||||||
{
|
|
||||||
s64 Result = Maximum(A, B);
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline v2s operator+(v2s A, v2s B)
|
|
||||||
{
|
|
||||||
v2s Result = {A.x + B.x, A.y + B.y};
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline v2s operator-(v2s A, v2s B)
|
|
||||||
{
|
|
||||||
v2s Result = {A.x - B.x, A.y - B.y};
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline v2s operator+=(v2s &A, v2s B) { return A = A + B; }
|
|
||||||
inline v2s operator-=(v2s &A, v2s B) { return A = A - B; }
|
|
||||||
|
|
||||||
inline v2 operator+(v2 A, v2 B)
|
|
||||||
{
|
|
||||||
v2 Result = {A.x + B.x, A.y + B.y};
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline v2 operator-(v2 A, v2 B)
|
|
||||||
{
|
|
||||||
v2 Result = {A.x - B.x, A.y - B.y};
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline v2 operator*(v2 A, r32 B)
|
|
||||||
{
|
|
||||||
v2 Result = {A.x*B, A.y*B};
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline v2 operator+=(v2 &A, v2 B) { return A = A + B; }
|
|
||||||
inline v2 operator-=(v2 &A, v2 B) { return A = A - B; }
|
|
||||||
|
|
||||||
inline v2 Min(v2 A, v2 B)
|
|
||||||
{
|
|
||||||
v2 Result = V2(Minimum(A.x, B.x), Minimum(A.y, B.y));
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline v2 Max(v2 A, v2 B)
|
|
||||||
{
|
|
||||||
v2 Result = V2(Maximum(A.x, B.x), Maximum(A.y, B.y));
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline v4 operator+(v4 A, v4 B)
|
|
||||||
{
|
|
||||||
v4 Result = {A.x + B.x, A.y + B.y, A.z + B.z, A.w + B.w};
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline v4 operator-(v4 A, v4 B)
|
|
||||||
{
|
|
||||||
v4 Result = {A.x - B.x, A.y - B.y, A.z - B.z, A.w - B.w};
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline v4 operator*(v4 A, r32 B)
|
|
||||||
{
|
|
||||||
v4 Result = {A.x*B, A.y*B, A.z*B, A.w*B};
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline v4 operator+=(v4 &A, v4 B) { return A = A + B; }
|
|
||||||
inline v4 operator-=(v4 &A, v4 B) { return A = A - B; }
|
|
||||||
|
|
||||||
inline v4 LinearBlend(v4 A, v4 B, r32 C)
|
|
||||||
{
|
|
||||||
v4 Result = A + (B - A) * C;
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //VN_MATH_H
|
|
|
@ -3,7 +3,11 @@
|
||||||
#ifndef VN_PLATFORM_H
|
#ifndef VN_PLATFORM_H
|
||||||
#define VN_PLATFORM_H
|
#define VN_PLATFORM_H
|
||||||
|
|
||||||
#include "vn_core.h"
|
#include "core/core.h"
|
||||||
|
#include "core/core_math.h"
|
||||||
|
#include "core/core_memory.h"
|
||||||
|
#include "core/core_string.h"
|
||||||
|
#include "core/core_thread_context.h"
|
||||||
|
|
||||||
// sixten: Services the platform provides to the application
|
// sixten: Services the platform provides to the application
|
||||||
|
|
||||||
|
@ -172,10 +176,10 @@ static platform_api Platform;
|
||||||
|
|
||||||
#include "vn_render.h"
|
#include "vn_render.h"
|
||||||
|
|
||||||
#define RENDER_ALLOCATE_TEXTURE(name) render_handle name(v2s Dim, render_texture_format Format, void *Data)
|
#define RENDER_ALLOCATE_TEXTURE(name) render_handle name(v2_s32 Dim, render_texture_format Format, void *Data)
|
||||||
typedef RENDER_ALLOCATE_TEXTURE(render_allocate_texture);
|
typedef RENDER_ALLOCATE_TEXTURE(render_allocate_texture);
|
||||||
|
|
||||||
#define RENDER_FILL_REGION(name) void name(render_handle Handle, v2s DestP, v2s DestDim, void *Data)
|
#define RENDER_FILL_REGION(name) void name(render_handle Handle, v2_s32 DestP, v2_s32 DestDim, void *Data)
|
||||||
typedef RENDER_FILL_REGION(render_fill_region);
|
typedef RENDER_FILL_REGION(render_fill_region);
|
||||||
|
|
||||||
struct vn_render_commands
|
struct vn_render_commands
|
||||||
|
@ -200,10 +204,6 @@ struct vn_render_commands
|
||||||
v2 RenderDim;
|
v2 RenderDim;
|
||||||
};
|
};
|
||||||
|
|
||||||
#include "vn_memory.h"
|
|
||||||
#include "vn_string.h"
|
|
||||||
#include "vn_thread_context.h"
|
|
||||||
|
|
||||||
// sixten: Services the application provides to the platform
|
// sixten: Services the application provides to the platform
|
||||||
|
|
||||||
struct vn_input
|
struct vn_input
|
||||||
|
@ -231,4 +231,9 @@ struct vn_memory
|
||||||
#define VN_UPDATE_AND_RENDER(name) void name(thread_context *ThreadContext, vn_memory *Memory, vn_input *Input, vn_render_commands *RenderCommands)
|
#define VN_UPDATE_AND_RENDER(name) void name(thread_context *ThreadContext, vn_memory *Memory, vn_input *Input, vn_render_commands *RenderCommands)
|
||||||
typedef VN_UPDATE_AND_RENDER(vn_update_and_render);
|
typedef VN_UPDATE_AND_RENDER(vn_update_and_render);
|
||||||
|
|
||||||
|
#include "core/core_math.cpp"
|
||||||
|
#include "core/core_memory.cpp"
|
||||||
|
#include "core/core_string.cpp"
|
||||||
|
#include "core/core_thread_context.cpp"
|
||||||
|
|
||||||
#endif //VN_PLATFORM_H
|
#endif //VN_PLATFORM_H
|
||||||
|
|
|
@ -9,9 +9,9 @@ inline b32 AreEqual(render_handle A, render_handle B)
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline v2s GetTextureDim(render_handle Handle)
|
inline v2_s32 GetTextureDim(render_handle Handle)
|
||||||
{
|
{
|
||||||
v2s Result = V2S(Handle.U32[2], Handle.U32[3]);
|
v2_s32 Result = V2S32(Handle.U32[2], Handle.U32[3]);
|
||||||
return(Result);
|
return(Result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ static void *PushCommand_(render_group *Group, render_command_type Type, u64 Siz
|
||||||
|
|
||||||
Result = Commands->PushBufferAt;
|
Result = Commands->PushBufferAt;
|
||||||
Commands->PushBufferAt += Size;
|
Commands->PushBufferAt += Size;
|
||||||
ZeroSize(Result, Size);
|
Fill(Result, 0, Size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
struct text_op
|
struct text_op
|
||||||
{
|
{
|
||||||
range_s64 Range;
|
range1_s64 Range;
|
||||||
string ReplaceString;
|
string ReplaceString;
|
||||||
string CopyString;
|
string CopyString;
|
||||||
s64 NewCursor;
|
s64 NewCursor;
|
||||||
|
@ -224,7 +224,7 @@ static text_op TextOpFromAction(memory_arena *Arena, string String,
|
||||||
|
|
||||||
Op.NewCursor = State->Cursor;
|
Op.NewCursor = State->Cursor;
|
||||||
Op.NewMark = State->Mark;
|
Op.NewMark = State->Mark;
|
||||||
Op.Range = RangeS64(0, 0);
|
Op.Range = Range1S64(0, 0);
|
||||||
Op.ReplaceString = StrLit("");
|
Op.ReplaceString = StrLit("");
|
||||||
|
|
||||||
s64 Delta = 0;
|
s64 Delta = 0;
|
||||||
|
@ -264,7 +264,7 @@ static text_op TextOpFromAction(memory_arena *Arena, string String,
|
||||||
|
|
||||||
if(Action->Flags & TextActionFlag_Delete)
|
if(Action->Flags & TextActionFlag_Delete)
|
||||||
{
|
{
|
||||||
Op.Range = RangeS64(Op.NewCursor, Op.NewMark);
|
Op.Range = Range1S64(Op.NewCursor, Op.NewMark);
|
||||||
Op.NewCursor = Op.NewMark = Op.Range.Min;
|
Op.NewCursor = Op.NewMark = Op.Range.Min;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,12 +275,12 @@ static text_op TextOpFromAction(memory_arena *Arena, string String,
|
||||||
if(State->Cursor == State->Mark)
|
if(State->Cursor == State->Mark)
|
||||||
{
|
{
|
||||||
Op.NewCursor += Op.ReplaceString.Count;
|
Op.NewCursor += Op.ReplaceString.Count;
|
||||||
Op.Range = RangeS64(State->Cursor, State->Cursor);
|
Op.Range = Range1S64(State->Cursor, State->Cursor);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Op.NewCursor += Op.ReplaceString.Count;
|
Op.NewCursor += Op.ReplaceString.Count;
|
||||||
Op.Range = RangeS64(State->Cursor, State->Mark);
|
Op.Range = Range1S64(State->Cursor, State->Mark);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
213
code/vn_types.h
213
code/vn_types.h
|
@ -1,213 +0,0 @@
|
||||||
/* date = April 26th 2023 4:55 pm */
|
|
||||||
|
|
||||||
#ifndef VN_TYPES_H
|
|
||||||
#define VN_TYPES_H
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <intrin.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
||||||
struct string
|
|
||||||
{
|
|
||||||
s64 Count;
|
|
||||||
u8 *Data;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct string16
|
|
||||||
{
|
|
||||||
s64 Count;
|
|
||||||
s16 *Data;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef string buffer;
|
|
||||||
typedef string16 buffer16;
|
|
||||||
|
|
||||||
#define StrLit(String) MakeString(String, ArrayCount(String) - 1)
|
|
||||||
#define Str16Lit(String) MakeString16(String, ArrayCount(String) - 1)
|
|
||||||
|
|
||||||
inline string MakeString(char *Data, s64 Count)
|
|
||||||
{
|
|
||||||
string Result = {Count, (u8 *)Data};
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline string MakeString16(wchar_t *Data, s64 Count)
|
|
||||||
{
|
|
||||||
string Result = {Count, (u8 *)Data};
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct string_node
|
|
||||||
{
|
|
||||||
string String;
|
|
||||||
string_node *Next;
|
|
||||||
string_node *Prev;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct string_list
|
|
||||||
{
|
|
||||||
string_node *First;
|
|
||||||
string_node *Last;
|
|
||||||
|
|
||||||
s64 TotalCount;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct v2s
|
|
||||||
{
|
|
||||||
s32 x, y;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline v2s V2S(s32 x, s32 y)
|
|
||||||
{
|
|
||||||
v2s Result = {x, y};
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct v2u
|
|
||||||
{
|
|
||||||
u32 x, y;
|
|
||||||
};
|
|
||||||
|
|
||||||
inline v2u V2U(u32 x, u32 y)
|
|
||||||
{
|
|
||||||
v2u Result = {x, y};
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct v2
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
r32 x, y;
|
|
||||||
};
|
|
||||||
r32 E[2];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
inline v2 V2(r32 x, r32 y)
|
|
||||||
{
|
|
||||||
v2 Result = {x, y};
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline v2 V2(v2s V)
|
|
||||||
{
|
|
||||||
v2 Result = {(r32)V.x, (r32)V.y};
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct v3
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
r32 x, y, z;
|
|
||||||
};
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
r32 r, g, b;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
inline v3 V3(r32 x, r32 y, r32 z)
|
|
||||||
{
|
|
||||||
v3 Result = {x, y, z};
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct v4
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
r32 x, y, z, w;
|
|
||||||
};
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
r32 r, g, b, a;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
inline v4 V4(r32 x, r32 y, r32 z, r32 w)
|
|
||||||
{
|
|
||||||
v4 Result = {x, y, z, w};
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
enum axis2
|
|
||||||
{
|
|
||||||
Axis2_X,
|
|
||||||
Axis2_Y,
|
|
||||||
Axis2_Count,
|
|
||||||
};
|
|
||||||
|
|
||||||
inline axis2 Opposite(axis2 Axis)
|
|
||||||
{
|
|
||||||
axis2 Result = (axis2)(!(u32)Axis);
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct range_s64
|
|
||||||
{
|
|
||||||
s64 Min;
|
|
||||||
s64 Max;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct range_r32
|
|
||||||
{
|
|
||||||
r32 Min;
|
|
||||||
r32 Max;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct range2_r32
|
|
||||||
{
|
|
||||||
v2 Min;
|
|
||||||
v2 Max;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ticket_mutex
|
|
||||||
{
|
|
||||||
u64 volatile Ticket;
|
|
||||||
u64 volatile Serving;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif //VN_TYPES_H
|
|
|
@ -664,7 +664,7 @@ static void UI_DrawBox(ui_box *Box, render_group *Group, glyph_atlas *GlyphAtlas
|
||||||
r32 R = (((Box->Key.Value >> 0) & ((1 << 22) - 1)) / (r32)((1 << 22) - 1));
|
r32 R = (((Box->Key.Value >> 0) & ((1 << 22) - 1)) / (r32)((1 << 22) - 1));
|
||||||
r32 G = (((Box->Key.Value >> 21) & ((1 << 22) - 1)) / (r32)((1 << 22) - 1));
|
r32 G = (((Box->Key.Value >> 21) & ((1 << 22) - 1)) / (r32)((1 << 22) - 1));
|
||||||
r32 B = (((Box->Key.Value >> 42) & ((1 << 22) - 1)) / (r32)((1 << 22) - 1));
|
r32 B = (((Box->Key.Value >> 42) & ((1 << 22) - 1)) / (r32)((1 << 22) - 1));
|
||||||
v4 Red = V4(R, G, B, 1);
|
v4 Red = V4R32(R, G, B, 1);
|
||||||
PushQuad(Group, Box->Rect.Min, Box->ComputedDim, Red, Red, Red, Red, 0, 1.8, 1.8);
|
PushQuad(Group, Box->Rect.Min, Box->ComputedDim, Red, Red, Red, Red, 0, 1.8, 1.8);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -34,7 +34,7 @@ static void Workspace_ProcessCommands(workspace *Workspace)
|
||||||
Command = Command->Next;
|
Command = Command->Next;
|
||||||
|
|
||||||
DLLRemove(Workspace->FirstCommand, Workspace->LastCommand, ToRemove);
|
DLLRemove(Workspace->FirstCommand, Workspace->LastCommand, ToRemove);
|
||||||
ZeroSize(ToRemove, sizeof(workspace_command));
|
Fill(ToRemove, 0, sizeof(workspace_command));
|
||||||
DLLInsertLast(Workspace->FirstFreeCommand, Workspace->LastFreeCommand, ToRemove);
|
DLLInsertLast(Workspace->FirstFreeCommand, Workspace->LastFreeCommand, ToRemove);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,8 +54,8 @@ inline string Workspace_GetViewName(workspace_view *View)
|
||||||
static void Workspace_ViewListerInputCallback(render_group *Group, glyph_atlas *Atlas, ui_box *Box, void *Data)
|
static void Workspace_ViewListerInputCallback(render_group *Group, glyph_atlas *Atlas, ui_box *Box, void *Data)
|
||||||
{
|
{
|
||||||
workspace_view_command_palette *CommandPalette = (workspace_view_command_palette *)Data;
|
workspace_view_command_palette *CommandPalette = (workspace_view_command_palette *)Data;
|
||||||
string ToCursor = MakeString((char *)Box->String.Data, CommandPalette->ListerInputEditState.Cursor);
|
string ToCursor = MakeString(Box->String.Data, CommandPalette->ListerInputEditState.Cursor);
|
||||||
string ToMark = MakeString((char *)Box->String.Data, CommandPalette->ListerInputEditState.Mark);
|
string ToMark = MakeString(Box->String.Data, CommandPalette->ListerInputEditState.Mark);
|
||||||
|
|
||||||
r32 TargetCursorX = CalculateRasterizedTextWidth(Atlas, Box->Font, Box->FontSize, ToCursor);
|
r32 TargetCursorX = CalculateRasterizedTextWidth(Atlas, Box->Font, Box->FontSize, ToCursor);
|
||||||
r32 TargetMarkerX = CalculateRasterizedTextWidth(Atlas, Box->Font, Box->FontSize, ToMark);
|
r32 TargetMarkerX = CalculateRasterizedTextWidth(Atlas, Box->Font, Box->FontSize, ToMark);
|
||||||
|
@ -88,7 +88,7 @@ static void Workspace_ViewListerInputCallback(render_group *Group, glyph_atlas *
|
||||||
// sixten: Draw cursor
|
// sixten: Draw cursor
|
||||||
if(CommandPalette->ListerFieldSelected)
|
if(CommandPalette->ListerFieldSelected)
|
||||||
{
|
{
|
||||||
range_r32 CursorSpan = RangeR32(CursorX, TargetCursorX);
|
range1_r32 CursorSpan = Range1R32(CursorX, TargetCursorX);
|
||||||
r32 Height = Box->FontSize + 4;
|
r32 Height = Box->FontSize + 4;
|
||||||
v2 Offset = V2(7.5F + CursorSpan.Min, (BoxDim.y - Height) / 2);
|
v2 Offset = V2(7.5F + CursorSpan.Min, (BoxDim.y - Height) / 2);
|
||||||
v2 Dim = V2(1.25F + CursorSpan.Max - CursorSpan.Min, Height);
|
v2 Dim = V2(1.25F + CursorSpan.Max - CursorSpan.Min, Height);
|
||||||
|
|
|
@ -37,7 +37,7 @@ struct workspace_view_editor
|
||||||
struct workspace_view_command_palette
|
struct workspace_view_command_palette
|
||||||
{
|
{
|
||||||
b32 ListerFieldSelected;
|
b32 ListerFieldSelected;
|
||||||
char ListerInput[128];
|
u8 ListerInput[128];
|
||||||
s32 ListerInputUsed;
|
s32 ListerInputUsed;
|
||||||
text_edit_state ListerInputEditState;
|
text_edit_state ListerInputEditState;
|
||||||
};
|
};
|
||||||
|
|
|
@ -604,18 +604,23 @@ inline void Win32_GetRelevantPaths(win32_state *State)
|
||||||
Win32_PlatformError("Path to executable is too long. Try running the game from another directory", true);
|
Win32_PlatformError("Path to executable is too long. Try running the game from another directory", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
string EXEPathString = MakeStringFromCString(State->EXEPath);
|
string EXEPathString = MakeString(State->EXEPath);
|
||||||
|
|
||||||
s64 OnePastLastSlash = LastIndexOf(EXEPathString, '\\') + 1;
|
s64 OnePastLastSlash = LastIndexOf(EXEPathString, '\\') + 1;
|
||||||
s64 BuildIndex = LastIndexOf(EXEPathString, StrLit("build"));
|
|
||||||
|
|
||||||
if(BuildIndex == -1)
|
s64 BuildIndex = LastIndexOf(EXEPathString, StrLit("\\build\\")) + 1;
|
||||||
|
if(BuildIndex == 0)
|
||||||
{
|
{
|
||||||
State->ContentsPath = MakeString((char *)EXEPathString.Data, OnePastLastSlash);
|
BuildIndex = LastIndexOf(EXEPathString, StrLit("//build//")) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(BuildIndex == 0)
|
||||||
|
{
|
||||||
|
State->ContentsPath = MakeString(EXEPathString.Data, OnePastLastSlash);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
State->ContentsPath = MakeString((char *)EXEPathString.Data, BuildIndex);
|
State->ContentsPath = MakeString(EXEPathString.Data, BuildIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
string DLLName = StrLit("vn.dll");
|
string DLLName = StrLit("vn.dll");
|
||||||
|
|
|
@ -63,7 +63,7 @@ command_list =
|
||||||
.cursor_at_end = false,
|
.cursor_at_end = false,
|
||||||
.cmd =
|
.cmd =
|
||||||
{
|
{
|
||||||
{ "cloc ./code/*.*", .os = "win" },
|
{ "cloc ./code/ --exclude-dir=third_party", .os = "win" },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue