From bc004d191ea8bb368f69df2ec6f09ab2653902cd Mon Sep 17 00:00:00 2001 From: kichithewolf Date: Sat, 8 Mar 2025 13:54:19 -0500 Subject: [PATCH 1/7] create settings and gameentry for LGPE, move trade program --- SerialPrograms/CMakeLists.txt | 8 +- SerialPrograms/SerialPrograms.pro | 8 +- .../NintendoSwitch_Commands_Routines.cpp | 48 +++++ .../NintendoSwitch_Commands_Routines.h | 3 + .../Programs/NintendoSwitch_GameEntry.cpp | 200 ++++++++++++++++++ .../Programs/NintendoSwitch_GameEntry.h | 15 ++ .../Source/PokemonLGPE/PokemonLGPE_Panels.cpp | 5 +- .../PokemonLGPE/PokemonLGPE_Settings.cpp | 105 +++++++++ .../Source/PokemonLGPE/PokemonLGPE_Settings.h | 58 +++++ .../Programs/PokemonLGPE_GameEntry.cpp | 104 +++++++++ .../Programs/PokemonLGPE_GameEntry.h | 49 +++++ .../PokemonLGPE_AlolanTrade.cpp | 5 +- .../PokemonLGPE_AlolanTrade.h | 0 13 files changed, 600 insertions(+), 8 deletions(-) create mode 100644 SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.cpp create mode 100644 SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.h create mode 100644 SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp create mode 100644 SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h rename SerialPrograms/Source/PokemonLGPE/Programs/{ => ShinyHunting}/PokemonLGPE_AlolanTrade.cpp (98%) rename SerialPrograms/Source/PokemonLGPE/Programs/{ => ShinyHunting}/PokemonLGPE_AlolanTrade.h (100%) diff --git a/SerialPrograms/CMakeLists.txt b/SerialPrograms/CMakeLists.txt index f77fddf39e..f3608098ee 100644 --- a/SerialPrograms/CMakeLists.txt +++ b/SerialPrograms/CMakeLists.txt @@ -1364,10 +1364,14 @@ file(GLOB MAIN_SOURCES Source/PokemonLA/Resources/PokemonLA_WeatherAndTimeIcons.h Source/PokemonLGPE/Inference/PokemonLGPE_ShinySymbolDetector.cpp Source/PokemonLGPE/Inference/PokemonLGPE_ShinySymbolDetector.h - Source/PokemonLGPE/Programs/PokemonLGPE_AlolanTrade.cpp - Source/PokemonLGPE/Programs/PokemonLGPE_AlolanTrade.h + Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.cpp + Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.h + Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp + Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h Source/PokemonLGPE/PokemonLGPE_Panels.cpp Source/PokemonLGPE/PokemonLGPE_Panels.h + Source/PokemonLGPE/PokemonLGPE_Settings.cpp + Source/PokemonLGPE/PokemonLGPE_Settings.h Source/PokemonRSE/Inference/Dialogs/PokemonRSE_DialogDetector.cpp Source/PokemonRSE/Inference/Dialogs/PokemonRSE_DialogDetector.h Source/PokemonRSE/Inference/Sounds/PokemonRSE_ShinySoundDetector.cpp diff --git a/SerialPrograms/SerialPrograms.pro b/SerialPrograms/SerialPrograms.pro index 9fb53ce8dd..38263c21cb 100644 --- a/SerialPrograms/SerialPrograms.pro +++ b/SerialPrograms/SerialPrograms.pro @@ -669,8 +669,10 @@ SOURCES += \ Source/PokemonLA/Resources/PokemonLA_PokemonSprites.cpp \ Source/PokemonLA/Resources/PokemonLA_WeatherAndTimeIcons.cpp \ Source/PokemonLGPE/Inference/PokemonLGPE_ShinySymbolDetector.cpp \ - Source/PokemonLGPE/Programs/PokemonLGPE_AlolanTrade.cpp \ + Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.cpp \ + Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp \ Source/PokemonLGPE/PokemonLGPE_Panels.cpp \ + Source/PokemonLGPE/PokemonLGPE_Settings.cpp \ Source/PokemonRSE/Inference/Dialogs/PokemonRSE_DialogDetector.cpp \ Source/PokemonRSE/Inference/PokemonRSE_ShinyNumberDetector.cpp \ Source/PokemonRSE/Inference/Sounds/PokemonRSE_ShinySoundDetector.cpp \ @@ -1852,8 +1854,10 @@ HEADERS += \ Source/PokemonLA/Resources/PokemonLA_PokemonSprites.h \ Source/PokemonLA/Resources/PokemonLA_WeatherAndTimeIcons.h \ Source/PokemonLGPE/Inference/PokemonLGPE_ShinySymbolDetector.h \ - Source/PokemonLGPE/Programs/PokemonLGPE_AlolanTrade.h \ + Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.h \ + Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h \ Source/PokemonLGPE/PokemonLGPE_Panels.h \ + Source/PokemonLGPE/PokemonLGPE_Settings.h \ Source/PokemonRSE/Inference/Dialogs/PokemonRSE_DialogDetector.h \ Source/PokemonRSE/Inference/PokemonRSE_ShinyNumberDetector.h \ Source/PokemonRSE/Inference/Sounds/PokemonRSE_ShinySoundDetector.h \ diff --git a/SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.cpp b/SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.cpp index cc625bd07a..c8d793d920 100644 --- a/SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.cpp +++ b/SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.cpp @@ -72,6 +72,54 @@ void close_game(VideoStream& stream, ProControllerContext& context){ pbf_mash_button(context, BUTTON_B, 350); } +void close_game(VideoStream& stream, JoyconContext& context){ + // Use mashing to ensure that the X press succeeds. If it fails, the SR + // will fail and can kill a den for the autohosts. + + // this sequence will close the game from the home screen, + // regardless of whether the game is initially open or closed. + + // if game initially open. | if game initially closed + pbf_mash_button(context, BUTTON_X, 800ms); // - Close game. | - does nothing + pbf_move_joystick(context, 128, 255, 100ms, 10ms); // - Does nothing. | - moves selector away from the closed game to avoid opening it. + pbf_move_joystick(context, 128, 255, 100ms, 10ms); // - Does nothing. | - Press Down a second time in case we drop one. + pbf_mash_button(context, BUTTON_A, 400ms); // - Confirm close game. | - opens an app on the home screen (e.g. Online) + // - Does nothing. | - goes back to home screen. + pbf_press_button(context, BUTTON_HOME, 160ms, ConsoleSettings::instance().SETTINGS_TO_HOME_DELAY0); + context.wait_for_all_requests(); + +// cout << "waiting..." << endl; +// context.wait_for(10s); + + // send a second Home button press, if the first one is dropped + bool video_available = (bool)stream.video().snapshot(); + if (video_available){ + HomeWatcher detector; + int ret = wait_until( + stream, context, + std::chrono::milliseconds(5000), + { detector } + ); + if (ret == 0){ + stream.log("Detected Home screen."); + }else{ // if game initially open. | if game initially closed + // initial Home button press was dropped + // - Does nothing. | - goes back to home screen, from opened app + pbf_press_button(context, BUTTON_HOME, 160ms, ConsoleSettings::instance().SETTINGS_TO_HOME_DELAY0); + } + }else{ + // - wait some time after first Home button press + // to avoid triggering zoom + context.wait_for(std::chrono::milliseconds(1000)); + // - Does nothing. | - Press Home a second time in case we drop one. + pbf_press_button(context, BUTTON_HOME, 160ms, ConsoleSettings::instance().SETTINGS_TO_HOME_DELAY0); + } + + + // fail-safe against button drops and unexpected error messages. + pbf_mash_button(context, BUTTON_X, 400ms); + pbf_mash_button(context, BUTTON_B, 2000ms); +} } diff --git a/SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.h b/SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.h index b4c475627a..e4571562f3 100644 --- a/SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.h +++ b/SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.h @@ -9,6 +9,7 @@ #include "CommonFramework/Tools/VideoStream.h" #include "NintendoSwitch/Controllers/NintendoSwitch_ProController.h" +#include "NintendoSwitch/Controllers/NintendoSwitch_Joycon.h" namespace PokemonAutomation{ namespace NintendoSwitch{ @@ -16,6 +17,8 @@ namespace NintendoSwitch{ void close_game(VideoStream& stream, ProControllerContext& device); +void close_game(VideoStream& stream, JoyconContext& device); + diff --git a/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.cpp b/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.cpp index 9dfad6a947..64bb44e44d 100644 --- a/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.cpp +++ b/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.cpp @@ -312,6 +312,206 @@ bool openedgame_to_gamemenu( +void move_to_user(JoyconContext& context, uint8_t user_slot){ + if (user_slot != 0){ + // Move to correct user. + for (uint8_t c = 0; c < 9; c++){ // Extra iteration in case one gets dropped. + pbf_move_joystick(context, 0, 128, 160ms, 160ms); + } + for (uint8_t c = 1; c < user_slot; c++){ + pbf_move_joystick(context, 0, 128, 160ms, 160ms); + } + } +} + +void start_game_from_home_with_inference( + VideoStream& stream, JoyconContext& context, + uint8_t game_slot, + uint8_t user_slot, + Milliseconds start_game_wait +){ + context.wait_for_all_requests(); + { + HomeWatcher detector; + int ret = run_until( + stream, context, + [](JoyconContext& context){ + pbf_mash_button(context, BUTTON_B, 10000ms); + }, + { detector } + ); + if (ret == 0){ + stream.log("Detected Home screen."); + }else{ + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "start_game_from_home_with_inference(): Failed to detect Home screen after 10 seconds.", + stream + ); + } + context.wait_for(std::chrono::milliseconds(100)); + } + + if (game_slot != 0){ + ssf_press_button(context, BUTTON_HOME, ConsoleSettings::instance().SETTINGS_TO_HOME_DELAY0, 160ms); + for (uint8_t c = 1; c < game_slot; c++){ + pbf_move_joystick(context, 255, 128, 160ms, 0ms); + } + context.wait_for_all_requests(); + } + + pbf_press_button(context, BUTTON_A, 160ms, 840ms); + + while (true){ + HomeWatcher home(std::chrono::milliseconds(2000)); + StartGameUserSelectWatcher user_select(COLOR_GREEN); + UpdateMenuWatcher update_menu(COLOR_PURPLE); + CheckOnlineWatcher check_online(COLOR_CYAN); + BlackScreenWatcher black_screen(COLOR_BLUE); + context.wait_for_all_requests(); + int ret = wait_until( + stream, context, + std::chrono::seconds(30), + { + home, + user_select, + update_menu, + check_online, + black_screen, + } + ); + + // Wait for screen to stabilize. + context.wait_for(std::chrono::milliseconds(100)); + + switch (ret){ + case 0: + stream.log("Detected home screen (again).", COLOR_RED); + pbf_press_button(context, BUTTON_A, 160ms, 840ms); + break; + case 1: + stream.log("Detected user-select screen."); + move_to_user(context, user_slot); + pbf_press_button(context, BUTTON_A, 80ms, start_game_wait); + break; + case 2: + stream.log("Detected update menu.", COLOR_RED); + pbf_move_joystick(context, 128, 0, 50ms, 0ms); + pbf_press_button(context, BUTTON_A, 160ms, 840ms); + break; + case 3: + stream.log("Detected check online.", COLOR_RED); + context.wait_for(std::chrono::seconds(1)); + break; + case 4: + stream.log("Detected black screen. Game started..."); + return; + default: + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "start_game_from_home_with_inference(): No recognizable state after 30 seconds.", + stream + ); + } + } +} + +void start_game_from_home( + VideoStream& stream, JoyconContext& context, + bool tolerate_update_menu, + uint8_t game_slot, + uint8_t user_slot, + Milliseconds start_game_mash +){ + context.wait_for_all_requests(); + if (stream.video().snapshot()){ + stream.log("start_game_from_home(): Video capture available. Using inference..."); + start_game_from_home_with_inference(stream, context, game_slot, user_slot, start_game_mash); + return; + }else{ + stream.log("start_game_from_home(): Video capture not available.", COLOR_RED); + } + + if (game_slot != 0){ + ssf_press_button(context, BUTTON_HOME, ConsoleSettings::instance().SETTINGS_TO_HOME_DELAY0, 160ms); + for (uint8_t c = 1; c < game_slot; c++){ + pbf_move_joystick(context, 255, 128, 80ms, 0ms); + } + } + + if (tolerate_update_menu){ + if (ConsoleSettings::instance().START_GAME_REQUIRES_INTERNET){ + throw UserSetupError( + stream.logger(), + "Cannot have both \"Tolerate Update Menu\" and \"Start Game Requires Internet\" enabled at the same time without video feedback." + ); + } + + // If the update menu isn't there, these will get swallowed by the opening + // animation for the select user menu. + pbf_press_button(context, BUTTON_A, 80ms, 1400ms); // Choose game + pbf_move_joystick(context, 128, 255, 100ms, 0ms); // Skip the update window. + move_to_user(context, user_slot); + } + +// cout << "START_GAME_REQUIRES_INTERNET = " << ConsoleSettings::instance().START_GAME_REQUIRES_INTERNET << endl; + if (!ConsoleSettings::instance().START_GAME_REQUIRES_INTERNET && user_slot == 0){ + // Mash your way into the game. + pbf_mash_button(context, BUTTON_A, start_game_mash); + }else{ + pbf_press_button(context, BUTTON_A, 80ms, 1400ms); // Enter select user menu. + move_to_user(context, user_slot); + ssf_press_button(context, BUTTON_A, 160ms); // Enter game + + // Switch to mashing ZL instead of A to get into the game. + // Mash your way into the game. + Milliseconds duration = start_game_mash; + if (ConsoleSettings::instance().START_GAME_REQUIRES_INTERNET){ + // Need to wait a bit longer for the internet check. + duration += ConsoleSettings::instance().START_GAME_INTERNET_CHECK_DELAY0; + } +// pbf_mash_button(context, BUTTON_ZL, duration); + pbf_wait(context, duration); + } + context.wait_for_all_requests(); +} + +bool openedgame_to_gamemenu( + VideoStream& stream, JoyconContext& context, + Milliseconds timeout +){ + { + stream.log("Waiting to load game..."); + GameLoadingDetector detector(false); + int ret = wait_until( + stream, context, + timeout, + {{detector}} + ); + if (ret < 0){ + stream.log("Timed out waiting to enter game.", COLOR_RED); + return false; + } + } + { + stream.log("Waiting for game menu..."); + GameLoadingDetector detector(true); + int ret = wait_until( + stream, context, + timeout, + {{detector}} + ); + if (ret < 0){ + stream.log("Timed out waiting for game menu.", COLOR_RED); + return false; + } + } + return true; +} + + + + diff --git a/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.h b/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.h index 500ccb14f2..b914a5fc45 100644 --- a/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.h +++ b/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.h @@ -9,6 +9,7 @@ #include "CommonFramework/Tools/VideoStream.h" #include "NintendoSwitch/Controllers/NintendoSwitch_ProController.h" +#include "NintendoSwitch/Controllers/NintendoSwitch_Joycon.h" namespace PokemonAutomation{ namespace NintendoSwitch{ @@ -35,6 +36,20 @@ bool openedgame_to_gamemenu( +void start_game_from_home( + VideoStream& stream, JoyconContext& context, + bool tolerate_update_menu, + uint8_t game_slot, + uint8_t user_slot, + Milliseconds start_game_mash +); + +bool openedgame_to_gamemenu( + VideoStream& stream, JoyconContext& context, + Milliseconds timeout +); + + } } #endif diff --git a/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Panels.cpp b/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Panels.cpp index 27183a59bd..39b64fd114 100644 --- a/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Panels.cpp +++ b/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Panels.cpp @@ -7,8 +7,9 @@ #include "CommonFramework/GlobalSettingsPanel.h" #include "Pokemon/Pokemon_Strings.h" #include "PokemonLGPE_Panels.h" +#include "PokemonLGPE_Settings.h" -#include "Programs/PokemonLGPE_AlolanTrade.h" +#include "Programs/ShinyHunting/PokemonLGPE_AlolanTrade.h" namespace PokemonAutomation{ namespace NintendoSwitch{ @@ -22,7 +23,7 @@ std::vector PanelListFactory::make_panels() const{ std::vector ret; ret.emplace_back("---- Settings ----"); - //ret.emplace_back(make_settings()); + ret.emplace_back(make_settings()); //ret.emplace_back("---- General ----"); diff --git a/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.cpp b/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.cpp new file mode 100644 index 0000000000..a0eab156c7 --- /dev/null +++ b/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.cpp @@ -0,0 +1,105 @@ +/* Pokemon Let's Go Settings + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#include "Pokemon/Pokemon_Strings.h" +#include "PokemonLGPE_Settings.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonLGPE{ + using namespace Pokemon; + + + +GameSettings& GameSettings::instance(){ + static GameSettings settings; + return settings; +} +GameSettings::GameSettings() + : BatchOption(LockMode::LOCK_WHILE_RUNNING) + , m_general("General Settings:") + , m_menu_navigation("Menu Navigation Timings:") + , GAME_TO_HOME_DELAY0( + "Game to Home Delay:
Delay from pressing home to entering the the Switch home menu.", + LockMode::LOCK_WHILE_RUNNING, + "1000 ms" + ) + , LOAD_REGION_TIMEOUT0( + "Load Region Timeout:
Wait at most this long to enter a region before giving up.", + LockMode::LOCK_WHILE_RUNNING, + "30 s" + ) + , m_start_game_timings("Start Game Timings:") + , START_GAME_MASH0( + "1. Start Game Mash:
Mash A for this long to start the game.", + LockMode::LOCK_WHILE_RUNNING, + "2000 ms" + ) + , START_GAME_WAIT1( + "2. Start Game Wait:
Wait this long for the game to load.", + LockMode::LOCK_WHILE_RUNNING, + "40 s" + ) + , ENTER_GAME_MASH0( + "3. Enter Game Mash:
Mash A for this long to enter the game.", + LockMode::LOCK_WHILE_RUNNING, + "5000 ms" + ) + , ENTER_GAME_WAIT0( + "4. Enter Game Wait:
Wait this long for the game to enter the overworld.", + LockMode::LOCK_WHILE_RUNNING, + "15 s" + ) +{ + PA_ADD_STATIC(m_general); + + PA_ADD_STATIC(m_menu_navigation); + PA_ADD_OPTION(GAME_TO_HOME_DELAY0); + PA_ADD_OPTION(LOAD_REGION_TIMEOUT0); + + PA_ADD_STATIC(m_start_game_timings); + PA_ADD_OPTION(START_GAME_MASH0); + PA_ADD_OPTION(START_GAME_WAIT1); + PA_ADD_OPTION(ENTER_GAME_MASH0); + PA_ADD_OPTION(ENTER_GAME_WAIT0); +} + + + + + +GameSettings_Descriptor::GameSettings_Descriptor() + : PanelDescriptor( + Color(), + "PokemonLGPE:GlobalSettings", + STRING_POKEMON + " LGPE", "Game Settings", + "ComputerControl/blob/master/Wiki/Programs/PokemonLGPE/PokemonSettings.md", + "Global " + STRING_POKEMON + " Let's Go Settings" + ) +{} + + + +GameSettingsPanel::GameSettingsPanel(const GameSettings_Descriptor& descriptor) + : SettingsPanelInstance(descriptor) + , settings(GameSettings::instance()) +{ + PA_ADD_OPTION(settings); +} + + + + + +} +} +} + + + + + + diff --git a/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.h b/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.h new file mode 100644 index 0000000000..247b7f2534 --- /dev/null +++ b/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.h @@ -0,0 +1,58 @@ +/* Pokemon Let's Go Settings + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#ifndef PokemonAutomation_PokemonLGPE_Settings_H +#define PokemonAutomation_PokemonLGPE_Settings_H + +#include "Common/Cpp/Options/StaticTextOption.h" +#include "Common/Cpp/Options/FloatingPointOption.h" +#include "Common/Cpp/Options/TimeDurationOption.h" +#include "CommonFramework/Panels/SettingsPanel.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonLGPE{ + + +class GameSettings : public BatchOption{ + GameSettings(); +public: + static GameSettings& instance(); + + SectionDividerOption m_general; + + SectionDividerOption m_menu_navigation; + MillisecondsOption GAME_TO_HOME_DELAY0; + MillisecondsOption LOAD_REGION_TIMEOUT0; + + SectionDividerOption m_start_game_timings; + MillisecondsOption START_GAME_MASH0; + MillisecondsOption START_GAME_WAIT1; + MillisecondsOption ENTER_GAME_MASH0; + MillisecondsOption ENTER_GAME_WAIT0; +}; + + + + +class GameSettings_Descriptor : public PanelDescriptor{ +public: + GameSettings_Descriptor(); +}; + + +class GameSettingsPanel : public SettingsPanelInstance{ +public: + GameSettingsPanel(const GameSettings_Descriptor& descriptor); +private: + GameSettings& settings; +}; + + +} +} +} +#endif diff --git a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp b/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp new file mode 100644 index 0000000000..7f7a725bb1 --- /dev/null +++ b/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp @@ -0,0 +1,104 @@ +/* Game Entry + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#include "CommonFramework/VideoPipeline/VideoFeed.h" +#include "CommonFramework/Tools/ErrorDumper.h" +#include "CommonFramework/Tools/ProgramEnvironment.h" +#include "CommonTools/Async/InferenceRoutines.h" +#include "CommonTools/VisualDetectors/BlackScreenDetector.h" +#include "NintendoSwitch/NintendoSwitch_Settings.h" +#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" +#include "NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.h" +#include "NintendoSwitch/Programs/NintendoSwitch_GameEntry.h" +#include "PokemonLGPE/PokemonLGPE_Settings.h" +#include "PokemonLGPE_GameEntry.h" + +//#include +//using std::cout; +//using std::endl; + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonLGPE{ + + +bool reset_game_to_gamemenu( + VideoStream& stream, JoyconContext& context, + bool tolerate_update_menu +){ + bool video_available = (bool)stream.video().snapshot(); + if (video_available || + ConsoleSettings::instance().START_GAME_REQUIRES_INTERNET || + tolerate_update_menu + ){ + close_game(stream, context); + start_game_from_home( + stream, + context, + tolerate_update_menu, + 0, 0, + GameSettings::instance().START_GAME_MASH0 + ); + }else{ + pbf_press_button(context, BUTTON_X, 400ms, 0ms); + pbf_mash_button(context, BUTTON_A, GameSettings::instance().START_GAME_MASH0); + } + + // Now the game has opened: + return openedgame_to_gamemenu(stream, context, GameSettings::instance().START_GAME_WAIT1); +} + +bool gamemenu_to_ingame( + VideoStream& stream, JoyconContext& context, + Milliseconds mash_duration, Milliseconds enter_game_timeout +){ + stream.log("Mashing A to enter game..."); + BlackScreenOverWatcher detector(COLOR_RED, {0.2, 0.2, 0.6, 0.6}); + pbf_mash_button(context, BUTTON_A, mash_duration); + context.wait_for_all_requests(); + stream.log("Waiting to enter game..."); + int ret = wait_until( + stream, context, + std::chrono::milliseconds(enter_game_timeout * (1000 / TICKS_PER_SECOND)), + {{detector}} + ); + if (ret == 0){ + stream.log("Entered game!"); + return true; + }else{ + stream.log("Timed out waiting to enter game.", COLOR_RED); + return false; + } +} + +bool reset_game_from_home( + ProgramEnvironment& env, VideoStream& stream, JoyconContext& context, + bool tolerate_update_menu, + Milliseconds post_wait_time +){ + bool ok = true; + ok &= reset_game_to_gamemenu(stream, context, tolerate_update_menu); + ok &= gamemenu_to_ingame( + stream, context, + GameSettings::instance().ENTER_GAME_MASH0, + GameSettings::instance().ENTER_GAME_WAIT0 + ); + if (!ok){ + dump_image(stream.logger(), env.program_info(), stream.video(), "StartGame"); + } + stream.log("Entered game! Waiting out grace period."); + pbf_wait(context, post_wait_time); + context.wait_for_all_requests(); + return ok; +} + + + + + +} +} +} diff --git a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h b/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h new file mode 100644 index 0000000000..ed2172adcf --- /dev/null +++ b/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h @@ -0,0 +1,49 @@ +/* Game Entry + * + * From: https://github.com/PokemonAutomation/Arduino-Source + * + */ + +#ifndef PokemonAutomation_PokemonLGPE_GameEntry_H +#define PokemonAutomation_PokemonLGPE_GameEntry_H + +#include +#include "CommonFramework/Tools/VideoStream.h" +#include "NintendoSwitch/Controllers/NintendoSwitch_Joycon.h" + +namespace PokemonAutomation{ + class ProgramEnvironment; +namespace NintendoSwitch{ +namespace PokemonLGPE{ + + + +// From Switch Home menu, reset game and wait until the game menu screen (where +// "Press A" is displayed to enter the game) is shown. +bool reset_game_to_gamemenu( + VideoStream& stream, JoyconContext& context, + bool tolerate_update_menu +); + +// From the game menu screen (where "Press A" is displayed to enter the game), +// mash A to enter the game and wait until the black screen is gone. +bool gamemenu_to_ingame( + VideoStream& stream, JoyconContext& context, + Milliseconds mash_duration, Milliseconds enter_game_timeout +); + +// From Switch Home menu, start game and wait until the player character appears in game. +// post_wait_time: how many ticks to wait after the black screen (shown when loading the map) is over. +bool reset_game_from_home( + ProgramEnvironment& env, VideoStream& stream, JoyconContext& context, + bool tolerate_update_menu, + uint16_t post_wait_time = 125 +); + + + + +} +} +} +#endif diff --git a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_AlolanTrade.cpp b/SerialPrograms/Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.cpp similarity index 98% rename from SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_AlolanTrade.cpp rename to SerialPrograms/Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.cpp index b6d0efb72b..f10d46c5be 100644 --- a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_AlolanTrade.cpp +++ b/SerialPrograms/Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.cpp @@ -164,6 +164,7 @@ void AlolanTrade::program(SingleSwitchProgramEnvironment& env, CancellableScope& while (!shiny_found) { //Run trades for (uint16_t i = 0; i < NUM_TRADES; i++) { + env.log("Running trade."); run_trade(env, context); stats.trades++; @@ -236,7 +237,7 @@ void AlolanTrade::program(SingleSwitchProgramEnvironment& env, CancellableScope& //Move left, check next. pbf_move_joystick(context, 0, 128, 100ms, 100ms); - pbf_press_button(context, BUTTON_X, 0ms, 2000ms); + pbf_press_button(context, BUTTON_X, 0ms, 1000ms); context.wait_for_all_requests(); } /* @@ -263,7 +264,7 @@ void AlolanTrade::program(SingleSwitchProgramEnvironment& env, CancellableScope& } */ //Break for now since resetting the game doesn't work. - break; + //break; } if (GO_HOME_WHEN_DONE) { diff --git a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_AlolanTrade.h b/SerialPrograms/Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.h similarity index 100% rename from SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_AlolanTrade.h rename to SerialPrograms/Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.h From 0123ffab8ab6308756c9304ff2a84304d4842b74 Mon Sep 17 00:00:00 2001 From: kichithewolf Date: Tue, 11 Mar 2025 16:08:39 -0400 Subject: [PATCH 2/7] working reset sequence, adjust alolantrade timings --- .../NintendoSwitch_Commands_Routines.cpp | 4 +- .../PokemonLGPE/PokemonLGPE_Settings.cpp | 12 ++--- .../Source/PokemonLGPE/PokemonLGPE_Settings.h | 1 - .../Programs/PokemonLGPE_GameEntry.cpp | 48 +++++++++++++++++-- .../Programs/PokemonLGPE_GameEntry.h | 2 +- .../ShinyHunting/PokemonLGPE_AlolanTrade.cpp | 24 ++++------ 6 files changed, 57 insertions(+), 34 deletions(-) diff --git a/SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.cpp b/SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.cpp index c8d793d920..babd36a77e 100644 --- a/SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.cpp +++ b/SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.cpp @@ -80,10 +80,10 @@ void close_game(VideoStream& stream, JoyconContext& context){ // regardless of whether the game is initially open or closed. // if game initially open. | if game initially closed - pbf_mash_button(context, BUTTON_X, 800ms); // - Close game. | - does nothing + pbf_mash_button(context, BUTTON_X, 800ms); // - Close game. | - does nothing pbf_move_joystick(context, 128, 255, 100ms, 10ms); // - Does nothing. | - moves selector away from the closed game to avoid opening it. pbf_move_joystick(context, 128, 255, 100ms, 10ms); // - Does nothing. | - Press Down a second time in case we drop one. - pbf_mash_button(context, BUTTON_A, 400ms); // - Confirm close game. | - opens an app on the home screen (e.g. Online) + pbf_mash_button(context, BUTTON_A, 400ms); // - Confirm close game. | - opens an app on the home screen (e.g. Online) // - Does nothing. | - goes back to home screen. pbf_press_button(context, BUTTON_HOME, 160ms, ConsoleSettings::instance().SETTINGS_TO_HOME_DELAY0); context.wait_for_all_requests(); diff --git a/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.cpp b/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.cpp index a0eab156c7..4950da0aec 100644 --- a/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.cpp +++ b/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.cpp @@ -27,11 +27,6 @@ GameSettings::GameSettings() LockMode::LOCK_WHILE_RUNNING, "1000 ms" ) - , LOAD_REGION_TIMEOUT0( - "Load Region Timeout:
Wait at most this long to enter a region before giving up.", - LockMode::LOCK_WHILE_RUNNING, - "30 s" - ) , m_start_game_timings("Start Game Timings:") , START_GAME_MASH0( "1. Start Game Mash:
Mash A for this long to start the game.", @@ -41,15 +36,15 @@ GameSettings::GameSettings() , START_GAME_WAIT1( "2. Start Game Wait:
Wait this long for the game to load.", LockMode::LOCK_WHILE_RUNNING, - "40 s" + "20 s" ) , ENTER_GAME_MASH0( "3. Enter Game Mash:
Mash A for this long to enter the game.", LockMode::LOCK_WHILE_RUNNING, - "5000 ms" + "5 s" ) , ENTER_GAME_WAIT0( - "4. Enter Game Wait:
Wait this long for the game to enter the overworld.", + "4. Enter Game Wait:
Wait this long for the opening animations to finish.", LockMode::LOCK_WHILE_RUNNING, "15 s" ) @@ -58,7 +53,6 @@ GameSettings::GameSettings() PA_ADD_STATIC(m_menu_navigation); PA_ADD_OPTION(GAME_TO_HOME_DELAY0); - PA_ADD_OPTION(LOAD_REGION_TIMEOUT0); PA_ADD_STATIC(m_start_game_timings); PA_ADD_OPTION(START_GAME_MASH0); diff --git a/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.h b/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.h index 247b7f2534..a6508c2be4 100644 --- a/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.h +++ b/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.h @@ -26,7 +26,6 @@ class GameSettings : public BatchOption{ SectionDividerOption m_menu_navigation; MillisecondsOption GAME_TO_HOME_DELAY0; - MillisecondsOption LOAD_REGION_TIMEOUT0; SectionDividerOption m_start_game_timings; MillisecondsOption START_GAME_MASH0; diff --git a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp b/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp index 7f7a725bb1..5ceffbc1f5 100644 --- a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp +++ b/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp @@ -13,6 +13,7 @@ #include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.h" #include "NintendoSwitch/Programs/NintendoSwitch_GameEntry.h" +#include "NintendoSwitch/Inference/NintendoSwitch_DetectHome.h" #include "PokemonLGPE/PokemonLGPE_Settings.h" #include "PokemonLGPE_GameEntry.h" @@ -34,6 +35,13 @@ bool reset_game_to_gamemenu( ConsoleSettings::instance().START_GAME_REQUIRES_INTERNET || tolerate_update_menu ){ + //Handle Right Joycon attempting to update + //If no update, this will open the All Software menu + //The active game will be closed from there + //pbf_move_joystick(context, 0, 128, 100ms, 10ms); + //pbf_move_joystick(context, 0, 128, 100ms, 10ms); + //pbf_press_button(context, BUTTON_A, 100ms, 10ms); + close_game(stream, context); start_game_from_home( stream, @@ -55,17 +63,47 @@ bool gamemenu_to_ingame( VideoStream& stream, JoyconContext& context, Milliseconds mash_duration, Milliseconds enter_game_timeout ){ - stream.log("Mashing A to enter game..."); - BlackScreenOverWatcher detector(COLOR_RED, {0.2, 0.2, 0.6, 0.6}); + //Includes choosing the controller. + //Controllers are disconnected? on selection screen so make sure to mash. + stream.log("Mashing A to enter game and select controller..."); pbf_mash_button(context, BUTTON_A, mash_duration); context.wait_for_all_requests(); + + //White screen, Pikachu/Eevee running across the screen. + //Mash A at then end. + BlackScreenOverWatcher detector(COLOR_RED, {0.2, 0.2, 0.6, 0.6}); stream.log("Waiting to enter game..."); - int ret = wait_until( + int ret = run_until( stream, context, - std::chrono::milliseconds(enter_game_timeout * (1000 / TICKS_PER_SECOND)), - {{detector}} + [&enter_game_timeout](JoyconContext& context){ + pbf_wait(context, enter_game_timeout); + pbf_press_button(context, BUTTON_A, 400ms, 10ms); + pbf_wait(context, 5000ms); + }, + {detector} ); + context.wait_for_all_requests(); if (ret == 0){ + stream.log("At continue screen."); + }else{ + stream.log("Timed out waiting to enter game and select continue.", COLOR_RED); + return false; + } + pbf_wait(context, 1000ms); + context.wait_for_all_requests(); + + //Continue your adventure. + BlackScreenOverWatcher detector2(COLOR_YELLOW, {0.2, 0.2, 0.6, 0.6}); + int ret2 = run_until( + stream, context, + [](JoyconContext& context){ + pbf_press_button(context, BUTTON_A, 400ms, 10ms); + pbf_wait(context, 5000ms); + }, + {detector2} + ); + context.wait_for_all_requests(); + if (ret2 == 0){ stream.log("Entered game!"); return true; }else{ diff --git a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h b/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h index ed2172adcf..2323e993f7 100644 --- a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h +++ b/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h @@ -37,7 +37,7 @@ bool gamemenu_to_ingame( bool reset_game_from_home( ProgramEnvironment& env, VideoStream& stream, JoyconContext& context, bool tolerate_update_menu, - uint16_t post_wait_time = 125 + Milliseconds post_wait_time = 125ms ); diff --git a/SerialPrograms/Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.cpp b/SerialPrograms/Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.cpp index f10d46c5be..b770a09b94 100644 --- a/SerialPrograms/Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.cpp +++ b/SerialPrograms/Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.cpp @@ -16,6 +16,7 @@ #include "Pokemon/Pokemon_Strings.h" #include "CommonTools/VisualDetectors/BlackScreenDetector.h" #include "PokemonLGPE/Inference/PokemonLGPE_ShinySymbolDetector.h" +#include "PokemonLGPE/Programs/PokemonLGPE_GameEntry.h" #include "PokemonLGPE_AlolanTrade.h" namespace PokemonAutomation{ @@ -192,8 +193,8 @@ void AlolanTrade::program(SingleSwitchProgramEnvironment& env, CancellableScope& //Open menu, open party, open boxes env.log("Opening boxes."); pbf_press_button(context, BUTTON_X, 200ms, 500ms); - pbf_press_button(context, BUTTON_A, 200ms, 1000ms); - pbf_press_button(context, BUTTON_Y, 200ms, 1500ms); + pbf_press_button(context, BUTTON_A, 200ms, 1500ms); + pbf_press_button(context, BUTTON_Y, 200ms, 2000ms); context.wait_for_all_requests(); //Sort by order caught @@ -240,7 +241,7 @@ void AlolanTrade::program(SingleSwitchProgramEnvironment& env, CancellableScope& pbf_press_button(context, BUTTON_X, 0ms, 1000ms); context.wait_for_all_requests(); } - /* + if (!shiny_found) { env.log("Out of Pokemon to trade and no shiny found. Resetting game."); send_program_status_notification( @@ -248,23 +249,14 @@ void AlolanTrade::program(SingleSwitchProgramEnvironment& env, CancellableScope& "Out of Pokemon to trade and no shiny found. Resetting game." ); - //TODO: Need to make proper GameEntry eventually - //Thankfully, Joycon is upright after going to home. - //Go to home and close game - pbf_press_button(context, BUTTON_HOME, 200ms, 3000ms); - pbf_press_button(context, BUTTON_X, 200ms, 200ms); - pbf_press_button(context, BUTTON_A, 200ms, 1000ms); - - //TODO: - //joycon context->pro controller context? - start_game_from_home(env.console, context, true, 0, 0, std::chrono::milliseconds(2000)); + //Reset game + pbf_press_button(context, BUTTON_HOME, 200ms, 2000ms); + reset_game_from_home(env, env.console, context, true, 3000ms); + context.wait_for_all_requests(); stats.resets++; env.update_stats(); } - */ - //Break for now since resetting the game doesn't work. - //break; } if (GO_HOME_WHEN_DONE) { From 1a404412371045ef9e5a7cf7078b829e00a72eeb Mon Sep 17 00:00:00 2001 From: kichithewolf Date: Tue, 11 Mar 2025 16:47:03 -0400 Subject: [PATCH 3/7] headers --- .../Source/PokemonLGPE/PokemonLGPE_Settings.cpp | 2 +- .../Source/PokemonLGPE/PokemonLGPE_Settings.h | 2 +- .../PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp | 9 ++++----- .../PokemonLGPE/Programs/PokemonLGPE_GameEntry.h | 2 +- .../ShinyHunting/PokemonLGPE_AlolanTrade.cpp | 13 ++++++------- 5 files changed, 13 insertions(+), 15 deletions(-) diff --git a/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.cpp b/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.cpp index 4950da0aec..cf99cdc421 100644 --- a/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.cpp +++ b/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.cpp @@ -1,6 +1,6 @@ /* Pokemon Let's Go Settings * - * From: https://github.com/PokemonAutomation/Arduino-Source + * From: https://github.com/PokemonAutomation/ * */ diff --git a/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.h b/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.h index a6508c2be4..792dd6e0a4 100644 --- a/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.h +++ b/SerialPrograms/Source/PokemonLGPE/PokemonLGPE_Settings.h @@ -1,6 +1,6 @@ /* Pokemon Let's Go Settings * - * From: https://github.com/PokemonAutomation/Arduino-Source + * From: https://github.com/PokemonAutomation/ * */ diff --git a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp b/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp index 5ceffbc1f5..b66dc54809 100644 --- a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp +++ b/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp @@ -1,6 +1,6 @@ /* Game Entry * - * From: https://github.com/PokemonAutomation/Arduino-Source + * From: https://github.com/PokemonAutomation/ * */ @@ -36,8 +36,7 @@ bool reset_game_to_gamemenu( tolerate_update_menu ){ //Handle Right Joycon attempting to update - //If no update, this will open the All Software menu - //The active game will be closed from there + //Need detector for update prompt //pbf_move_joystick(context, 0, 128, 100ms, 10ms); //pbf_move_joystick(context, 0, 128, 100ms, 10ms); //pbf_press_button(context, BUTTON_A, 100ms, 10ms); @@ -69,8 +68,8 @@ bool gamemenu_to_ingame( pbf_mash_button(context, BUTTON_A, mash_duration); context.wait_for_all_requests(); - //White screen, Pikachu/Eevee running across the screen. - //Mash A at then end. + //White screen, Pikachu/Eevee running across the screen. Mash will not speed it up. + //Mash A at then end to enter continue screen BlackScreenOverWatcher detector(COLOR_RED, {0.2, 0.2, 0.6, 0.6}); stream.log("Waiting to enter game..."); int ret = run_until( diff --git a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h b/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h index 2323e993f7..21e08b2b41 100644 --- a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h +++ b/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h @@ -1,6 +1,6 @@ /* Game Entry * - * From: https://github.com/PokemonAutomation/Arduino-Source + * From: https://github.com/PokemonAutomation/ * */ diff --git a/SerialPrograms/Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.cpp b/SerialPrograms/Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.cpp index b770a09b94..a862786348 100644 --- a/SerialPrograms/Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.cpp +++ b/SerialPrograms/Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.cpp @@ -136,7 +136,7 @@ void AlolanTrade::program(SingleSwitchProgramEnvironment& env, CancellableScope& /* WARNING: JOYCON TEST PROGRAM. Not well tested. Bare minimum in general. - Only works with Right joycon atm. Do not update right joycon. + Only works with Right joycon atm. Do not update right joycon. Decline the update before running this. Right joycon required for home button (this means no on-switch screenshots). Also don't remap any of the buttons in the switch button mapping settings. Yet? Could use this to add Home and Screenshot. @@ -157,7 +157,7 @@ void AlolanTrade::program(SingleSwitchProgramEnvironment& env, CancellableScope& "you don't have any pokemon your trading partner wants" detect dialog box, detect yes/no confirm box actual enter game and start screen detectors - menu detectors, reset game from home, etc. + menu detectors, etc. get rid of all this blindly mashing A in general...so need everything really. */ @@ -180,11 +180,10 @@ void AlolanTrade::program(SingleSwitchProgramEnvironment& env, CancellableScope& //To check pokemon in menu boxes //Open menu - always defaults to center (Party) - /* Menu: - Play with Partner - Pokedex - Bag - Party - Communicate - Save (these all have a colored line under when selected) - (Press Y for options) - */ + //Menu: + // --Play with Partner--(centered) + //Pokedex - Bag - Party - Communicate - Save (these all have a colored line under when selected + an arrow to indicate) + //(Press Y for options) //Wait a bit. pbf_wait(context, 2500ms); From d9d3574ae8223e3b4d74b4a1001107f646c47e08 Mon Sep 17 00:00:00 2001 From: kichithewolf Date: Fri, 14 Mar 2025 10:02:05 -0400 Subject: [PATCH 4/7] remove unneeded video check --- .../Programs/PokemonLGPE_GameEntry.cpp | 31 +++++-------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp b/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp index b66dc54809..3849f38bbd 100644 --- a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp +++ b/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp @@ -30,29 +30,14 @@ bool reset_game_to_gamemenu( VideoStream& stream, JoyconContext& context, bool tolerate_update_menu ){ - bool video_available = (bool)stream.video().snapshot(); - if (video_available || - ConsoleSettings::instance().START_GAME_REQUIRES_INTERNET || - tolerate_update_menu - ){ - //Handle Right Joycon attempting to update - //Need detector for update prompt - //pbf_move_joystick(context, 0, 128, 100ms, 10ms); - //pbf_move_joystick(context, 0, 128, 100ms, 10ms); - //pbf_press_button(context, BUTTON_A, 100ms, 10ms); - - close_game(stream, context); - start_game_from_home( - stream, - context, - tolerate_update_menu, - 0, 0, - GameSettings::instance().START_GAME_MASH0 - ); - }else{ - pbf_press_button(context, BUTTON_X, 400ms, 0ms); - pbf_mash_button(context, BUTTON_A, GameSettings::instance().START_GAME_MASH0); - } + close_game(stream, context); + start_game_from_home( + stream, + context, + tolerate_update_menu, + 0, 0, + GameSettings::instance().START_GAME_MASH0 + ); // Now the game has opened: return openedgame_to_gamemenu(stream, context, GameSettings::instance().START_GAME_WAIT1); From 7a8ef0b3d4f5c7f6bacc5e71104878b481c98d00 Mon Sep 17 00:00:00 2001 From: kichithewolf Date: Fri, 14 Mar 2025 14:38:48 -0400 Subject: [PATCH 5/7] remove more video checks --- .../Programs/NintendoSwitch_GameEntry.cpp | 60 ------------------- .../Programs/NintendoSwitch_GameEntry.h | 3 +- .../Programs/PokemonLGPE_GameEntry.cpp | 10 ++-- .../Programs/PokemonLGPE_GameEntry.h | 4 +- .../ShinyHunting/PokemonLGPE_AlolanTrade.cpp | 2 +- 5 files changed, 7 insertions(+), 72 deletions(-) diff --git a/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.cpp b/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.cpp index 64bb44e44d..074db1a3b6 100644 --- a/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.cpp +++ b/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.cpp @@ -416,66 +416,6 @@ void start_game_from_home_with_inference( } } -void start_game_from_home( - VideoStream& stream, JoyconContext& context, - bool tolerate_update_menu, - uint8_t game_slot, - uint8_t user_slot, - Milliseconds start_game_mash -){ - context.wait_for_all_requests(); - if (stream.video().snapshot()){ - stream.log("start_game_from_home(): Video capture available. Using inference..."); - start_game_from_home_with_inference(stream, context, game_slot, user_slot, start_game_mash); - return; - }else{ - stream.log("start_game_from_home(): Video capture not available.", COLOR_RED); - } - - if (game_slot != 0){ - ssf_press_button(context, BUTTON_HOME, ConsoleSettings::instance().SETTINGS_TO_HOME_DELAY0, 160ms); - for (uint8_t c = 1; c < game_slot; c++){ - pbf_move_joystick(context, 255, 128, 80ms, 0ms); - } - } - - if (tolerate_update_menu){ - if (ConsoleSettings::instance().START_GAME_REQUIRES_INTERNET){ - throw UserSetupError( - stream.logger(), - "Cannot have both \"Tolerate Update Menu\" and \"Start Game Requires Internet\" enabled at the same time without video feedback." - ); - } - - // If the update menu isn't there, these will get swallowed by the opening - // animation for the select user menu. - pbf_press_button(context, BUTTON_A, 80ms, 1400ms); // Choose game - pbf_move_joystick(context, 128, 255, 100ms, 0ms); // Skip the update window. - move_to_user(context, user_slot); - } - -// cout << "START_GAME_REQUIRES_INTERNET = " << ConsoleSettings::instance().START_GAME_REQUIRES_INTERNET << endl; - if (!ConsoleSettings::instance().START_GAME_REQUIRES_INTERNET && user_slot == 0){ - // Mash your way into the game. - pbf_mash_button(context, BUTTON_A, start_game_mash); - }else{ - pbf_press_button(context, BUTTON_A, 80ms, 1400ms); // Enter select user menu. - move_to_user(context, user_slot); - ssf_press_button(context, BUTTON_A, 160ms); // Enter game - - // Switch to mashing ZL instead of A to get into the game. - // Mash your way into the game. - Milliseconds duration = start_game_mash; - if (ConsoleSettings::instance().START_GAME_REQUIRES_INTERNET){ - // Need to wait a bit longer for the internet check. - duration += ConsoleSettings::instance().START_GAME_INTERNET_CHECK_DELAY0; - } -// pbf_mash_button(context, BUTTON_ZL, duration); - pbf_wait(context, duration); - } - context.wait_for_all_requests(); -} - bool openedgame_to_gamemenu( VideoStream& stream, JoyconContext& context, Milliseconds timeout diff --git a/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.h b/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.h index b914a5fc45..8ff307bacb 100644 --- a/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.h +++ b/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.h @@ -36,9 +36,8 @@ bool openedgame_to_gamemenu( -void start_game_from_home( +void start_game_from_home_with_inference( VideoStream& stream, JoyconContext& context, - bool tolerate_update_menu, uint8_t game_slot, uint8_t user_slot, Milliseconds start_game_mash diff --git a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp b/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp index 3849f38bbd..afb11157fc 100644 --- a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp +++ b/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp @@ -27,14 +27,12 @@ namespace PokemonLGPE{ bool reset_game_to_gamemenu( - VideoStream& stream, JoyconContext& context, - bool tolerate_update_menu + VideoStream& stream, JoyconContext& context ){ close_game(stream, context); - start_game_from_home( + start_game_from_home_with_inference( stream, context, - tolerate_update_menu, 0, 0, GameSettings::instance().START_GAME_MASH0 ); @@ -98,11 +96,11 @@ bool gamemenu_to_ingame( bool reset_game_from_home( ProgramEnvironment& env, VideoStream& stream, JoyconContext& context, - bool tolerate_update_menu, Milliseconds post_wait_time ){ + bool ok = true; - ok &= reset_game_to_gamemenu(stream, context, tolerate_update_menu); + ok &= reset_game_to_gamemenu(stream, context); ok &= gamemenu_to_ingame( stream, context, GameSettings::instance().ENTER_GAME_MASH0, diff --git a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h b/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h index 21e08b2b41..54f245edcc 100644 --- a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h +++ b/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.h @@ -21,8 +21,7 @@ namespace PokemonLGPE{ // From Switch Home menu, reset game and wait until the game menu screen (where // "Press A" is displayed to enter the game) is shown. bool reset_game_to_gamemenu( - VideoStream& stream, JoyconContext& context, - bool tolerate_update_menu + VideoStream& stream, JoyconContext& context ); // From the game menu screen (where "Press A" is displayed to enter the game), @@ -36,7 +35,6 @@ bool gamemenu_to_ingame( // post_wait_time: how many ticks to wait after the black screen (shown when loading the map) is over. bool reset_game_from_home( ProgramEnvironment& env, VideoStream& stream, JoyconContext& context, - bool tolerate_update_menu, Milliseconds post_wait_time = 125ms ); diff --git a/SerialPrograms/Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.cpp b/SerialPrograms/Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.cpp index a862786348..1cbb33b04a 100644 --- a/SerialPrograms/Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.cpp +++ b/SerialPrograms/Source/PokemonLGPE/Programs/ShinyHunting/PokemonLGPE_AlolanTrade.cpp @@ -250,7 +250,7 @@ void AlolanTrade::program(SingleSwitchProgramEnvironment& env, CancellableScope& //Reset game pbf_press_button(context, BUTTON_HOME, 200ms, 2000ms); - reset_game_from_home(env, env.console, context, true, 3000ms); + reset_game_from_home(env, env.console, context, 3000ms); context.wait_for_all_requests(); stats.resets++; From 3a40a59114be829d73980fd65bf11fb62a023a62 Mon Sep 17 00:00:00 2001 From: kichithewolf Date: Fri, 14 Mar 2025 15:48:36 -0400 Subject: [PATCH 6/7] right joycon checks where home press needed --- .../Programs/NintendoSwitch_GameEntry.cpp | 11 +++++++++++ .../PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp | 12 +++++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.cpp b/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.cpp index 074db1a3b6..7a0c3b46c4 100644 --- a/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.cpp +++ b/SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_GameEntry.cpp @@ -12,6 +12,7 @@ #include "CommonTools/InferenceCallbacks/VisualInferenceCallback.h" #include "CommonTools/Async/InferenceRoutines.h" #include "CommonTools/VisualDetectors/BlackScreenDetector.h" +#include "Controllers/ControllerTypes.h" #include "NintendoSwitch/NintendoSwitch_Settings.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h" @@ -331,6 +332,16 @@ void start_game_from_home_with_inference( Milliseconds start_game_wait ){ context.wait_for_all_requests(); + + if (!(context.controller().controller_type() == ControllerType::NintendoSwitch_RightJoycon)) { + stream.log("Right Joycon required!", COLOR_RED); + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "start_game_from_home_with_inference(): Right Joycon required.", + stream + ); + } + { HomeWatcher detector; int ret = run_until( diff --git a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp b/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp index afb11157fc..d4a2cacd55 100644 --- a/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp +++ b/SerialPrograms/Source/PokemonLGPE/Programs/PokemonLGPE_GameEntry.cpp @@ -7,8 +7,10 @@ #include "CommonFramework/VideoPipeline/VideoFeed.h" #include "CommonFramework/Tools/ErrorDumper.h" #include "CommonFramework/Tools/ProgramEnvironment.h" +#include "CommonFramework/Exceptions/OperationFailedException.h" #include "CommonTools/Async/InferenceRoutines.h" #include "CommonTools/VisualDetectors/BlackScreenDetector.h" +#include "Controllers/ControllerCapability.h" #include "NintendoSwitch/NintendoSwitch_Settings.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" #include "NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.h" @@ -98,7 +100,15 @@ bool reset_game_from_home( ProgramEnvironment& env, VideoStream& stream, JoyconContext& context, Milliseconds post_wait_time ){ - + if (!(context.controller().controller_type() == ControllerType::NintendoSwitch_RightJoycon)) { + stream.log("Right Joycon required!", COLOR_RED); + OperationFailedException::fire( + ErrorReport::SEND_ERROR_REPORT, + "reset_game_from_home(): Right Joycon required.", + stream + ); + return false; + } bool ok = true; ok &= reset_game_to_gamemenu(stream, context); ok &= gamemenu_to_ingame( From a107ed3c678e4e298da0c61e489bd5ca62de1ec1 Mon Sep 17 00:00:00 2001 From: kichithewolf Date: Fri, 14 Mar 2025 19:49:03 -0400 Subject: [PATCH 7/7] one last video check removal --- .../NintendoSwitch_Commands_Routines.cpp | 36 ++++++------------- 1 file changed, 11 insertions(+), 25 deletions(-) diff --git a/SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.cpp b/SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.cpp index babd36a77e..b5cc55736e 100644 --- a/SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.cpp +++ b/SerialPrograms/Source/NintendoSwitch/Commands/NintendoSwitch_Commands_Routines.cpp @@ -88,34 +88,20 @@ void close_game(VideoStream& stream, JoyconContext& context){ pbf_press_button(context, BUTTON_HOME, 160ms, ConsoleSettings::instance().SETTINGS_TO_HOME_DELAY0); context.wait_for_all_requests(); -// cout << "waiting..." << endl; -// context.wait_for(10s); - - // send a second Home button press, if the first one is dropped - bool video_available = (bool)stream.video().snapshot(); - if (video_available){ - HomeWatcher detector; - int ret = wait_until( - stream, context, - std::chrono::milliseconds(5000), - { detector } - ); - if (ret == 0){ - stream.log("Detected Home screen."); - }else{ // if game initially open. | if game initially closed - // initial Home button press was dropped - // - Does nothing. | - goes back to home screen, from opened app - pbf_press_button(context, BUTTON_HOME, 160ms, ConsoleSettings::instance().SETTINGS_TO_HOME_DELAY0); - } - }else{ - // - wait some time after first Home button press - // to avoid triggering zoom - context.wait_for(std::chrono::milliseconds(1000)); - // - Does nothing. | - Press Home a second time in case we drop one. + HomeWatcher detector; + int ret = wait_until( + stream, context, + std::chrono::milliseconds(5000), + { detector } + ); + if (ret == 0){ + stream.log("Detected Home screen."); + }else{ // if game initially open. | if game initially closed + // initial Home button press was dropped + // - Does nothing. | - goes back to home screen, from opened app pbf_press_button(context, BUTTON_HOME, 160ms, ConsoleSettings::instance().SETTINGS_TO_HOME_DELAY0); } - // fail-safe against button drops and unexpected error messages. pbf_mash_button(context, BUTTON_X, 400ms); pbf_mash_button(context, BUTTON_B, 2000ms);