remove crtlib stubs

This commit is contained in:
jacob 2025-12-31 15:52:52 -06:00
parent d449abc7ca
commit 0c20353811
21 changed files with 127 additions and 935 deletions

View File

@ -13,10 +13,6 @@
#error Missing compile time definition for 'IsAsanEnabled'
#endif
#ifndef IsCrtlibEnabled
#error Missing compile time definition for 'IsCrtlibEnabled'
#endif
#ifndef IsDebinfoEnabled
#error Missing compile time definition for 'IsDebinfoEnabled'
#endif
@ -115,8 +111,28 @@
//~ C headers
#if IsLanguageC
// C standard library
#include <stdint.h>
#include <stdarg.h>
#include <memory.h>
#include <math.h>
//- Intrinsics
#if IsArchX64
// Intrinsic headers:
// -mmintrin.h MMX
// -xmmintrin.h SSE
// -emmintrin.h SSE2
// -pmmintrin.h SSE3
// -tmmintrin.h SSSE3
// -smmintrin.h SSE4.1
// -nmmintrin.h SSE4.2
// -ammintrin.h SSE4A
// -wmmintrin.h AES
// -immintrin.h AVX, AVX2, FMA
#include <intrin.h>
#include <nmmintrin.h> // SSE4.2
#endif
#endif
////////////////////////////////////////////////////////////
@ -232,6 +248,12 @@
#define NsFromSeconds(s) ((i64)((s) * 1000000000.0))
#define SecondsFromNs(ns) ((f64)(ns) / 1000000000.0)
//- Busy-wait
#if IsArchX64
#define YieldCpu()
#else
#endif
////////////////////////////////////////////////////////////
//~ Linked list helper macros
@ -378,26 +400,6 @@
#define Color_Orange Rgba32(0xFF00A5FF)
#define Color_Purple Rgba32(0xFFFF00FF)
#define Color_Cyan Rgba32(0xFFFFFF00)
////////////////////////////////////////////////////////////
//~ Intrinsic headers
#if IsLanguageC
// Intrinsic header info:
// mmintrin.h MMX
// xmmintrin.h SSE
// emmintrin.h SSE2
// pmmintrin.h SSE3
// tmmintrin.h SSSE3
// smmintrin.h SSE4.1
// nmmintrin.h SSE4.2
// ammintrin.h SSE4A
// wmmintrin.h AES
// immintrin.h AVX, AVX2, FMA
#include <intrin.h>
#include <nmmintrin.h> // SSE4.2
#endif
////////////////////////////////////////////////////////////
//~ Type helper macros
@ -577,8 +579,6 @@
ForceInline i64 Atomic64FetchTestSet (Atomic64 *x, i64 c, i64 e) { return (i64)_InterlockedCompareExchange64(&x->_v, e, c); }
ForceInline i64 Atomic64FetchXor (Atomic64 *x, i64 c) { return (i64)_InterlockedXor64(&x->_v, c); }
ForceInline i64 Atomic64FetchAdd (Atomic64 *x, i64 a) { return (i64)_InterlockedExchangeAdd64(&x->_v, a); }
#else
#error Atomics not implemented
#endif
#endif

View File

@ -5,7 +5,6 @@
//- Api
#include "base.cgh"
#if IsLanguageC
#include "base_intrinsics.h"
#include "base_memory.h"
#include "base_arena.h"
#include "base_futex.h"
@ -35,7 +34,6 @@
//- Impl
#if IsLanguageC
#include "base_tweak.c"
#include "base_memory.c"
#include "base_arena.c"
#include "base_sync.c"
#include "base_uid.c"

View File

