// File: /workspace/github_c_makefile_star2_O3/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 0x11d8f(%rip), %rsi     # 0x19b6e
movq %rax, %rdi
callq 0x2220
movq %rax, %r15
movl $0x20, %esi
movl $0x1, %edx
movq %rbx, %rdi
movq %rax, %rcx
callq 0x23a0
xorl %ecx, %ecx
cmpq $0x1, %rax
sete %cl
leaq 0x11aa5(%rip), %r12     # 0x198b4
leaq 0x12a0b(%rip), %r14     # 0x1a821
movq %r12, %rdi
movl $0x17a, %esi            # imm = 0x17A
movq %r14, %rdx
callq 0x273b
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 0x23a0
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 0x273b
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)
je 0x801b
movq %r13, -0x40(%rbp)
xorl %r14d, %r14d
imulq $0x38, %r14, %r15
movq 0x8(%rbx,%r15), %rdi
movl (%rbx,%r15), %esi
callq 0x7c73
movq %rax, %r12
movq 0x8(%rbx,%r15), %rsi
leaq 0x11cac(%rip), %rdi     # 0x19b71
movq %rax, %rdx
xorl %eax, %eax
callq 0x2050
movb (%r12), %dl
testb %dl, %dl
je 0x7f24
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 0x7ee1
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 0x7f29
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 0x1735a
leaq -0xa0(%rbp), %rdi
movq %r15, %rsi
callq 0x18268
movq -0x48(%rbp), %r15
movq %r13, -0x38(%rbp)
movq -0xe0(%rbp), %rdi
leaq -0xd0(%rbp), %rax
cmpq %rax, %rdi
je 0x7f7f
movq -0xd0(%rbp), %rsi
incq %rsi
callq 0x21e0
movq %r12, %rdi
callq 0x2230
movq 0x8(%rbx), %rdi
movq 0x10(%rbx), %r12
movl $0x1, %esi
movq %r12, %rdx
movq -0x30(%rbp), %r13
movq %r13, %rcx
callq 0x23a0
xorl %ecx, %ecx
cmpq %r12, %rax
sete %cl
leaq 0x11902(%rip), %rdi     # 0x198b4
movl $0x17a, %esi            # imm = 0x17A
leaq 0x12863(%rip), %rdx     # 0x1a821
callq 0x273b
movq -0x38(%rbp), %rax
subq -0x40(%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 0x7ea4
movq %r13, -0x38(%rbp)
movq -0xa0(%rbp), %rax
movq -0x98(%rbp), %rcx
movq -0x40(%rbp), %r13
jmp 0x8023
xorl %eax, %eax
xorl %ecx, %ecx
movq %r13, -0x38(%rbp)
leaq -0xb0(%rbp), %rdx
movq %rdx, -0x30(%rdx)
movq $0x1, -0x28(%rdx)
xorps %xmm0, %xmm0
movups %xmm0, -0x20(%rdx)
movl $0x3f800000, -0x10(%rdx) # imm = 0x3F800000
movups %xmm0, -0x8(%rdx)
cmpq %rax, %rcx
movq -0x30(%rbp), %r14
je 0x815c
xorl %ebx, %ebx
leaq 0x11856(%rip), %r15     # 0x198b4
leaq 0x11b24(%rip), %r12     # 0x19b89
movq %rbx, %rcx
shlq $0x5, %rcx
movq (%rax,%rcx), %rax
movb (%rax), %cl
testb %cl, %cl
je 0x80c1
incq %rax
movl $0x14e7, %esi           # imm = 0x14E7
movsbq %cl, %rcx
incq %rsi
imulq %rcx, %rsi
movb (%rax), %cl
incq %rax
testb %cl, %cl
jne 0x807e
movq %rsi, %rax
movabsq $0x1000000101, %rcx     # imm = 0x1000000101
mulq %rcx
movq %rsi, %rcx
subq %rdx, %rcx
shrq %rcx
addq %rdx, %rcx
shrq $0x1b, %rcx
movq %rcx, %rax
shlq $0x1c, %rax
subq %rax, %rcx
addq %rsi, %rcx
jmp 0x80c6
movl $0x14e7, %ecx           # imm = 0x14E7
movq -0xe0(%rbp), %rdi
movq -0xd8(%rbp), %r8
movq %rcx, %rax
xorl %edx, %edx
divq %r8
movq %rdx, %rsi
movq (%rdi,%rdx,8), %rdx
movl $0x0, %eax
testq %rdx, %rdx
je 0x8123
movq (%rdx), %r9
movq %r9, %rax
cmpq 0x8(%r9), %rcx
je 0x8123
movq (%r9), %r9
testq %r9, %r9
je 0x8121
movq 0x8(%r9), %rdi
movq %rdi, %rax
xorl %edx, %edx
divq %r8
movl $0x0, %eax
cmpq %rsi, %rdx
jne 0x8123
movq %r9, %rax
cmpq %rdi, %rcx
jne 0x80f9
jmp 0x8123
xorl %eax, %eax
xorl %ecx, %ecx
testq %rax, %rax
sete %cl
movq %r15, %rdi
movl $0x1e6, %esi            # imm = 0x1E6
movq %r12, %rdx
callq 0x273b
incq %rbx
movq -0xa0(%rbp), %rax
movq -0x98(%rbp), %rcx
subq %rax, %rcx
sarq $0x5, %rcx
cmpq %rcx, %rbx
jb 0x8065
movq -0x38(%rbp), %rax
subq %r13, %rax
movq -0x48(%rbp), %r15
cmpq 0x10(%r15), %rax
jne 0x84bc
movq %r14, %rdi
callq 0x2030
movq %rax, -0x40(%rbp)
movq 0x38(%r15), %rax
cmpq %rax, 0x40(%r15)
je 0x83fd
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, -0x38(%rbp)
movq %rax, 0x20(%r14,%r12)
movq 0x20(%r15), %rax
movl (%rax,%r12), %eax
decl %eax
cmpl $0x4, %eax
ja 0x83ef
leaq 0x116d4(%rip), %r14     # 0x198b4
leaq 0x10fed(%rip), %rcx     # 0x191d4
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 0x23a0
xorl %ecx, %ecx
cmpq $0x1, %rax
sete %cl
movq %r14, %rdi
movl $0x17a, %esi            # imm = 0x17A
leaq 0x12602(%rip), %r14     # 0x1a821
movq %r14, %rdx
callq 0x273b
movl -0x74(%rbp), %eax
imull -0x78(%rbp), %eax
movzbl -0x70(%rbp), %r15d
imull %eax, %r15d
movq -0x80(%rbp), %rdi
jmp 0x82f8
movq -0x80(%rbp), %rdi
movq -0x38(%rbp), %rax
movl 0x30(%rax,%r12), %r14d
movl $0x1, %esi
movq %r14, %rdx
movq -0x30(%rbp), %rcx
callq 0x23a0
cmpq %r14, %rax
sete %al
leaq 0x125b6(%rip), %rdx     # 0x1a821
jmp 0x838d
movl $0x30, %esi
movl $0x1, %edx
leaq -0x80(%rbp), %rdi
movq -0x30(%rbp), %rcx
callq 0x23a0
xorl %ecx, %ecx
cmpq $0x1, %rax
sete %cl
movq %r14, %rdi
movl $0x17a, %esi            # imm = 0x17A
leaq 0x12582(%rip), %r14     # 0x1a821
movq %r14, %rdx
callq 0x273b
movq -0x70(%rbp), %rdi
movl -0x78(%rbp), %r15d
movl $0x10, %esi
jmp 0x8378
movl $0x30, %esi
movl $0x1, %edx
leaq -0x80(%rbp), %rdi
movq -0x30(%rbp), %rcx
callq 0x23a0
xorl %ecx, %ecx
cmpq $0x1, %rax
sete %cl
movq %r14, %rdi
movl $0x17a, %esi            # imm = 0x17A
leaq 0x12539(%rip), %r14     # 0x1a821
movq %r14, %rdx
callq 0x273b
movq -0x80(%rbp), %rdi
movl -0x70(%rbp), %r15d
movl $0x1, %esi
jmp 0x8378
movl $0x30, %esi
movl $0x1, %edx
leaq -0x80(%rbp), %rdi
movq -0x30(%rbp), %rcx
callq 0x23a0
xorl %ecx, %ecx
cmpq $0x1, %rax
sete %cl
movq %r14, %rdi
movl $0x17a, %esi            # imm = 0x17A
leaq 0x124f3(%rip), %rdx     # 0x1a821
callq 0x273b
movq -0x70(%rbp), %r15
movq -0x60(%rbp), %rdi
movl $0x20, %esi
movq %r15, %rdx
movq -0x30(%rbp), %rcx
callq 0x23a0
xorl %ecx, %ecx
cmpq %r15, %rax
sete %cl
movq %r14, %rdi
movl $0x17a, %esi            # imm = 0x17A
leaq 0x124be(%rip), %r14     # 0x1a821
movq %r14, %rdx
callq 0x273b
movq -0x68(%rbp), %r15
movq -0x58(%rbp), %rdi
movl $0x8, %esi
movq %r15, %rdx
movq -0x30(%rbp), %rcx
callq 0x23a0
movq %r14, %rdx
cmpq %r15, %rax
sete %al
movzbl %al, %ecx
leaq 0x1151d(%rip), %rdi     # 0x198b4
movl $0x17a, %esi            # imm = 0x17A
callq 0x273b
movq -0x30(%rbp), %rdi
callq 0x2030
movq -0x38(%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 0x8193
jmp 0x83fd
leaq 0x12457(%rip), %rdi     # 0x1a84d
callq 0x2300
jmp 0x83bc
movq -0x30(%rbp), %r14
movq %r14, %rdi
callq 0x2030
subq -0x40(%rbp), %rax
cmpq 0x18(%r15), %rax
jne 0x84db
movq %r14, %rdi
movq -0xa8(%rbp), %rsi
xorl %edx, %edx
callq 0x2210
movq %r15, %rbx
movq (%r15), %r15
movq 0x20(%rbx), %rdi
movl $0x38, %esi
movq %r15, %rdx
movq %r14, %rcx
callq 0x23a0
xorl %ecx, %ecx
cmpq %r15, %rax
sete %cl
leaq 0x11463(%rip), %rdi     # 0x198b4
leaq 0x123c9(%rip), %rdx     # 0x1a821
movl $0x17a, %esi            # imm = 0x17A
callq 0x273b
movq %r14, %rdi
callq 0x21c0
movq 0x40(%rbx), %rsi
subq 0x38(%rbx), %rsi
sarq $0x4, %rsi
movabsq $-0x5555555555555555, %rax # imm = 0xAAAAAAAAAAAAAAAB
imulq %rax, %rsi
leaq 0x117fa(%rip), %rdi     # 0x19c85
xorl %eax, %eax
callq 0x2050
leaq -0xe0(%rbp), %rdi
callq 0x1750a
leaq -0xa0(%rbp), %rdi
callq 0x17398
addq $0xb8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0x11725(%rip), %rdi     # 0x19be8
leaq 0x113ea(%rip), %rsi     # 0x198b4
leaq 0x11751(%rip), %rcx     # 0x19c22
movl $0x1ee, %edx            # imm = 0x1EE
callq 0x2120
leaq 0x11770(%rip), %rdi     # 0x19c52
leaq 0x113cb(%rip), %rsi     # 0x198b4
leaq 0x11732(%rip), %rcx     # 0x19c22
movl $0x217, %edx            # imm = 0x217
callq 0x2120
movq %rax, %rbx
jmp 0x8524
movq %rax, %rbx
movq -0xe0(%rbp), %rdi
leaq -0xd0(%rbp), %rax
cmpq %rax, %rdi
je 0x8524
movq -0xd0(%rbp), %rsi
incq %rsi
callq 0x21e0
leaq -0xa0(%rbp), %rdi
callq 0x17398
movq %rbx, %rdi
callq 0x2380