// File: /workspace/github_cpp_makefile_star2_O3/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 0x4049fa
leaq -0x29(%rbp), %rdx
movb %al, (%rdx)
leaq -0x50(%rbp), %rdi
xorl %esi, %esi
callq 0x40ad1c
movq (%rbx), %rdi
movl $0x3556d, %esi          # imm = 0x3556D
callq 0x4049fa
movb %al, -0x29(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405b5f
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405b6c
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x40ad1c
movq (%rbx), %rdi
movl $0x35574, %esi          # imm = 0x35574
callq 0x4049fa
movb %al, -0x29(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405b8e
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405b9b
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x40ad1c
movq (%rbx), %rdi
movl $0x35575, %esi          # imm = 0x35575
callq 0x4049fa
movb %al, -0x29(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405bbd
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405bca
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x40ad1c
movq (%rbx), %rdi
movl $0x3557c, %esi          # imm = 0x3557C
callq 0x4049fa
movb %al, -0x29(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405bec
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405bf9
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x40ad1c
movq (%rbx), %rdi
movl $0x3557d, %esi          # imm = 0x3557D
callq 0x4049fa
movb %al, -0x29(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405c1b
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405c28
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x40ad1c
movq (%rbx), %rdi
movl $0x368dc, %esi          # imm = 0x368DC
callq 0x4049fa
movb %al, -0x29(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405c4a
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405c57
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x40ad1c
movq (%rbx), %rdi
movl $0x366dd, %esi          # imm = 0x366DD
callq 0x4049fa
movb %al, -0x29(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405c79
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405c86
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x40ad1c
movq (%rbx), %rdi
movl $0x3680f, %esi          # imm = 0x3680F
callq 0x4049fa
movb %al, -0x29(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405ca8
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405cb5
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x40ad1c
movq (%rbx), %rdi
movl $0x368a2, %esi          # imm = 0x368A2
callq 0x4049fa
movb %al, -0x29(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405cd7
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405ce4
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x40ad1c
movq (%rbx), %rdi
movl $0x37333, %esi          # imm = 0x37333
callq 0x4049fa
movb %al, -0x29(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405d06
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405d13
leaq -0x50(%rbp), %rdi
leaq -0x29(%rbp), %rdx
callq 0x40ad1c
movl $0x30b10, %r14d         # imm = 0x30B10
leaq -0x50(%rbp), %r15
leaq -0x29(%rbp), %r12
movq (%rbx), %rdi
movl %r14d, %esi
callq 0x4049fa
movb %al, -0x29(%rbp)
cmpb $-0x1, %al
je 0x405d50
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405d45
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405d50
movq %r15, %rdi
movq %r12, %rdx
callq 0x40ae0e
incl %r14d
cmpl $0x30b24, %r14d         # imm = 0x30B24
jne 0x405d21
movl $0x3090f, %r14d         # imm = 0x3090F
leaq -0x50(%rbp), %r15
leaq -0x29(%rbp), %r12
addl $0x5, %r14d
movq (%rbx), %rdi
movl %r14d, %esi
callq 0x4049fa
movb %al, -0x29(%rbp)
movq -0x48(%rbp), %rsi
cmpq -0x40(%rbp), %rsi
je 0x405d8e
movb %al, (%rsi)
incq -0x48(%rbp)
jmp 0x405d99
movq %r15, %rdi
movq %r12, %rdx
callq 0x40ad1c
cmpl $0x309e2, %r14d         # imm = 0x309E2
jb 0x405d6a
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 0x405e4d
cmpb $0x10, %dl
setb %r9b
cmpb $0x10, %r8b
setb %r10b
orb %r9b, %r10b
cmpb $0x1, %r10b
jne 0x405e4d
cmpl $0xe, %r12d
sete %r9b
cmpb $0x22, %r8b
sete %r10b
testb %r10b, %r9b
jne 0x405e4d
cmpl $0xe, %eax
sete %r9b
cmpb $0x22, %dl
sete %r10b
testb %r10b, %r9b
jne 0x405e4d
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 0x405e58
movb %r8b, (%rsi,%rcx)
movq -0x50(%rbp), %rax
movb %dl, (%rax,%rdi)
decl %r13d
jne 0x405db0
movq -0x50(%rbp), %rax
cmpq %rax, -0x48(%rbp)
je 0x405ee6
leaq 0x1863e5(%rip), %r12    # 0x58c257
leaq 0x1862b7(%rip), %r14    # 0x58c130
leaq 0x186409(%rip), %r13    # 0x58c289
xorl %r15d, %r15d
cmpl $0xa, %r15d
jg 0x405ea0
movq %r12, %rdi
testl %r15d, %r15d
je 0x405eb8
cmpl $0x6, %r15d
jne 0x405ebd
leaq 0x1863c9(%rip), %rdi    # 0x58c267
jmp 0x405eb8
cmpl $0xb, %r15d
je 0x405eb1
cmpl $0x1e, %r15d
jne 0x405ebd
movq %r13, %rdi
jmp 0x405eb8
leaq 0x1863c3(%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 0x405e83
movq (%rbx), %rdi
movzbl (%rax), %edx
movl $0x3556c, %esi          # imm = 0x3556C
callq 0x404a24
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x1(%rax), %edx
movl $0x3556d, %esi          # imm = 0x3556D
callq 0x404a24
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x2(%rax), %edx
movl $0x35574, %esi          # imm = 0x35574
callq 0x404a24
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x3(%rax), %edx
movl $0x35575, %esi          # imm = 0x35575
callq 0x404a24
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x4(%rax), %edx
movl $0x3557c, %esi          # imm = 0x3557C
callq 0x404a24
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x5(%rax), %edx
movl $0x3557d, %esi          # imm = 0x3557D
callq 0x404a24
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x6(%rax), %edx
movl $0x368dc, %esi          # imm = 0x368DC
callq 0x404a24
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x7(%rax), %edx
movl $0x366dd, %esi          # imm = 0x366DD
callq 0x404a24
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x8(%rax), %edx
movl $0x3680f, %esi          # imm = 0x3680F
callq 0x404a24
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x9(%rax), %edx
movl $0x368a2, %esi          # imm = 0x368A2
callq 0x404a24
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0xa(%rax), %edx
movl $0x37333, %esi          # imm = 0x37333
callq 0x404a24
movl $0xb, %r15d
movl $0x30b10, %r14d         # imm = 0x30B10
movq (%rbx), %rdi
movl %r14d, %esi
callq 0x4049fa
cmpb $-0x1, %al
je 0x405ffc
movq (%rbx), %rdi
movslq %r15d, %rax
movq -0x50(%rbp), %rcx
movzbl (%rcx,%rax), %edx
movl %r14d, %esi
callq 0x404a24
incl %r15d
incl %r14d
cmpl $0x30b24, %r14d         # imm = 0x30B24
jne 0x405fd4
movslq %r15d, %r15
movl $0x30914, %r14d         # imm = 0x30914
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl (%rax,%r15), %edx
movl %r14d, %esi
callq 0x404a24
incq %r15
addl $0x5, %r14d
cmpl $0x309eb, %r14d         # imm = 0x309EB
jne 0x406011
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x406043
callq 0x410b90
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x406074
jmp 0x406074
jmp 0x406074
jmp 0x406074
jmp 0x406074
jmp 0x406074
jmp 0x406074
jmp 0x406074
jmp 0x406074
jmp 0x406074
jmp 0x406074
jmp 0x406074
jmp 0x406074
jmp 0x406074
jmp 0x406074
jmp 0x406074
jmp 0x406074
movq %rax, %rbx
movq -0x50(%rbp), %rdi
testq %rdi, %rdi
je 0x406085
callq 0x410b90
movq %rbx, %rdi
callq 0x4bb660
nop