@ -1,105 +0,0 @@
////////////////////////////////////////////////////////////
//~ Sqrt intrinsics
Inline f32 IxSqrtF32(f32 f)
{
__m128 n = _mm_set_ss(f);
n = _mm_sqrt_ss(n);
return _mm_cvtss_f32(n);
}
Inline f64 IxSqrtF64(f64 f)
{
__m128d n = _mm_set_sd(f);
n = _mm_sqrt_sd(_mm_setzero_pd(), n);
return _mm_cvtsd_f64(n);
}
Inline f32 IxRsqrtF32(f32 f)
{
__m128 n = _mm_set_ss(f);
n = _mm_rsqrt_ss(n);
return _mm_cvtss_f32(n);
}
////////////////////////////////////////////////////////////
//~ Round intrinsics
Inline i32 IxRoundF32ToI32(f32 f)
{
return _mm_cvtss_si32(_mm_round_ss(_mm_setzero_ps(), _mm_set_ss(f), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC));
}
Inline f32 IxRoundF32ToF32(f32 f)
{
return _mm_cvtss_f32(_mm_round_ss(_mm_setzero_ps(), _mm_set_ss(f), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC));
}
Inline i64 IxRoundF64ToI64(f64 f)
{
return _mm_cvtsd_si64(_mm_round_sd(_mm_setzero_pd(), _mm_set_sd(f), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC));
}
Inline f64 IxRoundF64ToF64(f64 f)
{
return _mm_cvtsd_f64(_mm_round_sd(_mm_setzero_pd(), _mm_set_sd(f), _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC));
}
////////////////////////////////////////////////////////////
//~ Floor intrinsics
Inline i32 IxFloorF32ToI32(f32 f)
{
return _mm_cvtss_si32(_mm_floor_ss(_mm_setzero_ps(), _mm_set_ss(f)));
}
Inline f32 IxFloorF32ToF32(f32 f)
{
return _mm_cvtss_f32(_mm_floor_ss(_mm_setzero_ps(), _mm_set_ss(f)));
}
Inline i64 IxFloorF64ToI64(f64 f)
{
return _mm_cvtsd_si64(_mm_floor_sd(_mm_setzero_pd(), _mm_set_sd(f)));
}
Inline f64 IxFloorF64ToF64(f64 f)
{
return _mm_cvtsd_f64(_mm_floor_sd(_mm_setzero_pd(), _mm_set_sd(f)));
}
////////////////////////////////////////////////////////////
//~ Ceil intrinsics
Inline i32 IxCeilF32ToI32(f32 f)
{
return _mm_cvtss_si32(_mm_ceil_ss(_mm_setzero_ps(), _mm_set_ss(f)));
}
Inline f32 IxCeilF32ToF32(f32 f)
{
return _mm_cvtss_f32(_mm_ceil_ss(_mm_setzero_ps(), _mm_set_ss(f)));
}
Inline i64 IxCeilF64ToI64(f64 f)
{
return _mm_cvtsd_si64(_mm_ceil_sd(_mm_setzero_pd(), _mm_set_sd(f)));
}
Inline f64 IxCeilF64ToF64(f64 f)
{
return _mm_cvtsd_f64(_mm_ceil_sd(_mm_setzero_pd(), _mm_set_sd(f)));
}
////////////////////////////////////////////////////////////
//~ Truncate intrinsics
Inline f32 IxTruncF32ToF32(f32 f)
{
return _mm_cvtss_f32(_mm_round_ss(_mm_setzero_ps(), _mm_set_ss(f), _MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC));
}
Inline f64 IxTruncF64ToF64(f64 f)
{
return _mm_cvtsd_f64(_mm_round_sd(_mm_setzero_pd(), _mm_set_sd(f), _MM_FROUND_TO_ZERO | _MM_FROUND_NO_EXC));
}

View File

