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 38c4d74629..8e7add03b7 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,8 @@ SidHelper::SidHelper()
&NOTIFICATION_ERROR_FATAL,
})
{
+ PA_ADD_OPTION(SIDS_DISPLAY);
+ PA_ADD_OPTION(LANGUAGE);
PA_ADD_OPTION(TARGET_ADVANCES);
PA_ADD_OPTION(NUM_CANDIDATES);
PA_ADD_OPTION(GO_HOME_WHEN_DONE);
@@ -93,17 +109,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);
@@ -221,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);
@@ -250,7 +266,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);
@@ -263,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 f197519444..5bc5c5d7f5 100644
--- a/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_SidHelper.h
+++ b/SerialPrograms/Source/PokemonFRLG/Programs/RngManipulation/PokemonFRLG_SidHelper.h
@@ -10,7 +10,9 @@
#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"
+#include "PokemonFRLG_RngDisplays.h"
namespace PokemonAutomation{
@@ -34,9 +36,13 @@ class SidHelper : public SingleSwitchProgramInstance {
) override {}
private:
+ OCR::LanguageOCROption LANGUAGE;
+
SimpleIntegerOption TARGET_ADVANCES;
SimpleIntegerOption NUM_CANDIDATES;
+ SidHelperDisplay SIDS_DISPLAY;
+
GoHomeWhenDoneOption GO_HOME_WHEN_DONE;
EventNotificationOption NOTIFICATION_SIDS;
EventNotificationsOption NOTIFICATIONS;