// File: /workspace/github_cpp_makefile_star2_O2/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)
andq $0x0, -0x40(%rbp)
movq (%rdi), %rdi
movl $0x3556c, %esi          # imm = 0x3556C
callq 0x4049d6
leaq -0x29(%rbp), %rsi
movb %al, (%rsi)
leaq -0x50(%rbp), %rdi
callq 0x409faa
movq (%rbx), %rdi
movl $0x3556d, %esi          # imm = 0x3556D
callq 0x4049d6
leaq -0x29(%rbp), %rsi
movb %al, (%rsi)
leaq -0x50(%rbp), %rdi
callq 0x409faa
movq (%rbx), %rdi
movl $0x35574, %esi          # imm = 0x35574
callq 0x4049d6
leaq -0x29(%rbp), %rsi
movb %al, (%rsi)
leaq -0x50(%rbp), %rdi
callq 0x409faa
movq (%rbx), %rdi
movl $0x35575, %esi          # imm = 0x35575
callq 0x4049d6
leaq -0x29(%rbp), %rsi
movb %al, (%rsi)
leaq -0x50(%rbp), %rdi
callq 0x409faa
movq (%rbx), %rdi
movl $0x3557c, %esi          # imm = 0x3557C
callq 0x4049d6
leaq -0x29(%rbp), %rsi
movb %al, (%rsi)
leaq -0x50(%rbp), %rdi
callq 0x409faa
movq (%rbx), %rdi
movl $0x3557d, %esi          # imm = 0x3557D
callq 0x4049d6
leaq -0x29(%rbp), %rsi
movb %al, (%rsi)
leaq -0x50(%rbp), %rdi
callq 0x409faa
movq (%rbx), %rdi
movl $0x368dc, %esi          # imm = 0x368DC
callq 0x4049d6
leaq -0x29(%rbp), %rsi
movb %al, (%rsi)
leaq -0x50(%rbp), %rdi
callq 0x409faa
movq (%rbx), %rdi
movl $0x366dd, %esi          # imm = 0x366DD
callq 0x4049d6
leaq -0x29(%rbp), %rsi
movb %al, (%rsi)
leaq -0x50(%rbp), %rdi
callq 0x409faa
movq (%rbx), %rdi
movl $0x3680f, %esi          # imm = 0x3680F
callq 0x4049d6
leaq -0x29(%rbp), %rsi
movb %al, (%rsi)
leaq -0x50(%rbp), %rdi
callq 0x409faa
movq (%rbx), %rdi
movl $0x368a2, %esi          # imm = 0x368A2
callq 0x4049d6
leaq -0x29(%rbp), %rsi
movb %al, (%rsi)
leaq -0x50(%rbp), %rdi
callq 0x409faa
movq (%rbx), %rdi
movl $0x37333, %esi          # imm = 0x37333
callq 0x4049d6
leaq -0x29(%rbp), %rsi
movb %al, (%rsi)
leaq -0x50(%rbp), %rdi
callq 0x409faa
movl $0x30b10, %r14d         # imm = 0x30B10
leaq -0x50(%rbp), %r15
leaq -0x29(%rbp), %r12
cmpl $0x30b24, %r14d         # imm = 0x30B24
je 0x405af9
movq (%rbx), %rdi
movl %r14d, %esi
callq 0x4049d6
movb %al, -0x29(%rbp)
cmpb $-0x1, %al
je 0x405af4
movq %r15, %rdi
movq %r12, %rsi
callq 0x409c42
incl %r14d
jmp 0x405ace
movl $0x30914, %r14d         # imm = 0x30914
leaq -0x50(%rbp), %r15
leaq -0x29(%rbp), %r12
cmpl $0x309e7, %r14d         # imm = 0x309E7
jae 0x405b2f
movq (%rbx), %rdi
movl %r14d, %esi
callq 0x4049d6
movb %al, -0x29(%rbp)
movq %r15, %rdi
movq %r12, %rsi
callq 0x409faa
addl $0x5, %r14d
jmp 0x405b07
leaq 0x8(%rbx), %r14
movl $0x186a0, %r13d         # imm = 0x186A0
leaq -0x50(%rbp), %r15
subl $0x1, %r13d
jb 0x405bf8
movq %r14, %rdi
movq %r15, %rsi
callq 0x40edb0
movl %eax, %r12d
movq %r14, %rdi
movq %r15, %rsi
callq 0x40edb0
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 0x405be8
cmpb $0x10, %dl
setb %r9b
cmpb $0x10, %r8b
setb %r10b
orb %r9b, %r10b
cmpb $0x1, %r10b
jne 0x405be8
cmpl $0xe, %r12d
sete %r9b
cmpb $0x22, %r8b
sete %r10b
testb %r10b, %r9b
jne 0x405be8
cmpl $0xe, %eax
sete %r9b
cmpb $0x22, %dl
sete %r10b
testb %r10b, %r9b
jne 0x405be8
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 0x405b3d
movb %r8b, (%rsi,%rcx)
movq -0x50(%rbp), %rax
movb %dl, (%rax,%rdi)
jmp 0x405b3d
leaq 0x185658(%rip), %r12    # 0x58b257
leaq 0x18552a(%rip), %r14    # 0x58b130
leaq 0x18565a(%rip), %r13    # 0x58b267
xorl %r15d, %r15d
movq -0x50(%rbp), %rax
movq -0x48(%rbp), %rcx
subq %rax, %rcx
cmpq %r15, %rcx
jbe 0x405c6f
movq %r12, %rdi
testl %r15d, %r15d
je 0x405c4f
cmpl $0x1e, %r15d
je 0x405c3f
cmpl $0xb, %r15d
je 0x405c48
cmpl $0x6, %r15d
jne 0x405c54
movq %r13, %rdi
jmp 0x405c4f
leaq 0x185643(%rip), %rdi    # 0x58b289
jmp 0x405c4f
leaq 0x18562c(%rip), %rdi    # 0x58b27b
callq 0x4e8680
movq -0x50(%rbp), %rax
movzbl (%rax,%r15), %edx
movq %r14, %rdi
movl %r15d, %esi
xorl %eax, %eax
callq 0x4e1140
incq %r15
jmp 0x405c10
movq (%rbx), %rdi
movzbl (%rax), %edx
movl $0x3556c, %esi          # imm = 0x3556C
callq 0x404a00
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x1(%rax), %edx
movl $0x3556d, %esi          # imm = 0x3556D
callq 0x404a00
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x2(%rax), %edx
movl $0x35574, %esi          # imm = 0x35574
callq 0x404a00
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x3(%rax), %edx
movl $0x35575, %esi          # imm = 0x35575
callq 0x404a00
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x4(%rax), %edx
movl $0x3557c, %esi          # imm = 0x3557C
callq 0x404a00
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x5(%rax), %edx
movl $0x3557d, %esi          # imm = 0x3557D
callq 0x404a00
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x6(%rax), %edx
movl $0x368dc, %esi          # imm = 0x368DC
callq 0x404a00
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x7(%rax), %edx
movl $0x366dd, %esi          # imm = 0x366DD
callq 0x404a00
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x8(%rax), %edx
movl $0x3680f, %esi          # imm = 0x3680F
callq 0x404a00
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0x9(%rax), %edx
movl $0x368a2, %esi          # imm = 0x368A2
callq 0x404a00
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl 0xa(%rax), %edx
movl $0x37333, %esi          # imm = 0x37333
callq 0x404a00
movl $0x30b10, %r14d         # imm = 0x30B10
pushq $0xb
popq %r12
movslq %r12d, %r15
cmpl $0x30b24, %r14d         # imm = 0x30B24
je 0x405d92
movq (%rbx), %rdi
movl %r14d, %esi
callq 0x4049d6
cmpb $-0x1, %al
je 0x405d8d
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl (%rax,%r15), %edx
movl %r14d, %esi
callq 0x404a00
incl %r12d
incl %r14d
jmp 0x405d5b
addl $0x2b, %r12d
movslq %r12d, %r12
movl $0x30914, %r14d         # imm = 0x30914
cmpq %r15, %r12
je 0x405dc1
movq (%rbx), %rdi
movq -0x50(%rbp), %rax
movzbl (%rax,%r15), %edx
movl %r14d, %esi
callq 0x404a00
incq %r15
addl $0x5, %r14d
jmp 0x405d9f
leaq -0x50(%rbp), %rdi
callq 0x404baa
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x405dfb
jmp 0x405dfb
jmp 0x405dfb
jmp 0x405dfb
jmp 0x405dfb
jmp 0x405dfb
jmp 0x405dfb
jmp 0x405dfb
jmp 0x405dfb
jmp 0x405dfb
jmp 0x405dfb
jmp 0x405dfb
jmp 0x405dfb
jmp 0x405dfb
jmp 0x405dfb
jmp 0x405dfb
jmp 0x405dfb
movq %rax, %rbx
leaq -0x50(%rbp), %rdi
callq 0x404baa
movq %rbx, %rdi
callq 0x4ba600
nop