@ -31,140 +31,13 @@ u64 ClampU64(u64 v, u64 min, u64 max) { return v < min ? min : v > max ? max : v
i64 ClampI64(i64 v, i64 min, i64 max) { return v < min ? min : v > max ? max : v; }
f64 ClampF64(f64 v, f64 min, f64 max) { return v < min ? min : v > max ? max : v; }
////////////////////////////////////////////////////////////
//~ Rounding ops
//- Round
f32 RoundF32(f32 f)
{
return IxRoundF32ToF32(f);
}
f64 RoundF64(f64 f)
{
return IxRoundF64ToF64(f);
}
i32 RoundF32ToI32(f32 f)
{
return IxRoundF32ToI32(f);
}
i64 RoundF64ToI64(f64 f)
{
return IxRoundF64ToI64(f);
}
//- Floor
f32 FloorF32(f32 f)
{
return IxFloorF32ToF32(f);
}
f64 FloorF64(f64 f)
{
return IxFloorF64ToF64(f);
}
i32 FloorF32ToI32(f32 f)
{
return IxFloorF32ToI32(f);
}
i64 FloorF64ToI64(f64 f)
{
return IxFloorF64ToI64(f);
}
//- Ceil
f32 CeilF32(f32 f)
{
return IxCeilF32ToF32(f);
}
f64 CeilF64(f64 f)
{
return IxCeilF64ToF64(f);
}
i32 CeilF32ToI32(f32 f)
{
return IxCeilF32ToI32(f);
}
i64 CeilF64ToI64(f64 f)
{
return IxCeilF64ToI64(f);
}
//- Trunc
f32 TruncF32(f32 f)
{
return IxTruncF32ToF32(f);
}
f64 TruncF64(f64 f)
{
return IxTruncF64ToF64(f);
}
////////////////////////////////////////////////////////////
//~ Fmod
f32 ModF32(f32 x, f32 m)
{
return x - m * TruncF32(x / m);
}
f64 ModF64(f64 x, f64 m)
{
return x - m * TruncF64(x / m);
}
////////////////////////////////////////////////////////////
//~ Abs
f32 AbsF32(f32 f)
{
u32 truncated = *(u32 *)&f & 0x7FFFFFFF;
return *(f32 *)&truncated;
}
f64 AbsF64(f64 f)
{
u64 truncated = *(u64 *)&f & 0x7FFFFFFFFFFFFFFFULL;
return *(f64 *)&truncated;
}
u32 AbsI32(i32 v)
{
return (u32)(v * ((v >= 0) - (v < 0)));
}
u64 AbsI64(i64 v)
{
return (u64)(v * ((v >= 0) - (v < 0)));
}
i32 SignF32(f32 f)
{
u32 sign_bit = (*(u32 *)&f >> 31) & 1;
return 1 + -((i32)(sign_bit << 1));
}
i64 SignF64(f64 f)
{
u64 sign_bit = (*(u64 *)&f >> 63) & 1;
return 1 + -((i64)(sign_bit << 1));
}
////////////////////////////////////////////////////////////
//~ Exponential ops
//- Pow u64
// Taken from https://gist.github.com/orlp/3551590
u64 PowU64(u64 base, u8 exp)
u64 PowU64(u64 v, u8 exp)
{
PERSIST const u8 highest_bit_set[] = {
0, 1, 2, 2, 3, 3, 3, 3,
@ -174,7 +47,7 @@ u64 PowU64(u64 base, u8 exp)
6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 6,
6, 6, 6, 6, 6, 6, 6, 255, // Anything past 63 is a guaranteed overflow with base > 1
6, 6, 6, 6, 6, 6, 6, 255, // Anything past 63 is a guaranteed overflow with v > 1
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255,
@ -208,11 +81,11 @@ u64 PowU64(u64 base, u8 exp)
case 255:
{
// 255 = overflow, return 0
if (base == 1)
if (v == 1)
{
return 1;
}
// if (base == -1)
// if (v == -1)
// {
// return 1 - 2 * (exp & 1);
// }
@ -220,281 +93,42 @@ u64 PowU64(u64 base, u8 exp)
} break;
case 6:
{
if (exp & 1) result *= base;
if (exp & 1) result *= v;
exp >>= 1;
base *= base;
v *= v;
} FALLTHROUGH;
case 5:
{
if (exp & 1) result *= base;
if (exp & 1) result *= v;
exp >>= 1;
base *= base;
v *= v;
} FALLTHROUGH;
case 4:
{
if (exp & 1) result *= base;
if (exp & 1) result *= v;
exp >>= 1;
base *= base;
v *= v;
} FALLTHROUGH;
case 3:
{
if (exp & 1) result *= base;
if (exp & 1) result *= v;
exp >>= 1;
base *= base;
v *= v;
} FALLTHROUGH;
case 2:
{
if (exp & 1) result *= base;
if (exp & 1) result *= v;
exp >>= 1;
base *= base;
v *= v;
} FALLTHROUGH;
case 1:
{
if (exp & 1) result *= base;
if (exp & 1) result *= v;
} FALLTHROUGH;
default: return result;
}
}
//- Logn
// Based on FreeBSD's implementation
// https://github.com/freebsd/freebsd-src/blob/main/lib/msun/src/e_logf.c
f32 LnF32(f32 x)
{
PERSIST const f32 ln2_hi = 6.9313812256e-01f;
PERSIST const f32 ln2_lo = 9.0580006145e-06f;
i32 x_int = *(i32 *)&x;
i32 k = 0;
if (x_int < 0x00800000)
{
f32 two_p25 = 3.3554432000e+07;
if ((x_int & 0x7fffffff) == 0)
{
// Return -inf if x is 0
return -F32Infinity;
}
else if (x_int < 0)
{
// Return NaN if x is negative
return F32Nan;
}
k -= 25;
x *= two_p25;
x_int = *(i32 *)&x;
}
else if (x_int >= 0x7f800000)
{
return x + x;
}
k += (x_int >> 23) - 127;
x_int &= 0x007fffff;
i32 i = (x_int + (0x95f64 << 3)) & 0x800000;
i32 x_int_normalized = x_int | (i ^ 0x3f800000);
x = *(f32 *)&x_int_normalized - 1.0f;
k += (i >> 23);
if ((0x007fffff & (0x8000 + x_int)) < 0xc000)
{
if (x == 0)
{
if (k == 0)
{
return 0;
}
else
{
return (f32)k * ln2_hi + (f32)k * ln2_lo;
}
}
f32 r = x * x * (0.5f - 0.33333333333333333f * x);
if (k == 0)
{
return x - r;
}
else
{
return (f32)k * ln2_hi - ((r - (f32)k * ln2_lo) - x);
}
}
f32 s = x / (2.0f + x);
f32 z = s * s;
f32 w = z * z;
f32 r = (z * (0.66666662693f + w * 0.28498786688f)) + (w * (0.40000972152f + w * 0.24279078841f));
if (((x_int - (0x6147a << 3)) | ((0x6b851 << 3) - x_int)) > 0)
{
f32 hfsq = 0.5f * x * x;
if (k == 0)
{
return x - (hfsq - s * (hfsq + r));
}
else
{
return (f32)k * ln2_hi - ((hfsq - (s * (hfsq + r) + (f32)k * ln2_lo)) - x);
}
}
else
{
if (k == 0)
{
return x - s * (x - r);
}
else
{
return (f32)k * ln2_hi - ((s * (x - r) - (f32)k * ln2_lo) - x);
}
}
}
//- Exp
// Based on FreeBSD's implementation
// https://github.com/freebsd/freebsd-src/blob/main/lib/msun/src/e_expf.c
f32 ExpF32(f32 x)
{
PERSIST const f32 half[2] = { 0.5, -0.5 };
PERSIST const f32 o_threshold = 8.8721679688e+01f;
PERSIST const f32 u_threshold = -1.0397208405e+02f;
PERSIST const f32 ln2_hi[2] = { 6.9314575195e-01f, -6.9314575195e-01f };
PERSIST const f32 ln2_lo[2] = { 1.4286067653e-06f, -1.4286067653e-06f };
PERSIST const f32 inv_ln2 = 1.4426950216e+00f;
PERSIST const f32 huge = 1.0e+30f;
PERSIST const f32 two_m100 = 7.8886090522e-31f;
u32 x_uint = *(u32 *)&x;
i32 x_sign_bit = (i32)((x_uint >> 31) & 1);
x_uint &= 0x7fffffff;
// Filter out non-finite argument
if (x_uint >= 0x42b17218)
{ // if |x|>=88.721...
if (x_uint > 0x7f800000)
{
return x + x; // NaN
}
else if (x_uint == 0x7f800000)
{
return (x_sign_bit == 0) ? x : 0;
}
if (x > o_threshold)
{
// Overflow
return F32Infinity;
}
else if (x < u_threshold)
{
// Underflow
return two_m100 * two_m100;
}
}
// Argument reduction
i32 k = 0;
f32 hi = 0;
f32 lo = 0;
if (x_uint > 0x3eb17218)
{
if (x_uint < 0x3F851592)
{
hi = x - ln2_hi[x_sign_bit];
lo = ln2_lo[x_sign_bit];
k = 1 - x_sign_bit - x_sign_bit;
}
else
{
k = (i32)(inv_ln2 * x + half[x_sign_bit]);
hi = x - (f32)k * ln2_hi[0];
lo = (f32)k * ln2_lo[0];
}
x = hi - lo;
}
else if (x_uint < 0x39000000)
{
if (huge + x > 1.0f)
{
return 1.0f + x;
}
}
else
{
k = 0;
}
f32 two_pk;
if (k >= -125)
{
u32 temp = ((u32)(0x7f + k)) << 23;
two_pk = *(f32 *)&temp;
}
else
{
u32 temp = ((u32)(0x7f + (k + 100))) << 23;
two_pk = *(f32 *)&temp;
}
f32 t = x * x;
f32 c = x - t * (1.6666625440e-1f + t * -2.7667332906e-3f);
if (k == 0)
{
return 1.0f - ((x * c) / (c - 2.0f) - x);
}
else
{
f32 y = 1.0f - ((lo - (x * c) / (2.0f - c)) - hi);
if (k >= -125)
{
if (k == 128)
{
u32 temp = 0x7f800000;
return y * 2.0f * (*(f32 *)&temp);
}
return y * two_pk;
}
else
{
return y * two_pk * two_m100;
}
}
}
//- Pow
f32 PowF32(f32 a, f32 b)
{
if (a >= 0)
{
// a is positive
return ExpF32(LnF32(a) * b);
}
else
{
// a is negative
i32 res_sign = RoundF32ToI32(b) % 2 == 0 ? 1 : -1;
return ExpF32(LnF32(-a) * b) * res_sign;
}
}
//- Sqrt
f32 SqrtF32(f32 x)
{
return IxSqrtF32(x);
}
f64 SqrtF64(f64 x)
{
return IxSqrtF64(x);
}
f32 RSqrtF32(f32 x)
{
return IxRsqrtF32(x);
}
////////////////////////////////////////////////////////////
//~ Align
@ -523,236 +157,6 @@ u64 AlignU64ToNextPow2(u64 x)
return result;
}
////////////////////////////////////////////////////////////
//~ Trig
// Functions based on Cephes implementation (https://www.netlib.org/cephes/):
// - SinApproxF32
// - CosApproxF32
// - ReduceToPio4
// - ArcTanF32
//- Reduce
//
// Reduce postive x to range [0, Pi/4] (Cody-Waite argument reduction)
//
// Returns 0 if x > (2^24 - 1)
// Sets octant_out=-1 on error
f32 ReduceToPio4(f32 x, i32 *octant_out)
{
i32 octant = -1;
if (x <= ((1 << 24) - 1))
{
octant = (i32)(x * (4 / Pi)); // Integer part of x/(Pi/4)
f32 y = (f32)octant;
if (octant & 1)
{
octant += 1;
y += 1.0;
}
// Modulo 360 degrees
octant &= 7;
if (x > 8192)
{
x = x - y * (Pi / 4);
}
else
{
// Extended precision modular arithmetic
x = ((x - y * 0.78515625) - y * 2.4187564849853515625e-4) - y * 3.77489497744594108e-8;
}
}
*octant_out = octant;
return x;
}
//- Sin approximation
//
// Approximate sin in range [0, Pi/4]
f32 SinApproxF32(f32 x)
{
f32 x_sq = x * x;
return (((-1.9515295891E-4 * x_sq + 8.3321608736E-3) * x_sq - 1.6666654611E-1) * x_sq * x) + x;
}
//- Cos approximation
f32 CosApproxF32(f32 x)
{
f32 x_sq = x * x;
return (((2.443315711809948E-005 * x_sq - 1.388731625493765E-003) * x_sq + 4.166664568298827E-002) * x_sq * x_sq) - (x_sq * 0.5) + 1;
}
//- Sin
f32 SinF32(f32 x)
{
f32 sign = 1;
if (IsF32Nan(x))
{
return 0;
}
else if (x < 0)
{
sign = -1;
x = -x;
}
i32 octant;
x = ReduceToPio4(x, &octant);
// Reflect in x axis
if (octant > 3)
{
sign = -sign;
octant -= 4;
}
switch (octant)
{
case -1: return 0;
case 1: case 2: return CosApproxF32(x) * sign;
default: return SinApproxF32(x) * sign;
}
}
//- Cos
f32 CosF32(f32 x)
{
f32 sign = 1;
if (IsF32Nan(x))
{
return 0;
}
else if (x < 0)
{
x = -x;
}
i32 octant;
x = ReduceToPio4(x, &octant);
// Reflect in x axis
if (octant > 3)
{
sign = -sign;
octant -= 4;
}
if (octant > 1)
{
sign = -sign;
}
switch (octant)
{
case -1: return 0;
case 1: case 2: return SinApproxF32(x) * sign;
default: return CosApproxF32(x) * sign;
}
}
//- ArcTan
f32 ArcTanF32(f32 x)
{
f32 sign = 1;
if (x < 0)
{
sign = -1;
x = -x;
}
// Reduce range
f32 y;
if (x > 2.414213562373095)
{ // tan((Pi / 8) * 3)
y = Pi / 2;
x = -(1.f / x);
}
else if (x > 0.4142135623730950)
{ // tan(Pi / 8)
y = Pi / 4;
x = (x - 1.f) / (x + 1.f);
}
else
{
y = 0;
}
f32 x_sq = x * x;
y += ((((8.05374449538e-2 * x_sq - 1.38776856032E-1) * x_sq + 1.99777106478E-1) * x_sq - 3.33329491539E-1) * x_sq * x + x);
return y * sign;
}
//- ArcTan2
f32 ArcTan2F32(f32 y, f32 x)
{
f32 result;
if (x == 0)
{
if (y < 0)
{
result = 3 * Pi / 2;
}
else if (y == 0)
{
result = 0;
}
else
{
result = Pi / 2;
}
}
else if (y == 0)
{
if (x < 0)
{
result = Pi;
}
else
{
result = 0;
}
}
else
{
f32 offset;
if (x < 0)
{
offset = Pi;
}
else if (y < 0)
{
offset = Pi * 2;
}
else
{
offset = 0;
}
result = ArcTanF32(y / x) + offset;
}
return result;
}
//- ArcSin
f32 ArcSinF32(f32 x)
{
// TODO: Dedicated arcsin approximation
return ArcTan2F32(x, SqrtF32(1.0f - (x * x)));
}
//- ArcCos
f32 ArcCosF32(f32 x)
{
// TODO: Dedicated arccos approximation
return (Pi / 2.0f) - ArcTan2F32(x, SqrtF32(1.0f - (x * x)));
}
////////////////////////////////////////////////////////////
//~ Angle unwind
@ -787,22 +191,22 @@ f32 LerpAngleF32(f32 a, f32 b, f32 t)
i32 LerpI32(i32 val0, i32 val1, f32 t)
{
return val0 + RoundF32ToI32(((f32)val1 - (f32)val0) * t);
return val0 + RoundF32(((f32)val1 - (f32)val0) * t);
}
i64 LerpI64(i64 val0, i64 val1, f64 t)
{
return val0 + RoundF64ToI64(((f64)val1 - (f64)val0) * t);
return val0 + RoundF64(((f64)val1 - (f64)val0) * t);
}
i32 LerpU32(u32 val0, u32 val1, f32 t)
{
return val0 + (u64)RoundF32ToI32(((f32)val1 - (f32)val0) * t);
return val0 + RoundF32(((f32)val1 - (f32)val0) * t);
}
i64 LerpU64(u64 val0, u64 val1, f64 t)
{
return val0 + (u64)RoundF64ToI64(((f64)val1 - (f64)val0) * t);
return val0 + RoundF64(((f64)val1 - (f64)val0) * t);
}
////////////////////////////////////////////////////////////
@ -1032,21 +436,6 @@ Vec2 CeilVec2(Vec2 a)
return VEC2(CeilF32(a.x), CeilF32(a.y));
}
Vec2I32 RoundVec2ToI32(Vec2 a)
{
return VEC2I32(RoundF32ToI32(a.x), RoundF32ToI32(a.y));
}
Vec2I32 FloorVec2ToI32(Vec2 a)
{
return VEC2I32(FloorF32ToI32(a.x), FloorF32ToI32(a.y));
}
Vec2I32 CeilVec2ToI32(Vec2 a)
{
return VEC2I32(CeilF32ToI32(a.x), CeilF32ToI32(a.y));
}
//- Angle
// Returns 1 if winding between vectors a & b is clockwise or straight, -1 if counter-clockwise
@ -1514,7 +903,8 @@ f32 RotationFromXform(Xform xf)
Vec2 ScaleFromXform(Xform xf)
{
f32 det_sign = SignF32(DeterminantFromXform(xf));
f32 det = DeterminantFromXform(xf);
i32 det_sign = (det >= 0) - (det < 0);
return VEC2(Vec2Len(xf.bx), det_sign * Vec2Len(xf.by));
}

