// File: /workspace/github_cpp_makefile_star2_O2/Thilotilo[P]DoaERando/Randomizer.cpp
// Function: DoaERando::Randomizer::RewriteTitleScreen(int, int, int, int)
void Randomizer::RewriteTitleScreen(int major, int minor, int patch, int seed)
{
    // I assume there are line pointers here, but I simply don't know where
    // they are, so I'm simply replacing the extra characters I don't want
    // display with 0xFF, but I'm not actually moving any line starts

    // Line format:
    // first 2 bytes - location to write (lower nibble of byte 2
    //                 defines horizontal start position)
    // third byte - number of bytes to write
    const int CREDIT_START = 0x349A1;
    int index = CREDIT_START;

    // adding scoping braces for readability
    // RANDOMIZER
    {
        std::vector<BYTE> randomizerLine {
            0x21,0xAB,0x0A,0x21,0x10,0x1D,0x13,0x1E,0x1C,0x18,0x29,0x14,0x21 // RANDOMIZER
        };
        // Fill remaining bytes for this line with 0xFF
        randomizerLine.resize(0x0F, 0xFF);
        // Write the data
        for (int i = 0; i < randomizerLine.size(); ++i, ++index)
        {
            myRom->WriteByte(index, randomizerLine[i]);
        }
    }


    // VERSION X.Y.Z
    {
        int combinedVersionDigits = numDigits(major) + numDigits(minor) + numDigits(patch);
        BYTE versionLineLen = 8 + combinedVersionDigits + 2; // 8 for VERSION_, 2 for dots between versions
        if (versionLineLen % 2 == 1) // Make sure we always have an even number of characters for centering
        {
            versionLineLen++;
        }
        // Set the lower nibble to a centering offset based upon the version length
        BYTE versionOffset = (0x10 - static_cast<BYTE>(versionLineLen/2)) | 0xE0;
        // Write VERSION_
        std::vector<BYTE> versionLine {0x21, versionOffset, 0x17, 0x25,0x14,0x21,0x22,0x18,0x1E,0x1D,0x0A};
        if (combinedVersionDigits % 2 == 1) // Add an extra space to get us to an even number of characters
        {
            versionLine.push_back(0x0A);
        }
        // Add patch numbers
        appendNumber(versionLine, major);
        versionLine.push_back(0x63);
        appendNumber(versionLine, minor);
        versionLine.push_back(0x63);
        appendNumber(versionLine, patch);
        // Fill remaining bytes for this line with 0xFF
        versionLine.resize(0x1A, 0xFF);
        // Write the data
        for (int i = 0; i < versionLine.size(); ++i, ++index)
        {
            myRom->WriteByte(index, versionLine[i]);
        }
    }

    // SEED X
    {
        int seedDigits = numDigits(seed);
        BYTE seedLineLen = 5 + seedDigits;
        if (seedLineLen % 2 == 1) // Make sure we always have an even number of characters for centering
        {
            seedLineLen++;
        }
        // Set the lower nibble to a centering offset based upon the seed length
        BYTE seedOffset = (0x10 - static_cast<BYTE>(seedLineLen/2)) | 0x20;
        // Write SEED_
        std::vector<BYTE> seedLine {0x22,seedOffset,0x12,0x22,0x14,0x14,0x13,0x0A};
        if (seedDigits % 2 == 0) // Write an extra space if needed to get to even character count
        {
            seedLine.push_back(0x0A);
        }
        // Add seed number
        appendNumber(seedLine, seed);
        // Fill remaining bytes for this line with 0xFF
        seedLine.resize(0x15, 0xFF);
        // Write the data
        for (int i = 0; i < seedLine.size(); ++i, ++index)
        {
            myRom->WriteByte(index, seedLine[i]);
        }
    }

    // 4 BLANK LINES
    {
        std::vector<BYTE> blankLine0 {0x22, 0x65, 0x0F};
        blankLine0.resize(0x12, 0xFF);
        for (int i = 0; i < blankLine0.size(); ++i, ++index)
        {
            myRom->WriteByte(index, blankLine0[i]);
        }

        std::vector<BYTE> blankLine1 {0x22, 0xA2, 0x1D};
        blankLine1.resize(0x20, 0xFF);
        for (int i = 0; i < blankLine1.size(); ++i, ++index)
        {
            myRom->WriteByte(index, blankLine1[i]);
        }

        std::vector<BYTE> blankLine2 {0x22, 0xE6, 0x13};
        blankLine2.resize(0x16, 0xFF);
        for (int i = 0; i < blankLine2.size(); ++i, ++index)
        {
            myRom->WriteByte(index, blankLine2[i]);
        }

        std::vector<BYTE> blankLine3 {0x23, 0x29, 0x0B};
        blankLine3.resize(0x0E, 0xFF);
        for (int i = 0; i < blankLine3.size(); ++i, ++index)
        {
            myRom->WriteByte(index, blankLine3[i]);
        }
    }

    // CREATED BY THILOTILO
    {
        // Text data
        std::vector<BYTE> createdByLine {
            0x23,0x66,0x18,0x12,0x21,0x14,0x10,0x23,0x14,0x13,0x0A,0x11,0x28,0x0A,0x23,0x17,0x18,0x1B,0x1E,0x23,0x18,0x1B,0x1E};
        // Fill remaining bytes for this line with 0xFF
        createdByLine.resize(0x1B, 0xFF);
        // Write the data
        for (int i = 0; i < createdByLine.size(); ++i, ++index)
        {
            myRom->WriteByte(index, createdByLine[i]);
        }
    }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0x78, %rsp
movl %r8d, -0x64(%rbp)
movl %ecx, -0x68(%rbp)
movl %edx, %r15d
movl %esi, %r14d
movq %rdi, %rbx
movabsq $0x1e131d10210aab21, %rax # imm = 0x1E131D10210AAB21
leaq -0x60(%rbp), %rsi
movq %rax, (%rsi)
movl $0x1429181c, 0x8(%rsi)  # imm = 0x1429181C
movb $0x21, 0xc(%rsi)
leaq -0x40(%rbp), %rdi
pushq $0xd
popq %rdx
leaq -0x80(%rbp), %rcx
callq 0x409c64
leaq -0x60(%rbp), %rdx
movb $-0x1, (%rdx)
leaq -0x40(%rbp), %rdi
pushq $0xf
popq %rsi
callq 0x409e1c
xorl %r12d, %r12d
movq -0x40(%rbp), %rax
movq -0x38(%rbp), %rcx
subq %rax, %rcx
cmpq %r12, %rcx
jbe 0x4096f5
leaq 0x349a1(%r12), %rsi
movq (%rbx), %rdi
movzbl (%rax,%r12), %edx
callq 0x404a00
incq %r12
jmp 0x4096cb
leaq -0x40(%rbp), %rdi
callq 0x404baa
movl %r14d, -0x84(%rbp)
movl %r14d, %edi
callq 0x409b84
movl %eax, %r14d
movl %r15d, %r13d
movl %r15d, %edi
callq 0x409b84
movl %eax, %r15d
addl %r14d, %r15d
movl -0x68(%rbp), %edi
callq 0x409b84
movl %eax, %r14d
addl %r15d, %r14d
movl %r14d, %eax
andl $0x1, %eax
addl %r14d, %eax
addb $0xa, %al
shrb %al
movb $0x10, %cl
subb %al, %cl
orb $-0x20, %cl
leaq -0x60(%rbp), %rsi
movb $0x21, (%rsi)
movb %cl, 0x1(%rsi)
movabsq $0x1d1e182221142517, %rax # imm = 0x1D1E182221142517
movq %rax, 0x2(%rsi)
movb $0xa, 0xa(%rsi)
leaq -0x40(%rbp), %rdi
pushq $0xb
popq %rdx
leaq -0x80(%rbp), %rcx
callq 0x409c64
andl $0x80000001, %r14d      # imm = 0x80000001
cmpl $0x1, %r14d
jne 0x40978c
leaq -0x60(%rbp), %rsi
movb $0xa, (%rsi)
leaq -0x40(%rbp), %rdi
callq 0x409faa
leaq -0x40(%rbp), %rdi
movl -0x84(%rbp), %esi
callq 0x409ba9
leaq -0x60(%rbp), %rsi
movb $0x63, (%rsi)
leaq -0x40(%rbp), %rdi
callq 0x409faa
leaq -0x40(%rbp), %rdi
movl %r13d, %esi
callq 0x409ba9
leaq -0x60(%rbp), %rsi
movb $0x63, (%rsi)
leaq -0x40(%rbp), %rdi
callq 0x409faa
leaq -0x40(%rbp), %rdi
movl -0x68(%rbp), %esi
callq 0x409ba9
leaq -0x60(%rbp), %rdx
movb $-0x1, (%rdx)
leaq -0x40(%rbp), %rdi
pushq $0x1a
popq %rsi
callq 0x409e1c
xorl %r14d, %r14d
movq -0x40(%rbp), %rax
movq -0x38(%rbp), %rcx
subq %rax, %rcx
cmpq %r14, %rcx
jbe 0x409815
movq (%rbx), %rdi
movzbl (%rax,%r14), %edx
leal (%r12,%r14), %esi
addl $0x349a1, %esi          # imm = 0x349A1
callq 0x404a00
incq %r14
jmp 0x4097e9
leaq -0x40(%rbp), %rdi
callq 0x404baa
movl -0x64(%rbp), %edi
callq 0x409b84
movl %eax, %r15d
leal 0x5(%r15), %eax
leal 0x6(%r15), %ecx
testb $0x1, %al
movzbl %al, %eax
movzbl %cl, %ecx
cmovel %eax, %ecx
shrb %cl
movb $0x10, %al
subb %cl, %al
orb $0x20, %al
leaq -0x60(%rbp), %rsi
movb $0x22, (%rsi)
movb %al, 0x1(%rsi)
movl $0x14142212, 0x2(%rsi)  # imm = 0x14142212
movw $0xa13, 0x6(%rsi)       # imm = 0xA13
leaq -0x40(%rbp), %rdi
pushq $0x8
popq %rdx
leaq -0x80(%rbp), %rcx
callq 0x409c64
testb $0x1, %r15b
jne 0x409881
leaq -0x60(%rbp), %rsi
movb $0xa, (%rsi)
leaq -0x40(%rbp), %rdi
callq 0x409faa
leaq -0x40(%rbp), %rdi
movl -0x64(%rbp), %esi
callq 0x409ba9
leaq -0x60(%rbp), %rdx
movb $-0x1, (%rdx)
leaq -0x40(%rbp), %rdi
pushq $0x15
popq %rsi
callq 0x409e1c
addl %r12d, %r14d
addl $0x349a1, %r14d         # imm = 0x349A1
xorl %r15d, %r15d
movq -0x40(%rbp), %rax
movq -0x38(%rbp), %rcx
subq %rax, %rcx
cmpq %r15, %rcx
jbe 0x4098d5
movq (%rbx), %rdi
movzbl (%rax,%r15), %edx
movl %r14d, %esi
callq 0x404a00
incq %r15
incl %r14d
jmp 0x4098ad
leaq -0x40(%rbp), %rdi
callq 0x404baa
leaq -0x60(%rbp), %rsi
movw $0x6522, (%rsi)         # imm = 0x6522
movb $0xf, 0x2(%rsi)
leaq -0x40(%rbp), %rdi
pushq $0x3
popq %rdx
leaq -0x80(%rbp), %rcx
callq 0x409c64
leaq -0x60(%rbp), %rdx
movb $-0x1, (%rdx)
leaq -0x40(%rbp), %rdi
pushq $0x12
popq %rsi
callq 0x409e1c
xorl %r15d, %r15d
movq -0x40(%rbp), %rax
movq -0x38(%rbp), %rcx
subq %rax, %rcx
cmpq %r15, %rcx
jbe 0x409939
movq (%rbx), %rdi
movzbl (%rax,%r15), %edx
movl %r14d, %esi
callq 0x404a00
incq %r15
incl %r14d
jmp 0x409911
leaq -0x80(%rbp), %rsi
movw $0xa222, (%rsi)         # imm = 0xA222
movb $0x1d, 0x2(%rsi)
leaq -0x60(%rbp), %rdi
pushq $0x3
popq %rdx
leaq -0xa0(%rbp), %rcx
callq 0x409c64
leaq -0x80(%rbp), %rdx
movb $-0x1, (%rdx)
leaq -0x60(%rbp), %rdi
pushq $0x20
popq %rsi
callq 0x409e1c
xorl %r15d, %r15d
movq -0x60(%rbp), %rax
movq -0x58(%rbp), %rcx
subq %rax, %rcx
cmpq %r15, %rcx
jbe 0x409997
movq (%rbx), %rdi
movzbl (%rax,%r15), %edx
movl %r14d, %esi
callq 0x404a00
incq %r15
incl %r14d
jmp 0x40996f
leaq -0xa0(%rbp), %rsi
movw $0xe622, (%rsi)         # imm = 0xE622
movb $0x13, 0x2(%rsi)
leaq -0x80(%rbp), %rdi
pushq $0x3
popq %rdx
leaq -0x44(%rbp), %rcx
callq 0x409c64
leaq -0xa0(%rbp), %rdx
movb $-0x1, (%rdx)
leaq -0x80(%rbp), %rdi
pushq $0x16
popq %rsi
callq 0x409e1c
xorl %r15d, %r15d
movq -0x80(%rbp), %rax
movq -0x78(%rbp), %rcx
subq %rax, %rcx
cmpq %r15, %rcx
jbe 0x4099f8
movq (%rbx), %rdi
movzbl (%rax,%r15), %edx
movl %r14d, %esi
callq 0x404a00
incq %r15
incl %r14d
jmp 0x4099d0
leaq -0x44(%rbp), %rsi
movw $0x2923, (%rsi)         # imm = 0x2923
movb $0xb, 0x2(%rsi)
leaq -0xa0(%rbp), %rdi
pushq $0x3
popq %rdx
leaq -0x41(%rbp), %rcx
callq 0x409c64
leaq -0x44(%rbp), %rdx
movb $-0x1, (%rdx)
leaq -0xa0(%rbp), %rdi
pushq $0xe
popq %rsi
callq 0x409e1c
xorl %r15d, %r15d
movq -0xa0(%rbp), %rax
movq -0x98(%rbp), %rcx
subq %rax, %rcx
cmpq %r15, %rcx
jbe 0x409a5f
movq (%rbx), %rdi
movzbl (%rax,%r15), %edx
movl %r14d, %esi
callq 0x404a00
incq %r15
incl %r14d
jmp 0x409a31
leaq -0xa0(%rbp), %rdi
callq 0x404baa
leaq -0x80(%rbp), %rdi
callq 0x404baa
leaq -0x60(%rbp), %r15
movq %r15, %rdi
callq 0x404baa
leaq -0x40(%rbp), %rdi
callq 0x404baa
movups 0x181aaa(%rip), %xmm0   # 0x58b53a
movaps %xmm0, (%r15)
movabsq $0x1e1b18231e1b1817, %rax # imm = 0x1E1B18231E1B1817
movq %rax, 0xf(%r15)
leaq -0x40(%rbp), %rdi
leaq -0x60(%rbp), %rsi
pushq $0x17
popq %rdx
leaq -0x80(%rbp), %rcx
callq 0x409c64
leaq -0x60(%rbp), %rdx
movb $-0x1, (%rdx)
leaq -0x40(%rbp), %rdi
pushq $0x1b
popq %rsi
callq 0x409e1c
xorl %r15d, %r15d
movq -0x40(%rbp), %rax
movq -0x38(%rbp), %rcx
subq %rax, %rcx
cmpq %r15, %rcx
jbe 0x409af4
movq (%rbx), %rdi
movzbl (%rax,%r15), %edx
movl %r14d, %esi
callq 0x404a00
incq %r15
incl %r14d
jmp 0x409acc
leaq -0x40(%rbp), %rdi
callq 0x404baa
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x409b70
jmp 0x409b70
jmp 0x409b70
jmp 0x409b34
jmp 0x409b3d
jmp 0x409b4e
jmp 0x409b4e
jmp 0x409b5c
jmp 0x409b5c
jmp 0x409b70
jmp 0x409b70
jmp 0x409b34
jmp 0x409b70
jmp 0x409b70
jmp 0x409b34
jmp 0x409b70
jmp 0x409b70
jmp 0x409b70
jmp 0x409b34
jmp 0x409b70
movq %rax, %rbx
jmp 0x409b7c
jmp 0x409b70
jmp 0x409b70
movq %rax, %rbx
leaq -0xa0(%rbp), %rdi
callq 0x404baa
jmp 0x409b51
movq %rax, %rbx
leaq -0x80(%rbp), %rdi
callq 0x404baa
jmp 0x409b5f
movq %rax, %rbx
leaq -0x60(%rbp), %rdi
callq 0x404baa
jmp 0x409b73
jmp 0x409b70
jmp 0x409b70
jmp 0x409b70
movq %rax, %rbx
leaq -0x40(%rbp), %rdi
callq 0x404baa
movq %rbx, %rdi
callq 0x4ba600