// File: /workspace/github_c_makefile_star2_O0/FredTheDino[P]Fog/src/engine/unix_assets.cpp
// Function: load_font(AssetFile*, Asset::Header*)
void load_font(AssetFile *file, Asset::Header *header) {
    Asset::Font font = {};
    {
        Asset::Header sdf_header = *header;
        sdf_header.asset_id = 0xFFFFFFF;  // Invalid value
        sdf_header.type = Asset::Type::TEXTURE;
        sdf_header.file_path = (char *) malloc(header->file_path_length);
        strcpy(sdf_header.file_path, header->file_path);
        sdf_header.file_path[header->file_path_length - 2] = 'f';
        sdf_header.file_path[header->file_path_length - 3] = 'd';
        sdf_header.file_path[header->file_path_length - 4] = 's';
        load_texture(file, &sdf_header, false);
        assert(sdf_header.asset_id != 0xFFFFFFF);
        font.texture = file->assets[sdf_header.asset_id].image.id;
    }
    float inv_width  = 1.0 / OPENGL_TEXTURE_WIDTH;
    float inv_height = 1.0 / OPENGL_TEXTURE_HEIGHT;
    FILE *font_file = fopen(header->file_path, "r");
    assert(font_file);
    char *read_line = nullptr;
    size_t size = 0;

    font.glyphs = (Asset::Font::Glyph *) malloc(font.num_glyphs * sizeof(Asset::Font::Glyph));
    long expected_glyphs = 0, expected_kernings = 0;
    while (getline(&read_line, &size, font_file) != -1) {
        char *line = read_line;
        if (starts_with(line, "char")) {
            if (starts_with(line, "chars")) {
                expected_glyphs = read_next_long(&line);
                assert(expected_glyphs);
            } else {
                Asset::Font::Glyph g = {
                    // id
                    (u8) read_next_long(&line),
                    // x, y
                    read_next_long(&line) * inv_width,
                    read_next_long(&line) * inv_height,
                    // w, h
                    read_next_long(&line) * inv_width,
                    read_next_long(&line) * inv_height,
                    // xo, yo
                    read_next_long(&line) * inv_width,
                    read_next_long(&line) * inv_height,
                    // advance
                    read_next_long(&line) * inv_width
                };
                font.height = std::max(g.h, font.height);
                font.glyphs[g.id] = g;
            }
        } else if (starts_with(line, "kerning")) {
            if (starts_with(line, "kernings")) {
                expected_kernings = read_next_long(&line);
                font.kernings = (Asset::Font::Kerning *) malloc(expected_kernings *
                                                  sizeof(Asset::Font::Kerning));
            } else {
                long first = read_next_long(&line);
                long second = read_next_long(&line);
                assert(first <= 0xFF && second <= 0xFF);
                font.kernings[font.num_kernings++] = {
                    (u16) (first << 8 | second),
                    read_next_long(&line) * inv_width
                };
            }
        }

        free(read_line);
        read_line = nullptr;
        size = 0;
    }
    assert(expected_kernings == font.num_kernings);
    std::sort(font.kernings, font.kernings + font.num_kernings);

    header->asset_size = sizeof(Asset::Data) +
                         sizeof(Asset::Font::Kerning) * font.num_kernings +
                         sizeof(Asset::Font::Glyph)   * font.num_glyphs;
    Asset::Data asset = {.font = font};
    add_asset_to_file(file, header, &asset);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x120, %rsp            # imm = 0x120
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
leaq -0x40(%rbp), %rdi
xorl %esi, %esi
movl $0x30, %edx
callq 0x2150
movq $0x100, -0x30(%rbp)     # imm = 0x100
movq -0x10(%rbp), %rsi
leaq -0x78(%rbp), %rdi
movl $0x38, %edx
callq 0x2200
movl $0xfffffff, -0x44(%rbp) # imm = 0xFFFFFFF
movl $0x1, -0x78(%rbp)
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdi
callq 0x2350
movq %rax, -0x70(%rbp)
movq -0x70(%rbp), %rdi
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rsi
callq 0x2240
movq -0x70(%rbp), %rax
movq -0x10(%rbp), %rcx
movq 0x10(%rcx), %rcx
subq $0x2, %rcx
movb $0x66, (%rax,%rcx)
movq -0x70(%rbp), %rax
movq -0x10(%rbp), %rcx
movq 0x10(%rcx), %rcx
subq $0x3, %rcx
movb $0x64, (%rax,%rcx)
movq -0x70(%rbp), %rax
movq -0x10(%rbp), %rcx
movq 0x10(%rcx), %rcx
subq $0x4, %rcx
movb $0x73, (%rax,%rcx)
movq -0x8(%rbp), %rdi
leaq -0x78(%rbp), %rsi
xorl %edx, %edx
callq 0x77c0
cmpl $0xfffffff, -0x44(%rbp) # imm = 0xFFFFFFF
je 0x7a93
jmp 0x7ab2
leaq 0x20dcc(%rip), %rdi     # 0x28866
leaq 0x20cb3(%rip), %rsi     # 0x28754
movl $0x92, %edx
leaq 0x20dda(%rip), %rcx     # 0x28887
callq 0x2180
movq -0x8(%rbp), %rdi
addq $0x38, %rdi
movl -0x44(%rbp), %eax
movl %eax, %esi
callq 0x210a0
movzwl 0x12(%rax), %eax
movq %rax, -0x40(%rbp)
movss 0x20550(%rip), %xmm0    # 0x28024
movss %xmm0, -0x7c(%rbp)
movss 0x20543(%rip), %xmm0    # 0x28024
movss %xmm0, -0x80(%rbp)
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
leaq 0x20dcc(%rip), %rsi     # 0x288c1
callq 0x22f0
movq %rax, -0x88(%rbp)
cmpq $0x0, -0x88(%rbp)
je 0x7b0d
jmp 0x7b2c
leaq 0x20da0(%rip), %rdi     # 0x288b4
leaq 0x20c39(%rip), %rsi     # 0x28754
movl $0x98, %edx
leaq 0x20d60(%rip), %rcx     # 0x28887
callq 0x2180
movq $0x0, -0x90(%rbp)
movq $0x0, -0x98(%rbp)
movq -0x30(%rbp), %rdi
shlq $0x5, %rdi
callq 0x2350
movq %rax, -0x20(%rbp)
movq $0x0, -0xa0(%rbp)
movq $0x0, -0xa8(%rbp)
movq -0x88(%rbp), %rdx
leaq -0x90(%rbp), %rdi
leaq -0x98(%rbp), %rsi
callq 0x2610
cmpq $-0x1, %rax
je 0x7eb1
movq -0x90(%rbp), %rax
movq %rax, -0xb0(%rbp)
movq -0xb0(%rbp), %rdi
leaq 0x20d15(%rip), %rsi     # 0x288be
callq 0x7960
cmpb $0x0, %al
je 0x7d57
movq -0xb0(%rbp), %rdi
leaq 0x20cff(%rip), %rsi     # 0x288c3
callq 0x7960
cmpb $0x0, %al
je 0x7c10
leaq -0xb0(%rbp), %rdi
callq 0x78d0
movq %rax, -0xa0(%rbp)
cmpq $0x0, -0xa0(%rbp)
je 0x7bec
jmp 0x7c0b
leaq 0x20cd6(%rip), %rdi     # 0x288c9
leaq 0x20b5a(%rip), %rsi     # 0x28754
movl $0xa3, %edx
leaq 0x20c81(%rip), %rcx     # 0x28887
callq 0x2180
jmp 0x7d52
leaq -0xb0(%rbp), %rdi
callq 0x78d0
movb %al, -0xd0(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x78d0
cvtsi2ss %rax, %xmm0
mulss -0x7c(%rbp), %xmm0
movss %xmm0, -0xcc(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x78d0
cvtsi2ss %rax, %xmm0
mulss -0x80(%rbp), %xmm0
movss %xmm0, -0xc8(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x78d0
cvtsi2ss %rax, %xmm0
mulss -0x7c(%rbp), %xmm0
movss %xmm0, -0xc4(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x78d0
cvtsi2ss %rax, %xmm0
mulss -0x80(%rbp), %xmm0
movss %xmm0, -0xc0(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x78d0
cvtsi2ss %rax, %xmm0
mulss -0x7c(%rbp), %xmm0
movss %xmm0, -0xbc(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x78d0
cvtsi2ss %rax, %xmm0
mulss -0x80(%rbp), %xmm0
movss %xmm0, -0xb8(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x78d0
cvtsi2ss %rax, %xmm0
mulss -0x7c(%rbp), %xmm0
movss %xmm0, -0xb4(%rbp)
leaq -0xd0(%rbp), %rdi
addq $0x10, %rdi
leaq -0x40(%rbp), %rsi
addq $0x8, %rsi
callq 0x210c0
movss (%rax), %xmm0
movss %xmm0, -0x38(%rbp)
movq -0x20(%rbp), %rax
movzbl -0xd0(%rbp), %ecx
shlq $0x5, %rcx
addq %rcx, %rax
movq -0xd0(%rbp), %rcx
movq %rcx, (%rax)
movq -0xc8(%rbp), %rcx
movq %rcx, 0x8(%rax)
movq -0xc0(%rbp), %rcx
movq %rcx, 0x10(%rax)
movq -0xb8(%rbp), %rcx
movq %rcx, 0x18(%rax)
jmp 0x7e8a
movq -0xb0(%rbp), %rdi
leaq 0x20b74(%rip), %rsi     # 0x288d9
callq 0x7960
cmpb $0x0, %al
je 0x7e88
movq -0xb0(%rbp), %rdi
leaq 0x20b9f(%rip), %rsi     # 0x2891f
callq 0x7960
cmpb $0x0, %al
je 0x7db5
leaq -0xb0(%rbp), %rdi
callq 0x78d0
movq %rax, -0xa8(%rbp)
movq -0xa8(%rbp), %rdi
shlq $0x3, %rdi
callq 0x2350
movq %rax, -0x18(%rbp)
jmp 0x7e86
leaq -0xb0(%rbp), %rdi
callq 0x78d0
movq %rax, -0xd8(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x78d0
movq %rax, -0xe0(%rbp)
xorl %eax, %eax
cmpq $0xff, -0xd8(%rbp)
movb %al, -0x119(%rbp)
jg 0x7e04
cmpq $0xff, -0xe0(%rbp)
setle %al
movb %al, -0x119(%rbp)
movb -0x119(%rbp), %al
testb $0x1, %al
jne 0x7e10
jmp 0x7e12
jmp 0x7e31
leaq 0x20ac8(%rip), %rdi     # 0x288e1
leaq 0x20934(%rip), %rsi     # 0x28754
movl $0xbf, %edx
leaq 0x20a5b(%rip), %rcx     # 0x28887
callq 0x2180
movq -0xd8(%rbp), %rax
shlq $0x8, %rax
orq -0xe0(%rbp), %rax
movw %ax, -0xe8(%rbp)
leaq -0xb0(%rbp), %rdi
callq 0x78d0
cvtsi2ss %rax, %xmm0
mulss -0x7c(%rbp), %xmm0
movss %xmm0, -0xe4(%rbp)
movq -0x18(%rbp), %rax
movq -0x28(%rbp), %rcx
movq %rcx, %rdx
addq $0x1, %rdx
movq %rdx, -0x28(%rbp)
movq -0xe8(%rbp), %rdx
movq %rdx, (%rax,%rcx,8)
jmp 0x7e88
jmp 0x7e8a
movq -0x90(%rbp), %rdi
callq 0x2300
movq $0x0, -0x90(%rbp)
movq $0x0, -0x98(%rbp)
jmp 0x7b69
movq -0xa8(%rbp), %rax
cmpq -0x28(%rbp), %rax
jne 0x7ec0
jmp 0x7edf
leaq 0x20a3a(%rip), %rdi     # 0x28901
leaq 0x20886(%rip), %rsi     # 0x28754
movl $0xcb, %edx
leaq 0x209ad(%rip), %rcx     # 0x28887
callq 0x2180
movq -0x18(%rbp), %rdi
movq -0x18(%rbp), %rsi
movq -0x28(%rbp), %rax
shlq $0x3, %rax
addq %rax, %rsi
callq 0x21100
movq -0x28(%rbp), %rax
shlq $0x3, %rax
addq $0x30, %rax
movq -0x30(%rbp), %rcx
shlq $0x5, %rcx
addq %rcx, %rax
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x30(%rax)
leaq -0x118(%rbp), %rdi
leaq -0x40(%rbp), %rsi
movl $0x30, %edx
callq 0x2200
movq -0x8(%rbp), %rdi
movq -0x10(%rbp), %rsi
leaq -0x118(%rbp), %rdx
callq 0x7680
addq $0x120, %rsp            # imm = 0x120
popq %rbp
retq
nopl (%rax)