View File

@ -212,56 +212,43 @@ i64 ClampI64(i64 v, i64 min, i64 max);
f64 ClampF64(f64 v, f64 min, f64 max);
////////////////////////////////////////////////////////////
//~ Rounding ops
//~ Float helpers
//- Round
f32 RoundF32(f32 f);
f64 RoundF64(f64 f);
i32 RoundF32ToI32(f32 f);
i64 RoundF64ToI64(f64 f);
#define RoundF32(v) roundf(v)
#define RoundF64(v) round(v)
//- Floor
f32 FloorF32(f32 f);
f64 FloorF64(f64 f);
i32 FloorF32ToI32(f32 f);
i64 FloorF64ToI64(f64 f);
#define FloorF32(v) floorf(v)
#define FloorF64(v) floor(v)
//- Ceil
f32 CeilF32(f32 f);
f64 CeilF64(f64 f);
i32 CeilF32ToI32(f32 f);
i64 CeilF64ToI64(f64 f);
#define CeilF32(v) ceilf(v)
#define CeilF64(v) ceil(v)
//- Trunc
f32 TruncF32(f32 f);
f64 TruncF64(f64 f);
#define TruncF32(v) truncf(v)
#define TruncF64(v) trunc(v)
////////////////////////////////////////////////////////////
//~ Fmod
//- Mod
#define ModF32(v, m) fmodf((v), (m))
#define ModF64(v, m) fmod((v), (m))
f32 ModF32(f32 x, f32 m);
f64 ModF64(f64 x, f64 m);
////////////////////////////////////////////////////////////
//~ Abs
f32 AbsF32(f32 f);
f64 AbsF64(f64 f);
u32 AbsI32(i32 v);
u64 AbsI64(i64 v);
i32 SignF32(f32 f);
i64 SignF64(f64 f);
//- Abs
#define AbsF32(v) fabsf(v)
#define AbsF64(v) absf(v)
////////////////////////////////////////////////////////////
//~ Exponential ops
u64 PowU64(u64 base, u8 exp);
f32 LnF32(f32 x);
f32 ExpF32(f32 x);
f32 PowF32(f32 a, f32 b);
f32 SqrtF32(f32 x);
f64 SqrtF64(f64 x);
f32 RSqrtF32(f32 x);
u64 PowU64(u64 v, u8 exp);
#define PowF32(v, exp) powf((v), (exp))
#define SqrtF32(v) sqrtf(v)
#define LnF32(v) log(v)
#define Log2F32(v) log2f(v)
#define Log10F32(v) log10f(v)
////////////////////////////////////////////////////////////
//~ Align
@ -272,15 +259,11 @@ u64 AlignU64ToNextPow2(u64 x);
////////////////////////////////////////////////////////////
//~ Trig
f32 ReduceToPio4(f32 x, i32 *octant_out);
f32 SinApproxF32(f32 x);
f32 CosApproxF32(f32 x);
f32 SinF32(f32 x);
f32 CosF32(f32 x);
f32 ArcTanF32(f32 x);
f32 ArcTan2F32(f32 y, f32 x);
f32 ArcSinF32(f32 x);
f32 ArcCosF32(f32 x);
#define SinF32(v) sinf(v)
#define CosF32(v) cosf(v)
#define TanF32(x) tanf(x)
#define ArcTanF32(x) atanf(x)
#define ArcTan2F32(y, x) atan2f((y), (x))
////////////////////////////////////////////////////////////
//~ Angle unwind
@ -351,9 +334,6 @@ Vec2 PerpVec2TowardsDir(Vec2 v, Vec2 dir);
Vec2 RoundVec2(Vec2 a);
Vec2 FloorVec2(Vec2 a);
Vec2 CeilVec2(Vec2 a);
Vec2I32 RoundVec2ToI32(Vec2 a);
Vec2I32 FloorVec2ToI32(Vec2 a);
Vec2I32 CeilVec2ToI32(Vec2 a);
//- Angle
i32 WindingFromVec2(Vec2 a, Vec2 b);
@ -374,8 +354,6 @@ Vec2 SlerpVec2(Vec2 val0, Vec2 val1, f32 t);
////////////////////////////////////////////////////////////
//~ Vec2I32
#define Vec2I32FromFields(v) VEC2I32((v).x, (v).y)
b32 MatchVec2I32(Vec2I32 a, Vec2I32 b);
Vec2I32 NegVec2I32(Vec2I32 a);
Vec2I32 AddVec2I32(Vec2I32 a, Vec2I32 b);

