// File: /workspace/github_c_makefile_star2_O1/FredTheDino[P]Fog/src/engine/unix_assets.cpp
// Function: dump_asset_file(AssetFile*, char const*)
void dump_asset_file(AssetFile *file, const char *out_path) {
    FILE *output_file = fopen(out_path, "wb");

    write_to_file(output_file, &file->header);
    u64 header_location = ftell(output_file);
    write_to_file(output_file, &file->asset_headers[0],
                  file->header.number_of_assets);

#ifdef GEN_SOURCE_FILE
#define WRITE_TO_SORUCE(...) fprintf(source_file, __VA_ARGS__)
    FILE *source_file = fopen("src/fog_assets.cpp", "w");
#else
#define WRITE_TO_SORUCE(...)
#endif
    WRITE_TO_SORUCE("// Don't edit this file, this file contains the asset ids\n"
                         "// for all assets in the game, and is autogenerated.\n"
                         "// Editing this file will result in a bad day.\n");
    std::vector<std::string> entiries;
    u64 string_begin = ftell(output_file);
    u64 string_cur = string_begin;
    // Write assets
    WRITE_TO_SORUCE("namespace Res {\n");
    for (u64 i = 0; i < file->asset_headers.size(); i++) {
        auto *header = &file->asset_headers[i];
        const char *asset_name = asset_name_from_file(header->file_path, header->type);
        printf("\tFound asset: %s -> %s\n", header->file_path,
               asset_name);
        WRITE_TO_SORUCE("constexpr Asset::AssetID %s = %llu;\n", asset_name, i);
        header->hash = Asset::asset_hash(asset_name);
        entiries.push_back(asset_name);
        free((void *) asset_name);

        write_to_file(output_file, header->file_path, header->file_path_length);
        header->file_path = (char *) (string_cur - string_begin);
        string_cur = ftell(output_file);
    }
    WRITE_TO_SORUCE("constexpr u64 NUM_ASSETS = %u;\n", (u32) entiries.size());

    WRITE_TO_SORUCE("\n// A hash table for absolute references outside\n// the code, used between builds of the engine, don't use these in your\n// game if you can avoid it.\n");
    // Write hash table
    std::unordered_set<u64> collisions;
    WRITE_TO_SORUCE("constexpr u64 HASH_LUT[] = {\n");
    for (u64 i = 0; i < entiries.size(); i++) {
        const char *c = entiries[i].c_str();
        u64 hash = Asset::asset_hash(c);
        ASSERT(collisions.count(hash) == 0, "Collision in asset system, update the hash function. (asset_hash)");
        WRITE_TO_SORUCE("    [%s] = %llu,\n", c, hash);
    }
    WRITE_TO_SORUCE("};");
    WRITE_TO_SORUCE("} // Namespace Res\n");
#ifdef GEN_SOURCE_FILE
    fclose(source_file);
#endif
    assert(string_cur - string_begin == file->header.size_of_strings);

    // Serialization of assets
    u64 data_begin = ftell(output_file);
    for (u64 i = 0; i < file->assets.size(); i++) {
        Asset::Data asset = file->assets[i];
        Asset::Header *header = &file->asset_headers[i];
        header->offset = ftell(output_file);
        switch (file->asset_headers[i].type) {
            case (Asset::Type::TEXTURE): {
                write_to_file(output_file, &asset);
                u64 size = asset.image.width * asset.image.height *
                           asset.image.components;
                write_to_file(output_file, asset.image.data, size);
            } break;
            case (Asset::Type::SHADER): {
                write_to_file(output_file, asset.shader_source, header->asset_size);
            } break;
            case (Asset::Type::FONT): {
                write_to_file(output_file, &asset);
                u64 num_glyphs = asset.font.num_glyphs;
                write_to_file(output_file, asset.font.glyphs, num_glyphs);
                u64 num_kernings = asset.font.num_kernings;
                write_to_file(output_file, asset.font.kernings, num_kernings);
            } break;
            case (Asset::Type::SOUND): {
                write_to_file(output_file, &asset);
                write_to_file(output_file, asset.sound.data, asset.sound.size);
            } break;
            case (Asset::Type::SPRITE): {
                write_to_file(output_file, &asset);
                write_to_file(output_file, asset.sprite.points, asset.sprite.num_points);
            } break;
            default:
                printf("UNIMPLEMENTED ASSET TYPE\n");
                continue;
                break;
        };
        header->asset_size = ftell(output_file) - header->offset;
    }
    u64 data_end = ftell(output_file);
    assert(data_end - data_begin == file->header.size_of_data);

    fseek(output_file, header_location, SEEK_SET);
    write_to_file(output_file, &file->asset_headers[0],
                  file->header.number_of_assets);

    fclose(output_file);
    printf("\tLoaded %lu assets\n", file->assets.size());
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xb8, %rsp
movq %rsi, %rax
movq %rdi, %rbx
leaq 0x12c7c(%rip), %rsi     # 0x1ab6e
movq %rax, %rdi
callq 0x2210
movq %rax, %r15
movl $0x20, %esi
movl $0x1, %edx
movq %rbx, %rdi
movq %rax, %rcx
callq 0x23b0
xorl %ecx, %ecx
cmpq $0x1, %rax
sete %cl
leaq 0x12992(%rip), %r12     # 0x1a8b4
leaq 0x138ff(%rip), %r14     # 0x1b828
movq %r12, %rdi
movl $0x17a, %esi            # imm = 0x17A
movq %r14, %rdx
callq 0x274b
movq %r15, %rdi
callq 0x2030
movq %rax, -0xa8(%rbp)
movq (%rbx), %r13
movq 0x20(%rbx), %rdi
movl $0x38, %esi
movq %r13, %rdx
movq %r15, %rcx
callq 0x23b0
xorl %ecx, %ecx
cmpq %r13, %rax
sete %cl
movq %r12, %rdi
movl $0x17a, %esi            # imm = 0x17A
movq %r14, %rdx
movq %rbx, %r14
movq %rbx, -0x48(%rbp)
callq 0x274b
xorps %xmm0, %xmm0
movaps %xmm0, -0xa0(%rbp)
movq $0x0, -0x90(%rbp)
movq %r15, -0x30(%rbp)
movq %r15, %rdi
callq 0x2030
movq %rax, %r13
movq 0x20(%rbx), %rbx
cmpq %rbx, 0x28(%r14)
movq %rax, -0x38(%rbp)
je 0x8116
xorl %r14d, %r14d
imulq $0x38, %r14, %r15
movq 0x8(%rbx,%r15), %rdi
movl (%rbx,%r15), %esi
callq 0x7d86
movq %rax, %r12
movq 0x8(%rbx,%r15), %rsi
leaq 0x12b99(%rip), %rdi     # 0x1ab71
movq %rax, %rdx
xorl %eax, %eax
callq 0x2050
movb (%r12), %dl
testb %dl, %dl
je 0x8037
leaq 0x1(%r12), %rax
movl $0x14e7, %ecx           # imm = 0x14E7
movsbq %dl, %rdx
incq %rcx
imulq %rdx, %rcx
movb (%rax), %dl
incq %rax
testb %dl, %dl
jne 0x7ff4
movq %rcx, %rax
movabsq $0x1000000101, %rdx     # imm = 0x1000000101
mulq %rdx
movq %rcx, %rax
subq %rdx, %rax
shrq %rax
addq %rdx, %rax
shrq $0x1b, %rax
movq %rax, %rdx
shlq $0x1c, %rdx
subq %rdx, %rax
addq %rcx, %rax
jmp 0x803c
movl $0x14e7, %eax           # imm = 0x14E7
addq %r15, %rbx
movq %rax, 0x28(%rbx)
leaq -0xe0(%rbp), %r15
movq %r15, %rdi
movq %r12, %rsi
leaq -0x80(%rbp), %rdx
callq 0x18660
leaq -0xa0(%rbp), %rdi
movq %r15, %rsi
callq 0x19582
movq -0x48(%rbp), %r15
movq %r13, -0x40(%rbp)
movq -0xe0(%rbp), %rdi
leaq -0xd0(%rbp), %rax
cmpq %rax, %rdi
je 0x8092
movq -0xd0(%rbp), %rsi
incq %rsi
callq 0x21d0
movq %r12, %rdi
callq 0x2220
movq 0x8(%rbx), %rdi
movq 0x10(%rbx), %r12
movl $0x1, %esi
movq %r12, %rdx
movq -0x30(%rbp), %r13
movq %r13, %rcx
callq 0x23b0
xorl %ecx, %ecx
cmpq %r12, %rax
sete %cl
leaq 0x127ef(%rip), %rdi     # 0x1a8b4
movl $0x17a, %esi            # imm = 0x17A
leaq 0x13757(%rip), %rdx     # 0x1b828
callq 0x274b
movq -0x40(%rbp), %rax
subq -0x38(%rbp), %rax
movq %rax, 0x8(%rbx)
movq %r13, %rdi
callq 0x2030
movq %rax, %r13
incq %r14
movq 0x20(%r15), %rbx
movq 0x28(%r15), %rax
subq %rbx, %rax
sarq $0x3, %rax
movabsq $0x6db6db6db6db6db7, %rcx # imm = 0x6DB6DB6DB6DB6DB7
imulq %rcx, %rax
cmpq %rax, %r14
jb 0x7fb7
leaq -0xb0(%rbp), %rax
movq %rax, -0x30(%rax)
movq $0x1, -0x28(%rax)
xorps %xmm0, %xmm0
movups %xmm0, -0x20(%rax)
movl $0x3f800000, -0x10(%rax) # imm = 0x3F800000
movups %xmm0, -0x8(%rax)
movq -0xa0(%rbp), %rax
cmpq %rax, -0x98(%rbp)
movq -0x30(%rbp), %r14
je 0x8211
xorl %ebx, %ebx
leaq 0x12758(%rip), %r15     # 0x1a8b4
leaq 0x12a26(%rip), %r12     # 0x1ab89
movq %rbx, %rcx
shlq $0x5, %rcx
movq (%rax,%rcx), %rax
movb (%rax), %dl
testb %dl, %dl
je 0x81bf
incq %rax
movl $0x14e7, %ecx           # imm = 0x14E7
movsbq %dl, %rdx
incq %rcx
imulq %rdx, %rcx
movb (%rax), %dl
incq %rax
testb %dl, %dl
jne 0x817c
movq %rcx, %rax
movabsq $0x1000000101, %rdx     # imm = 0x1000000101
mulq %rdx
movq %rcx, %rax
subq %rdx, %rax
shrq %rax
addq %rdx, %rax
shrq $0x1b, %rax
movq %rax, %rdx
shlq $0x1c, %rdx
subq %rdx, %rax
addq %rcx, %rax
jmp 0x81c4
movl $0x14e7, %eax           # imm = 0x14E7
movq %rax, -0x80(%rbp)
leaq -0xe0(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x19800
xorl %ecx, %ecx
testq %rax, %rax
sete %cl
movq %r15, %rdi
movl $0x1e6, %esi            # imm = 0x1E6
movq %r12, %rdx
callq 0x274b
incq %rbx
movq -0xa0(%rbp), %rax
movq -0x98(%rbp), %rcx
subq %rax, %rcx
sarq $0x5, %rcx
cmpq %rcx, %rbx
jb 0x8163
subq -0x38(%rbp), %r13
movq -0x48(%rbp), %r15
cmpq 0x10(%r15), %r13
jne 0x856e
movq %r14, %rdi
callq 0x2030
movq %rax, -0x38(%rbp)
movq 0x38(%r15), %rax
cmpq %rax, 0x40(%r15)
je 0x84af
xorl %r12d, %r12d
xorl %r13d, %r13d
xorl %ebx, %ebx
movups (%rax,%r13), %xmm0
movups 0x10(%rax,%r13), %xmm1
movups 0x20(%rax,%r13), %xmm2
movaps %xmm2, -0x60(%rbp)
movaps %xmm1, -0x70(%rbp)
movaps %xmm0, -0x80(%rbp)
movq 0x20(%r15), %r14
movq -0x30(%rbp), %rdi
callq 0x2030
movq %r14, -0x40(%rbp)
movq %rax, 0x20(%r14,%r12)
movq 0x20(%r15), %rax
movl (%rax,%r12), %eax
decl %eax
cmpl $0x4, %eax
ja 0x84a1
leaq 0x12622(%rip), %r14     # 0x1a8b4
leaq 0x11f3b(%rip), %rcx     # 0x1a1d4
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movl $0x30, %esi
movl $0x1, %edx
leaq -0x80(%rbp), %rdi
movq -0x30(%rbp), %rcx
callq 0x23b0
xorl %ecx, %ecx
cmpq $0x1, %rax
sete %cl
movq %r14, %rdi
movl $0x17a, %esi            # imm = 0x17A
leaq 0x13557(%rip), %r14     # 0x1b828
movq %r14, %rdx
callq 0x274b
movl -0x74(%rbp), %eax
imull -0x78(%rbp), %eax
movzbl -0x70(%rbp), %r15d
imull %eax, %r15d
movq -0x80(%rbp), %rdi
jmp 0x83aa
movq -0x80(%rbp), %rdi
movq -0x40(%rbp), %rax
movl 0x30(%rax,%r12), %r14d
movl $0x1, %esi
movq %r14, %rdx
movq -0x30(%rbp), %rcx
callq 0x23b0
cmpq %r14, %rax
sete %al
leaq 0x1350b(%rip), %rdx     # 0x1b828
jmp 0x843f
movl $0x30, %esi
movl $0x1, %edx
leaq -0x80(%rbp), %rdi
movq -0x30(%rbp), %rcx
callq 0x23b0
xorl %ecx, %ecx
cmpq $0x1, %rax
sete %cl
movq %r14, %rdi
movl $0x17a, %esi            # imm = 0x17A
leaq 0x134d7(%rip), %r14     # 0x1b828
movq %r14, %rdx
callq 0x274b
movq -0x70(%rbp), %rdi
movl -0x78(%rbp), %r15d
movl $0x10, %esi
jmp 0x842a
movl $0x30, %esi
movl $0x1, %edx
leaq -0x80(%rbp), %rdi
movq -0x30(%rbp), %rcx
callq 0x23b0
xorl %ecx, %ecx
cmpq $0x1, %rax
sete %cl
movq %r14, %rdi
movl $0x17a, %esi            # imm = 0x17A
leaq 0x1348e(%rip), %r14     # 0x1b828
movq %r14, %rdx
callq 0x274b
movq -0x80(%rbp), %rdi
movl -0x70(%rbp), %r15d
movl $0x1, %esi
jmp 0x842a
movl $0x30, %esi
movl $0x1, %edx
leaq -0x80(%rbp), %rdi
movq -0x30(%rbp), %rcx
callq 0x23b0
xorl %ecx, %ecx
cmpq $0x1, %rax
sete %cl
movq %r14, %rdi
movl $0x17a, %esi            # imm = 0x17A
leaq 0x13448(%rip), %rdx     # 0x1b828
callq 0x274b
movq -0x70(%rbp), %r15
movq -0x60(%rbp), %rdi
movl $0x20, %esi
movq %r15, %rdx
movq -0x30(%rbp), %rcx
callq 0x23b0
xorl %ecx, %ecx
cmpq %r15, %rax
sete %cl
movq %r14, %rdi
movl $0x17a, %esi            # imm = 0x17A
leaq 0x13413(%rip), %r14     # 0x1b828
movq %r14, %rdx
callq 0x274b
movq -0x68(%rbp), %r15
movq -0x58(%rbp), %rdi
movl $0x8, %esi
movq %r15, %rdx
movq -0x30(%rbp), %rcx
callq 0x23b0
movq %r14, %rdx
cmpq %r15, %rax
sete %al
movzbl %al, %ecx
leaq 0x1246b(%rip), %rdi     # 0x1a8b4
movl $0x17a, %esi            # imm = 0x17A
callq 0x274b
movq -0x30(%rbp), %rdi
callq 0x2030
movq -0x40(%rbp), %rcx
subl 0x20(%rcx,%r12), %eax
movl %eax, 0x30(%rcx,%r12)
movq -0x48(%rbp), %r15
incq %rbx
movq 0x38(%r15), %rax
movq 0x40(%r15), %rcx
subq %rax, %rcx
sarq $0x4, %rcx
movabsq $-0x5555555555555555, %rdx # imm = 0xAAAAAAAAAAAAAAAB
imulq %rdx, %rcx
addq $0x30, %r13
addq $0x38, %r12
cmpq %rcx, %rbx
jb 0x8245
jmp 0x84af
leaq 0x133ac(%rip), %rdi     # 0x1b854
callq 0x2300
jmp 0x846e
movq -0x30(%rbp), %r14
movq %r14, %rdi
callq 0x2030
subq -0x38(%rbp), %rax
cmpq 0x18(%r15), %rax
jne 0x858d
movq %r14, %rdi
movq -0xa8(%rbp), %rsi
xorl %edx, %edx
callq 0x2200
movq %r15, %rbx
movq (%r15), %r15
movq 0x20(%rbx), %rdi
movl $0x38, %esi
movq %r15, %rdx
movq %r14, %rcx
callq 0x23b0
xorl %ecx, %ecx
cmpq %r15, %rax
sete %cl
leaq 0x123b1(%rip), %rdi     # 0x1a8b4
leaq 0x1331e(%rip), %rdx     # 0x1b828
movl $0x17a, %esi            # imm = 0x17A
callq 0x274b
movq %r14, %rdi
callq 0x21b0
movq 0x40(%rbx), %rsi
subq 0x38(%rbx), %rsi
sarq $0x4, %rsi
movabsq $-0x5555555555555555, %rax # imm = 0xAAAAAAAAAAAAAAAB
imulq %rax, %rsi
leaq 0x12748(%rip), %rdi     # 0x1ac85
xorl %eax, %eax
callq 0x2050
leaq -0xe0(%rbp), %rdi
callq 0x1880c
leaq -0xa0(%rbp), %rdi
callq 0x1869e
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x12673(%rip), %rdi     # 0x1abe8
leaq 0x12338(%rip), %rsi     # 0x1a8b4
leaq 0x1269f(%rip), %rcx     # 0x1ac22
movl $0x1ee, %edx            # imm = 0x1EE
callq 0x2120
leaq 0x126be(%rip), %rdi     # 0x1ac52
leaq 0x12319(%rip), %rsi     # 0x1a8b4
leaq 0x12680(%rip), %rcx     # 0x1ac22
movl $0x217, %edx            # imm = 0x217
callq 0x2120
movq %rax, %rbx
leaq -0xe0(%rbp), %rdi
callq 0x1880c
jmp 0x85e7
movq %rax, %rbx
jmp 0x85e7
movq %rax, %rbx
movq -0xe0(%rbp), %rdi
leaq -0xd0(%rbp), %rax
cmpq %rax, %rdi
je 0x85e7
movq -0xd0(%rbp), %rsi
incq %rsi
callq 0x21d0
leaq -0xa0(%rbp), %rdi
callq 0x1869e
movq %rbx, %rdi
callq 0x2380