// File: OpenFodder[P]SOS_Unpacker/SOS_Unpacker.cpp
// Function: ExtractFiles(std::vector<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&)
void ExtractFiles(const std::vector<std::string> pTrackBuffers, const std::string& pTargetFolder) {

    // Track3 is the directory listing
    UBYTE* TrackPtr = (UBYTE*)pTrackBuffers[2].data();
    UDWORD FileCount = readBEDWord(TrackPtr + 0x18);

    // Move to first file entry
    TrackPtr += 0x20;
    for (UDWORD Count = 0; Count < FileCount; ++Count) {
        std::string Filename((char*)TrackPtr);
        UDWORD Filesize = readBEDWord(TrackPtr + 0x1C);
        UBYTE FileTrack = *(TrackPtr + 0x1A);
        UBYTE FileBlock = *(TrackPtr + 0x1B);

        std::cout << std::setw(15) << Filename << "  Track: ";
        std::cout << std::setw(4) << ((size_t)FileTrack) << "  Block: ";
        std::cout << std::setw(3) << ((size_t)FileBlock) << "  Size: ";
        std::cout << std::setw(6) << ((size_t)Filesize) << " bytes\n";

        std::string FileData;
        // Read each block
        SDWORD FileRemaining = Filesize;
        while (FileRemaining > 0) {
            UBYTE* FileTrackPtr = (UBYTE*)pTrackBuffers[FileTrack].data();
            UBYTE *FileTrackPtrEnd = (UBYTE*)pTrackBuffers[FileTrack].data() + pTrackBuffers[FileTrack].size();
            FileTrackPtr += (FileBlock * 512);

            if (FileTrackPtr > FileTrackPtrEnd || (FileTrackPtr + 512) > FileTrackPtrEnd) {
                std::cout << "  Track: " << ((size_t)FileTrack) << ": Read past end of available track data.\n\n";
                break;
            }
            FileData.append((char*)FileTrackPtr, 510);
            FileRemaining -= 510;
            FileTrackPtr += 510;

            FileTrack = *FileTrackPtr++;
            FileBlock = *FileTrackPtr++;
        }

        // Truncate to actual file size
        FileData.resize(Filesize);

        std::ofstream outfile;
        outfile.open(pTargetFolder + "//" + Filename, std::ios_base::out | std::ios::binary);
        outfile.write((char*)FileData.data(), FileData.size());
        outfile.close();

        // Next File
        TrackPtr += 0x20;
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x390, %rsp            # imm = 0x390
movq %rdi, -0x2f0(%rbp)
movq %rdi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movl $0x2, %esi
callq 0x1b5b0
movq %rax, %rdi
callq 0x42f0
movq %rax, -0x18(%rbp)
movq -0x18(%rbp), %rdi
addq $0x18, %rdi
callq 0x1b5d0
movl %eax, -0x1c(%rbp)
movq -0x18(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x18(%rbp)
movl $0x0, -0x20(%rbp)
movl -0x20(%rbp), %eax
cmpl -0x1c(%rbp), %eax
jae 0x1ae0a
movq -0x18(%rbp), %rax
movq %rax, -0x300(%rbp)
leaq -0x41(%rbp), %rdi
movq %rdi, -0x2f8(%rbp)
callq 0x4430
movq -0x300(%rbp), %rsi
movq -0x2f8(%rbp), %rdx
leaq -0x40(%rbp), %rdi
callq 0x4320
jmp 0x1a8e3
leaq -0x41(%rbp), %rdi
callq 0x4260
movq -0x18(%rbp), %rdi
addq $0x1c, %rdi
callq 0x1b5d0
movl %eax, -0x304(%rbp)
jmp 0x1a901
movl -0x304(%rbp), %eax
movl %eax, -0x58(%rbp)
movq -0x18(%rbp), %rax
movb 0x1a(%rax), %al
movb %al, -0x59(%rbp)
movq -0x18(%rbp), %rax
movb 0x1b(%rax), %al
movb %al, -0x5a(%rbp)
movl $0xf, %edi
callq 0x1b610
movl %eax, -0x308(%rbp)
jmp 0x1a930
movl -0x308(%rbp), %eax
movl %eax, -0x60(%rbp)
movl -0x60(%rbp), %esi
movq 0xc67d(%rip), %rdi      # 0x26fc0
callq 0x4290
movq %rax, -0x310(%rbp)
jmp 0x1a951
movq -0x310(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x41e0
movq %rax, -0x318(%rbp)
jmp 0x1a96a
movq -0x318(%rbp), %rdi
leaq 0x3a51(%rip), %rsi      # 0x1e3c9
callq 0x4220
jmp 0x1a97f
movl $0x4, %edi
callq 0x1b610
movl %eax, -0x31c(%rbp)
jmp 0x1a991
movl -0x31c(%rbp), %eax
movl %eax, -0x64(%rbp)
movl -0x64(%rbp), %esi
movq 0xc61c(%rip), %rdi      # 0x26fc0
callq 0x4290
movq %rax, -0x328(%rbp)
jmp 0x1a9b2
movq -0x328(%rbp), %rdi
movzbl -0x59(%rbp), %eax
movl %eax, %esi
callq 0x40a0
movq %rax, -0x330(%rbp)
jmp 0x1a9cd
movq -0x330(%rbp), %rdi
leaq 0x39f8(%rip), %rsi      # 0x1e3d3
callq 0x4220
jmp 0x1a9e2
movl $0x3, %edi
callq 0x1b610
movl %eax, -0x334(%rbp)
jmp 0x1a9f4
movl -0x334(%rbp), %eax
movl %eax, -0x68(%rbp)
movl -0x68(%rbp), %esi
movq 0xc5b9(%rip), %rdi      # 0x26fc0
callq 0x4290
movq %rax, -0x340(%rbp)
jmp 0x1aa15
movq -0x340(%rbp), %rdi
movzbl -0x5a(%rbp), %eax
movl %eax, %esi
callq 0x40a0
movq %rax, -0x348(%rbp)
jmp 0x1aa30
movq -0x348(%rbp), %rdi
leaq 0x399f(%rip), %rsi      # 0x1e3dd
callq 0x4220
jmp 0x1aa45
movl $0x6, %edi
callq 0x1b610
movl %eax, -0x34c(%rbp)
jmp 0x1aa57
movl -0x34c(%rbp), %eax
movl %eax, -0x6c(%rbp)
movl -0x6c(%rbp), %esi
movq 0xc556(%rip), %rdi      # 0x26fc0
callq 0x4290
movq %rax, -0x358(%rbp)
jmp 0x1aa78
movq -0x358(%rbp), %rdi
movl -0x58(%rbp), %eax
movl %eax, %esi
callq 0x40a0
movq %rax, -0x360(%rbp)
jmp 0x1aa92
movq -0x360(%rbp), %rdi
leaq 0x3946(%rip), %rsi      # 0x1e3e6
callq 0x4220
jmp 0x1aaa7
leaq -0x90(%rbp), %rdi
callq 0x4340
movl -0x58(%rbp), %eax
movl %eax, -0x94(%rbp)
cmpl $0x0, -0x94(%rbp)
jle 0x1ac83
movq -0x2f0(%rbp), %rdi
movzbl -0x59(%rbp), %eax
movl %eax, %esi
callq 0x1b5b0
movq %rax, %rdi
callq 0x42f0
movq -0x2f0(%rbp), %rdi
movq %rax, -0xa0(%rbp)
movzbl -0x59(%rbp), %eax
movl %eax, %esi
callq 0x1b5b0
movq %rax, %rdi
callq 0x42f0
movq -0x2f0(%rbp), %rdi
movq %rax, -0x368(%rbp)
movzbl -0x59(%rbp), %eax
movl %eax, %esi
callq 0x1b5b0
movq %rax, %rdi
callq 0x4170
movq %rax, %rcx
movq -0x368(%rbp), %rax
addq %rcx, %rax
movq %rax, -0xa8(%rbp)
movzbl -0x5a(%rbp), %ecx
shll $0x9, %ecx
movq -0xa0(%rbp), %rax
movslq %ecx, %rcx
addq %rcx, %rax
movq %rax, -0xa0(%rbp)
movq -0xa0(%rbp), %rax
cmpq -0xa8(%rbp), %rax
ja 0x1ab7e
movq -0xa0(%rbp), %rax
addq $0x200, %rax            # imm = 0x200
cmpq -0xa8(%rbp), %rax
jbe 0x1ac0b
movq 0xc43b(%rip), %rdi      # 0x26fc0
leaq 0x383d(%rip), %rsi      # 0x1e3c9
callq 0x4220
movq %rax, -0x370(%rbp)
jmp 0x1ab9a
movq -0x370(%rbp), %rdi
movzbl -0x59(%rbp), %eax
movl %eax, %esi
callq 0x40a0
movq %rax, -0x378(%rbp)
jmp 0x1abb5
movq -0x378(%rbp), %rdi
leaq 0x382b(%rip), %rsi      # 0x1e3ee
callq 0x4220
jmp 0x1abca
jmp 0x1ac83
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x41(%rbp), %rdi
callq 0x4260
jmp 0x1ae13
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x1adff
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x1adf3
movq -0xa0(%rbp), %rsi
leaq -0x90(%rbp), %rdi
movl $0x1fe, %edx            # imm = 0x1FE
callq 0x4060
jmp 0x1ac25
movl -0x94(%rbp), %eax
subl $0x1fe, %eax            # imm = 0x1FE
movl %eax, -0x94(%rbp)
movq -0xa0(%rbp), %rax
addq $0x1fe, %rax            # imm = 0x1FE
movq %rax, -0xa0(%rbp)
movq -0xa0(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0xa0(%rbp)
movb (%rax), %al
movb %al, -0x59(%rbp)
movq -0xa0(%rbp), %rax
movq %rax, %rcx
addq $0x1, %rcx
movq %rcx, -0xa0(%rbp)
movb (%rax), %al
movb %al, -0x5a(%rbp)
jmp 0x1aabc
movl -0x58(%rbp), %eax
movl %eax, %esi
leaq -0x90(%rbp), %rdi
callq 0x4330
jmp 0x1ac96
leaq -0x2a8(%rbp), %rdi
callq 0x4400
jmp 0x1aca4
movq -0x10(%rbp), %rsi
leaq 0x376a(%rip), %rdx      # 0x1e419
leaq -0x2e8(%rbp), %rdi
callq 0x1b680
jmp 0x1acbd
leaq -0x2c8(%rbp), %rdi
leaq -0x2e8(%rbp), %rsi
leaq -0x40(%rbp), %rdx
callq 0x1b630
jmp 0x1acd6
movl $0x10, %edi
movl $0x4, %esi
callq 0x1b700
movl %eax, -0x37c(%rbp)
jmp 0x1aced
movl -0x37c(%rbp), %edx
leaq -0x2a8(%rbp), %rdi
leaq -0x2c8(%rbp), %rsi
callq 0x4120
jmp 0x1ad08
leaq -0x2c8(%rbp), %rdi
callq 0x4488
leaq -0x2e8(%rbp), %rdi
callq 0x4488
leaq -0x90(%rbp), %rdi
movq %rdi, -0x390(%rbp)
callq 0x42f0
movq -0x390(%rbp), %rdi
movq %rax, -0x388(%rbp)
callq 0x4170
movq -0x388(%rbp), %rsi
movq %rax, %rdx
leaq -0x2a8(%rbp), %rdi
callq 0x4300
jmp 0x1ad5e
leaq -0x2a8(%rbp), %rdi
callq 0x4350
jmp 0x1ad6c
movq -0x18(%rbp), %rax
addq $0x20, %rax
movq %rax, -0x18(%rbp)
leaq -0x2a8(%rbp), %rdi
callq 0x4370
leaq -0x90(%rbp), %rdi
callq 0x4488
leaq -0x40(%rbp), %rdi
callq 0x4488
movl -0x20(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x20(%rbp)
jmp 0x1a8a3
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x1ade7
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x1addb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x2c8(%rbp), %rdi
callq 0x4488
leaq -0x2e8(%rbp), %rdi
callq 0x4488
leaq -0x2a8(%rbp), %rdi
callq 0x4370
leaq -0x90(%rbp), %rdi
callq 0x4488
leaq -0x40(%rbp), %rdi
callq 0x4488
jmp 0x1ae13
addq $0x390, %rsp            # imm = 0x390
popq %rbp
retq
movq -0x50(%rbp), %rdi
callq 0x4420
nopl (%rax)