// File: /workspace/github_cpp_makefile_star2_O1/Thilotilo[P]DoaERando/main.cpp
// Function: main
int main(void)
{
    ROM rom;
    rom.ReadRom("./SourceRom/Destiny_of_an_Emperor_USA.nes");
    ifstream fin("./config/seed.cfg");
    uint64_t seed;
    fin >> seed;
    ifstream modeFile("./config/newShuffle");
    bool useNewShuffle = modeFile.good();
    Randomizer randomizer(&rom, seed);

    for (uint8_t i=0; i<0xD9; ++i)
    {
        printf("General 0x%0x is ", i);
        randomizer.PrintName(i);
        printf("\n");
    }

    // This is a non-negotiable - it changes no behavior, but enables other features.
    randomizer.ImproveInitialBattlesAndFlags();
    randomizer.FixNMIGlitch();

    // Optional items
    randomizer.ImproveMap();

    // Need to do this before randomizing the starting generals
    randomizer.MakeAllGeneralsRecruitableAndEncounterable();

    // Need to do this before altering location-exit behavior
    randomizer.RemoveFinalIntroScreen();

    // Non-random fix, but needs to come before
    // ReturnToEntryDirectionOnFlagClear
    randomizer.DisableChapter1LockForSiShui();
    // Randomized features
    if (useNewShuffle)
    {
        printf("Using new shuffle algorithm...\n");
        randomizer.RemoveUneededEntranceTriggerCode();
        randomizer.ReconfigureQingZhouCave();
        randomizer.ReconfigureLiuKuiTentGeneral();
        randomizer.NewGeneralAndBattleShuffle();
        randomizer.MakeZhangBaoAndGuanXingAvailable();
        randomizer.MakeZone0GeneralsUnfirable();
        randomizer.UpdateLiuBeiTurnInTrigger();
        randomizer.ReturnToEntryDirectionOnFlagClear();
        randomizer.MakeAllGeneralsBilletable();
        randomizer.MakeWarlordsImmuneToAnSha();
    }
    else
    {
        printf("Using old shuffle algorithm...\n");
        randomizer.RandomizeStartingGenerals();
        randomizer.RandomizeGenerals();
        randomizer.RandomizeBattles();
    }

    randomizer.RandomizeTacticLevels();

    randomizer.ItemShuffle();
    randomizer.CaveShuffle();

    // QoL and other non-random features
    randomizer.IncreaseTacticGains();
    randomizer.MakeIronOreUseful();
    randomizer.MoveGemswordToSimaHuisHut();
    randomizer.MakeIntroLetterUseful();
    randomizer.LetWangGuiTravelToYangZhou();
    randomizer.DoubleXpGain();
    randomizer.DisableNonGeneralBattles();
    randomizer.ResurrectAllAfterDeath();
    randomizer.GivePartyMaxFoodFromNPC();
    randomizer.ModifyEncounterRate();
    randomizer.FixSlot7Glitch();
    randomizer.OnlyLaunchShuLuBuOnce();
    randomizer.RemoveZhugeLiangFetchQuest();
    randomizer.MoveGuiYangBattle();
    randomizer.ProtectChapter1Generals();
    randomizer.UpdateGeneralNames();

    randomizer.RewriteTitleScreen(MAJOR_RELEASE, MINOR_RELEASE, PATCH, seed);
    printf("Saving file...\n");
    rom.WriteRom("./RandoRoms/", MAJOR_RELEASE, MINOR_RELEASE, PATCH, seed);

    return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0xeb0, %rsp            # imm = 0xEB0
xorps %xmm0, %xmm0
movaps %xmm0, -0x40(%rbp)
movq $0x0, -0x30(%rbp)
leaq -0x70(%rbp), %r14
movq %r14, -0x10(%r14)
leaq 0x180fc5(%rip), %rsi    # 0x58c551
leaq 0x180fe7(%rip), %rdx    # 0x58c57a
leaq -0x80(%rbp), %rdi
callq 0x40ba00
leaq -0x40(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x404648
movq -0x80(%rbp), %rdi
cmpq %r14, %rdi
je 0x40b5b7
callq 0x410b90
leaq 0x180fbd(%rip), %rsi    # 0x58c57b
leaq -0xed0(%rbp), %rdi
movl $0x8, %edx
callq 0x456e50
leaq -0xed0(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x460820
leaq 0x180fa7(%rip), %rsi    # 0x58c58d
leaq -0xcc8(%rbp), %rdi
movl $0x8, %edx
callq 0x456e50
movq -0xcc8(%rbp), %rax
movq -0x18(%rax), %rax
movl -0xca8(%rbp,%rax), %r12d
movl -0x28(%rbp), %edx
leaq -0xac0(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x404dc4
leaq 0x180f7d(%rip), %rbx    # 0x58c5a1
leaq -0xac0(%rbp), %r14
xorl %r15d, %r15d
movq %rbx, %rdi
movl %r15d, %esi
xorl %eax, %eax
callq 0x4e21a0
movzbl %r15b, %esi
movq %r14, %rdi
callq 0x404e72
movl $0xa, %edi
callq 0x4e9e00
incl %r15d
cmpl $0xd9, %r15d
jne 0x40b62e
leaq -0xac0(%rbp), %rdi
callq 0x406858
leaq -0xac0(%rbp), %rdi
callq 0x4060f4
leaq -0xac0(%rbp), %rdi
callq 0x4069a6
leaq -0xac0(%rbp), %rdi
callq 0x406480
leaq -0xac0(%rbp), %rdi
callq 0x40780e
leaq -0xac0(%rbp), %rdi
callq 0x4062b8
testl %r12d, %r12d
je 0x40b6df
leaq 0x180f39(%rip), %rdi    # 0x58c5ea
callq 0x4e96e0
leaq -0xac0(%rbp), %rdi
callq 0x404efe
leaq -0xac0(%rbp), %rdi
callq 0x4065ca
leaq -0xac0(%rbp), %rdi
callq 0x4067b4
jmp 0x40b763
leaq 0x180f23(%rip), %rdi    # 0x58c609
callq 0x4e96e0
leaq -0xac0(%rbp), %rdi
callq 0x406fac
leaq -0xac0(%rbp), %rdi
callq 0x406d24
leaq -0xac0(%rbp), %rdi
callq 0x406e28
leaq -0xac0(%rbp), %rdi
callq 0x408b44
leaq -0xac0(%rbp), %rdi
callq 0x40633a
leaq -0xac0(%rbp), %rdi
callq 0x406ee4
leaq -0xac0(%rbp), %rdi
callq 0x407024
leaq -0xac0(%rbp), %rdi
callq 0x407886
leaq -0xac0(%rbp), %rdi
callq 0x407aa0
leaq -0xac0(%rbp), %rdi
callq 0x407ace
leaq -0xac0(%rbp), %rdi
callq 0x4064ca
leaq -0xac0(%rbp), %rdi
callq 0x405b3a
leaq -0xac0(%rbp), %rdi
callq 0x4050cc
leaq -0xac0(%rbp), %rdi
callq 0x40639c
leaq -0xac0(%rbp), %rdi
callq 0x40706a
leaq -0xac0(%rbp), %rdi
callq 0x407314
leaq -0xac0(%rbp), %rdi
callq 0x40737e
leaq -0xac0(%rbp), %rdi
callq 0x407688
leaq -0xac0(%rbp), %rdi
callq 0x406444
leaq -0xac0(%rbp), %rdi
callq 0x40636e
leaq -0xac0(%rbp), %rdi
callq 0x406192
leaq -0xac0(%rbp), %rdi
callq 0x406218
leaq -0xac0(%rbp), %rdi
callq 0x40626a
leaq -0xac0(%rbp), %rdi
callq 0x4060dc
leaq -0xac0(%rbp), %rdi
callq 0x4061d2
leaq -0xac0(%rbp), %rdi
callq 0x406306
leaq -0xac0(%rbp), %rdi
callq 0x406c1a
leaq -0xac0(%rbp), %rdi
callq 0x407a2a
leaq -0xac0(%rbp), %rdi
callq 0x407b38
movl -0x28(%rbp), %r8d
leaq -0xac0(%rbp), %rdi
movl $0x1, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x40a1e4
leaq 0x180dc1(%rip), %rdi    # 0x58c628
callq 0x4e96e0
leaq -0x50(%rbp), %r14
movq %r14, -0x10(%r14)
leaq 0x180d38(%rip), %rsi    # 0x58c5b3
leaq 0x180d3d(%rip), %rdx    # 0x58c5bf
leaq -0x60(%rbp), %rdi
callq 0x40ba00
movl -0x28(%rbp), %r9d
leaq -0x40(%rbp), %rdi
leaq -0x60(%rbp), %rsi
movl $0x1, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x404738
movq -0x60(%rbp), %rdi
cmpq %r14, %rdi
je 0x40b8b4
callq 0x410b90
movq -0xa0(%rbp), %rdi
testq %rdi, %rdi
je 0x40b8c5
callq 0x410b90
movq -0xc0(%rbp), %rdi
testq %rdi, %rdi
je 0x40b8d6
callq 0x410b90
movq -0xd8(%rbp), %rdi
testq %rdi, %rdi
je 0x40b8e7
callq 0x410b90
movq -0xf0(%rbp), %rdi
testq %rdi, %rdi
je 0x40b8f8
callq 0x410b90
leaq -0xcc8(%rbp), %rdi
callq 0x4577b0
leaq -0xed0(%rbp), %rdi
callq 0x4577b0
movq -0x40(%rbp), %rdi
testq %rdi, %rdi
je 0x40b91e
callq 0x410b90
xorl %eax, %eax
addq $0xeb0, %rsp            # imm = 0xEB0
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq
movq %rax, %rbx
movq -0x60(%rbp), %rdi
cmpq %r14, %rdi
je 0x40b970
callq 0x410b90
jmp 0x40b970
jmp 0x40b96d
movq %rax, %rbx
jmp 0x40b97c
jmp 0x40b94c
movq %rax, %rbx
jmp 0x40b988
jmp 0x40b966
movq %rax, %rbx
movq -0x80(%rbp), %rdi
cmpq %r14, %rdi
je 0x40b994
callq 0x410b90
jmp 0x40b994
movq %rax, %rbx
jmp 0x40b994
jmp 0x40b96d
movq %rax, %rbx
leaq -0xac0(%rbp), %rdi
callq 0x40b9aa
leaq -0xcc8(%rbp), %rdi
callq 0x4577b0
leaq -0xed0(%rbp), %rdi
callq 0x4577b0
movq -0x40(%rbp), %rdi
testq %rdi, %rdi
je 0x40b9a2
callq 0x410b90
movq %rbx, %rdi
callq 0x4bb660