tweak variable precision

This commit is contained in:
jacob 2026-01-01 15:52:25 -06:00
parent 31b277d8f7
commit fa04e56065
10 changed files with 88 additions and 98 deletions

View File

@ -508,26 +508,12 @@
#define I32Min ((i32)0x80000000)
#define I64Min ((i64)0x8000000000000000LL)
//- Float infinity / nan constants
//- Float infinity / nan
#if IsLanguageC
Global const u32 _f32_infinity_u32 = 0x7f800000;
Global const f32 *_f32_infinity = (f32 *)&_f32_infinity_u32;
#define F32Infinity (*_f32_infinity)
Global const u64 _f64_infinity_u64 = 0x7ff0000000000000ULL;
Global const f64 *_f64_infinity = (f64 *)&_f64_infinity_u64;
#define F64Infinity (*_f64_infinity)
Global const u32 _f32_nan_u32 = 0x7f800001;
Global const f32 *_f32_nan = (f32 *)&_f32_nan_u32;
#define F32Nan (*_f32_nan)
Global const u64 _f64_nan_u64 = 0x7ff8000000000001;
Global const f64 *_f64_nan = (f64 *)&_f64_nan_u64;
#define F64Nan (*_f64_nan)
#define IsF32Nan(x) (x != x)
#define IsF64Nan(x) (x != x)
#define Inf INFINITY
#define Nan NAN
#define IsInf(x) isinf(x)
#define IsNan(x) isnan(x)
#endif
////////////////////////////////////////////////////////////

View File

@ -242,7 +242,7 @@ f64 ClampF64(f64 v, f64 min, f64 max);
//- Abs
#define AbsF32(v) fabsf(v)
#define AbsF64(v) absf(v)
#define AbsF64(v) fabs(v)
////////////////////////////////////////////////////////////
//~ Exponential ops

View File