View File

@ -1,49 +0,0 @@
////////////////////////////////////////////////////////////
//~ Crtlib mem op stubs
#if !IsCrtlibEnabled
//- memcpy
__attribute((section(".text.memcpy")))
void *memcpy(void *__restrict dst, const void *__restrict src, u64 count)
{
char *dst_pchar = dst;
char *src_pchar = src;
for (u64 i = 0; i < count; ++i)
{
dst_pchar[i] = src_pchar[i];
}
return dst;
}
//- memset
__attribute((section(".text.memset")))
void *memset(void *dst, i32 c, u64 count)
{
char *dst_pchar = dst;
for (u64 i = 0; i < count; ++i)
{
dst_pchar[i] = (char)c;
}
return dst;
}
//- memcmp
__attribute((section(".text.memcmp")))
i32 memcmp(const void *p1, const void *p2, u64 count)
{
i32 result = 0;
char *p1_pchar = p1;
char *p2_pchar = p2;
for (u64 i = 0; i < count; ++i)
{
result = p1_pchar[i] - p2_pchar[i];
if (result != 0)
{
break;
}
}
return result;
}
#endif

View File

@ -29,14 +29,3 @@ void SetMemoryReadWrite(void *address, u64 size);
#define CopyBytes(dst, src, count) memcpy(dst, src, count)
#define SetBytes(dst, c, count) memset(dst, c, count)
#define CmpBytes(p1, p2, count) memcmp(p1, p2, count)
////////////////////////////////////////////////////////////
//~ Crtlib stubs
#if IsCrtlibEnabled
#include <memory.h>
#else
void *memcpy(void *__restrict dst, const void *__restrict src, u64 n);
void *memset(void *dst, i32 c, u64 n);
i32 memcmp(const void *p1, const void *p2, u64 n);
#endif

