From e6efe8b32458b21b4872833eb50775d192368e35 Mon Sep 17 00:00:00 2001 From: theAstrogoth Date: Fri, 24 Apr 2026 15:08:57 -0500 Subject: [PATCH 1/2] add text frames to sid helper --- .../RngManipulation/PokemonFRLG_SidHelper.cpp | 66 +++++++++++++++---- .../RngManipulation/PokemonFRLG_SidHelper.h | 3 + 2 files changed, 57 insertions(+), 12 deletions(-) diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_SidHelper.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_SidHelper.cpp index 38c4d74629..b61a17fad4 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_SidHelper.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_SidHelper.cpp @@ -53,12 +53,26 @@ std::unique_ptr SidHelper_Descriptor::make_stats() const{ } SidHelper::SidHelper() - : TARGET_ADVANCES( + : LANGUAGE( + "Game Language:
" + "Language affects the number of advances (based on the number of text characters) that pass after the last button press.", + { + Language::English, + Language::Japanese, + Language::Spanish, + Language::French, + Language::German, + Language::Italian, + }, + LockMode::LOCK_WHILE_RUNNING, + true + ) + , TARGET_ADVANCES( "Target Advances:
" "The target advances for finalizing the SID. This is arbitrary unless you're attempting to hit a specific TID/SID combination.
" "This value should always be odd.", LockMode::LOCK_WHILE_RUNNING, - 2301, 2000 // default, min + 2301, 2275 // default, min ) , NUM_CANDIDATES( "# Candidate SIDs:
" @@ -74,6 +88,7 @@ SidHelper::SidHelper() &NOTIFICATION_ERROR_FATAL, }) { + PA_ADD_OPTION(LANGUAGE); PA_ADD_OPTION(TARGET_ADVANCES); PA_ADD_OPTION(NUM_CANDIDATES); PA_ADD_OPTION(GO_HOME_WHEN_DONE); @@ -93,17 +108,17 @@ void set_sid_from_name_screen( // confirm name (SID delay starts now) pbf_press_button(context, BUTTON_A, 200ms, 1800ms); // advance to "...about to unfold!", picking the default rival name - pbf_press_button(context, BUTTON_A, 200ms, 2800ms); - pbf_press_button(context, BUTTON_A, 200ms, 1300ms); - pbf_press_button(context, BUTTON_A, 200ms, 1800ms); + pbf_press_button(context, BUTTON_A, 200ms, 2300ms); + pbf_press_button(context, BUTTON_A, 200ms, 1050ms); + pbf_press_button(context, BUTTON_A, 200ms, 1550ms); pbf_move_left_joystick(context, {0,-1}, 200ms, 300ms); - pbf_press_button(context, BUTTON_A, 200ms, 1300ms); - pbf_press_button(context, BUTTON_A, 200ms, 1800ms); - pbf_press_button(context, BUTTON_A, 200ms, 2800ms); + pbf_press_button(context, BUTTON_A, 200ms, 1050ms); + pbf_press_button(context, BUTTON_A, 200ms, 1550ms); + pbf_press_button(context, BUTTON_A, 200ms, 2300ms); - // 2000 + 3000 + 1500 + 2000 + 500 + 1500 + 2000 + 3000 + 200 ms - Milliseconds delay(SID_DELAY > 15700 - ? SID_DELAY - 15700 + // 2000 + 2500 + 1250 + 1750 + 500 + 1250 + 1750 + 2500 + 200 ms + Milliseconds delay(SID_DELAY > 13700 + ? SID_DELAY - 13700 : 0 ); pbf_press_button(context, BUTTON_A, 200ms, delay); @@ -250,7 +265,34 @@ void SidHelper::program(SingleSwitchProgramEnvironment& env, ProControllerContex double FRAMERATE = 59.999977; // FPS double FRAME_DURATION = 1000 / FRAMERATE; // ms - const uint64_t SID_DELAY = uint64_t((TARGET_ADVANCES - 1) * FRAME_DURATION / 2); // advances pass 2 by 2, first one doesn't count (?) + uint64_t FINAL_TEXT_FRAMES; + Language lang = LANGUAGE; + switch (lang){ + case Language::English: + FINAL_TEXT_FRAMES = 249; + break; + case Language::Japanese: + FINAL_TEXT_FRAMES = 194; + break; + case Language::Italian: + FINAL_TEXT_FRAMES = 236; + break; + case Language::French: + FINAL_TEXT_FRAMES = 205; + break; + case Language::German: + FINAL_TEXT_FRAMES = 208; + break; + case Language::Spanish: + FINAL_TEXT_FRAMES = 202; + break; + default: + FINAL_TEXT_FRAMES = 249; + } + + const double& FIXED_ADVANCES_OFFSET = 7; // determined empirically. Probably not console/setup dependent + + const uint64_t SID_DELAY = uint64_t((TARGET_ADVANCES - 2*FINAL_TEXT_FRAMES + FIXED_ADVANCES_OFFSET) * FRAME_DURATION / 2); // advances pass 2 by 2 env.log("Delay: " + std::to_string(SID_DELAY) + "ms"); set_sid_from_name_screen(env, context, SID_DELAY); diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_SidHelper.h b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_SidHelper.h index f197519444..82a76d99ba 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_SidHelper.h +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_SidHelper.h @@ -10,6 +10,7 @@ #include "Common/Cpp/Options/SimpleIntegerOption.h" #include "CommonFramework/Notifications/EventNotificationsTable.h" #include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" +#include "CommonTools/Options/LanguageOCROption.h" #include "NintendoSwitch/Options/NintendoSwitch_GoHomeWhenDoneOption.h" @@ -34,6 +35,8 @@ class SidHelper : public SingleSwitchProgramInstance { ) override {} private: + OCR::LanguageOCROption LANGUAGE; + SimpleIntegerOption TARGET_ADVANCES; SimpleIntegerOption NUM_CANDIDATES; From 922543213f8a3cce5c4b9e45334def8f99894fca Mon Sep 17 00:00:00 2001 From: theAstrogoth Date: Fri, 24 Apr 2026 22:54:02 -0500 Subject: [PATCH 2/2] add results display for SIDs --- .../PokemonFRLG_RngDisplays.cpp | 22 +++++++++++++++++++ .../RngManipulation/PokemonFRLG_RngDisplays.h | 15 +++++++++++++ .../RngManipulation/PokemonFRLG_SidHelper.cpp | 5 ++++- .../RngManipulation/PokemonFRLG_SidHelper.h | 3 +++ 4 files changed, 44 insertions(+), 1 deletion(-) diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngDisplays.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngDisplays.cpp index 8598682f6b..64bc3f4ff8 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngDisplays.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngDisplays.cpp @@ -15,6 +15,28 @@ namespace PokemonFRLG{ using namespace Pokemon; +SidHelperDisplay::SidHelperDisplay() + : GroupOption("TID/SID Results", LockMode::READ_ONLY) + , tid(false, "Trainer ID:", LockMode::READ_ONLY, "-", "") + , sids("SID Possibilities:", LockMode::READ_ONLY, "-", "") +{ + PA_ADD_STATIC(tid); + PA_ADD_STATIC(sids); +} +std::string SidHelperDisplay::get_sids_string(const std::vector>& sid_messages){ + std::string sid_str = ""; + for (auto& str_pair : sid_messages){ + sid_str += str_pair.first + ": "; + sid_str += str_pair.second + "\n"; + } + return sid_str; +} +void SidHelperDisplay::set(uint16_t trainerId, const std::vector>& sid_messages){ + tid.set(std::to_string(trainerId)); + sids.set(get_sids_string(sid_messages)); +} + + RngFilterDisplay::RngFilterDisplay() : GroupOption("Observed Stats", LockMode::READ_ONLY) , hp(false, "HP IV:", LockMode::READ_ONLY, "-", "") diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngDisplays.h b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngDisplays.h index 9ba631caa7..103d99143e 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngDisplays.h +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_RngDisplays.h @@ -9,6 +9,7 @@ #include #include "Common/Cpp/Options/StringOption.h" +#include "Common/Cpp/Options/TextEditOption.h" #include "CommonFramework/Notifications/EventNotificationsTable.h" #include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" #include "Pokemon/Pokemon_AdvRng.h" @@ -20,6 +21,20 @@ namespace PokemonFRLG{ using namespace Pokemon; +class SidHelperDisplay: public GroupOption{ +public: + SidHelperDisplay(); + + void set(uint16_t trainerId, const std::vector>& sid_messages); + +private: + static std::string get_sids_string(const std::vector>& sid_messages); + +public: + StringOption tid; + TextEditOption sids; +}; + class RngFilterDisplay : public GroupOption{ public: RngFilterDisplay(); diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_SidHelper.cpp b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_SidHelper.cpp index b61a17fad4..8e7add03b7 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_SidHelper.cpp +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_SidHelper.cpp @@ -88,6 +88,7 @@ SidHelper::SidHelper() &NOTIFICATION_ERROR_FATAL, }) { + PA_ADD_OPTION(SIDS_DISPLAY); PA_ADD_OPTION(LANGUAGE); PA_ADD_OPTION(TARGET_ADVANCES); PA_ADD_OPTION(NUM_CANDIDATES); @@ -236,7 +237,7 @@ std::vector> get_sid_messages( std::pair m; uint16_t sid = searcher.state.s0 >> 16; - m.first = "Advances " + std::to_string(searcher.state.advance); + m.first = std::to_string(searcher.state.advance) + " Advances"; m.second = std::to_string(sid); messages.push_back(m); @@ -305,6 +306,8 @@ void SidHelper::program(SingleSwitchProgramEnvironment& env, ProControllerContex env, context, tid, TARGET_ADVANCES, NUM_CANDIDATES ); + SIDS_DISPLAY.set(tid, sid_messages); + send_program_notification(env, NOTIFICATION_SIDS, COLOR_BLUE, "Possible SIDs:", sid_messages, ""); send_program_finished_notification(env, NOTIFICATION_PROGRAM_FINISH); diff --git a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_SidHelper.h b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_SidHelper.h index 82a76d99ba..5bc5c5d7f5 100644 --- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_SidHelper.h +++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_SidHelper.h @@ -12,6 +12,7 @@ #include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" #include "CommonTools/Options/LanguageOCROption.h" #include "NintendoSwitch/Options/NintendoSwitch_GoHomeWhenDoneOption.h" +#include "PokemonFRLG_RngDisplays.h" namespace PokemonAutomation{ @@ -40,6 +41,8 @@ class SidHelper : public SingleSwitchProgramInstance { SimpleIntegerOption TARGET_ADVANCES; SimpleIntegerOption NUM_CANDIDATES; + SidHelperDisplay SIDS_DISPLAY; + GoHomeWhenDoneOption GO_HOME_WHEN_DONE; EventNotificationOption NOTIFICATION_SIDS; EventNotificationsOption NOTIFICATIONS;