diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_BlindNavigation.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_BlindNavigation.cpp index 1bab80c19d..8f42bd5295 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_BlindNavigation.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_BlindNavigation.cpp @@ -7,6 +7,7 @@ #include "CommonTools/Random.h" #include "CommonFramework/Exceptions/OperationFailedException.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" +#include "NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h" #include "NintendoSwitch/Controllers/Procon/NintendoSwitch_ProController.h" #include "NintendoSwitch/NintendoSwitch_ConsoleHandle.h" #include "PokemonFRLG_BlindNavigation.h" @@ -16,26 +17,47 @@ namespace NintendoSwitch{ namespace PokemonFRLG{ -void set_seed_after_delay(ProControllerContext& context, SeedButton SEED_BUTTON, int64_t SEED_DELAY){ - // wait on title screen for the specified delay - pbf_wait(context, std::chrono::milliseconds(SEED_DELAY)); +void set_seed_after_delay(ProControllerContext& context, SeedButton SEED_BUTTON, BlackoutButton BLACKOUT_BUTTON, int64_t SEED_DELAY){ + // wait on title screen for the specified delay + // hold the "blackout" button starting from the black screen after the copyright text until getting to the continue screen + if (BLACKOUT_BUTTON != BlackoutButton::None){ + Button b_button; + switch (BLACKOUT_BUTTON){ + case BlackoutButton::L: + b_button = BUTTON_L; + break; + case BlackoutButton::R: + b_button = BUTTON_R; + break; + default: + b_button = BUTTON_L; + } + Milliseconds blackout_wait = 3600ms; // wait for the copyright text to disappear + Milliseconds blackout_delay = std::chrono::milliseconds(SEED_DELAY) - blackout_wait; + Milliseconds blackout_hold = 30000ms; // wait for leaves/flames to appear on the title screen. It's okay if this is held over the seed button press + ssf_do_nothing(context, blackout_wait); + ssf_press_button(context, b_button, blackout_delay, blackout_hold, 0ms); + }else{ + pbf_wait(context, std::chrono::milliseconds(SEED_DELAY)); + } + // hold the specified button for a few seconds through the transition to the Continue Screen - Button button; + Button s_button; switch (SEED_BUTTON){ case SeedButton::A: - button = BUTTON_A; + s_button = BUTTON_A; break; case SeedButton::Start: - button = BUTTON_PLUS; + s_button = BUTTON_PLUS; break; case SeedButton::L: - button = BUTTON_L; + s_button = BUTTON_L; break; default: - button = BUTTON_A; + s_button = BUTTON_A; break; } - pbf_press_button(context, button, 3000ms, 0ms); + pbf_press_button(context, s_button, 3000ms, 0ms); } void load_game_after_delay(ProControllerContext& context, uint64_t CONTINUE_SCREEN_DELAY){ @@ -564,6 +586,7 @@ void perform_blind_sequence( ProControllerContext& context, PokemonFRLG_RngTarget TARGET, SeedButton SEED_BUTTON, + BlackoutButton BLACKOUT_BUTTON, uint64_t SEED_DELAY, uint64_t CONTINUE_SCREEN_DELAY, uint64_t TEACHY_DELAY, @@ -571,7 +594,7 @@ void perform_blind_sequence( bool SAFARI_ZONE ){ pbf_press_button(context, BUTTON_A, 80ms, 0ms); // start the game from the Home screen - set_seed_after_delay(context, SEED_BUTTON, SEED_DELAY); + set_seed_after_delay(context, SEED_BUTTON, BLACKOUT_BUTTON, SEED_DELAY); load_game_after_delay(context, CONTINUE_SCREEN_DELAY); if (TEACHY_DELAY > 0){ wait_with_teachy_tv(context, TEACHY_DELAY); diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_BlindNavigation.h b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_BlindNavigation.h index 3c72cb293e..338c0e12fa 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_BlindNavigation.h +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_BlindNavigation.h @@ -52,6 +52,12 @@ namespace PokemonFRLG{ L }; + enum class BlackoutButton{ + None, + L, + R + }; + // checks seed, continue screen, and in-game timings for the specificed RNG manipulation target // and fires an error if any of the timings are too short. void check_timings( @@ -68,6 +74,7 @@ namespace PokemonFRLG{ ProControllerContext& context, PokemonFRLG_RngTarget TARGET, SeedButton SEED_BUTTON, + BlackoutButton BLACKOUT_BUTTON, uint64_t SEED_DELAY, uint64_t CONTINUE_SCREEN_DELAY, uint64_t TEACHY_DELAY, diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_HardReset.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_HardReset.cpp index 5a1cd85cf5..0751aebdea 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_HardReset.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_HardReset.cpp @@ -152,6 +152,7 @@ void reset_and_perform_blind_sequence( ProControllerContext& context, PokemonFRLG_RngTarget TARGET, SeedButton SEED_BUTTON, + BlackoutButton BLACKOUT_BUTTON, uint64_t SEED_DELAY, uint64_t CONTINUE_SCREEN_DELAY, uint64_t TEACHY_DELAY, @@ -185,8 +186,8 @@ void reset_and_perform_blind_sequence( context.wait_for_all_requests(); int ret = run_until( console, context, - [TARGET, SEED_BUTTON, SEED_DELAY, CONTINUE_SCREEN_DELAY, TEACHY_DELAY, INGAME_DELAY, SAFARI_ZONE](ProControllerContext& context) { - perform_blind_sequence(context, TARGET, SEED_BUTTON, SEED_DELAY, CONTINUE_SCREEN_DELAY, TEACHY_DELAY, INGAME_DELAY, SAFARI_ZONE); + [TARGET, SEED_BUTTON, BLACKOUT_BUTTON, SEED_DELAY, CONTINUE_SCREEN_DELAY, TEACHY_DELAY, INGAME_DELAY, SAFARI_ZONE](ProControllerContext& context) { + perform_blind_sequence(context, TARGET, SEED_BUTTON, BLACKOUT_BUTTON, SEED_DELAY, CONTINUE_SCREEN_DELAY, TEACHY_DELAY, INGAME_DELAY, SAFARI_ZONE); }, { update_detector, user_selection_detector }, 1000ms diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_HardReset.h b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_HardReset.h index 58d7428726..4d488daff3 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_HardReset.h +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_HardReset.h @@ -20,6 +20,7 @@ void reset_and_perform_blind_sequence( ProControllerContext& context, PokemonFRLG_RngTarget TARGET, SeedButton SEED_BUTTON, + BlackoutButton BLACKOUT_BUTTON, uint64_t SEED_DELAY, uint64_t CONTINUE_SCREEN_DELAY, uint64_t TEACHY_DELAY, diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngHelper.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngHelper.cpp index c40a38a197..9e64e28cd8 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngHelper.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngHelper.cpp @@ -104,6 +104,17 @@ RngHelper::RngHelper() LockMode::LOCK_WHILE_RUNNING, SeedButton::A ) + , EXTRA_BUTTON( + "Extra Button:
" + "Additional button presses that affect the seed.", + { + {BlackoutButton::None, "None", "None"}, + {BlackoutButton::L, "L", "Blackout L"}, + {BlackoutButton::R, "R", "Blackout R"}, + }, + LockMode::LOCK_WHILE_RUNNING, + BlackoutButton::None + ) , SEED_DELAY( "Seed Delay Time (ms):
" "The delay between starting the game and advancing past the title screen. Set this to match your target seed.", @@ -181,6 +192,7 @@ RngHelper::RngHelper() PA_ADD_OPTION(TARGET); PA_ADD_OPTION(NUM_RESETS); PA_ADD_OPTION(SEED_BUTTON); + PA_ADD_OPTION(EXTRA_BUTTON); PA_ADD_OPTION(SEED_DELAY); PA_ADD_OPTION(SEED_CALIBRATION); PA_ADD_OPTION(CONTINUE_SCREEN_FRAMES); @@ -252,8 +264,8 @@ void RngHelper::program(SingleSwitchProgramEnvironment& env, ProControllerContex // handle the blind part reset_and_perform_blind_sequence( - env.console, context, - TARGET, SEED_BUTTON, TOTAL_SEED_DELAY, + env.console, context, TARGET, + SEED_BUTTON, EXTRA_BUTTON, TOTAL_SEED_DELAY, CONTINUE_SCREEN_DELAY, TEACHY_DELAY, INGAME_DELAY, SAFARI_ZONE, PROFILE ); diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngHelper.h b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngHelper.h index b074c5ac67..ec0cb8b9b6 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngHelper.h +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngHelper.h @@ -40,9 +40,11 @@ class RngHelper : public SingleSwitchProgramInstance{ SimpleIntegerOption NUM_RESETS; EnumDropdownOption SEED_BUTTON; + EnumDropdownOption EXTRA_BUTTON; SimpleIntegerOption SEED_DELAY; SimpleIntegerOption SEED_CALIBRATION; + SimpleIntegerOption CONTINUE_SCREEN_FRAMES; FloatingPointOption CONTINUE_SCREEN_CALIBRATION; diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_StarterRng.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_StarterRng.cpp index 42a8708b8a..c3f43d10bc 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_StarterRng.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_StarterRng.cpp @@ -133,6 +133,17 @@ StarterRng::StarterRng() LockMode::LOCK_WHILE_RUNNING, SeedButton::A ) + , EXTRA_BUTTON( + "Extra Button:
" + "Additional button presses that affect the seed.", + { + {BlackoutButton::None, "None", "None"}, + {BlackoutButton::L, "L", "Blackout L"}, + {BlackoutButton::R, "R", "Blackout R"}, + }, + LockMode::LOCK_WHILE_RUNNING, + BlackoutButton::None + ) , SEED_DELAY( "Seed Delay Time (ms):
The delay between starting the game and advancing past the title screen. Set this to match your target seed.", LockMode::LOCK_WHILE_RUNNING, @@ -186,6 +197,7 @@ StarterRng::StarterRng() PA_ADD_OPTION(SEED); PA_ADD_OPTION(SEED_LIST); PA_ADD_OPTION(SEED_BUTTON); + PA_ADD_OPTION(EXTRA_BUTTON); PA_ADD_OPTION(SEED_DELAY); PA_ADD_OPTION(ADVANCES); // PA_ADD_OPTION(CONTINUE_SCREEN_FRAMES); @@ -1045,12 +1057,10 @@ void StarterRng::program(SingleSwitchProgramEnvironment& env, ProControllerConte env.log("Resetting Game..."); reset_and_perform_blind_sequence( - env.console, - context, - PokemonFRLG_RngTarget::starters, - SEED_BUTTON, CALIBRATED_SEED_DELAY, - CONTINUE_SCREEN_DELAY, - 0, INGAME_DELAY, false, PROFILE + env.console, context, PokemonFRLG_RngTarget::starters, + SEED_BUTTON, EXTRA_BUTTON, CALIBRATED_SEED_DELAY, + CONTINUE_SCREEN_DELAY, 0, INGAME_DELAY, + false, PROFILE ); stats.resets++; diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_StarterRng.h b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_StarterRng.h index 827da8dbe2..679edba274 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_StarterRng.h +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_StarterRng.h @@ -133,6 +133,7 @@ class StarterRng : public SingleSwitchProgramInstance{ StringOption SEED; TextEditOption SEED_LIST; EnumDropdownOption SEED_BUTTON; + EnumDropdownOption EXTRA_BUTTON; SimpleIntegerOption SEED_DELAY; SimpleIntegerOptionADVANCES;