// File: /workspace/github_cpp_makefile_star2_O3/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 0x180f8d(%rip), %rsi    # 0x58c551
leaq 0x180faf(%rip), %rdx    # 0x58c57a
leaq -0x80(%rbp), %rdi
callq 0x40ba38
leaq -0x40(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0x404648
movq -0x80(%rbp), %rdi
cmpq %r14, %rdi
je 0x40b5ef
callq 0x410b90
leaq 0x180f85(%rip), %rsi    # 0x58c57b
leaq -0xed0(%rbp), %rdi
movl $0x8, %edx
callq 0x456e50
leaq -0xed0(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x460820
leaq 0x180f6f(%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 0x404dd4
leaq 0x180f45(%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 0x404e82
movl $0xa, %edi
callq 0x4e9e00
incl %r15d
cmpl $0xd9, %r15d
jne 0x40b666
leaq -0xac0(%rbp), %rdi
callq 0x40680a
leaq -0xac0(%rbp), %rdi
callq 0x4060a6
leaq -0xac0(%rbp), %rdi
callq 0x406958
leaq -0xac0(%rbp), %rdi
callq 0x406432
leaq -0xac0(%rbp), %rdi
callq 0x4077c0
leaq -0xac0(%rbp), %rdi
callq 0x40626a
testl %r12d, %r12d
je 0x40b717
leaq 0x180f01(%rip), %rdi    # 0x58c5ea
callq 0x4e96e0
leaq -0xac0(%rbp), %rdi
callq 0x404f0e
leaq -0xac0(%rbp), %rdi
callq 0x40657c
leaq -0xac0(%rbp), %rdi
callq 0x406766
jmp 0x40b79b
leaq 0x180eeb(%rip), %rdi    # 0x58c609
callq 0x4e96e0
leaq -0xac0(%rbp), %rdi
callq 0x406f48
leaq -0xac0(%rbp), %rdi
callq 0x406cc0
leaq -0xac0(%rbp), %rdi
callq 0x406dc4
leaq -0xac0(%rbp), %rdi
callq 0x408b02
leaq -0xac0(%rbp), %rdi
callq 0x4062ec
leaq -0xac0(%rbp), %rdi
callq 0x406e80
leaq -0xac0(%rbp), %rdi
callq 0x406fc0
leaq -0xac0(%rbp), %rdi
callq 0x407838
leaq -0xac0(%rbp), %rdi
callq 0x407a5e
leaq -0xac0(%rbp), %rdi
callq 0x407a8c
leaq -0xac0(%rbp), %rdi
callq 0x40647c
leaq -0xac0(%rbp), %rdi
callq 0x405afc
leaq -0xac0(%rbp), %rdi
callq 0x4050da
leaq -0xac0(%rbp), %rdi
callq 0x40634e
leaq -0xac0(%rbp), %rdi
callq 0x407006
leaq -0xac0(%rbp), %rdi
callq 0x4072bc
leaq -0xac0(%rbp), %rdi
callq 0x407326
leaq -0xac0(%rbp), %rdi
callq 0x40763a
leaq -0xac0(%rbp), %rdi
callq 0x4063f6
leaq -0xac0(%rbp), %rdi
callq 0x406320
leaq -0xac0(%rbp), %rdi
callq 0x406144
leaq -0xac0(%rbp), %rdi
callq 0x4061ca
leaq -0xac0(%rbp), %rdi
callq 0x40621c
leaq -0xac0(%rbp), %rdi
callq 0x40608e
leaq -0xac0(%rbp), %rdi
callq 0x406184
leaq -0xac0(%rbp), %rdi
callq 0x4062b8
leaq -0xac0(%rbp), %rdi
callq 0x406bcc
leaq -0xac0(%rbp), %rdi
callq 0x4079e8
leaq -0xac0(%rbp), %rdi
callq 0x407af6
movl -0x28(%rbp), %r8d
leaq -0xac0(%rbp), %rdi
movl $0x1, %esi
xorl %edx, %edx
xorl %ecx, %ecx
callq 0x40a1f0
leaq 0x180d89(%rip), %rdi    # 0x58c628
callq 0x4e96e0
leaq -0x50(%rbp), %r14
movq %r14, -0x10(%r14)
leaq 0x180d00(%rip), %rsi    # 0x58c5b3
leaq 0x180d05(%rip), %rdx    # 0x58c5bf
leaq -0x60(%rbp), %rdi
callq 0x40ba38
movl -0x28(%rbp), %r9d
leaq -0x40(%rbp), %rdi
leaq -0x60(%rbp), %rsi
movl $0x1, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
callq 0x404734
movq -0x60(%rbp), %rdi
cmpq %r14, %rdi
je 0x40b8ec
callq 0x410b90
movq -0xa0(%rbp), %rdi
testq %rdi, %rdi
je 0x40b8fd
callq 0x410b90
movq -0xc0(%rbp), %rdi
testq %rdi, %rdi
je 0x40b90e
callq 0x410b90
movq -0xd8(%rbp), %rdi
testq %rdi, %rdi
je 0x40b91f
callq 0x410b90
movq -0xf0(%rbp), %rdi
testq %rdi, %rdi
je 0x40b930
callq 0x410b90
leaq -0xcc8(%rbp), %rdi
callq 0x4577b0
leaq -0xed0(%rbp), %rdi
callq 0x4577b0
movq -0x40(%rbp), %rdi
testq %rdi, %rdi
je 0x40b956
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 0x40b9a8
callq 0x410b90
jmp 0x40b9a8
jmp 0x40b9a5
movq %rax, %rbx
jmp 0x40b9b4
jmp 0x40b984
movq %rax, %rbx
jmp 0x40b9c0
jmp 0x40b99e
movq %rax, %rbx
movq -0x80(%rbp), %rdi
cmpq %r14, %rdi
je 0x40b9cc
callq 0x410b90
jmp 0x40b9cc
movq %rax, %rbx
jmp 0x40b9cc
jmp 0x40b9a5
movq %rax, %rbx
leaq -0xac0(%rbp), %rdi
callq 0x40b9e2
leaq -0xcc8(%rbp), %rdi
callq 0x4577b0
leaq -0xed0(%rbp), %rdi
callq 0x4577b0
movq -0x40(%rbp), %rdi
testq %rdi, %rdi
je 0x40b9da
callq 0x410b90
movq %rbx, %rdi
callq 0x4bb660