// File: /workspace/github_cpp_makefile_star2_O1/Thilotilo[P]DoaERando/Randomizer.cpp
// Function: DoaERando::Randomizer::ItemShuffle()
void Randomizer::ItemShuffle()
{
    std::vector<BYTE> chestContentsToRandomize;

    // Grab starting items
    chestContentsToRandomize.push_back(myRom->ReadByte(0x3556C));
    chestContentsToRandomize.push_back(myRom->ReadByte(0x3556D));
    chestContentsToRandomize.push_back(myRom->ReadByte(0x35574));
    chestContentsToRandomize.push_back(myRom->ReadByte(0x35575));
    chestContentsToRandomize.push_back(myRom->ReadByte(0x3557C));
    chestContentsToRandomize.push_back(myRom->ReadByte(0x3557D));

    // Add Zhao Yun's sister's item
    chestContentsToRandomize.push_back(myRom->ReadByte(0x368DC));

    // Add Intro Letr item (We'll put gemsword behind this item)
    chestContentsToRandomize.push_back(myRom->ReadByte(0x366DD));

    // Add Silver Key item
    chestContentsToRandomize.push_back(myRom->ReadByte(0x3680F));

    // Add Gunpowder Item
    chestContentsToRandomize.push_back(myRom->ReadByte(0x368A2));

    // Add Qing Long Item
    chestContentsToRandomize.push_back(myRom->ReadByte(0x37333));

    // Grab hidden items
    const int HIDDEN_ITEM_OFFSET = 0x30B10;
    for (int i = HIDDEN_ITEM_OFFSET; i < HIDDEN_ITEM_OFFSET + 20; ++i)
    {
        BYTE item = myRom->ReadByte(i);
        if (item != 0xFF) // I found a keyhole, i = 2
        {
            chestContentsToRandomize.push_back(item);
        }
    }

    // Grab non-hidden items
    const int ITEMS_OFFSET = 0x30914; // (Every 5th byte is the item ID) - data starts at 30910
    const int ITEMS_OFFSET_END = 0x309E7;
    for (int i = ITEMS_OFFSET; i < ITEMS_OFFSET_END; i += 5)
    {
        chestContentsToRandomize.push_back(myRom->ReadByte(i));
    }

    for (int i = 0; i < 100000; ++i)
    {
        int index1 = myRNG.GetRandomIndexFromByteVector(chestContentsToRandomize);
        int index2 = myRNG.GetRandomIndexFromByteVector(chestContentsToRandomize);

        BYTE item1 = chestContentsToRandomize[index1];
        BYTE item2 = chestContentsToRandomize[index2];

        // 3 Conditions we have to verify
        // 1) Make sure that we're not swapping coins into starting inventory or talk-and-speak inventory
        // 2) Make sure that the Silver Key is not behind Zhao Yun's sister
        // 3) Make sure that the Zhou Letr isn't in Guang Zong.
        if (!((index1 < 11 || index2 < 11) && (item1 < 0x10 || item2 < 0x10)) // 1
            || (index1 == 14 && item2 == 0x22) || (index2 == 14 && item1 == 0x22) // 2
            || (index1 == 8 && item2 == 0x18) || (index2 == 8 && item2 == 0x18)) // 3
        {
            chestContentsToRandomize[index1] = item2;
            chestContentsToRandomize[index2] = item1;
        }
    }

    int index = 0;

    for (int i = 0; i < chestContentsToRandomize.size(); ++i)
    {
        if (i == 0)
        {
            printf ("Starting items:\n");
        }
        if (i == 6)
        {
            printf ("Talk-and-get items:\n");
        }
        if (i == 11)
        {
            printf ("Hidden items:\n");
        }
        if (i == 30)
        {
            printf ("Normal chests:\n");
        }
        printf ("\tChest %d: 0x%02X\n", i, chestContentsToRandomize[i]);
    }

    // Write new starting items
    myRom->WriteByte(0x3556C, chestContentsToRandomize[index++]);
    myRom->WriteByte(0x3556D, chestContentsToRandomize[index++]);
    myRom->WriteByte(0x35574, chestContentsToRandomize[index++]);
    myRom->WriteByte(0x35575, chestContentsToRandomize[index++]);
    myRom->WriteByte(0x3557C, chestContentsToRandomize[index++]);
    myRom->WriteByte(0x3557D, chestContentsToRandomize[index++]);

    // Write new Zhou Letr item
    myRom->WriteByte(0x368DC, chestContentsToRandomize[index++]);

    // Write new Intro Letr item
    myRom->WriteByte(0x366DD, chestContentsToRandomize[index++]);

    // Write new Silver Key item
    myRom->WriteByte(0x3680F, chestContentsToRandomize[index++]);

    // Write new Gunpowder Item
    myRom->WriteByte(0x368A2, chestContentsToRandomize[index++]);

    // Write new Qing Long Item
    myRom->WriteByte(0x37333, chestContentsToRandomize[index++]);

    // Write new hidden items
    for (int i = HIDDEN_ITEM_OFFSET; i < HIDDEN_ITEM_OFFSET + 20; ++i)
    {
        BYTE item = myRom->ReadByte(i);
        if (item != 0xFF) // I found a keyhole, i = 2
        {
            myRom->WriteByte(i, chestContentsToRandomize[index++]);
        }
    }

    for (int i = ITEMS_OFFSET; i < ITEMS_OFFSET_END; i += 5)
    {
        myRom->WriteByte(i, chestContentsToRandomize[index++]);
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
movq %rdi, %rbx
xorps %xmm0, %xmm0
movaps %xmm0, -0x50(%rbp)
movq $0x0, -0x40(%rbp)
movq (%rdi), %rdi
movl $0x3556c, %esi          # imm = 0x3556C
callq 0x4049fe
movb %al, -0x29(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405b7f
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405b8c
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x40ad06
movq (%rbx), %rdi
movl $0x3556d, %esi          # imm = 0x3556D
callq 0x4049fe
movb %al, -0x29(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405bae
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405bbb
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x40ad06
movq (%rbx), %rdi
movl $0x35574, %esi          # imm = 0x35574
callq 0x4049fe
movb %al, -0x29(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405bdd
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405bea
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x40ad06
movq (%rbx), %rdi
movl $0x35575, %esi          # imm = 0x35575
callq 0x4049fe
movb %al, -0x29(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405c0c
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405c19
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x40ad06
movq (%rbx), %rdi
movl $0x3557c, %esi          # imm = 0x3557C
callq 0x4049fe
movb %al, -0x29(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405c3b
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405c48
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x40ad06
movq (%rbx), %rdi
movl $0x3557d, %esi          # imm = 0x3557D
callq 0x4049fe
movb %al, -0x29(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405c6a
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405c77
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x40ad06
movq (%rbx), %rdi
movl $0x368dc, %esi          # imm = 0x368DC
callq 0x4049fe
movb %al, -0x29(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405c99
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405ca6
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x40ad06
movq (%rbx), %rdi
movl $0x366dd, %esi          # imm = 0x366DD
callq 0x4049fe
movb %al, -0x29(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405cc8
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405cd5
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x40ad06
movq (%rbx), %rdi
movl $0x3680f, %esi          # imm = 0x3680F
callq 0x4049fe
movb %al, -0x29(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405cf7
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405d04
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x40ad06
movq (%rbx), %rdi
movl $0x368a2, %esi          # imm = 0x368A2
callq 0x4049fe
movb %al, -0x29(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405d26
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405d33
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x40ad06
movq (%rbx), %rdi
movl $0x37333, %esi          # imm = 0x37333
callq 0x4049fe
movb %al, -0x29(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405d55
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405d62
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x40ad06
movl $0x30b10, %r14d         # imm = 0x30B10
leaq -0x50(%rbp), %r15
leaq -0x29(%rbp), %r12
movq (%rbx), %rdi
movl %r14d, %esi
callq 0x4049fe
movb %al, -0x29(%rbp)
cmpb $-0x1, %al
je 0x405d9f
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405d94
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405d9f
movq %r15, %rdi
movq %r12, %rdx
callq 0x40adf8
incl %r14d
cmpl $0x30b24, %r14d         # imm = 0x30B24
jne 0x405d70
movl $0x3090f, %r14d         # imm = 0x3090F
leaq -0x50(%rbp), %r15
leaq -0x29(%rbp), %r12
addl $0x5, %r14d
movq (%rbx), %rdi
movl %r14d, %esi
callq 0x4049fe
movb %al, -0x29(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405ddd
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405de8
movq %r15, %rdi
movq %r12, %rdx
callq 0x40ad06
cmpl $0x309e2, %r14d         # imm = 0x309E2
jb 0x405db9
leaq 0x8(%rbx), %r14
movl $0x186a0, %r13d         # imm = 0x186A0
leaq -0x50(%rbp), %r15
movq %r14, %rdi
movq %r15, %rsi
callq 0x410892
movl %eax, %r12d
movq %r14, %rdi
movq %r15, %rsi
callq 0x410892
movslq %r12d, %rcx
movq -0x50(%rbp), %rsi
movb (%rsi,%rcx), %dl
movslq %eax, %rdi
movb (%rsi,%rdi), %r8b
cmpl $0xb, %ecx
setge %r9b
cmpl $0xb, %edi
setge %r10b
testb %r10b, %r9b
jne 0x405e9c
cmpb $0x10, %dl
setb %r9b
cmpb $0x10, %r8b
setb %r10b
orb %r9b, %r10b
cmpb $0x1, %r10b
jne 0x405e9c
cmpl $0xe, %r12d
sete %r9b
cmpb $0x22, %r8b
sete %r10b
testb %r10b, %r9b
jne 0x405e9c
cmpl $0xe, %eax
sete %r9b
cmpb $0x22, %dl
sete %r10b
testb %r10b, %r9b
jne 0x405e9c
cmpl $0x8, %r12d
sete %r9b
cmpb $0x18, %r8b
sete %r10b
cmpl $0x8, %eax
sete %al
orb %r9b, %al
andb %r10b, %al
cmpb $0x1, %al
jne 0x405ea7
movb %r8b, (%rsi,%rcx)
movq -0x50(%rbp), %rax
movb %dl, (%rax,%rdi)
decl %r13d
jne 0x405dff
movq -0x50(%rbp), %rax
cmpq %rax, -0x48(%rbp)
je 0x405f35
leaq 0x186396(%rip), %r12    # 0x58c257
leaq 0x186268(%rip), %r14    # 0x58c130
leaq 0x1863ba(%rip), %r13    # 0x58c289
xorl %r15d, %r15d
cmpl $0xa, %r15d
jg 0x405eef
movq %r12, %rdi
testl %r15d, %r15d
je 0x405f07
cmpl $0x6, %r15d
jne 0x405f0c
leaq 0x18637a(%rip), %rdi    # 0x58c267
jmp 0x405f07
cmpl $0xb, %r15d
je 0x405f00
cmpl $0x1e, %r15d
jne 0x405f0c
movq %r13, %rdi
jmp 0x405f07
leaq 0x186374(%rip), %rdi    # 0x58c27b
callq 0x4e96e0
movq -0x50(%rbp), %rax
movzbl (%rax,%r15), %edx
movq %r14, %rdi
movl %r15d, %esi
xorl %eax, %eax
callq 0x4e21a0
incq %r15
movq -0x50(%rbp), %rax
movq -0x48(%rbp), %rcx
subq %rax, %rcx
cmpq %r15, %rcx
ja 0x405ed2
movq (%rbx), %rdi
movzbl (%rax), %edx
movl $0x3556c, %esi          # imm = 0x3556C
callq 0x404a28
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x1(%rax), %edx
movl $0x3556d, %esi          # imm = 0x3556D
callq 0x404a28
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x2(%rax), %edx
movl $0x35574, %esi          # imm = 0x35574
callq 0x404a28
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x3(%rax), %edx
movl $0x35575, %esi          # imm = 0x35575
callq 0x404a28
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x4(%rax), %edx
movl $0x3557c, %esi          # imm = 0x3557C
callq 0x404a28
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x5(%rax), %edx
movl $0x3557d, %esi          # imm = 0x3557D
callq 0x404a28
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x6(%rax), %edx
movl $0x368dc, %esi          # imm = 0x368DC
callq 0x404a28
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x7(%rax), %edx
movl $0x366dd, %esi          # imm = 0x366DD
callq 0x404a28
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x8(%rax), %edx
movl $0x3680f, %esi          # imm = 0x3680F
callq 0x404a28
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x9(%rax), %edx
movl $0x368a2, %esi          # imm = 0x368A2
callq 0x404a28
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0xa(%rax), %edx
movl $0x37333, %esi          # imm = 0x37333
callq 0x404a28
movl $0xb, %r15d
movl $0x30b10, %r14d         # imm = 0x30B10
movq (%rbx), %rdi
movl %r14d, %esi
callq 0x4049fe
cmpb $-0x1, %al
je 0x40604b
movq (%rbx), %rdi
movslq %r15d, %rax
movq -0x50(%rbp), %rcx
movzbl (%rcx,%rax), %edx
movl %r14d, %esi
callq 0x404a28
incl %r15d
incl %r14d
cmpl $0x30b24, %r14d         # imm = 0x30B24
jne 0x406023
movslq %r15d, %r15
movl $0x30914, %r14d         # imm = 0x30914
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl (%rax,%r15), %edx
movl %r14d, %esi
callq 0x404a28
incq %r15
addl $0x5, %r14d
cmpl $0x309eb, %r14d         # imm = 0x309EB
jne 0x406060
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x406092
callq 0x410b90
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x4060c3
jmp 0x4060c3
jmp 0x4060c3
jmp 0x4060c3
jmp 0x4060c3
jmp 0x4060c3
jmp 0x4060c3
jmp 0x4060c3
jmp 0x4060c3
jmp 0x4060c3
jmp 0x4060c3
jmp 0x4060c3
jmp 0x4060c3
jmp 0x4060c3
jmp 0x4060c3
jmp 0x4060c3
jmp 0x4060c3
movq %rax, %rbx
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x4060d4
callq 0x410b90
movq %rbx, %rdi
callq 0x4bb660