// File: /workspace/github_cpp_makefile_star2_O3/Thilotilo[P]DoaERando/Randomizer.cpp
// Function: DoaERando::Randomizer::CaveShuffle()
void Randomizer::CaveShuffle()
{
    // These are world map offsets
    const int XU_ZHE_CAVE_OFFSET = 0x07;
    const int MT_GANG_TAI_ENTRANCE_OFFSET = 0x0B;
    const int MT_GANG_TAI_EXIT_OFFSET = 0x1F;
    const int WU_CAVE_EXIT_OFFSET = 0x26;
    const int WU_CAVE_ENTRANCE_OFFSET = 0x39;
    const int GOLD_KEY_CAVE_OFFSET = 0x46;
    const int CHANG_AN_ENTRANCE_OFFSET = 0x58;
    const int CHANG_AN_EXIT_OFFSET = 0x61;
    const int NAN_YANG_CAVE_OFFSET = 0x63;
    const int WEI_CAVE_2_ENTRANCE_OFFSET = 0x6C;
    const int WEI_CAVE_2_EXIT_OFFSET = 0x7B;
    const int WEI_CAVE_1_EXIT_OFFSET = 0x7E;
    const int WEI_CAVE_1_ENTRANCE_OFFSET = 0x93;
    const int SALTPETER_CAVE_OFFSET = 0x99;

    // Magic numbers are bad, but 8 million consts to start a method are obnoxious.
    vector<vector<BYTE>> CaveWarpOffsets = {
        {XU_ZHE_CAVE_OFFSET,          0x08, 0x09},
        {MT_GANG_TAI_ENTRANCE_OFFSET, 0x0A},
        {MT_GANG_TAI_EXIT_OFFSET,     0x1E},
        {WU_CAVE_EXIT_OFFSET,         0x27},
        {WU_CAVE_ENTRANCE_OFFSET,     0x38},
        {GOLD_KEY_CAVE_OFFSET,        0x47, 0x48},
        {CHANG_AN_ENTRANCE_OFFSET,    0x57, 0x59},
        {CHANG_AN_EXIT_OFFSET,        0x60, 0x62},
        {NAN_YANG_CAVE_OFFSET,        0x64, 0x65},
        {WEI_CAVE_2_ENTRANCE_OFFSET,  0x6D, 0x7D},
        {WEI_CAVE_2_EXIT_OFFSET,      0x7A, 0x7C},
        {WEI_CAVE_1_EXIT_OFFSET,      0x7F, 0x80},
        {WEI_CAVE_1_ENTRANCE_OFFSET,  0x94, 0x95},
        {SALTPETER_CAVE_OFFSET,       0x9A, 0x9B}
    };

    vector<vector<BYTE>> ShuffledOffsets = CaveWarpOffsets;

    for (int i = 0; i < 10000; ++i)
    {
        int location1 = myRNG.GetRandomInt(0, ShuffledOffsets.size() - 1);
        int location2 = myRNG.GetRandomInt(0, ShuffledOffsets.size() - 1);
        swap(ShuffledOffsets[location1], ShuffledOffsets[location2]);
    }

    // Now do sanity checks
    // For now, let's prevent the following:
    // 1) Wu Cave entrance should not be a single-entrance cave to prevent softlocks from canal
    // 2) Mt Gang Tai Exit cannot be a single-entrance cave, and it's other side cannot come to
    //    one of the Wei caves if the other is a Single Exit cave
    // 3) Wei1 Exit & Wei2 Entrance can't be opposite ends of the same cave
    // 4) Wei1 Exit & Wei2 Entrance can't both be single-entrance caves.
    while (IsSingleExitCave(ShuffledOffsets[4][0]) ||
           IsSingleExitCave(ShuffledOffsets[2][0]) ||
           (AreExitsFromSameCave(ShuffledOffsets[2][0], ShuffledOffsets[9][0]) &&
            IsSingleExitCave(ShuffledOffsets[11][0])) ||
           (AreExitsFromSameCave(ShuffledOffsets[2][0], ShuffledOffsets[11][0]) &&
            IsSingleExitCave(ShuffledOffsets[9][0])) ||
           AreExitsFromSameCave(ShuffledOffsets[9][0], ShuffledOffsets[11][0]) ||
           (IsSingleExitCave(ShuffledOffsets[9][0]) && IsSingleExitCave(ShuffledOffsets[11][0])))
    {
        int location1 = myRNG.GetRandomInt(0, ShuffledOffsets.size() - 1);
        int location2 = myRNG.GetRandomInt(0, ShuffledOffsets.size() - 1);
        swap(ShuffledOffsets[location1], ShuffledOffsets[location2]);
    }

    // Collect all the bytes we need to update
    std::vector<std::vector<BYTE>> bytesToWrite;
    for (int i = 0; i < ShuffledOffsets.size(); ++i)
    {
        printf("Putting cave id 0x%02X in the vanilla 0x%02X location\n",
               ShuffledOffsets[i][0], CaveWarpOffsets[i][0]);
        int lsb = myRom->ReadByte(0x1C210 + ShuffledOffsets[i][0]);
        int msb = myRom->ReadByte(0x1C2C0 + ShuffledOffsets[i][0]);
        int shuffledAddressInBank = (msb << 8) | lsb;

        lsb = myRom->ReadByte(0x1C210 + CaveWarpOffsets[i][1]);
        msb = myRom->ReadByte(0x1C2C0 + CaveWarpOffsets[i][1]);
        int caveExitAddressInBank = (msb << 8) | lsb;

        // This puts the destination of the shuffled world map address into the vanilla location
        std::vector<BYTE> updateToWrite;
        updateToWrite.push_back(CaveWarpOffsets[i][0]);
        for (int j = 4; j < 9; ++j)
        {
            updateToWrite.push_back(myRom->ReadByteAtBank(0x7, shuffledAddressInBank + j));
        }

        bytesToWrite.push_back(updateToWrite);

        // This puts the destination of the vanilla cave exits to the shuffled world map location
        for (int j = 1; j < ShuffledOffsets[i].size(); ++j)
        {
            std::vector<BYTE> updatedCaveEntrance;
            updatedCaveEntrance.push_back(ShuffledOffsets[i][j]);
            for (int k = 4; k < 9; ++k)
            {
                updatedCaveEntrance.push_back(myRom->ReadByteAtBank(0x7, caveExitAddressInBank + k));
            }
            bytesToWrite.push_back(updatedCaveEntrance);
        }
    }

    // Now write everything
    for (auto& entry : bytesToWrite)
    {
        int lsb = myRom->ReadByte(0x1C210 + entry[0]);
        int msb = myRom->ReadByte(0x1C2C0 + entry[0]);
        int addressInBank = (msb << 8) | lsb;

        for (int i = 1; i < entry.size(); ++i)
        {
            myRom->WriteByteAtBank(0x7, addressInBank + i + 3, entry[i]);
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x218, %rsp            # imm = 0x218
movq %rdi, %r13
leaq -0xb0(%rbp), %rsi
movw $0x807, (%rsi)          # imm = 0x807
movb $0x9, 0x2(%rsi)
leaq -0x240(%rbp), %r14
leaq -0x3b(%rbp), %rcx
movl $0x3, %edx
movq %r14, %rdi
callq 0x40a9ca
leaq -0x228(%rbp), %r15
leaq -0x50(%rbp), %rsi
movw $0xa0b, (%rsi)          # imm = 0xA0B
leaq -0x3a(%rbp), %rcx
movl $0x2, %edx
movq %r15, %rdi
callq 0x40a9ca
leaq -0x210(%rbp), %r15
leaq -0x4e(%rbp), %rsi
movw $0x1e1f, (%rsi)         # imm = 0x1E1F
leaq -0x39(%rbp), %rcx
movl $0x2, %edx
movq %r15, %rdi
callq 0x40a9ca
leaq -0x1f8(%rbp), %r15
leaq -0x4c(%rbp), %rsi
movw $0x2726, (%rsi)         # imm = 0x2726
leaq -0x38(%rbp), %rcx
movl $0x2, %edx
movq %r15, %rdi
callq 0x40a9ca
leaq -0x1e0(%rbp), %r15
leaq -0x4a(%rbp), %rsi
movw $0x3839, (%rsi)         # imm = 0x3839
leaq -0x37(%rbp), %rcx
movl $0x2, %edx
movq %r15, %rdi
callq 0x40a9ca
leaq -0x1c8(%rbp), %r15
leaq -0x70(%rbp), %rsi
movw $0x4746, (%rsi)         # imm = 0x4746
movb $0x48, 0x2(%rsi)
leaq -0x36(%rbp), %rcx
movl $0x3, %edx
movq %r15, %rdi
callq 0x40a9ca
leaq -0x1b0(%rbp), %r15
leaq -0x90(%rbp), %rsi
movw $0x5758, (%rsi)         # imm = 0x5758
movb $0x59, 0x2(%rsi)
leaq -0x35(%rbp), %rcx
movl $0x3, %edx
movq %r15, %rdi
callq 0x40a9ca
leaq -0x198(%rbp), %r15
leaq -0x34(%rbp), %rsi
movw $0x6061, (%rsi)         # imm = 0x6061
movb $0x62, 0x2(%rsi)
leaq -0x31(%rbp), %rcx
movl $0x3, %edx
movq %r15, %rdi
callq 0x40a9ca
leaq -0x180(%rbp), %r15
leaq -0xea(%rbp), %rsi
movw $0x6463, (%rsi)         # imm = 0x6463
movb $0x65, 0x2(%rsi)
leaq -0x30(%rbp), %rcx
movl $0x3, %edx
movq %r15, %rdi
callq 0x40a9ca
leaq -0x168(%rbp), %r15
leaq -0xe7(%rbp), %rsi
movw $0x6d6c, (%rsi)         # imm = 0x6D6C
movb $0x7d, 0x2(%rsi)
leaq -0x2f(%rbp), %rcx
movl $0x3, %edx
movq %r15, %rdi
callq 0x40a9ca
leaq -0x150(%rbp), %r15
leaq -0xe4(%rbp), %rsi
movw $0x7a7b, (%rsi)         # imm = 0x7A7B
movb $0x7c, 0x2(%rsi)
leaq -0x2e(%rbp), %rcx
movl $0x3, %edx
movq %r15, %rdi
callq 0x40a9ca
leaq -0x138(%rbp), %r15
leaq -0xe1(%rbp), %rsi
movw $0x7f7e, (%rsi)         # imm = 0x7F7E
movb $-0x80, 0x2(%rsi)
leaq -0x2d(%rbp), %rcx
movl $0x3, %edx
movq %r15, %rdi
callq 0x40a9ca
leaq -0x120(%rbp), %r15
leaq -0xde(%rbp), %rsi
movw $0x9493, (%rsi)         # imm = 0x9493
movb $-0x6b, 0x2(%rsi)
leaq -0x2c(%rbp), %rcx
movl $0x3, %edx
movq %r15, %rdi
callq 0x40a9ca
leaq -0x108(%rbp), %r15
leaq -0xdb(%rbp), %rsi
movw $0x9a99, (%rsi)         # imm = 0x9A99
movb $-0x65, 0x2(%rsi)
leaq -0x2b(%rbp), %rcx
movl $0x3, %edx
movq %r15, %rdi
callq 0x40a9ca
leaq -0xd8(%rbp), %rdi
leaq -0x240(%rbp), %rsi
leaq -0x2a(%rbp), %rcx
movl $0xe, %edx
callq 0x40aa08
movl $0x138, %ebx            # imm = 0x138
movq -0x240(%rbp,%rbx), %rdi
testq %rdi, %rdi
je 0x405332
callq 0x410b90
addq $-0x18, %rbx
cmpq $-0x18, %rbx
jne 0x405320
leaq -0x240(%rbp), %rdi
leaq -0xd8(%rbp), %rsi
callq 0x40aa4a
leaq 0x8(%r13), %r14
movl $0x2710, %r12d          # imm = 0x2710
movq -0x240(%rbp), %rbx
movq -0x238(%rbp), %rax
subq %rbx, %rax
shrq $0x3, %rax
imull $0xaaaaaaab, %eax, %edx # imm = 0xAAAAAAAB
decl %edx
movq %r14, %rdi
xorl %esi, %esi
callq 0x41086c
movl %eax, %r15d
movq -0x238(%rbp), %rax
subq -0x240(%rbp), %rax
shrq $0x3, %rax
imull $0xaaaaaaab, %eax, %edx # imm = 0xAAAAAAAB
decl %edx
movq %r14, %rdi
xorl %esi, %esi
callq 0x41086c
movslq %r15d, %rcx
movq -0x240(%rbp), %rbx
leaq (%rcx,%rcx,2), %rcx
cltq
leaq (%rax,%rax,2), %rax
movups (%rbx,%rcx,8), %xmm0
movq 0x10(%rbx,%rcx,8), %rdx
movq (%rbx,%rax,8), %rsi
movq %rsi, (%rbx,%rcx,8)
movq 0x8(%rbx,%rax,8), %rsi
movq %rsi, 0x8(%rbx,%rcx,8)
movq 0x10(%rbx,%rax,8), %rsi
movq %rsi, 0x10(%rbx,%rcx,8)
movups %xmm0, (%rbx,%rax,8)
movq %rdx, 0x10(%rbx,%rax,8)
decl %r12d
jne 0x405360
movq %r13, %r12
movq 0x60(%rbx), %rax
movzbl (%rax), %eax
cmpl $0x62, %eax
jg 0x405410
cmpl $0x7, %eax
je 0x405420
cmpl $0x46, %eax
je 0x405420
jmp 0x4054ae
cmpl $0x63, %eax
je 0x405420
cmpl $0x99, %eax
jne 0x4054ae
movq -0x238(%rbp), %rax
subq %rbx, %rax
shrq $0x3, %rax
imull $0xaaaaaaab, %eax, %edx # imm = 0xAAAAAAAB
decl %edx
movq %r14, %rdi
xorl %esi, %esi
callq 0x41086c
movl %eax, %r15d
movq -0x238(%rbp), %rax
subq -0x240(%rbp), %rax
shrq $0x3, %rax
imull $0xaaaaaaab, %eax, %edx # imm = 0xAAAAAAAB
decl %edx
movq %r14, %rdi
xorl %esi, %esi
callq 0x41086c
movslq %r15d, %rcx
movq -0x240(%rbp), %rbx
leaq (%rcx,%rcx,2), %rcx
cltq
leaq (%rax,%rax,2), %rax
movups (%rbx,%rcx,8), %xmm0
movq 0x10(%rbx,%rcx,8), %rdx
movq (%rbx,%rax,8), %rsi
movq %rsi, (%rbx,%rcx,8)
movq 0x8(%rbx,%rax,8), %rsi
movq %rsi, 0x8(%rbx,%rcx,8)
movq 0x10(%rbx,%rax,8), %rsi
movq %rsi, 0x10(%rbx,%rcx,8)
movups %xmm0, (%rbx,%rax,8)
movq %rdx, 0x10(%rbx,%rax,8)
jmp 0x4053f5
movq 0x30(%rbx), %rax
movzbl (%rax), %r13d
cmpl $0x62, %r13d
jg 0x4054d2
cmpl $0x7, %r13d
je 0x405420
cmpl $0x46, %r13d
je 0x405420
jmp 0x4054e9
cmpl $0x63, %r13d
je 0x405420
cmpl $0x99, %r13d
je 0x405420
movq 0xd8(%rbx), %rax
movzbl (%rax), %r15d
movl %r13d, %edi
movl %r15d, %esi
callq 0x405a61
movq 0x108(%rbx), %rcx
movzbl (%rcx), %ecx
testb %al, %al
je 0x40553b
cmpl $0x62, %ecx
jg 0x405526
cmpl $0x7, %ecx
je 0x405420
cmpl $0x46, %ecx
je 0x405420
jmp 0x40553b
cmpl $0x63, %ecx
je 0x405420
cmpl $0x99, %ecx
je 0x405420
movl %r13d, %edi
movl %ecx, %r13d
movl %ecx, %esi
callq 0x405a61
testb %al, %al
je 0x40557f
cmpl $0x62, %r15d
jg 0x405568
cmpl $0x7, %r15d
je 0x405420
cmpl $0x46, %r15d
je 0x405420
jmp 0x40557f
cmpl $0x63, %r15d
je 0x405420
cmpl $0x99, %r15d
je 0x405420
movl %r15d, %edi
movl %r13d, %esi
callq 0x405a61
testb %al, %al
jne 0x405420
cmpl $0x62, %r15d
jg 0x4055a6
cmpl $0x7, %r15d
je 0x4055b5
cmpl $0x46, %r15d
je 0x4055b5
jmp 0x4055e8
cmpl $0x99, %r15d
je 0x4055b5
cmpl $0x63, %r15d
jne 0x4055e8
cmpl $0x62, %r13d
jg 0x4055d1
cmpl $0x7, %r13d
je 0x405420
cmpl $0x46, %r13d
je 0x405420
jmp 0x4055e8
cmpl $0x99, %r13d
je 0x405420
cmpl $0x63, %r13d
je 0x405420
xorps %xmm0, %xmm0
movaps %xmm0, -0xb0(%rbp)
movq $0x0, -0xa0(%rbp)
cmpq %rbx, -0x238(%rbp)
je 0x405938
movq %r12, %r13
leaq -0x90(%rbp), %r14
xorl %edx, %edx
movq %rdx, -0xb8(%rbp)
leaq (,%rdx,8), %rax
leaq (%rax,%rax,2), %r15
movq (%rbx,%r15), %rax
movzbl (%rax), %esi
movq -0xd8(%rbp), %rax
movq (%rax,%r15), %rax
movzbl (%rax), %edx
leaq 0x186ab4(%rip), %rdi    # 0x58c0f9
xorl %eax, %eax
callq 0x4e21a0
movq (%r13), %rdi
movq -0x240(%rbp), %rax
movq (%rax,%r15), %rax
movzbl (%rax), %esi
addl $0x1c210, %esi          # imm = 0x1C210
callq 0x4049fa
movb %al, -0x48(%rbp)
movq (%r13), %rdi
movq -0x240(%rbp), %rax
movq -0xb8(%rbp), %rcx
leaq (%rcx,%rcx,2), %r15
movq (%rax,%r15,8), %rax
movzbl (%rax), %esi
addl $0x1c2c0, %esi          # imm = 0x1C2C0
callq 0x4049fa
movb %al, -0x29(%rbp)
movq (%r13), %rdi
movq -0xd8(%rbp), %rax
movq (%rax,%r15,8), %rax
movzbl 0x1(%rax), %esi
addl $0x1c210, %esi          # imm = 0x1C210
callq 0x4049fa
movl %eax, %ebx
movq (%r13), %rdi
movq -0xd8(%rbp), %rax
movq (%rax,%r15,8), %rax
movzbl 0x1(%rax), %esi
addl $0x1c2c0, %esi          # imm = 0x1C2C0
callq 0x4049fa
movl %eax, %r13d
xorps %xmm0, %xmm0
movaps %xmm0, -0x70(%rbp)
movq $0x0, -0x60(%rbp)
movq -0xd8(%rbp), %rax
movq %r15, -0xc0(%rbp)
movq (%rax,%r15,8), %rdx
leaq -0x70(%rbp), %rdi
xorl %esi, %esi
callq 0x40ae0e
movzbl -0x48(%rbp), %eax
movzbl -0x29(%rbp), %ecx
shll $0x8, %ecx
movzbl %bl, %edx
movq %rdx, -0x48(%rbp)
movzbl %r13b, %r13d
shll $0x8, %r13d
leal (%rcx,%rax), %ebx
addl $0x4, %ebx
xorl %r15d, %r15d
movq (%r12), %rdi
leal (%rbx,%r15), %edx
movl $0x7, %esi
callq 0x404a0a
movb %al, -0x90(%rbp)
movq -0x68(%rbp), %rsi
cmpq -0x60(%rbp), %rsi
je 0x405751
movb %al, (%rsi)
incq -0x68(%rbp)
jmp 0x40575d
leaq -0x70(%rbp), %rdi
movq %r14, %rdx
callq 0x40ad1c
incl %r15d
cmpl $0x5, %r15d
jne 0x405727
leaq -0xb0(%rbp), %rdi
leaq -0x70(%rbp), %rsi
callq 0x40aae6
movq -0x240(%rbp), %rbx
movq -0xc0(%rbp), %rcx
movq 0x8(%rbx,%rcx,8), %rax
subq (%rbx,%rcx,8), %rax
cmpq $0x2, %rax
jb 0x405855
leaq (%rbx,%rcx,8), %rax
movq -0x48(%rbp), %rcx
addl %ecx, %r13d
addl $0x4, %r13d
movl $0x1, %r15d
xorps %xmm0, %xmm0
movaps %xmm0, -0x90(%rbp)
movq $0x0, -0x80(%rbp)
movq (%rax), %rdx
addq %r15, %rdx
movq %r14, %rdi
xorl %esi, %esi
callq 0x40ae0e
xorl %ebx, %ebx
movq (%r12), %rdi
leal (%rbx,%r13), %edx
movl $0x7, %esi
callq 0x404a0a
movb %al, -0x34(%rbp)
movq -0x88(%rbp), %rsi
cmpq -0x80(%rbp), %rsi
je 0x4057fd
movb %al, (%rsi)
incq -0x88(%rbp)
jmp 0x405809
movq %r14, %rdi
leaq -0x34(%rbp), %rdx
callq 0x40ad1c
incl %ebx
cmpl $0x5, %ebx
jne 0x4057d0
leaq -0xb0(%rbp), %rdi
movq %r14, %rsi
callq 0x40aae6
movq -0x90(%rbp), %rdi
testq %rdi, %rdi
je 0x405830
callq 0x410b90
incq %r15
movq -0x240(%rbp), %rbx
movq -0xc0(%rbp), %rax
leaq (%rbx,%rax,8), %rax
movq 0x8(%rax), %rcx
subq (%rax), %rcx
cmpq %r15, %rcx
ja 0x4057ac
movq -0x70(%rbp), %rdi
testq %rdi, %rdi
je 0x40586a
callq 0x410b90
movq -0x240(%rbp), %rbx
movq -0xb8(%rbp), %rdx
incq %rdx
movq -0x238(%rbp), %rax
subq %rbx, %rax
sarq $0x3, %rax
movabsq $-0x5555555555555555, %rcx # imm = 0xAAAAAAAAAAAAAAAB
imulq %rcx, %rax
cmpq %rdx, %rax
movq %r12, %r13
ja 0x405616
movq -0xb0(%rbp), %rbx
movq -0xa8(%rbp), %r15
cmpq %r15, %rbx
je 0x405938
movq (%r13), %rdi
movq (%rbx), %rax
movzbl (%rax), %esi
addl $0x1c210, %esi          # imm = 0x1C210
callq 0x4049fa
movl %eax, %r14d
movq (%r13), %rdi
movq (%rbx), %rax
movzbl (%rax), %esi
addl $0x1c2c0, %esi          # imm = 0x1C2C0
callq 0x4049fa
movq (%rbx), %rcx
movq 0x8(%rbx), %rdx
subq %rcx, %rdx
cmpq $0x2, %rdx
jb 0x40592f
movzbl %al, %eax
shll $0x8, %eax
movzbl %r14b, %r14d
orl %eax, %r14d
movl $0x1, %r12d
movq (%r13), %rdi
movzbl (%rcx,%r12), %ecx
leal (%r14,%r12), %edx
addl $0x3, %edx
movl $0x7, %esi
callq 0x404a34
incq %r12
movq (%rbx), %rcx
movq 0x8(%rbx), %rax
subq %rcx, %rax
cmpq %r12, %rax
ja 0x405903
addq $0x18, %rbx
jmp 0x4058aa
leaq -0xb0(%rbp), %rdi
callq 0x40ab22
leaq -0x240(%rbp), %rdi
callq 0x40ab22
leaq -0xd8(%rbp), %rdi
callq 0x40ab22
addq $0x218, %rsp            # imm = 0x218
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
jmp 0x405a4d
movq %rax, %rbx
movl $0x138, %r12d           # imm = 0x138
movq -0x240(%rbp,%r12), %rdi
testq %rdi, %rdi
je 0x405991
callq 0x410b90
addq $-0x18, %r12
cmpq $-0x18, %r12
jne 0x40597f
movb $0x1, %al
jmp 0x4059bc
jmp 0x4059b7
jmp 0x4059b7
jmp 0x4059b7
jmp 0x4059b7
jmp 0x4059b7
jmp 0x4059b7
jmp 0x4059b7
jmp 0x4059b7
jmp 0x4059b7
jmp 0x4059b7
jmp 0x4059b7
jmp 0x4059b7
movq %rax, %rbx
xorl %eax, %eax
cmpq %r15, %r14
sete %cl
testb %al, %al
jne 0x405a59
testb %cl, %cl
jne 0x405a59
movq -0x18(%r15), %rdi
testq %rdi, %rdi
je 0x4059e0
callq 0x410b90
addq $-0x18, %r15
cmpq %r14, %r15
jne 0x4059d2
jmp 0x405a59
movq %rax, %rbx
jmp 0x405a59
jmp 0x405a00
jmp 0x405a00
jmp 0x405a00
jmp 0x405a00
jmp 0x405a0e
jmp 0x405a0e
jmp 0x405a07
jmp 0x405a00
movq %rax, %rbx
jmp 0x405a35
jmp 0x405a13
movq %rax, %rbx
jmp 0x405a27
jmp 0x405a0e
movq %rax, %rbx
jmp 0x405a41
movq %rax, %rbx
movq -0x90(%rbp), %rdi
testq %rdi, %rdi
je 0x405a27
callq 0x410b90
movq -0x70(%rbp), %rdi
testq %rdi, %rdi
je 0x405a35
callq 0x410b90
leaq -0xb0(%rbp), %rdi
callq 0x40ab22
leaq -0x240(%rbp), %rdi
callq 0x40ab22
leaq -0xd8(%rbp), %rdi
callq 0x40ab22
movq %rbx, %rdi
callq 0x4bb660