// File: 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
subq $0xf00, %rsp            # imm = 0xF00
movl $0x0, -0x4(%rbp)
leaq -0x20(%rbp), %rdi
callq 0x4145f0
leaq -0x41(%rbp), %rdi
movq %rdi, -0xef0(%rbp)
callq 0x41ffa0
movq -0xef0(%rbp), %rdx
leaq 0x187415(%rip), %rsi    # 0x59b4de
leaq -0x40(%rbp), %rdi
callq 0x49a8d0
jmp 0x4140d4
leaq -0x20(%rbp), %rdi
leaq -0x40(%rbp), %rsi
callq 0x4046d0
jmp 0x4140e3
leaq -0x40(%rbp), %rdi
callq 0x497ea0
leaq -0x41(%rbp), %rdi
callq 0x41ffc0
leaq 0x18740c(%rip), %rsi    # 0x59b508
leaq -0x260(%rbp), %rdi
movl $0x8, %edx
callq 0x464940
jmp 0x41410f
leaq -0x260(%rbp), %rdi
leaq -0x268(%rbp), %rsi
callq 0x46e450
jmp 0x414124
leaq 0x1873ef(%rip), %rsi    # 0x59b51a
leaq -0x470(%rbp), %rdi
movl $0x8, %edx
callq 0x464940
jmp 0x41413e
movq -0x470(%rbp), %rax
movq -0x18(%rax), %rax
leaq -0x470(%rbp,%rax), %rdi
callq 0x468a70
movb %al, -0xef1(%rbp)
jmp 0x41415e
movb -0xef1(%rbp), %al
andb $0x1, %al
movb %al, -0x471(%rbp)
movl -0x268(%rbp), %edx
leaq -0xeb8(%rbp), %rdi
leaq -0x20(%rbp), %rsi
callq 0x405fb0
jmp 0x414184
movb $0x0, -0xeb9(%rbp)
movzbl -0xeb9(%rbp), %eax
cmpl $0xd9, %eax
jge 0x414260
movzbl -0xeb9(%rbp), %esi
leaq 0x187383(%rip), %rdi    # 0x59b52e
xorl %eax, %eax
callq 0x4f06e0
jmp 0x4141b4
movzbl -0xeb9(%rbp), %esi
leaq -0xeb8(%rbp), %rdi
callq 0x4060e0
jmp 0x4141c9
leaq 0x18e89a(%rip), %rdi    # 0x5a2a6a
xorl %eax, %eax
callq 0x4f06e0
jmp 0x4141d9
jmp 0x4141db
movb -0xeb9(%rbp), %al
addb $0x1, %al
movb %al, -0xeb9(%rbp)
jmp 0x41418b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x41420e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0x40(%rbp), %rdi
callq 0x497ea0
leaq -0x41(%rbp), %rdi
callq 0x41ffc0
jmp 0x4145d4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x4145d4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x4145c8
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x4145bc
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x4145b0
leaq -0xeb8(%rbp), %rdi
callq 0x409190
jmp 0x41426e
leaq -0xeb8(%rbp), %rdi
callq 0x4085a0
jmp 0x41427c
leaq -0xeb8(%rbp), %rdi
callq 0x4093d0
jmp 0x41428a
leaq -0xeb8(%rbp), %rdi
callq 0x408b10
jmp 0x414298
leaq -0xeb8(%rbp), %rdi
callq 0x40b120
jmp 0x4142a6
leaq -0xeb8(%rbp), %rdi
callq 0x408870
jmp 0x4142b4
testb $0x1, -0x471(%rbp)
je 0x41435f
leaq 0x187278(%rip), %rdi    # 0x59b540
xorl %eax, %eax
callq 0x4f06e0
jmp 0x4142d1
leaq -0xeb8(%rbp), %rdi
callq 0x409d70
jmp 0x4142df
leaq -0xeb8(%rbp), %rdi
callq 0x4098a0
jmp 0x4142ed
leaq -0xeb8(%rbp), %rdi
callq 0x409a70
jmp 0x4142fb
leaq -0xeb8(%rbp), %rdi
callq 0x40cb00
jmp 0x414309
leaq -0xeb8(%rbp), %rdi
callq 0x408930
jmp 0x414317
leaq -0xeb8(%rbp), %rdi
callq 0x409be0
jmp 0x414325
leaq -0xeb8(%rbp), %rdi
callq 0x409e40
jmp 0x414333
leaq -0xeb8(%rbp), %rdi
callq 0x40b1f0
jmp 0x414341
leaq -0xeb8(%rbp), %rdi
callq 0x40b620
jmp 0x41434f
leaq -0xeb8(%rbp), %rdi
callq 0x40b670
jmp 0x41435d
jmp 0x41439b
leaq 0x1871fa(%rip), %rdi    # 0x59b560
xorl %eax, %eax
callq 0x4f06e0
jmp 0x41436f
leaq -0xeb8(%rbp), %rdi
callq 0x4061c0
jmp 0x41437d
leaq -0xeb8(%rbp), %rdi
callq 0x408cd0
jmp 0x41438b
leaq -0xeb8(%rbp), %rdi
callq 0x409050
jmp 0x414399
jmp 0x41439b
leaq -0xeb8(%rbp), %rdi
callq 0x408b80
jmp 0x4143a9
leaq -0xeb8(%rbp), %rdi
callq 0x407c90
jmp 0x4143b7
leaq -0xeb8(%rbp), %rdi
callq 0x406410
jmp 0x4143c5
leaq -0xeb8(%rbp), %rdi
callq 0x4089c0
jmp 0x4143d3
leaq -0xeb8(%rbp), %rdi
callq 0x409ea0
jmp 0x4143e1
leaq -0xeb8(%rbp), %rdi
callq 0x40a800
jmp 0x4143ef
leaq -0xeb8(%rbp), %rdi
callq 0x40a890
jmp 0x4143fd
leaq -0xeb8(%rbp), %rdi
callq 0x40aec0
jmp 0x41440b
leaq -0xeb8(%rbp), %rdi
callq 0x408a90
jmp 0x414419
leaq -0xeb8(%rbp), %rdi
callq 0x408980
jmp 0x414427
leaq -0xeb8(%rbp), %rdi
callq 0x4086d0
jmp 0x414435
leaq -0xeb8(%rbp), %rdi
callq 0x408790
jmp 0x414443
leaq -0xeb8(%rbp), %rdi
callq 0x408800
jmp 0x414451
leaq -0xeb8(%rbp), %rdi
callq 0x408570
jmp 0x41445f
leaq -0xeb8(%rbp), %rdi
callq 0x408730
jmp 0x41446d
leaq -0xeb8(%rbp), %rdi
callq 0x4088e0
jmp 0x41447b
leaq -0xeb8(%rbp), %rdi
callq 0x4096e0
jmp 0x414489
leaq -0xeb8(%rbp), %rdi
callq 0x40b580
jmp 0x414497
leaq -0xeb8(%rbp), %rdi
callq 0x40b700
jmp 0x4144a5
movl -0x268(%rbp), %r8d
leaq -0xeb8(%rbp), %rdi
movl $0x1, %esi
xorl %ecx, %ecx
movl %ecx, %edx
callq 0x40eb80
jmp 0x4144c3
leaq 0x1870b6(%rip), %rdi    # 0x59b580
xorl %eax, %eax
callq 0x4f06e0
jmp 0x4144d3
leaq -0xee1(%rbp), %rdi
movq %rdi, -0xf00(%rbp)
callq 0x41ffa0
movq -0xf00(%rbp), %rdx
leaq 0x18709c(%rip), %rsi    # 0x59b590
leaq -0xee0(%rbp), %rdi
callq 0x49a8d0
jmp 0x414502
movl -0x268(%rbp), %r9d
leaq -0x20(%rbp), %rdi
leaq -0xee0(%rbp), %rsi
movl $0x1, %edx
xorl %r8d, %r8d
movl %r8d, %ecx
callq 0x404850
jmp 0x414526
leaq -0xee0(%rbp), %rdi
callq 0x497ea0
leaq -0xee1(%rbp), %rdi
callq 0x41ffc0
movl $0x0, -0x4(%rbp)
leaq -0xeb8(%rbp), %rdi
callq 0x414610
leaq -0x470(%rbp), %rdi
callq 0x4652a0
leaq -0x260(%rbp), %rdi
callq 0x4652a0
leaq -0x20(%rbp), %rdi
callq 0x414650
movl -0x4(%rbp), %eax
addq $0xf00, %rsp            # imm = 0xF00
popq %rbp
retq
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
jmp 0x4145a4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x50(%rbp)
movl %eax, -0x54(%rbp)
leaq -0xee0(%rbp), %rdi
callq 0x497ea0
leaq -0xee1(%rbp), %rdi
callq 0x41ffc0
leaq -0xeb8(%rbp), %rdi
callq 0x414610
leaq -0x470(%rbp), %rdi
callq 0x4652a0
leaq -0x260(%rbp), %rdi
callq 0x4652a0
leaq -0x20(%rbp), %rdi
callq 0x414650
movq -0x50(%rbp), %rdi
callq 0x4c9ba0
nopw %cs:(%rax,%rax)