@ -101,73 +101,63 @@ String StringFromSints(Arena *arena, u64 sints_count, i64 *sints, u64 base, u64
String StringFromFloat(Arena *arena, f64 f, u32 precision)
{
String result = Zi;
result.text = ArenaNext(arena, u8);
TempArena scratch = BeginScratch(arena);
if (IsNan(f))
{
if (IsF32Nan(f))
result = PushString(arena, Lit("NaN"));
}
else if (IsInf(f))
{
if (f >= 0)
{
result.len += PushString(arena, Lit("NaN")).len;
}
else if (f == F64Infinity)
{
result.len += PushString(arena, Lit("inf")).len;
}
else if (f == -F64Infinity)
{
result.len += PushString(arena, Lit("-inf")).len;
result = PushString(arena, Lit("inf"));
}
else
{
if (f < 0)
result = PushString(arena, Lit("-inf"));
}
}
else
{
result.text = ArenaNext(arena, u8);
i32 sign = (f >= 0) - (f < 0);
u64 part_whole = 0;
u64 part_frac = 0;
if (precision > 0)
{
part_whole = f * sign;
part_frac = RoundF64(((f * sign) - part_whole) * PowU64(10, precision));
}
else
{
part_whole = RoundF64(f * sign);
}
result.len += StringFromSint(arena, (i64)part_whole * sign, 10, 0).len;
if (part_frac != 0)
{
result.len += StringFromChar(arena, '.').len;
i64 frac_start_idx = result.len;
result.len += StringFromUint(arena, part_frac, 10, precision).len;
// Remove trailing zeroes
for (i64 char_idx = result.len - 1; char_idx > frac_start_idx; --char_idx)
{
StringFromChar(arena, '-');
f = -f;
++result.len;
}
// Add one half of next precision level to round up
f += 0.5 / (f64)PowU64(10, (u8)precision);
f64 part_whole = TruncF64(f);
f64 part_frac = f - part_whole;
// Print whole part
{
// Build backwards text starting from least significant digit
u8 *backwards_text = ArenaNext(scratch.arena, u8);
u64 backwards_text_len = 0;
do
u8 c = result.text[char_idx];
if (c == '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);
} while (part_whole > 0);
// Reverse text into final string
PushStructsNoZero(arena, u8, backwards_text_len);
for (u64 i = backwards_text_len; i-- > 0;)
{
result.text[result.len++] = backwards_text[i];
result.len -= 1;
}
}
// Print frac part
if (precision > 0)
{
StringFromChar(arena, '.');
for (u64 i = 0; i < precision; ++i)
else
{
part_frac *= 10.0;
u64 digit = (u64)part_frac;
part_frac -= digit;
StringFromChar(arena, IntChars[digit % 10]);
break;
}
result.len += (u64)precision + 1;
}
}
}
EndScratch(scratch);
return result;
}
@ -299,7 +289,14 @@ f64 FloatFromString(String str)
if (ok)
{
result = ((f64)whole_part + ((f64)frac_part / PowU64(10, str.len - (frac_start_idx + 1)))) * sign;
if (frac_part != 0)
{
result = ((f64)whole_part + ((f64)frac_part / PowU64(10, str.len - (frac_start_idx + 1)))) * sign;
}
else
{
result = (f64)whole_part * sign;
}
}
else
{

View File

@ -87,32 +87,31 @@ TweakVarArray GetAllTweakVars(Arena *arena)
}
////////////////////////////////////////////////////////////
//~ Tweak var retrieval helpers
//~ Tweak utils
b32 TweakBool(String name, b32 default_value)
b32 TweakBool_(String name, b32 default_value)
{
b32 result = 0;
TempArena scratch = BeginScratchNoConflict();
{
TweakDesc desc = Zi;
desc.kind = TweakKind_Bool;
String tweak_str = TweakEx(scratch.arena, name, desc, StringFromBool(scratch.arena, default_value), 0);
String default_value_str = StringFromBool(scratch.arena, default_value);
String tweak_str = TweakEx(scratch.arena, name, desc, default_value_str, 0);
result = BoolFromString(tweak_str);
}
EndScratch(scratch);
return result;
}
f64 TweakFloat(String name, f64 default_value, f64 min, f64 max)
f64 TweakFloat_(String name, f64 default_value, TweakDesc desc)
{
f64 result = 0;
desc.kind = TweakKind_Float;
TempArena scratch = BeginScratchNoConflict();
{
TweakDesc desc = Zi;
desc.kind = TweakKind_Float;
desc.range.min = min;
desc.range.max = max;
String tweak_str = TweakEx(scratch.arena, name, desc, StringFromFloat(scratch.arena, default_value, 6), 0);
String default_value_str = StringFromFloat(scratch.arena, default_value, desc.precision);
String tweak_str = TweakEx(scratch.arena, name, desc, default_value_str, 0);
result = FloatFromString(tweak_str);
}
EndScratch(scratch);

View File

@ -11,6 +11,7 @@ Struct(TweakDesc)
{
TweakKind kind;
RngF64 range;
i32 precision;
};
Struct(TweakVar)
@ -70,7 +71,15 @@ String TweakEx(Arena *arena, String name, TweakDesc desc, String new_value, b32
TweakVarArray GetAllTweakVars(Arena *arena);
////////////////////////////////////////////////////////////
//~ Tweak var retrieval helpers
//~ Tweak utils
b32 TweakBool(String name, b32 default_value);
f64 TweakFloat(String name, f64 default_value, f64 min, f64 max);
b32 TweakBool_(String name, b32 default_value);
#define TweakBool(_name, _default_value) TweakBool_(Lit(_name), (_default_value))
f64 TweakFloat_(String name, f64 default_value, TweakDesc desc);
#define TweakFloat(_name, _default_value, _min, _max, ...) TweakFloat_(Lit(_name), (_default_value), (TweakDesc) { \
.range.min = (_min), \
.range.max = (_max), \
.precision = 6, \
__VA_ARGS__ \
})

View File

@ -180,15 +180,15 @@ GC_Run GC_RunFromString(Arena *arena, String str, GC_FontKey font, f32 font_size
GC_RunRect *rect = &result.rects[glyph_idx];
f32 advance = glyph->advance;
if (TweakBool(Lit("Ceil glyph advances"), 0))
if (TweakBool("Ceil glyph advances", 0))
{
advance = CeilF32(advance);
}
if (TweakBool(Lit("Floor glyph advances"), 0))
if (TweakBool("Floor glyph advances", 0))
{
advance = FloorF32(advance);
}
if (TweakBool(Lit("Round glyph advances"), 1))
if (TweakBool("Round glyph advances", 1))
{
advance = RoundF32(advance);
}

View File

@ -1351,7 +1351,7 @@ u32 G_PushRef(G_ArenaHandle arena_handle, G_ResourceHandle resource_handle, G_Re
if (d3d_desc.AddressU == 0) d3d_desc.AddressU = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
if (d3d_desc.AddressV == 0) d3d_desc.AddressV = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
if (d3d_desc.AddressW == 0) d3d_desc.AddressW = D3D12_TEXTURE_ADDRESS_MODE_CLAMP;
if (d3d_desc.MaxLOD >= F32Infinity)
if (d3d_desc.MaxLOD >= Inf)
{
d3d_desc.MaxLOD = D3D12_FLOAT32_MAX;
}

View File

@ -154,7 +154,7 @@ S_Shape S_MulXformShape(Xform xf, S_Shape shape)
Vec2 S_SupportPointFromShape(S_Shape shape, Vec2 dir)
{
Vec2 result = Zi;
f32 max_dot = -F32Infinity;
f32 max_dot = -Inf;
for (i32 i = 0; i < shape.points_count; ++i)
{
Vec2 p = shape.points[i];

View File

@ -83,7 +83,7 @@ V_WidgetTheme V_GetWidgetTheme(void)
theme.font = GC_FontKeyFromResource(ResourceKeyFromStore(&V_Resources, Lit("font/seguisb.ttf")));
// theme.font_size = 14;
theme.font_size = TweakFloat(Lit("Font size"), 14, 6, 50);
theme.font_size = TweakFloat("Font size", 14, 6, 50, .precision = 0);
theme.h1 = 2.00;
theme.h2 = 1.50;
theme.h3 = 1.17;
@ -93,7 +93,7 @@ V_WidgetTheme V_GetWidgetTheme(void)
// theme.rounding = 0;
// theme.rounding = 1;
theme.rounding = TweakFloat(Lit("Rounding"), 1, 0, 1);
theme.rounding = TweakFloat("Rounding", 1, 0, 1);
theme.text_color = Rgb32(0xffdddee0);
theme.text_padding_x = 5;
@ -1292,7 +1292,7 @@ void V_TickForever(WaveLaneCtx *lane)
V_Palette *palette = &frame->palette;
{
f32 palette_ease = TweakFloat(Lit("Command palette ease"), 30, 1, 100) * frame->dt;
f32 palette_ease = TweakFloat("Command palette ease", 30, 1, 100) * frame->dt;
palette->show = LerpF32(palette->show, palette->pref_show, palette_ease);
}
if (palette->show > 0.001)
@ -1629,8 +1629,7 @@ void V_TickForever(WaveLaneCtx *lane)
tweak_float = LerpF64(range_min, range_max, virtual_cursor_ratio);
tweak_float = ClampF64(tweak_float, range_min, range_max);
f64 precision = 6; // FIXME: Remove this
new_tweak_str = StringFromFloat(frame->arena, tweak_float, precision);
new_tweak_str = StringFromFloat(frame->arena, tweak_float, tweak_desc.precision);
}
if (slider_reps.draw.is_hot)
{

View File

@ -1127,7 +1127,7 @@ void UI_EndFrame(UI_Frame *frame)
box->solved_scale = MulVec2Vec2(parent->solved_scale, box->solved_scale);
}
f32 scale_snap = TweakFloat(Lit("UI scale snap"), 0.0050, 0, 0.01);
f32 scale_snap = TweakFloat("UI scale snap", 0.0050, 0, 0.01);
if (AbsF32(1.0 - box->solved_scale.x) < scale_snap)
{
box->solved_scale.x = 1;