// File: /workspace/github_cpp_makefile_star2_O3/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, -0x68(%rbp)
movl %ecx, -0x6c(%rbp)
movl %edx, %r12d
movl %esi, %r13d
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
leaq -0x88(%rbp), %rcx
movl $0xd, %edx
callq 0x40a9ca
leaq -0x60(%rbp), %rdx
movb $-0x1, (%rdx)
leaq -0x40(%rbp), %rdi
movl $0xf, %esi
callq 0x40ac06
movq -0x40(%rbp), %rdi
cmpq %rdi, -0x38(%rbp)
je 0x40a297
xorl %r14d, %r14d
leal 0x349a1(%r14), %esi
movq (%rbx), %rax
movzbl (%rdi,%r14), %edx
movq %rax, %rdi
callq 0x404a24
incq %r14
movq -0x40(%rbp), %rdi
movq -0x38(%rbp), %rax
subq %rdi, %rax
cmpq %r14, %rax
ja 0x40a264
addl $0x349a1, %r14d         # imm = 0x349A1
jmp 0x40a29d
movl $0x349a1, %r14d         # imm = 0x349A1
testq %rdi, %rdi
je 0x40a2a7
callq 0x410b90
movl $0x1, %r15d
movl $0x1, %eax
testl %r13d, %r13d
je 0x40a2dd
xorl %eax, %eax
movl %r13d, %ecx
movslq %ecx, %rdx
imulq $0x66666667, %rdx, %rcx # imm = 0x66666667
movq %rcx, %rsi
shrq $0x3f, %rsi
sarq $0x22, %rcx
addl %esi, %ecx
incl %eax
addl $0x9, %edx
cmpl $0x12, %edx
ja 0x40a2bc
testl %r12d, %r12d
movl -0x6c(%rbp), %edi
je 0x40a30d
xorl %r15d, %r15d
movl %r12d, %ecx
movslq %ecx, %rdx
imulq $0x66666667, %rdx, %rcx # imm = 0x66666667
movq %rcx, %rsi
shrq $0x3f, %rsi
sarq $0x22, %rcx
addl %esi, %ecx
incl %r15d
addl $0x9, %edx
cmpl $0x12, %edx
ja 0x40a2eb
addl %eax, %r15d
testl %edi, %edi
je 0x40a33b
xorl %eax, %eax
movl %edi, %ecx
movslq %ecx, %rdx
imulq $0x66666667, %rdx, %rcx # imm = 0x66666667
movq %rcx, %rsi
shrq $0x3f, %rsi
sarq $0x22, %rcx
addl %esi, %ecx
incl %eax
addl $0x9, %edx
cmpl $0x12, %edx
ja 0x40a318
jmp 0x40a340
movl $0x1, %eax
addl %eax, %r15d
movl %r15d, %eax
andl $0x1, %eax
addl %r15d, %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
leaq -0x88(%rbp), %rcx
movl $0xb, %edx
callq 0x40a9ca
andl $0x80000001, %r15d      # imm = 0x80000001
cmpl $0x1, %r15d
jne 0x40a3b9
movb $0xa, -0x60(%rbp)
movq -0x38(%rbp), %rsi
cmpq -0x30(%rbp), %rsi
je 0x40a3ac
movb $0xa, (%rsi)
incq -0x38(%rbp)
jmp 0x40a3b9
leaq -0x40(%rbp), %rdi
leaq -0x60(%rbp), %rdx
callq 0x40ad1c
leaq -0x40(%rbp), %rdi
movl %r13d, %esi
callq 0x40a8c3
movb $0x63, -0x60(%rbp)
movq -0x38(%rbp), %rsi
cmpq -0x30(%rbp), %rsi
je 0x40a3dc
movb $0x63, (%rsi)
incq -0x38(%rbp)
jmp 0x40a3e9
leaq -0x40(%rbp), %rdi
leaq -0x60(%rbp), %rdx
callq 0x40ad1c
leaq -0x40(%rbp), %rdi
movl %r12d, %esi
callq 0x40a8c3
movb $0x63, -0x60(%rbp)
movq -0x38(%rbp), %rsi
cmpq -0x30(%rbp), %rsi
je 0x40a40c
movb $0x63, (%rsi)
incq -0x38(%rbp)
jmp 0x40a419
leaq -0x40(%rbp), %rdi
leaq -0x60(%rbp), %rdx
callq 0x40ad1c
leaq -0x40(%rbp), %rdi
movl -0x6c(%rbp), %esi
callq 0x40a8c3
leaq -0x60(%rbp), %rdx
movb $-0x1, (%rdx)
leaq -0x40(%rbp), %rdi
movl $0x1a, %esi
callq 0x40ac06
movq -0x40(%rbp), %rdi
cmpq %rdi, -0x38(%rbp)
je 0x40a474
movl %r14d, %r12d
xorl %r15d, %r15d
leal (%r12,%r15), %esi
movq (%rbx), %rax
movzbl (%rdi,%r15), %edx
movq %rax, %rdi
callq 0x404a24
incq %r15
movq -0x40(%rbp), %rdi
movq -0x38(%rbp), %rax
subq %rdi, %rax
cmpq %r15, %rax
ja 0x40a44a
addl %r15d, %r14d
testq %rdi, %rdi
je 0x40a47e
callq 0x410b90
movl -0x68(%rbp), %eax
testl %eax, %eax
je 0x40a4ac
xorl %r15d, %r15d
movslq %eax, %rcx
imulq $0x66666667, %rcx, %rax # imm = 0x66666667
movq %rax, %rdx
shrq $0x3f, %rdx
sarq $0x22, %rax
addl %edx, %eax
incl %r15d
addl $0x9, %ecx
cmpl $0x12, %ecx
ja 0x40a488
jmp 0x40a4b2
movl $0x1, %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
leaq -0x88(%rbp), %rcx
movl $0x8, %edx
callq 0x40a9ca
testb $0x1, %r15b
jne 0x40a523
movb $0xa, -0x60(%rbp)
movq -0x38(%rbp), %rsi
cmpq -0x30(%rbp), %rsi
je 0x40a516
movb $0xa, (%rsi)
incq -0x38(%rbp)
jmp 0x40a523
leaq -0x40(%rbp), %rdi
leaq -0x60(%rbp), %rdx
callq 0x40ad1c
leaq -0x40(%rbp), %rdi
movl -0x68(%rbp), %esi
callq 0x40a8c3
leaq -0x60(%rbp), %rdx
movb $-0x1, (%rdx)
leaq -0x40(%rbp), %rdi
movl $0x15, %esi
callq 0x40ac06
movq -0x40(%rbp), %rdi
cmpq %rdi, -0x38(%rbp)
je 0x40a57e
movl %r14d, %r12d
xorl %r15d, %r15d
leal (%r12,%r15), %esi
movq (%rbx), %rax
movzbl (%rdi,%r15), %edx
movq %rax, %rdi
callq 0x404a24
incq %r15
movq -0x40(%rbp), %rdi
movq -0x38(%rbp), %rax
subq %rdi, %rax
cmpq %r15, %rax
ja 0x40a554
addl %r15d, %r14d
testq %rdi, %rdi
je 0x40a588
callq 0x410b90
leaq -0x60(%rbp), %rsi
movw $0x6522, (%rsi)         # imm = 0x6522
movb $0xf, 0x2(%rsi)
leaq -0x40(%rbp), %rdi
leaq -0x88(%rbp), %rcx
movl $0x3, %edx
callq 0x40a9ca
leaq -0x60(%rbp), %rdx
movb $-0x1, (%rdx)
leaq -0x40(%rbp), %rdi
movl $0x12, %esi
callq 0x40ac06
movq -0x40(%rbp), %rax
cmpq %rax, -0x38(%rbp)
je 0x40a5f6
movl %r14d, %r12d
xorl %r15d, %r15d
leal (%r12,%r15), %esi
movq (%rbx), %rdi
movzbl (%rax,%r15), %edx
callq 0x404a24
incq %r15
movq -0x40(%rbp), %rax
movq -0x38(%rbp), %rcx
subq %rax, %rcx
cmpq %r15, %rcx
ja 0x40a5cf
addl %r15d, %r14d
leaq -0x88(%rbp), %rsi
movw $0xa222, (%rsi)         # imm = 0xA222
movb $0x1d, 0x2(%rsi)
leaq -0x60(%rbp), %rdi
leaq -0xa0(%rbp), %rcx
movl $0x3, %edx
callq 0x40a9ca
leaq -0x88(%rbp), %rdx
movb $-0x1, (%rdx)
leaq -0x60(%rbp), %rdi
movl $0x20, %esi
callq 0x40ac06
movq -0x60(%rbp), %rax
cmpq %rax, -0x58(%rbp)
je 0x40a66a
movl %r14d, %r12d
xorl %r15d, %r15d
leal (%r12,%r15), %esi
movq (%rbx), %rdi
movzbl (%rax,%r15), %edx
callq 0x404a24
incq %r15
movq -0x60(%rbp), %rax
movq -0x58(%rbp), %rcx
subq %rax, %rcx
cmpq %r15, %rcx
ja 0x40a643
addl %r15d, %r14d
leaq -0xa0(%rbp), %rsi
movw $0xe622, (%rsi)         # imm = 0xE622
movb $0x13, 0x2(%rsi)
leaq -0x88(%rbp), %rdi
leaq -0x64(%rbp), %rcx
movl $0x3, %edx
callq 0x40a9ca
leaq -0xa0(%rbp), %rdx
movb $-0x1, (%rdx)
leaq -0x88(%rbp), %rdi
movl $0x16, %esi
callq 0x40ac06
movq -0x88(%rbp), %rax
cmpq %rax, -0x80(%rbp)
je 0x40a6e7
movl %r14d, %r12d
xorl %r15d, %r15d
leal (%r12,%r15), %esi
movq (%rbx), %rdi
movzbl (%rax,%r15), %edx
callq 0x404a24
incq %r15
movq -0x88(%rbp), %rax
movq -0x80(%rbp), %rcx
subq %rax, %rcx
cmpq %r15, %rcx
ja 0x40a6bd
addl %r15d, %r14d
leaq -0x64(%rbp), %rsi
movw $0x2923, (%rsi)         # imm = 0x2923
movb $0xb, 0x2(%rsi)
leaq -0xa0(%rbp), %rdi
leaq -0x61(%rbp), %rcx
movl $0x3, %edx
callq 0x40a9ca
leaq -0x64(%rbp), %rdx
movb $-0x1, (%rdx)
leaq -0xa0(%rbp), %rdi
movl $0xe, %esi
callq 0x40ac06
movq -0xa0(%rbp), %rdi
cmpq %rdi, -0x98(%rbp)
je 0x40a767
movl %r14d, %r12d
xorl %r15d, %r15d
leal (%r12,%r15), %esi
movq (%rbx), %rax
movzbl (%rdi,%r15), %edx
movq %rax, %rdi
callq 0x404a24
incq %r15
movq -0xa0(%rbp), %rdi
movq -0x98(%rbp), %rax
subq %rdi, %rax
cmpq %r15, %rax
ja 0x40a737
addl %r15d, %r14d
testq %rdi, %rdi
je 0x40a771
callq 0x410b90
movq -0x88(%rbp), %rdi
testq %rdi, %rdi
je 0x40a782
callq 0x410b90
movq -0x60(%rbp), %rdi
testq %rdi, %rdi
je 0x40a790
callq 0x410b90
movq -0x40(%rbp), %rdi
testq %rdi, %rdi
je 0x40a79e
callq 0x410b90
movups 0x181d95(%rip), %xmm0   # 0x58c53a
leaq -0x60(%rbp), %rsi
movaps %xmm0, (%rsi)
movabsq $0x1e1b18231e1b1817, %rax # imm = 0x1E1B18231E1B1817
movq %rax, 0xf(%rsi)
leaq -0x40(%rbp), %rdi
leaq -0x88(%rbp), %rcx
movl $0x17, %edx
callq 0x40a9ca
leaq -0x60(%rbp), %rdx
movb $-0x1, (%rdx)
leaq -0x40(%rbp), %rdi
movl $0x1b, %esi
callq 0x40ac06
movq -0x40(%rbp), %rdi
cmpq %rdi, -0x38(%rbp)
je 0x40a81b
movl %r14d, %r14d
xorl %r15d, %r15d
leal (%r14,%r15), %esi
movq (%rbx), %rax
movzbl (%rdi,%r15), %edx
movq %rax, %rdi
callq 0x404a24
incq %r15
movq -0x40(%rbp), %rdi
movq -0x38(%rbp), %rax
subq %rdi, %rax
cmpq %r15, %rax
ja 0x40a7f4
testq %rdi, %rdi
je 0x40a825
callq 0x410b90
addq $0x78, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
jmp 0x40a8aa
jmp 0x40a8aa
jmp 0x40a8aa
jmp 0x40a8aa
jmp 0x40a8aa
jmp 0x40a85c
jmp 0x40a865
jmp 0x40a87b
jmp 0x40a87b
jmp 0x40a891
jmp 0x40a891
jmp 0x40a8aa
jmp 0x40a8aa
jmp 0x40a85c
jmp 0x40a8aa
jmp 0x40a8aa
jmp 0x40a85c
jmp 0x40a8aa
jmp 0x40a85c
jmp 0x40a8aa
movq %rax, %rbx
jmp 0x40a8bb
jmp 0x40a8aa
jmp 0x40a8aa
movq %rax, %rbx
movq -0xa0(%rbp), %rdi
testq %rdi, %rdi
je 0x40a87e
callq 0x410b90
jmp 0x40a87e
movq %rax, %rbx
movq -0x88(%rbp), %rdi
testq %rdi, %rdi
je 0x40a894
callq 0x410b90
jmp 0x40a894
movq %rax, %rbx
movq -0x60(%rbp), %rdi
testq %rdi, %rdi
je 0x40a8ad
callq 0x410b90
jmp 0x40a8ad
jmp 0x40a8aa
jmp 0x40a8aa
jmp 0x40a8aa
movq %rax, %rbx
movq -0x40(%rbp), %rdi
testq %rdi, %rdi
je 0x40a8bb
callq 0x410b90
movq %rbx, %rdi
callq 0x4bb660