// File: /workspace/github_cpp_makefile_star2_O2/Thilotilo[P]DoaERando/Randomizer.cpp
// Function: DoaERando::Randomizer::MakeIntroLetterUseful()
void Randomizer::MakeIntroLetterUseful()
{
    // Text starting at AAB3 (2AAC3):
    std::vector<BYTE> newText {
        // Text 4C (offset 0)
        0xF9,0x2D,0x27, // Event for checking for the intro letr (3 bytes)
        // Text 4D (offset 3)
        0x1F,0x2D,0x34,0x2E,0x34,0x3D,0x2F,0x0A,0x30,0x0A,0x3B,0x34,0x2F,0x2F,0x34,0x2D,0xFB, // Present a letter (17 bytes)
        0x3E,0x35,0x0A,0x38,0x3D,0x2F,0x2D,0x3E,0x33,0x64,0x32,0x2F,0x38,0x3E,0x3D,0xFB, // of introduction (16 bytes)
        0x3E,0x2D,0x0A,0x3B,0x34,0x30,0x65,0x34,0x0A,0x30,0x2F,0x0A,0x3E,0x3D,0x32,0x34,0xEC, // or leave at once. (17 bytes)
        // Text 4E (offset 53)
        0x12,0x3E,0xF0,0xF0,0x90,0xEB,0xF0,0x1E,0xEC, // Come in please. (9 bytes)
        // Text 4F (offset 62)
        0xF9,0xC0,0x17, // Event for "Come in please" + moving the lady (3 bytes)
        // Text 50 (offset 65)
        0x18,0x0A,0x35,0x3E,0x64,0x3D,0x33,0x0A,0x30,0x0A,0x3B,0x3E,0x32,0x3A,0x34,0x33,0xFB, // I found a locked (17 bytes)
        0x2E,0x30,0x35,0x34,0x0A,0x38,0x3D,0x0A,0x1B,0x64,0x3E,0x0A,0x28,0x30,0x3D,0x36,0xFB, // safe in Luo Yang (17 bytes)
        0x30,0x3D,0x33,0x0A,0x3F,0x64,0x2F,0x0A,0x38,0x2F,0x0A,0x31,0x34,0x37,0x38,0x3D,0x33,0xFD, // and put it behind> (18 bytes)
        0x2F,0x37,0x30,0x2F,0x0A,0x39,0x30,0x2D,0x63,0x0A,0x18,0x35,0x0A,0x68,0x3E,0x64,0xFB, // that jar. If you (17 bytes)
        0x32,0x30,0x3D,0x0A,0x3E,0x3F,0x34,0x3D,0x0A,0x38,0x2F,0x62,0x0A,0x68,0x3E,0x64,0xFB, // can open it, you (17 bytes)
        0x3C,0x30,0x68,0x0A,0x3A,0x34,0x34,0x3F,0x0A,0x38,0x2F,0x2E,0xFD, // may keep its> (13 bytes)
        0x32,0x3E,0x3D,0x2F,0x34,0x3D,0x2F,0x2E,0xEC, // contents. (9 bytes)
    };

    for (unsigned int i = 0; i < newText.size(); ++i)
    {
        myRom->WriteByte(0x2AAC3 + i, newText[i]);
    }

    //0x2AB7F is the start for text id 51
    const unsigned int NUM_TEXT_BYTES_TO_RECLAIM = 0x2AB7F - 0x2AAC3 - newText.size();
    for (unsigned int i = 0; i < NUM_TEXT_BYTES_TO_RECLAIM; ++i)
    {
        myRom->WriteByte(0x2AAC3 + newText.size() + i, 0x00);
    }

    // AAB3 is the start:
    // 4C (offset 0) = AAB3
    // 4D (offset 3) = AAB6
    // 4E (offset 53 (0x35)) = AAE8
    // 4F (offset 62 (0x3E)) = AAF1
    // 50 (offset 65 (0x41)) = AAF4

    // no need to overwrite the 4C pointer, since it didn't change
    myRom->WriteByte(0x2815D, 0xB6);
    myRom->WriteByte(0x2815E, 0xE8);
    myRom->WriteByte(0x2815F, 0xF1);
    myRom->WriteByte(0x28160, 0xF4);
    // 4C - 4F already have AA as their pointer MSB
    myRom->WriteByte(0x28360, 0xAA);


    // Starts at 0x3673D
    std::vector<BYTE> newCode1 {
        0xA9, 0x1A,       // LDA #$1A (1A is the Intro Letr)
        0x85, 0xF2,       // STA $F2
        // This subroutine checks the party inventory for the item in $F2,
        // removes it if it finds it, and sets C to indicate if it was found.
        0x20, 0x39, 0x9E, // JSR $9E39
        0x90, 0x0B,       // BCC ($A741) (the second jump instruction)
        // We're here if the intro letr was found.
        // Setting 670Eb0 to 1 will make the lady use the second text on
        // subsequent entries to the hut.
        0xAD, 0x0E, 0x67, // LDA $670E
        0x09, 0x01,       // ORA #$01
        0x8D, 0x0E, 0x67, // LDA $670E
        // Head to other new code to trigger the text + lady move
        0x4C, 0xC0, 0x97, // JMP $97C0
        // Head to other new code for the failed-to-find intro letr path
        0x4C, 0xC8, 0x97, // JMP $97C8
    };

    for (unsigned int i = 0; i < newCode1.size(); ++i)
    {
        myRom->WriteByte(0x3673D + i, newCode1[i]);
    }

    // Starts at 0x357D0
    std::vector<BYTE> newCode2 {
        // success path
        0x20, 0x0D, 0xD1, // JSR $D10D
        0x4E, 0x01,       // Come in please
        // Jump to lady moving event (it will take care of returning)
        0x4C, 0x18, 0xA7, // JMP $A718
        // Into letr not found path
        // Check if we've turned in the intro letr previously by checking $670Eb0
        0xAD, 0x0E, 0x67, // LDA $67OE
        0x29, 0x01,       // AND #$01
        // If we turned it in before, go ahead with the success path
        0xD0, 0xF1,       // BNE $(97C0)
        // We don't have it and have never turned it in
        0x20, 0x0D, 0xD1, // JSR $D10D
        0x4D, 0x01,       // "Present a letter..."
        // Get us out of here
        0x4C, 0xA6, 0xC4, // JMP $C4A6 (switches back to bank E, then returns)
    };

    for (unsigned int i = 0; i < newCode2.size(); ++i)
    {
        myRom->WriteByte(0x357D0 + i, newCode2[i]);
    }

    // NPC Data starts at 0x3123A
    myRom->WriteByte(0x3123B, 0x01); // Remove the "use text 3 flag" for Shui Jing
    myRom->WriteByte(0x3123E, 0x50); // Change Shui Jing text to the new text
    myRom->WriteByte(0x3123F, 0x50); // Replace text 2 with the same
    myRom->WriteByte(0x31242, 0x01); // Remove the "use text 3 flag" for the lady
    // Lady's first text is already 4C, so no need to change that
    myRom->WriteByte(0x31246, 0x4F); // Lady text 2 = "Come in please" + move

    // Finally, there's a character in Chen Cang that sets 670E to #03 when you talk
    // to him.  Remove that section from the code (and free a few bytes in the process)
    myRom->WriteByte(0x366E4, 0x05); // Move the branch that was taking us to the 670E set to now just return

    // no longer executed bytes
    for (unsigned int i = 0; i < 8; ++i)
    {
        myRom->WriteByte(0x366ED + i, 0x00);
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %rbx
subq $0x108, %rsp            # imm = 0x108
movq %rdi, %rbx
leaq 0x184437(%rip), %rsi    # 0x58b3f3
leaq -0x120(%rbp), %r14
movl $0xad, %edx
movq %r14, %rdi
callq 0x401070
leaq -0x58(%rbp), %rdi
leaq -0x40(%rbp), %rcx
movl $0xad, %edx
movq %r14, %rsi
callq 0x409c64
movl $0x2aac3, %r14d         # imm = 0x2AAC3
leal -0x2aac3(%r14), %eax
movq -0x58(%rbp), %rcx
movq -0x50(%rbp), %r15
subq %rcx, %r15
cmpq %rax, %r15
jbe 0x407016
movq (%rbx), %rdi
movzbl (%rcx,%rax), %edx
movl %r14d, %esi
callq 0x404a00
incl %r14d
jmp 0x406feb
movl $0x2aac3, %r14d         # imm = 0x2AAC3
leal (%r15,%r14), %eax
movq (%rbx), %rdi
cmpl $0x2ab7f, %eax          # imm = 0x2AB7F
je 0x40703f
movl -0x50(%rbp), %esi
subl -0x58(%rbp), %esi
addl %r14d, %esi
xorl %edx, %edx
callq 0x404a00
incl %r14d
jmp 0x40701c
movl $0x2815d, %esi          # imm = 0x2815D
movl $0xb6, %edx
callq 0x404a00
movq (%rbx), %rdi
movl $0x2815e, %esi          # imm = 0x2815E
movl $0xe8, %edx
callq 0x404a00
movq (%rbx), %rdi
movl $0x2815f, %esi          # imm = 0x2815F
movl $0xf1, %edx
callq 0x404a00
movq (%rbx), %rdi
movl $0x28160, %esi          # imm = 0x28160
movl $0xf4, %edx
callq 0x404a00
movq (%rbx), %rdi
movl $0x28360, %esi          # imm = 0x28360
movl $0xaa, %edx
callq 0x404a00
movups 0x184403(%rip), %xmm0   # 0x58b4a0
leaq -0x40(%rbp), %rsi
movaps %xmm0, (%rsi)
movabsq $-0x6837b3683fb398f2, %rax # imm = 0x97C84C97C04C670E
movq %rax, 0xf(%rsi)
leaq -0x120(%rbp), %rdi
pushq $0x17
popq %rdx
leaq -0x70(%rbp), %rcx
callq 0x409c64
movl $0x3673d, %r14d         # imm = 0x3673D
leal -0x3673d(%r14), %eax
movq -0x120(%rbp), %rcx
movq -0x118(%rbp), %rdx
subq %rcx, %rdx
cmpq %rax, %rdx
jbe 0x4070fc
movq (%rbx), %rdi
movzbl (%rcx,%rax), %edx
movl %r14d, %esi
callq 0x404a00
incl %r14d
jmp 0x4070cb
movups 0x1843b4(%rip), %xmm0   # 0x58b4b7
leaq -0x70(%rbp), %rsi
movaps %xmm0, (%rsi)
movabsq $-0x3b59b3feb22ef2e0, %rax # imm = 0xC4A64C014DD10D20
movq %rax, 0xf(%rsi)
leaq -0x40(%rbp), %rdi
pushq $0x17
popq %rdx
leaq -0x19(%rbp), %rcx
callq 0x409c64
movl $0x357d0, %r14d         # imm = 0x357D0
leal -0x357d0(%r14), %eax
movq -0x40(%rbp), %rcx
movq -0x38(%rbp), %rdx
subq %rcx, %rdx
movq (%rbx), %rdi
cmpq %rax, %rdx
jbe 0x407159
movzbl (%rcx,%rax), %edx
movl %r14d, %esi
callq 0x404a00
incl %r14d
jmp 0x40712e
pushq $0x1
popq %rdx
movl $0x3123b, %esi          # imm = 0x3123B
callq 0x404a00
movq (%rbx), %rdi
pushq $0x50
popq %rdx
movl $0x3123e, %esi          # imm = 0x3123E
callq 0x404a00
movq (%rbx), %rdi
pushq $0x50
popq %rdx
movl $0x3123f, %esi          # imm = 0x3123F
callq 0x404a00
movq (%rbx), %rdi
pushq $0x1
popq %rdx
movl $0x31242, %esi          # imm = 0x31242
callq 0x404a00
movq (%rbx), %rdi
pushq $0x4f
popq %rdx
movl $0x31246, %esi          # imm = 0x31246
callq 0x404a00
movq (%rbx), %rdi
pushq $0x5
popq %rdx
movl $0x366e4, %esi          # imm = 0x366E4
callq 0x404a00
xorl %r14d, %r14d
pushq $0x8
popq %r15
subl $0x1, %r15d
jb 0x4071d9
movq (%rbx), %rdi
leal 0x366ed(%r14), %esi
xorl %edx, %edx
callq 0x404a00
incl %r14d
jmp 0x4071bd
leaq -0x40(%rbp), %rdi
callq 0x404baa
leaq -0x120(%rbp), %rdi
callq 0x404baa
leaq -0x58(%rbp), %rdi
callq 0x404baa
addq $0x108, %rsp            # imm = 0x108
popq %rbx
popq %r14
popq %r15
popq %rbp
retq
jmp 0x40721d
jmp 0x407230
jmp 0x407230
jmp 0x40720f
jmp 0x40720f
movq %rax, %rbx
leaq -0x40(%rbp), %rdi
callq 0x404baa
jmp 0x407220
movq %rax, %rbx
leaq -0x120(%rbp), %rdi
callq 0x404baa
jmp 0x407233
jmp 0x407230
movq %rax, %rbx
leaq -0x58(%rbp), %rdi
callq 0x404baa
movq %rbx, %rdi
callq 0x4ba600