// File: /workspace/github_c_makefile_star2_O0/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
subq $0x1d0, %rsp            # imm = 0x1D0
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq -0x10(%rbp), %rdi
leaq 0x1fe10(%rip), %rsi     # 0x28a0e
callq 0x22f0
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rdi
movq -0x8(%rbp), %rsi
movl $0x1, %edx
callq 0x211a0
movq -0x18(%rbp), %rdi
callq 0x2030
movq %rax, -0x20(%rbp)
movq -0x18(%rbp), %rax
movq %rax, -0x168(%rbp)
movq -0x8(%rbp), %rdi
addq $0x20, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x21280
movq -0x168(%rbp), %rdi
movq %rax, %rsi
movq -0x8(%rbp), %rax
movq (%rax), %rdx
callq 0x21210
leaq -0x38(%rbp), %rdi
callq 0x212a0
movq -0x18(%rbp), %rdi
callq 0x2030
movq %rax, -0x160(%rbp)
jmp 0x8c73
movq -0x160(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rax
movq %rax, -0x58(%rbp)
movq $0x0, -0x60(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x170(%rbp)
movq -0x8(%rbp), %rdi
addq $0x20, %rdi
callq 0x20f60
movq %rax, %rcx
movq -0x170(%rbp), %rax
cmpq %rcx, %rax
jae 0x8e1e
movq -0x8(%rbp), %rdi
addq $0x20, %rdi
movq -0x60(%rbp), %rsi
callq 0x21280
movq %rax, -0x68(%rbp)
movq -0x68(%rbp), %rax
movq 0x8(%rax), %rdi
movl (%rax), %esi
callq 0x8af0
movq %rax, -0x70(%rbp)
movq -0x68(%rbp), %rax
movq 0x8(%rax), %rsi
movq -0x70(%rbp), %rdx
leaq 0x1fd1d(%rip), %rdi     # 0x28a11
xorl %eax, %eax
callq 0x2050
jmp 0x8cfd
movq -0x70(%rbp), %rdi
callq 0x5b80
movq %rax, %rcx
movq -0x68(%rbp), %rax
movq %rcx, 0x28(%rax)
movq -0x70(%rbp), %rax
movq %rax, -0x180(%rbp)
leaq -0x91(%rbp), %rdi
movq %rdi, -0x178(%rbp)
callq 0x2480
movq -0x180(%rbp), %rsi
movq -0x178(%rbp), %rdx
leaq -0x90(%rbp), %rdi
callq 0x212f0
jmp 0x8d4b
leaq -0x38(%rbp), %rdi
leaq -0x90(%rbp), %rsi
callq 0x212c0
jmp 0x8d5d
leaq -0x90(%rbp), %rdi
callq 0x2170
leaq -0x91(%rbp), %rdi
callq 0x22b0
movq -0x70(%rbp), %rdi
callq 0x2300
movq -0x18(%rbp), %rdi
movq -0x68(%rbp), %rax
movq 0x8(%rax), %rsi
movq 0x10(%rax), %rdx
callq 0x213a0
jmp 0x8d95
movq -0x58(%rbp), %rcx
movq -0x40(%rbp), %rax
subq %rax, %rcx
movq -0x68(%rbp), %rax
movq %rcx, 0x8(%rax)
movq -0x18(%rbp), %rdi
callq 0x2030
movq %rax, -0x188(%rbp)
jmp 0x8dba
movq -0x188(%rbp), %rax
movq %rax, -0x58(%rbp)
movq -0x60(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x60(%rbp)
jmp 0x8c8e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x92d2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
jmp 0x8e0d
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0x90(%rbp), %rdi
callq 0x2170
leaq -0x91(%rbp), %rdi
callq 0x22b0
jmp 0x92d2
leaq -0xd0(%rbp), %rdi
callq 0x21410
movq $0x0, -0xd8(%rbp)
movq -0xd8(%rbp), %rax
movq %rax, -0x190(%rbp)
leaq -0x38(%rbp), %rdi
callq 0x21430
movq %rax, %rcx
movq -0x190(%rbp), %rax
cmpq %rcx, %rax
jae 0x8f0d
movq -0xd8(%rbp), %rsi
leaq -0x38(%rbp), %rdi
callq 0x21450
movq %rax, %rdi
callq 0x20f0
movq %rax, -0xe0(%rbp)
movq -0xe0(%rbp), %rdi
callq 0x5b80
movq %rax, -0xe8(%rbp)
leaq -0xd0(%rbp), %rdi
leaq -0xe8(%rbp), %rsi
callq 0x21470
movq %rax, -0x198(%rbp)
jmp 0x8ead
movq -0x198(%rbp), %rax
testq %rax, %rax
sete %al
movzbl %al, %ecx
leaq 0x1f890(%rip), %rdi     # 0x28754
leaq 0x1fb5e(%rip), %rdx     # 0x28a29
movl $0x1e6, %esi            # imm = 0x1E6
callq 0x28a0
jmp 0x8ed7
jmp 0x8ed9
movq -0xd8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xd8(%rbp)
jmp 0x8e35
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x48(%rbp)
movl %eax, -0x4c(%rbp)
leaq -0xd0(%rbp), %rdi
callq 0x216d0
jmp 0x92d2
movq -0x58(%rbp), %rax
subq -0x40(%rbp), %rax
movq -0x8(%rbp), %rcx
cmpq 0x10(%rcx), %rax
jne 0x8f21
jmp 0x8f40
leaq 0x1fb60(%rip), %rdi     # 0x28a88
leaq 0x1f825(%rip), %rsi     # 0x28754
movl $0x1ee, %edx            # imm = 0x1EE
leaq 0x1fb87(%rip), %rcx     # 0x28ac2
callq 0x2180
movq -0x18(%rbp), %rdi
callq 0x2030
movq %rax, -0x1a0(%rbp)
jmp 0x8f52
movq -0x1a0(%rbp), %rax
movq %rax, -0xf0(%rbp)
movq $0x0, -0xf8(%rbp)
movq -0xf8(%rbp), %rax
movq %rax, -0x1a8(%rbp)
movq -0x8(%rbp), %rdi
addq $0x38, %rdi
callq 0x21070
movq %rax, %rcx
movq -0x1a8(%rbp), %rax
cmpq %rcx, %rax
jae 0x91eb
movq -0x8(%rbp), %rdi
addq $0x38, %rdi
movq -0xf8(%rbp), %rsi
callq 0x210a0
movups (%rax), %xmm0
movups 0x10(%rax), %xmm1
movups 0x20(%rax), %xmm2
movaps %xmm2, -0x110(%rbp)
movaps %xmm1, -0x120(%rbp)
movaps %xmm0, -0x130(%rbp)
movq -0x8(%rbp), %rdi
addq $0x20, %rdi
movq -0xf8(%rbp), %rsi
callq 0x21280
movq %rax, -0x138(%rbp)
movq -0x18(%rbp), %rdi
callq 0x2030
movq %rax, -0x1b0(%rbp)
jmp 0x8ffa
movq -0x1b0(%rbp), %rcx
movq -0x138(%rbp), %rax
movq %rcx, 0x20(%rax)
movq -0x8(%rbp), %rdi
addq $0x20, %rdi
movq -0xf8(%rbp), %rsi
callq 0x21280
movl (%rax), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0x1b8(%rbp)
subl $0x4, %eax
ja 0x9192
movq -0x1b8(%rbp), %rax
leaq 0x1f030(%rip), %rcx     # 0x28074
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movq -0x18(%rbp), %rdi
leaq -0x130(%rbp), %rsi
movl $0x1, %edx
callq 0x214a0
jmp 0x9064
movl -0x128(%rbp), %eax
movl -0x124(%rbp), %ecx
imull %ecx, %eax
movzbl -0x120(%rbp), %ecx
imull %ecx, %eax
movq %rax, -0x140(%rbp)
movq -0x18(%rbp), %rdi
movq -0x130(%rbp), %rsi
movq -0x140(%rbp), %rdx
callq 0x21510
jmp 0x909d
jmp 0x91a4
movq -0x18(%rbp), %rdi
movq -0x130(%rbp), %rsi
movq -0x138(%rbp), %rax
movl 0x30(%rax), %eax
movl %eax, %edx
callq 0x213a0
jmp 0x90c0
jmp 0x91a4
movq -0x18(%rbp), %rdi
leaq -0x130(%rbp), %rsi
movl $0x1, %edx
callq 0x214a0
jmp 0x90dc
movq -0x120(%rbp), %rax
movq %rax, -0x148(%rbp)
movq -0x18(%rbp), %rdi
movq -0x110(%rbp), %rsi
movq -0x148(%rbp), %rdx
callq 0x21580
jmp 0x9103
movq -0x118(%rbp), %rax
movq %rax, -0x150(%rbp)
movq -0x18(%rbp), %rdi
movq -0x108(%rbp), %rsi
movq -0x150(%rbp), %rdx
callq 0x215f0
jmp 0x912a
jmp 0x91a4
movq -0x18(%rbp), %rdi
leaq -0x130(%rbp), %rsi
movl $0x1, %edx
callq 0x214a0
jmp 0x9143
movq -0x18(%rbp), %rdi
movq -0x130(%rbp), %rsi
movl -0x120(%rbp), %eax
movl %eax, %edx
callq 0x21510
jmp 0x915d
jmp 0x91a4
movq -0x18(%rbp), %rdi
leaq -0x130(%rbp), %rsi
movl $0x1, %edx
callq 0x214a0
jmp 0x9176
movq -0x18(%rbp), %rdi
movq -0x120(%rbp), %rsi
movl -0x128(%rbp), %eax
movl %eax, %edx
callq 0x21660
jmp 0x9190
jmp 0x91a4
leaq 0x1f959(%rip), %rdi     # 0x28af2
xorl %eax, %eax
callq 0x2050
jmp 0x91a2
jmp 0x91d4
movq -0x18(%rbp), %rdi
callq 0x2030
movq %rax, -0x1c0(%rbp)
jmp 0x91b6
movq -0x1c0(%rbp), %rax
movq -0x138(%rbp), %rcx
subq 0x20(%rcx), %rax
movl %eax, %ecx
movq -0x138(%rbp), %rax
movl %ecx, 0x30(%rax)
movq -0xf8(%rbp), %rax
addq $0x1, %rax
movq %rax, -0xf8(%rbp)
jmp 0x8f6b
movq -0x18(%rbp), %rdi
callq 0x2030
movq %rax, -0x1c8(%rbp)
jmp 0x91fd
movq -0x1c8(%rbp), %rax
movq %rax, -0x158(%rbp)
movq -0x158(%rbp), %rax
subq -0xf0(%rbp), %rax
movq -0x8(%rbp), %rcx
cmpq 0x18(%rcx), %rax
jne 0x9225
jmp 0x9244
leaq 0x1f8e0(%rip), %rdi     # 0x28b0c
leaq 0x1f521(%rip), %rsi     # 0x28754
movl $0x217, %edx            # imm = 0x217
leaq 0x1f883(%rip), %rcx     # 0x28ac2
callq 0x2180
movq -0x18(%rbp), %rdi
movq -0x20(%rbp), %rsi
xorl %edx, %edx
callq 0x22e0
jmp 0x9255
movq -0x18(%rbp), %rax
movq %rax, -0x1d0(%rbp)
movq -0x8(%rbp), %rdi
addq $0x20, %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x21280
movq -0x1d0(%rbp), %rdi
movq %rax, %rsi
movq -0x8(%rbp), %rax
movq (%rax), %rdx
callq 0x21210
jmp 0x9289
movq -0x18(%rbp), %rdi
callq 0x2260
jmp 0x9294
movq -0x8(%rbp), %rdi
addq $0x38, %rdi
callq 0x21070
movq %rax, %rsi
leaq 0x1f894(%rip), %rdi     # 0x28b3f
xorl %eax, %eax
callq 0x2050
jmp 0x92b4
leaq -0xd0(%rbp), %rdi
callq 0x216d0
leaq -0x38(%rbp), %rdi
callq 0x216f0
addq $0x1d0, %rsp            # imm = 0x1D0
popq %rbp
retq
leaq -0x38(%rbp), %rdi
callq 0x216f0
movq -0x48(%rbp), %rdi
callq 0x2470
nopw %cs:(%rax,%rax)