From 003a77d410512d49f7c7a8a409d8e5c6f4102c3b Mon Sep 17 00:00:00 2001 From: jacob Date: Thu, 1 Jan 2026 23:56:54 -0600 Subject: [PATCH] float parsing fixes --- src/base/base_string.c | 40 ++++++++++++++++++++------------- src/base/base_string.h | 2 +- src/base/base_tweak.h | 2 +- src/pp/pp_vis/pp_vis_core.c | 44 +++++++++++++++++++++++-------------- src/ui/ui_core.c | 5 ++--- 5 files changed, 57 insertions(+), 36 deletions(-) diff --git a/src/base/base_string.c b/src/base/base_string.c index c7268c64..f6f38be1 100644 --- a/src/base/base_string.c +++ b/src/base/base_string.c @@ -98,17 +98,18 @@ String StringFromSints(Arena *arena, u64 sints_count, i64 *sints, u64 base, u64 return result; } -String StringFromFloat(Arena *arena, f64 f, u32 precision) +String StringFromFloat(Arena *arena, f64 src, u32 precision) { String result = Zi; + precision = MinU32(precision, 16); - if (IsNan(f)) + if (IsNan(src)) { result = PushString(arena, Lit("NaN")); } - else if (IsInf(f)) + else if (IsInf(src)) { - if (f >= 0) + if (src >= 0) { result = PushString(arena, Lit("inf")); } @@ -121,21 +122,30 @@ String StringFromFloat(Arena *arena, f64 f, u32 precision) { result.text = ArenaNext(arena, u8); - i32 sign = (f >= 0) - (f < 0); - u64 part_whole = 0; - u64 part_frac = 0; - if (precision > 0) + if (src < 0) { - part_whole = f * sign; - part_frac = RoundF64(((f * sign) - part_whole) * PowU64(10, precision)); - } - else - { - part_whole = RoundF64(f * sign); + DEBUGBREAKABLE; } + u64 p = PowU64(10, precision); + f64 multiplied = RoundF64(src * p); + // f64 multiplied_rounded = RoundF64(multiplied); - result.len += StringFromSint(arena, (i64)part_whole * sign, 10, 0).len; + i32 sign = (src >= 0) - (src < 0); + u64 part_whole = TruncF64(AbsF64(multiplied) / p); + + u64 part_frac = TruncF64(AbsF64(AbsF64(src) - part_whole) * p); + + // Push sign + if (sign < 0 && (part_whole != 0 || part_frac != 0)) + { + result.len += StringFromChar(arena, '-').len; + } + + // Push whole part + result.len += StringFromUint(arena, part_whole, 10, 0).len; + + // Push frac part if (part_frac != 0) { result.len += StringFromChar(arena, '.').len; diff --git a/src/base/base_string.h b/src/base/base_string.h index 45714a02..2e2a5151 100644 --- a/src/base/base_string.h +++ b/src/base/base_string.h @@ -82,7 +82,7 @@ String StringFromChar(Arena *arena, char c); String StringFromUint(Arena *arena, u64 n, u64 base, u64 zfill); String StringFromUints(Arena *arena, u64 uints_count, u64 *uints, u64 base, u64 zfill); String StringFromSint(Arena *arena, i64 n, u64 base, u64 zfill); -String StringFromFloat(Arena *arena, f64 f, u32 precision); +String StringFromFloat(Arena *arena, f64 src, u32 precision); String StringFromPtr(Arena *arena, void *ptr); String StringFromhandle(Arena *arena, u64 v0, u64 v1); String StringFromUid(Arena *arena, Uid uid); diff --git a/src/base/base_tweak.h b/src/base/base_tweak.h index d75dce0f..f4415a7d 100644 --- a/src/base/base_tweak.h +++ b/src/base/base_tweak.h @@ -107,6 +107,6 @@ f64 TweakFloat_(String name, f64 initial, TweakFloatDesc desc); .category = Lit("Debug"), \ .min = (_min), \ .max = (_max), \ - .precision = 6, \ + .precision = 2, \ __VA_ARGS__ \ }) diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index f62fe137..2f623a4c 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -83,7 +83,7 @@ V_WidgetTheme V_GetWidgetTheme(void) theme.icon_font = UI_BuiltinIconFont(); // theme.font_size = 14; - theme.font_size = TweakFloat("Font size", 16, 6, 50, .precision = 0); + theme.font_size = TweakFloat("Font size", 14, 6, 50, .precision = 0); theme.h1 = 2.00; theme.h2 = 1.50; theme.h3 = 1.25; @@ -1331,8 +1331,8 @@ void V_TickForever(WaveLaneCtx *lane) UI_Push(BorderColor, window_border_color); UI_Push(BorderSize, theme.window_bd_sz); // UI_Push(Rounding, UI_RPIX(15 * theme.rounding)); - UI_Push(Rounding, UI_RGROW(0.1 * theme.rounding)); - UI_Push(Width, UI_FNT(50, 0)); + UI_Push(Rounding, UI_RGROW(0.075 * theme.rounding)); + UI_Push(Width, UI_FNT(40, 0)); UI_Push(Height, UI_SHRINK(0, 0)); UI_Push(ChildLayoutAxis, Axis_Y); UI_Push(FloatingPos, palette->pos); @@ -1526,17 +1526,26 @@ void V_TickForever(WaveLaneCtx *lane) b32 is_default = MatchString(new_tweak_str, tweak_var.initial); // Tweak label - UI_BuildSpacer(UI_PIX(spacing, 1), Axis_X); - if (is_default) { - UI_SetNext(TextColor, theme.col.hint); - UI_SetNext(FontSize, UI_Top(FontSize) * theme.h5); + UI_BuildSpacer(UI_PIX(spacing, 1), Axis_X); + if (is_default) + { + UI_SetNext(TextColor, theme.col.hint); + UI_SetNext(FontSize, UI_Top(FontSize) * theme.h5); + } + else + { + UI_SetNext(TextColor, Color_White); + } + UI_SetNext(ChildAlignment, UI_Region_Left); + UI_SetNext(Width, UI_SHRINK(0, 1)); + UI_SetNext(Height, UI_SHRINK(0, 1)); + UI_SetNext(Text, new_tweak_str); + UI_SetNext(Flags, UI_BoxFlag_DrawText); + UI_SetNext(BackgroundColor, 0); + UI_SetNext(BorderColor, 0); + UI_BuildBox(); } - else - { - UI_SetNext(TextColor, Color_White); - } - UI_BuildLabel(new_tweak_str); // Reset button if (!is_default) @@ -1641,7 +1650,7 @@ void V_TickForever(WaveLaneCtx *lane) f64 tweak_float = FloatFromString(new_tweak_str); { - if (is_active && (frame->ui_cursor.x != last_frame->ui_cursor.x)) + if (is_active) { f64 initial_slider_pos = slider_reps.drag.screen_rect.p0.x; f64 initial_marker_width = DimsFromRng2(marker_reps.drag.screen_rect).x; @@ -1655,7 +1664,10 @@ void V_TickForever(WaveLaneCtx *lane) tweak_float = LerpF64(range_min, range_max, virtual_cursor_ratio); tweak_float = ClampF64(tweak_float, range_min, range_max); - new_tweak_str = StringFromFloat(frame->arena, tweak_float, tweak_var.precision); + if (frame->ui_cursor.x != last_frame->ui_cursor.x) + { + new_tweak_str = StringFromFloat(frame->arena, tweak_float, tweak_var.precision); + } } if (is_hot) { @@ -1881,8 +1893,8 @@ void V_TickForever(WaveLaneCtx *lane) colors[LogLevel_Debug][0] = Rgb(0.4, 0.1, 0.4); colors[LogLevel_Debug][1] = Rgb(0.5, 0.2, 0.5); // Info colors - colors[LogLevel_Info][0] = Rgb(0.4, 0.4, 0.4); - colors[LogLevel_Info][1] = Rgb(0.5, 0.5, 0.5); + colors[LogLevel_Info][0] = Rgb(0.2, 0.2, 0.2); + colors[LogLevel_Info][1] = Rgb(0.25, 0.25, 0.25); // Success colors colors[LogLevel_Success][0] = Rgb(0.1, 0.3, 0.1); colors[LogLevel_Success][1] = Rgb(0.2, 0.4, 0.2); diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 2bc6f8b1..0f1dbafc 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -1129,7 +1129,7 @@ void UI_EndFrame(UI_Frame *frame) box->solved_scale = MulVec2Vec2(parent->solved_scale, box->solved_scale); } - f32 scale_snap = TweakFloat("UI scale snap", 0.0050, 0, 0.01); + f32 scale_snap = TweakFloat("UI scale snap threshold", 0.0050, 0, 0.01, .precision = 6); if (AbsF32(1.0 - box->solved_scale.x) < scale_snap) { box->solved_scale.x = 1; @@ -1575,8 +1575,7 @@ void UI_EndFrame(UI_Frame *frame) if (should_truncate) { // Get elipses run - // GC_Run elipses_run_unscaled = GC_RunFromString(scratch.arena, Lit("..."), box->desc.font, box->desc.font_size); - GC_Run elipses_run_unscaled = Zi; + GC_Run elipses_run_unscaled = GC_RunFromString32(scratch.arena, String32FromString(scratch.arena, Lit("...")), box->desc.font, box->desc.font_size); GC_Run elipses_run = UI_ScaleRun(frame->arena, elipses_run_unscaled, box->solved_scale); f32 truncation_offset = max_baseline_length - elipses_run.baseline_length;