From 4cd876ff886dfa9cba398a4ec57261d43b6dc56a Mon Sep 17 00:00:00 2001 From: jw098 Date: Sat, 7 Feb 2026 23:42:49 -0800 Subject: [PATCH 1/2] add inference stop condition to LZA Turbomacro --- .../Source/PokemonLZA/PokemonLZA_Panels.cpp | 2 + .../Programs/PokemonLZA_TurboMacro.cpp | 122 ++++++++++++++++++ .../Programs/PokemonLZA_TurboMacro.h | 54 ++++++++ SerialPrograms/cmake/SourceFiles.cmake | 2 + 4 files changed, 180 insertions(+) create mode 100644 SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.cpp create mode 100644 SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.h diff --git a/SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp b/SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp index 71a4b0fd6f..870ab5f524 100644 --- a/SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp +++ b/SerialPrograms/Source/PokemonLZA/PokemonLZA_Panels.cpp @@ -15,6 +15,7 @@ #include "Programs/PokemonLZA_ClothingBuyer.h" #include "Programs/PokemonLZA_StallBuyer.h" #include "Programs/PokemonLZA_PostKillCatcher.h" +#include "Programs/PokemonLZA_TurboMacro.h" // Trading #include "Programs/Trading/PokemonLZA_SelfBoxTrade.h" @@ -79,6 +80,7 @@ std::vector PanelListFactory::make_panels() const{ ret.emplace_back(make_single_switch_program()); ret.emplace_back(make_single_switch_program()); if (IS_BETA_VERSION){ + ret.emplace_back(make_single_switch_program()); } ret.emplace_back("---- Farming ----"); diff --git a/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.cpp b/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.cpp new file mode 100644 index 0000000000..0618ddab7e --- /dev/null +++ b/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.cpp @@ -0,0 +1,122 @@ +/* Turbo Macro + * + * From: https://github.com/PokemonAutomation/ + * + */ + + +#include "CommonTools/Async/InferenceRoutines.h" +#include "PokemonLA/Inference/Sounds/PokemonLA_ShinySoundDetector.h" +#include "PokemonLZA/Options/PokemonLZA_ShinyDetectedAction.h" +#include "NintendoSwitch/Programs/NintendoSwitch_GameEntry.h" +#include "PokemonLZA_TurboMacro.h" + +//#include +//using std::cout; +//using std::endl; + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonLZA{ + + +LZA_TurboMacro_Descriptor::LZA_TurboMacro_Descriptor() + : SingleSwitchProgramDescriptor( + "NintendoSwitch:TurboMacro", + "Nintendo Switch", "Turbo Macro", + "Programs/NintendoSwitch/TurboMacro.html", + "Create macros", + ProgramControllerClass::StandardController_NoRestrictions, + FeedbackType::NONE, + AllowCommandsWhenRunning::DISABLE_COMMANDS + ) +{} + +LZA_TurboMacro::LZA_TurboMacro() + : LOOP( + "Number of times to loop:", + LockMode::UNLOCK_WHILE_RUNNING, + 100, 0 + ) + , TABLE( + "Command Schedule:", + { + ControllerClass::NintendoSwitch_ProController, + ControllerClass::NintendoSwitch_LeftJoycon, + ControllerClass::NintendoSwitch_RightJoycon, + } + ) + , GO_HOME_WHEN_DONE(true) + , RUN_UNTIL_CALLBACK( + "Trigger to stop program:", + { + {RunUntilCallback::NONE, "none", "None (stop when done all loops)"}, + {RunUntilCallback::SHINY_SOUND, "shiny-sound", "Shiny Sound Detected"}, + }, + LockMode::LOCK_WHILE_RUNNING, + RunUntilCallback::NONE + ) +{ + PA_ADD_OPTION(LOOP); + PA_ADD_OPTION(GO_HOME_WHEN_DONE); + PA_ADD_OPTION(RUN_UNTIL_CALLBACK); + PA_ADD_OPTION(TABLE); +} + + +void LZA_TurboMacro::program(SingleSwitchProgramEnvironment& env, CancellableScope& scope){ + ProControllerContext context(scope, env.console.controller()); + + switch (RUN_UNTIL_CALLBACK){ + case RunUntilCallback::NONE: + run_table(env, scope); + break; + case RunUntilCallback::SHINY_SOUND: + run_table_stop_when_shiny_sound(env, scope); + break; + default: + throw InternalProgramError(nullptr, PA_CURRENT_FUNCTION, "TurboMacro::program(): Unknown RunUntilCallback"); + + } + + if (GO_HOME_WHEN_DONE){ + go_home(env.console, context); + } +} + + +void LZA_TurboMacro::run_table(SingleSwitchProgramEnvironment& env, CancellableScope& scope){ + for (uint32_t c = 0; c < LOOP; c++){ + TABLE.run(scope, env.console.controller()); + } +} + +void LZA_TurboMacro::run_table_stop_when_shiny_sound(SingleSwitchProgramEnvironment& env, CancellableScope& scope){ + ShinySoundDetectedActionOption shiny_detected_option("Shiny Detected", "", "1000 ms", ShinySoundDetectedAction::NOTIFY_ON_FIRST_ONLY); + ShinySoundHandler shiny_sound_handler(shiny_detected_option); + PokemonLA::ShinySoundDetector shiny_detector(env.console, [&](float error_coefficient) -> bool { + // Warning: This callback will be run from a different thread than this function. + // env.console.overlay().add_log("Shiny Sound Detected!", COLOR_YELLOW); + return shiny_sound_handler.on_shiny_sound( + env, env.console, + 0, + error_coefficient + ); + }); + + int ret = run_until( + env.console, scope, + [&](CancellableScope& scope){ + run_table(env, scope); + }, + {shiny_detector} + ); + + if (ret == 0){ + return; + } +} + +} +} +} diff --git a/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.h b/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.h new file mode 100644 index 0000000000..3f48c6530b --- /dev/null +++ b/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.h @@ -0,0 +1,54 @@ +/* Turbo Macro + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#ifndef PokemonAutomation_PokemonLZA_TurboMacro_H +#define PokemonAutomation_PokemonLZA_TurboMacro_H + +#include "Common/Cpp/Options/SimpleIntegerOption.h" +#include "Controllers/ControllerStateTable.h" +#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" +#include "NintendoSwitch/Options/NintendoSwitch_GoHomeWhenDoneOption.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonLZA{ + + +class LZA_TurboMacro_Descriptor : public SingleSwitchProgramDescriptor{ +public: + LZA_TurboMacro_Descriptor(); +}; + + +class LZA_TurboMacro : public SingleSwitchProgramInstance{ +public: + LZA_TurboMacro(); + + virtual void program(SingleSwitchProgramEnvironment& env, CancellableScope& scope) override; + + void run_table(SingleSwitchProgramEnvironment& env, CancellableScope& scope); + + void run_table_stop_when_shiny_sound(SingleSwitchProgramEnvironment& env, CancellableScope& scope); + + +private: + SimpleIntegerOption LOOP; + ControllerCommandTables TABLE; + GoHomeWhenDoneOption GO_HOME_WHEN_DONE; + + enum class RunUntilCallback{ + NONE, + SHINY_SOUND, + }; + EnumDropdownOption RUN_UNTIL_CALLBACK; +}; + + + +} +} +} +#endif // PokemonAutomation_PokemonLZA_TurboMacro_H diff --git a/SerialPrograms/cmake/SourceFiles.cmake b/SerialPrograms/cmake/SourceFiles.cmake index 170a19dca2..56846c99fc 100644 --- a/SerialPrograms/cmake/SourceFiles.cmake +++ b/SerialPrograms/cmake/SourceFiles.cmake @@ -1753,6 +1753,8 @@ file(GLOB LIBRARY_SOURCES Source/PokemonLZA/Programs/PokemonLZA_StallBuyer.h Source/PokemonLZA/Programs/PokemonLZA_TrainerBattle.cpp Source/PokemonLZA/Programs/PokemonLZA_TrainerBattle.h + Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.cpp + Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.h Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_AutoFossil.cpp Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_AutoFossil.h Source/PokemonLZA/Programs/ShinyHunting/PokemonLZA_BeldumHunter.cpp From ee1594fa8a0ad2139a321dbd19cb3ef2506445d6 Mon Sep 17 00:00:00 2001 From: jw098 Date: Sun, 8 Feb 2026 11:39:07 -0800 Subject: [PATCH 2/2] update descriptor. add stats. --- .../Programs/PokemonLZA_TurboMacro.cpp | 39 +++++++++++++++++-- .../Programs/PokemonLZA_TurboMacro.h | 3 ++ 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.cpp b/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.cpp index 0618ddab7e..1cddbc0f0a 100644 --- a/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.cpp +++ b/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.cpp @@ -9,6 +9,9 @@ #include "PokemonLA/Inference/Sounds/PokemonLA_ShinySoundDetector.h" #include "PokemonLZA/Options/PokemonLZA_ShinyDetectedAction.h" #include "NintendoSwitch/Programs/NintendoSwitch_GameEntry.h" +#include "Pokemon/Pokemon_Strings.h" +#include "CommonFramework/ProgramStats/StatsTracking.h" +#include "CommonFramework/Notifications/ProgramNotifications.h" #include "PokemonLZA_TurboMacro.h" //#include @@ -19,19 +22,40 @@ namespace PokemonAutomation{ namespace NintendoSwitch{ namespace PokemonLZA{ +using namespace Pokemon; LZA_TurboMacro_Descriptor::LZA_TurboMacro_Descriptor() : SingleSwitchProgramDescriptor( - "NintendoSwitch:TurboMacro", - "Nintendo Switch", "Turbo Macro", + "PokemonLZA:TurboMacro", STRING_POKEMON + " LZA", + "Turbo Macro", "Programs/NintendoSwitch/TurboMacro.html", - "Create macros", + "Create macros. Stops with specific trigger (e.g. shiny sound).", ProgramControllerClass::StandardController_NoRestrictions, FeedbackType::NONE, AllowCommandsWhenRunning::DISABLE_COMMANDS ) {} +class LZA_TurboMacro_Descriptor::Stats : public StatsTracker{ +public: + Stats() + : loops(m_stats["Loops"]) + , shinies(m_stats["Shiny Sounds"]) + , errors(m_stats["Errors"]) + { + m_display_order.emplace_back("Loops"); + m_display_order.emplace_back("Shiny Sounds"); + m_display_order.emplace_back("Errors", HIDDEN_IF_ZERO); + } + + std::atomic& loops; + std::atomic& shinies; + std::atomic& errors; +}; +std::unique_ptr LZA_TurboMacro_Descriptor::make_stats() const{ + return std::unique_ptr(new Stats()); +} + LZA_TurboMacro::LZA_TurboMacro() : LOOP( "Number of times to loop:", @@ -82,16 +106,23 @@ void LZA_TurboMacro::program(SingleSwitchProgramEnvironment& env, CancellableSco if (GO_HOME_WHEN_DONE){ go_home(env.console, context); } + send_program_finished_notification(env, NOTIFICATION_PROGRAM_FINISH); } void LZA_TurboMacro::run_table(SingleSwitchProgramEnvironment& env, CancellableScope& scope){ + LZA_TurboMacro_Descriptor::Stats& stats = + env.current_stats(); for (uint32_t c = 0; c < LOOP; c++){ TABLE.run(scope, env.console.controller()); + stats.loops++; + env.update_stats(); } } void LZA_TurboMacro::run_table_stop_when_shiny_sound(SingleSwitchProgramEnvironment& env, CancellableScope& scope){ + LZA_TurboMacro_Descriptor::Stats& stats = + env.current_stats(); ShinySoundDetectedActionOption shiny_detected_option("Shiny Detected", "", "1000 ms", ShinySoundDetectedAction::NOTIFY_ON_FIRST_ONLY); ShinySoundHandler shiny_sound_handler(shiny_detected_option); PokemonLA::ShinySoundDetector shiny_detector(env.console, [&](float error_coefficient) -> bool { @@ -113,6 +144,8 @@ void LZA_TurboMacro::run_table_stop_when_shiny_sound(SingleSwitchProgramEnvironm ); if (ret == 0){ + stats.shinies++; + env.update_stats(); return; } } diff --git a/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.h b/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.h index 3f48c6530b..c4ebda8b90 100644 --- a/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.h +++ b/SerialPrograms/Source/PokemonLZA/Programs/PokemonLZA_TurboMacro.h @@ -20,6 +20,9 @@ namespace PokemonLZA{ class LZA_TurboMacro_Descriptor : public SingleSwitchProgramDescriptor{ public: LZA_TurboMacro_Descriptor(); + + class Stats; + virtual std::unique_ptr make_stats() const override; };