View File

@ -133,7 +133,7 @@ String StringFromFloat(Arena *arena, f64 f, u32 precision)
u64 backwards_text_len = 0;
do
{
u64 digit = (u64)RoundF64ToI64(ModF64(part_whole, 10.0));
u64 digit = RoundF64(ModF64(part_whole, 10.0));
StringFromChar(scratch.arena, IntChars[digit % 10]);
++backwards_text_len;
part_whole = TruncF64(part_whole / 10.0);

View File

@ -516,40 +516,16 @@ i32 W32_Main(void)
}
////////////////////////////////////////////////////////////
//~ Crt main
//~ CRT main
#if IsCrtlibEnabled
#if IsConsoleApp
#if IsConsoleApp
int main(char **argc, int argv)
{
return W32_Main();
}
#else
int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance, _In_ LPWSTR cmdline_wstr, _In_ int show_code)
#else
int CALLBACK wWinMain(HINSTANCE instance, HINSTANCE prev_instance, LPWSTR cmdline_wstr, int show_code)
{
return W32_Main();
}
#endif // IsConsoleApp
#endif // IsCrtlibEnabled
////////////////////////////////////////////////////////////
//~ Crt stub
#if !IsCrtlibEnabled
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmissing-variable-declarations"
#pragma clang diagnostic ignored "-Wmissing-prototypes"
// Enable floating point
__attribute((used))
int _fltused;
__attribute((used))
void __stdcall wWinMainCRTStartup(void)
{
i32 result = W32_Main();
ExitProcess(result);
}
#pragma clang diagnostic pop
#endif // !IsCrtlibEnabled
#endif

