summaryrefslogtreecommitdiff
path: root/src/shaders/debug/debug_print.wgsl
blob: ee9b107eb39b7bbfecddd95f96692dc2c1e94f79 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// Debug print utility: renders a f32 value at a pixel position using 8×8 C64 font.
// Include: #include "debug/debug_print"
//
// Usage:
//   col = debug_f32(col, pos.xy, vec2f(10.0, 10.0), my_value);
//
// Format: [-]DDD.DDD  (8 chars × 8px wide = 64×8 pixel area)
// Range:  -999.999 to 999.999

// Returns the lit pixel (0 or 1) for glyph g, pixel row r [0-7], column c [0-7].
// Glyphs: 0-9 = digits, 10 = '-', 11 = '.', 12 = ' '
// Encoding: 2 u32s per glyph; hi covers rows 0-3, lo covers rows 4-7.
// Within each u32, row r occupies bits [(3-r%4)*8 + 7 : (3-r%4)*8].
fn _dbg_pixel(g: u32, r: u32, c: u32) -> u32 {
    let data = array<u32, 26>(
        0x3C666E76u, 0x66663C00u,  // '0'
        0x18381818u, 0x18187E00u,  // '1'
        0x3C66060Cu, 0x18307E00u,  // '2'
        0x3C66061Cu, 0x06663C00u,  // '3'
        0x0C1C2C4Cu, 0x7E0C0C00u,  // '4'
        0x7E607C06u, 0x06663C00u,  // '5'
        0x1C30607Cu, 0x66663C00u,  // '6'
        0x7E060C18u, 0x18181800u,  // '7'
        0x3C66663Cu, 0x66663C00u,  // '8'
        0x3C66663Eu, 0x060C3800u,  // '9'
        0x0000007Eu, 0x00000000u,  // '-'
        0x00000000u, 0x00181800u,  // '.'
        0x00000000u, 0x00000000u,  // ' '
    );
    let word = data[g * 2u + (r / 4u)];
    let shift = (3u - (r % 4u)) * 8u + (7u - c);
    return (word >> shift) & 1u;
}

// Overlays printed value onto col, returning updated RGB.
// pixel_pos : @builtin(position).xy
// origin    : top-left corner of text in screen pixels
// value     : f32 to display
fn debug_f32(col: vec3f, pixel_pos: vec2f, origin: vec2f, value: f32) -> vec3f {
    let ink_color = vec3f(1.0, 1.0, 0.0);  // yellow
    let lp = pixel_pos - origin;
    if (lp.x < 0.0 || lp.x >= 64.0 || lp.y < 0.0 || lp.y >= 8.0) {
        return col;
    }
    let ix = u32(lp.x);
    let iy = u32(lp.y);
    let char_col = ix / 8u;
    let bit_col  = ix % 8u;

    let neg      = value < 0.0;
    let abs_val  = min(abs(value), 999.999f);
    let int_part = u32(abs_val);
    let frac_s   = min(u32((abs_val - f32(int_part)) * 1000.0 + 0.5), 999u);

    var g: u32;
    switch char_col {
        case 0u:    { g = select(12u, 10u, neg); }       // sign
        case 1u:    { g = (int_part / 100u) % 10u; }     // hundreds
        case 2u:    { g = (int_part / 10u)  % 10u; }     // tens
        case 3u:    { g = int_part % 10u; }               // ones
        case 4u:    { g = 11u; }                          // '.'
        case 5u:    { g = (frac_s / 100u) % 10u; }       // tenths
        case 6u:    { g = (frac_s / 10u)  % 10u; }       // hundredths
        default:    { g = frac_s % 10u; }                 // thousandths
    }
    return mix(col, ink_color, f32(_dbg_pixel(g, iy, bit_col)));
}