View File

@ -344,7 +344,6 @@ void BuildEntryPoint(WaveLaneCtx *lane)
PushStringToList(perm, &cp.defs, Lit("-DIsConsoleApp=0"));
PushStringToList(perm, &cp.defs, Lit("-DIsRtcEnabled=1"));
PushStringToList(perm, &cp.defs, Lit("-DIsAsanEnabled=0"));
PushStringToList(perm, &cp.defs, Lit("-DIsCrtlibEnabled=1"));
PushStringToList(perm, &cp.defs, Lit("-DIsDebinfoEnabled=1"));
PushStringToList(perm, &cp.defs, Lit("-DIsDeveloperModeEnabled=1"));
PushStringToList(perm, &cp.defs, Lit("-DIsUnoptimized=1"));

View File

@ -19,10 +19,6 @@
#define IsAsanEnabled 0
#endif
#ifndef IsCrtlibEnabled
#define IsCrtlibEnabled 1
#endif
#ifndef IsDebinfoEnabled
#define IsDebinfoEnabled 1
#endif

View File

@ -15,7 +15,7 @@ Readonly M_Entry M_NilEntry = {
.arg_tokens[0] = &M_NilToken,
.arg_tokens[1] = &M_NilToken,
};
StaticAssert(countof(M_NilEntry.arg_tokens) == 2); // NilEntry must define point args to nil tokens
StaticAssert(countof(M_NilEntry.arg_tokens) == 2); // NilEntry must point args to nil tokens
Readonly M_Layer M_NilLayer = {
.next = &M_NilLayer,

View File

@ -42,7 +42,7 @@ Struct(M_Token)
struct M_TokenFile *file;
String s;
} extern Readonly M_NilToken;
};
Struct(M_TokenFile)
{
@ -57,7 +57,7 @@ Struct(M_TokenFile)
u64 tokens_count;
M_ErrorList errors;
} extern Readonly M_NilTokenFile;
};
Struct(M_TokenFileList)
{
@ -113,7 +113,7 @@ Struct(M_Entry)
M_Token *arg_tokens[2];
u64 args_count;
} extern Readonly M_NilEntry;
};
Struct(M_Layer)
{
@ -126,7 +126,7 @@ Struct(M_Layer)
M_Entry *last;
u64 count;
M_ErrorList errors;
} extern Readonly M_NilLayer;
};
Struct(M_LayerList)
{
@ -135,6 +135,14 @@ Struct(M_LayerList)
u64 count;
};
////////////////////////////////////////////////////////////
//~ State types
extern Readonly M_Token M_NilToken;
extern Readonly M_TokenFile M_NilTokenFile;
extern Readonly M_Entry M_NilEntry;
extern Readonly M_Layer M_NilLayer;
////////////////////////////////////////////////////////////
//~ Error helpers

View File

@ -201,7 +201,7 @@ void P_W32_SyncTimerForever(WaveLaneCtx *lane)
periods_sum_ns += (f64)periods[i];
}
f64 mean_ns = periods_sum_ns / (f64)countof(periods);
Atomic64Set(&P_W32.average_timer_period_ns.v, RoundF64ToI64(mean_ns));
Atomic64Set(&P_W32.average_timer_period_ns.v, RoundF64(mean_ns));
}
// Update fence

View File

@ -355,9 +355,9 @@ void V_TickForever(WaveLaneCtx *lane)
}
// TODO: Don't rely on ui report for draw size since it introduces one frame of delay when resizing
frame->ui_dims = RoundVec2ToI32(DimsFromRng2(vis_box_rep.screen_rect));
frame->ui_dims.x = MaxI32(frame->ui_dims.x, 64);
frame->ui_dims.y = MaxI32(frame->ui_dims.y, 64);
frame->ui_dims = RoundVec2(DimsFromRng2(vis_box_rep.screen_rect));
frame->ui_dims.x = MaxF32(frame->ui_dims.x, 64);
frame->ui_dims.y = MaxF32(frame->ui_dims.y, 64);
frame->draw_dims = frame->ui_dims;
//////////////////////////////

View File

@ -194,8 +194,8 @@ Struct(V_Frame)
String window_restore;
i32 zooms;
Vec2I32 ui_dims;
Vec2I32 draw_dims;
Vec2 ui_dims;
Vec2 draw_dims;
// Modes
b32 is_editing;

View File

@ -11,7 +11,7 @@ Enum(V_SelectionMode)
Struct(V_DParams)
{
Vec2I32 target_size;
Vec2 target_size;
G_Texture2DRef target_ro;
G_RWTexture2DRef target_rw;

View File

@ -22,8 +22,6 @@ Struct(SPR_Texture)
u32 height;
};
extern Readonly SPR_Texture SPR_NilTexture;
////////////////////////////////////////////////////////////
//~ Sheet types
@ -104,8 +102,6 @@ Struct(SPR_Sheet)
SPR_SliceGroupBin *slice_group_bins;
};
extern Readonly SPR_Sheet SPR_NilSheet;
////////////////////////////////////////////////////////////
//~ Cache types
@ -147,6 +143,8 @@ Struct(SPR_Ctx)
};
extern SPR_Ctx SPR;
extern Readonly SPR_Sheet SPR_NilSheet;
extern Readonly SPR_Texture SPR_NilTexture;
////////////////////////////////////////////////////////////
//~ Load jobs

View File

@ -1,4 +1,7 @@
Readonly TAR_Entry TAR_nil_entry = ZI;
Readonly TAR_Entry TAR_nil_entry = Zi;
////////////////////////////////////////////////////////////
//~ Helpers
u64 TAR_U64FromOctString(String str)
{
@ -11,6 +14,9 @@ u64 TAR_U64FromOctString(String str)
return n;
}
////////////////////////////////////////////////////////////
//~ Archive
// `prefix` will be prepended to all file names in the archive
//
// NOTE: The resulting archive merely points into the supplied tar data, no

View File

@ -12,7 +12,7 @@ Struct(TAR_Entry)
b32 is_dir;
TAR_Entry *next;
TAR_Entry *next_child; // If entry is dir, points to first child. Otherwise points to next sibling.
} extern Readonly TAR_nil_entry;
};
Struct(TAR_Archive)
{
@ -64,9 +64,17 @@ Packed(Struct(TAR_Header)
});
////////////////////////////////////////////////////////////
//~ Archive
//~ State types
extern Readonly TAR_nil_entry;
////////////////////////////////////////////////////////////
//~ Helpers
u64 TAR_U64FromOctString(String str);
TAR_Archive TAR_ArchiveFromString(Arena *arena, String data, String prefix);
////////////////////////////////////////////////////////////
//~ Archive
TAR_Archive TAR_ArchiveFromString(Arena *arena, String data, String prefix);
TAR_Entry *TAR_EntryFromName(TAR_Archive *archive, String name);

View File

@ -816,7 +816,7 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color)
f32 hot_blend_rate = target_hot == 1 ? 1 : (15 * frame->dt);
f32 active_blend_rate = target_active == 1 ? 1 : (15 * frame->dt);
f32 hovered_blend_rate = target_hovered == 1 ? 1 : (15 * frame->dt);
f32 selected_blend_rate = (30 * frame->dt);
f32 selected_blend_rate = (30* frame->dt);
report->exists = LerpF32(report->exists, target_exists, exists_blend_rate);
report->hot = LerpF32(report->hot, target_hot, hot_blend_rate);