From 5a845c243e4f46c0f1285f34c74b08fd723475be Mon Sep 17 00:00:00 2001 From: theAstrogoth Date: Mon, 10 Aug 2026 09:45:40 -0500 Subject: [PATCH 1/5] add BDSP summary reader --- .../Rng/PokemonBDSP_SummaryReader.cpp | 163 ++++++++++++++++++ .../Inference/Rng/PokemonBDSP_SummaryReader.h | 66 +++++++ 2 files changed, 229 insertions(+) create mode 100644 SerialPrograms/Source/PokemonBDSP/Inference/Rng/PokemonBDSP_SummaryReader.cpp create mode 100644 SerialPrograms/Source/PokemonBDSP/Inference/Rng/PokemonBDSP_SummaryReader.h diff --git a/SerialPrograms/Source/PokemonBDSP/Inference/Rng/PokemonBDSP_SummaryReader.cpp b/SerialPrograms/Source/PokemonBDSP/Inference/Rng/PokemonBDSP_SummaryReader.cpp new file mode 100644 index 0000000000..48f0ac42f7 --- /dev/null +++ b/SerialPrograms/Source/PokemonBDSP/Inference/Rng/PokemonBDSP_SummaryReader.cpp @@ -0,0 +1,163 @@ +/* BDSP Summary Reader + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#include +#include "Common/Cpp/Logging/AbstractLogger.h" +#include "CommonFramework/ImageTypes/ImageViewRGB32.h" +#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h" +#include "CommonTools/OCR/OCR_NumberReader.h" +#include "CommonTools/OCR/OCR_Routines.h" +#include "Pokemon/Inference/Pokemon_NatureReader.h" +#include "PokemonBDSP/Inference/BoxSystem/PokemonBDSP_BoxNatureDetector.h" +#include "PokemonBDSP_SummaryReader.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonBDSP{ + +using namespace Pokemon; + + +static const std::vector& MEMO_TEXT_FILTERS(){ + static std::vector filters{ + // Red. + {0xff600000, 0xffff8080}, + {0xff800000, 0xffff6060}, + // Black, as a fallback. + {0xff000000, 0xff606060}, + {0xff000000, 0xff909090}, + }; + return filters; +} + + +const LanguageSet& summary_nature_languages(){ + return NATURE_READER().languages(); +} + + +SummaryReader::SummaryReader(Color color) + : m_color(color) + , m_box_nature (0.055, 0.190, 0.410, 0.062) + , m_box_gender (0.790, 0.094, 0.024, 0.040) + , m_box_hp (0.228, 0.168, 0.080, 0.054) + , m_box_attack (0.376, 0.288, 0.048, 0.052) + , m_box_defense(0.376, 0.436, 0.048, 0.052) + , m_box_spatk (0.112, 0.288, 0.048, 0.052) + , m_box_spdef (0.112, 0.436, 0.048, 0.052) + , m_box_speed (0.242, 0.543, 0.048, 0.052) +{} + +void SummaryReader::make_memo_overlays(VideoOverlaySet& items) const{ + items.add(m_color, m_box_nature, "nature"); + items.add(m_color, m_box_gender, "gender"); +} + +void SummaryReader::make_skills_overlays(VideoOverlaySet& items) const{ + items.add(m_color, m_box_gender, "gender"); + items.add(m_color, m_box_hp, "hp"); + items.add(m_color, m_box_attack, "atk"); + items.add(m_color, m_box_defense, "def"); + items.add(m_color, m_box_spatk, "spatk"); + items.add(m_color, m_box_spdef, "spdef"); + items.add(m_color, m_box_speed, "spe"); +} + + +NatureCheckerValue SummaryReader::read_nature( + Logger& logger, Language language, const ImageViewRGB32& frame +) const{ + if (language == Language::None){ + return NatureCheckerValue::UnableToDetect; + } + ImageViewRGB32 line = extract_box_reference(frame, m_box_nature); + OCR::StringMatchResult result = NATURE_READER().read_substring( + logger, language, line, MEMO_TEXT_FILTERS() + ); + result.clear_beyond_log10p(NatureReader::MAX_LOG10P); + if (result.results.size() != 1){ + return NatureCheckerValue::UnableToDetect; + } + return NATURE_CHECKER_VALUE_STRINGS().get_enum(result.results.begin()->second.token); +} + + +BdspGender SummaryReader::read_gender(Logger& logger, const ImageViewRGB32& frame) const{ + ImageViewRGB32 box = extract_box_reference(frame, m_box_gender); + + size_t blue_pixels = 0; + size_t pink_pixels = 0; + for (size_t y = 0; y < box.height(); y++){ + for (size_t x = 0; x < box.width(); x++){ + uint32_t pixel = box.pixel(x, y); + uint32_t red = (pixel >> 16) & 0xff; + uint32_t green = (pixel >> 8) & 0xff; + uint32_t blue = pixel & 0xff; + if (blue > red + 40 && blue > green + 20){ + blue_pixels++; + }else if (red > green + 40 && blue > green + 40){ + pink_pixels++; + } + } + } + logger.log("Gender symbol: " + std::to_string(blue_pixels) + " blue pixels, " + + std::to_string(pink_pixels) + " pink."); + if (blue_pixels == 0 && pink_pixels == 0){ + return BdspGender::Genderless; + } + return blue_pixels > pink_pixels ? BdspGender::Male : BdspGender::Female; +} + + +int16_t SummaryReader::read_stat( + Logger& logger, const ImageViewRGB32& frame, const ImageFloatBox& box +) const{ + ImageViewRGB32 image = extract_box_reference(frame, box); + int value = OCR::read_number_waterfill(logger, image, 0xff000000, 0xff808080); + if (value < 5 || value > 40){ + return -1; + } + return (int16_t)value; +} + + +int16_t SummaryReader::read_hp_total(Logger& logger, const ImageViewRGB32& frame) const{ + ImageViewRGB32 image = extract_box_reference(frame, m_box_hp); + int value = OCR::read_number_waterfill(logger, image, 0xff000000, 0xff808080); + if (value < 0){ + return -1; + } + std::string digits = std::to_string(value); + if (digits.size() < 2){ + // Only the current HP came through, or nothing did. Either way the total is + // not in there. + return -1; + } + int total = std::stoi(digits.substr(digits.size() - 2)); + logger.log("HP read as \"" + digits + "\", taking " + std::to_string(total) + + " as the total."); + if (total < 15 || total > 30){ + return -1; + } + return (int16_t)total; +} + + +StatReads SummaryReader::read_stats(Logger& logger, const ImageViewRGB32& frame) const{ + StatReads ret; + ret.hp = read_hp_total(logger, frame); + ret.attack = read_stat(logger, frame, m_box_attack); + ret.defense = read_stat(logger, frame, m_box_defense); + ret.spatk = read_stat(logger, frame, m_box_spatk); + ret.spdef = read_stat(logger, frame, m_box_spdef); + ret.speed = read_stat(logger, frame, m_box_speed); + return ret; +} + + +} +} +} diff --git a/SerialPrograms/Source/PokemonBDSP/Inference/Rng/PokemonBDSP_SummaryReader.h b/SerialPrograms/Source/PokemonBDSP/Inference/Rng/PokemonBDSP_SummaryReader.h new file mode 100644 index 0000000000..154ff5b224 --- /dev/null +++ b/SerialPrograms/Source/PokemonBDSP/Inference/Rng/PokemonBDSP_SummaryReader.h @@ -0,0 +1,66 @@ +/* BDSP Summary Reader + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#ifndef PokemonAutomation_PokemonBDSP_SummaryReader_H +#define PokemonAutomation_PokemonBDSP_SummaryReader_H + +#include +#include "Common/Cpp/Color.h" +#include "CommonFramework/ImageTools/ImageBoxes.h" +#include "CommonFramework/Language.h" +#include "Pokemon/Pokemon_BdspRng.h" +#include "Pokemon/Pokemon_NatureChecker.h" +#include "Pokemon/Pokemon_StatsCalculation.h" + +namespace PokemonAutomation{ + class Logger; + class ImageViewRGB32; + class VideoOverlaySet; +namespace NintendoSwitch{ +namespace PokemonBDSP{ + + +const LanguageSet& summary_nature_languages(); + + +class SummaryReader{ +public: + SummaryReader(Color color = COLOR_RED); + + void make_memo_overlays(VideoOverlaySet& items) const; + void make_skills_overlays(VideoOverlaySet& items) const; + + Pokemon::NatureCheckerValue read_nature( + Logger& logger, Language language, const ImageViewRGB32& frame + ) const; + + Pokemon::BdspGender read_gender(Logger& logger, const ImageViewRGB32& frame) const; + + Pokemon::StatReads read_stats(Logger& logger, const ImageViewRGB32& frame) const; + +private: + int16_t read_stat( + Logger& logger, const ImageViewRGB32& frame, const ImageFloatBox& box + ) const; + + int16_t read_hp_total(Logger& logger, const ImageViewRGB32& frame) const; + + Color m_color; + ImageFloatBox m_box_nature; + ImageFloatBox m_box_gender; + ImageFloatBox m_box_hp; + ImageFloatBox m_box_attack; + ImageFloatBox m_box_defense; + ImageFloatBox m_box_spatk; + ImageFloatBox m_box_spdef; + ImageFloatBox m_box_speed; +}; + + +} +} +} +#endif From c34de6bdd1d47de96aad27481ee90b7ef10a97e2 Mon Sep 17 00:00:00 2001 From: theAstrogoth Date: Mon, 10 Aug 2026 09:46:34 -0500 Subject: [PATCH 2/5] add summary reader test program --- .../Source/PokemonBDSP/PokemonBDSP_Panels.cpp | 2 + .../PokemonBDSP_SummaryReaderTester.cpp | 139 ++++++++++++++++++ .../PokemonBDSP_SummaryReaderTester.h | 38 +++++ 3 files changed, 179 insertions(+) create mode 100644 SerialPrograms/Source/PokemonBDSP/Programs/TestPrograms/PokemonBDSP_SummaryReaderTester.cpp create mode 100644 SerialPrograms/Source/PokemonBDSP/Programs/TestPrograms/PokemonBDSP_SummaryReaderTester.h diff --git a/SerialPrograms/Source/PokemonBDSP/PokemonBDSP_Panels.cpp b/SerialPrograms/Source/PokemonBDSP/PokemonBDSP_Panels.cpp index a95654dd6a..4010f10640 100644 --- a/SerialPrograms/Source/PokemonBDSP/PokemonBDSP_Panels.cpp +++ b/SerialPrograms/Source/PokemonBDSP/PokemonBDSP_Panels.cpp @@ -41,6 +41,7 @@ #include "Programs/TestPrograms/PokemonBDSP_ShinyEncounterTester.h" #include "Programs/TestPrograms/PokemonBDSP_SoundListener.h" +#include "Programs/TestPrograms/PokemonBDSP_SummaryReaderTester.h" namespace PokemonAutomation{ namespace NintendoSwitch{ @@ -103,6 +104,7 @@ std::vector PanelListFactory::make_panels() const{ ret.emplace_back("---- Developer Tools ----"); ret.emplace_back(make_single_switch_program()); ret.emplace_back(make_single_switch_program()); + ret.emplace_back(make_single_switch_program()); } return ret; diff --git a/SerialPrograms/Source/PokemonBDSP/Programs/TestPrograms/PokemonBDSP_SummaryReaderTester.cpp b/SerialPrograms/Source/PokemonBDSP/Programs/TestPrograms/PokemonBDSP_SummaryReaderTester.cpp new file mode 100644 index 0000000000..67381770ee --- /dev/null +++ b/SerialPrograms/Source/PokemonBDSP/Programs/TestPrograms/PokemonBDSP_SummaryReaderTester.cpp @@ -0,0 +1,139 @@ +/* Summary Reader Tester + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#include +#include +#include "Common/Cpp/Color.h" +#include "CommonFramework/VideoPipeline/VideoFeed.h" +#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h" +#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h" +#include "Pokemon/Pokemon_NatureChecker.h" +#include "Pokemon/Pokemon_Strings.h" +#include "PokemonBDSP/Inference/Rng/PokemonBDSP_SummaryReader.h" +#include "PokemonBDSP_SummaryReaderTester.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonBDSP{ + +using namespace std::chrono_literals; +using namespace Pokemon; + + +SummaryReaderTester_Descriptor::SummaryReaderTester_Descriptor() + : SingleSwitchProgramDescriptor( + "PokemonBDSP:SummaryReaderTester", + STRING_POKEMON + " BDSP", "Summary Reader Tester", + "", + "Read a " + STRING_POKEMON + "'s nature, gender and stats off its summary pages. " + "Start on the Trainer Memo page.", + ProgramControllerClass::StandardController_NoRestrictions, + FeedbackType::REQUIRED, + AllowCommandsWhenRunning::DISABLE_COMMANDS + ) +{} + + +SummaryReaderTester::SummaryReaderTester() + : LANGUAGE( + "Game Language:
Needed for the nature, which is read as text.", + summary_nature_languages(), + LockMode::LOCK_WHILE_RUNNING, true + ) +{ + PA_ADD_OPTION(LANGUAGE); +} + + +static std::string or_unread(int16_t value){ + return value < 0 ? "???" : std::to_string(value); +} + + +void SummaryReaderTester::program( + SingleSwitchProgramEnvironment& env, ProControllerContext& context +){ + env.log("Start on the Trainer Memo page — the one reading " + "\"This " + STRING_POKEMON + " is pretty [nature] by nature.\""); + env.log("If no boxes appear on the video, check that the overlay's box display " + "is switched on for this console."); + + VideoOverlaySet overlays(env.console.overlay()); + SummaryReader reader; + + { + reader.make_memo_overlays(overlays); + + VideoSnapshot screen = env.console.video().snapshot(); + NatureCheckerValue nature = reader.read_nature(env.logger(), LANGUAGE, screen); + BdspGender gender = reader.read_gender(env.logger(), screen); + + env.log("Nature: " + std::string( + nature == NatureCheckerValue::UnableToDetect + ? "??? (not read)" + : NATURE_CHECKER_VALUE_STRINGS().get_string(nature) + ), COLOR_BLUE); + env.log("Gender: " + std::string(bdsp_gender_name(gender)), COLOR_BLUE); + if (gender == BdspGender::Genderless){ + env.log("Genderless means the symbol was not found. A starter always has one.", + COLOR_ORANGE); + } + + pbf_wait(context, 5s); + context.wait_for_all_requests(); + } + + env.log("Moving to the " + STRING_POKEMON + " Skills page..."); + pbf_press_dpad(context, DPAD_RIGHT, 100ms, 100ms); + context.wait_for_all_requests(); + pbf_wait(context, 1500ms); + context.wait_for_all_requests(); + + { + overlays.clear(); + reader.make_skills_overlays(overlays); + + VideoSnapshot screen = env.console.video().snapshot(); + StatReads stats = reader.read_stats(env.logger(), screen); + BdspGender gender = reader.read_gender(env.logger(), screen); + + env.log("Gender (from this page): " + std::string(bdsp_gender_name(gender)), COLOR_BLUE); + env.log("HP (total): " + or_unread(stats.hp), COLOR_BLUE); + env.log("Attack: " + or_unread(stats.attack), COLOR_BLUE); + env.log("Defense: " + or_unread(stats.defense), COLOR_BLUE); + env.log("Sp. Atk: " + or_unread(stats.spatk), COLOR_BLUE); + env.log("Sp. Def: " + or_unread(stats.spdef), COLOR_BLUE); + env.log("Speed: " + or_unread(stats.speed), COLOR_BLUE); + + + size_t unread = 0; + for (int16_t value : {stats.hp, stats.attack, stats.defense, + stats.spatk, stats.spdef, stats.speed}){ + if (value < 0){ + unread++; + } + } + if (unread == 0){ + env.log("All six read.", COLOR_BLUE); + }else{ + env.log(std::to_string(unread) + " of 6 stats could not be read. One is survivable; " + "several means the boxes need moving, and the overlay will show where.", + COLOR_ORANGE); + } + + env.log("Boxes are on the overlay. Compare them against the numbers on screen.", + COLOR_BLUE); + pbf_wait(context, 15s); + context.wait_for_all_requests(); + } +} + + + + +} +} +} diff --git a/SerialPrograms/Source/PokemonBDSP/Programs/TestPrograms/PokemonBDSP_SummaryReaderTester.h b/SerialPrograms/Source/PokemonBDSP/Programs/TestPrograms/PokemonBDSP_SummaryReaderTester.h new file mode 100644 index 0000000000..eb69111598 --- /dev/null +++ b/SerialPrograms/Source/PokemonBDSP/Programs/TestPrograms/PokemonBDSP_SummaryReaderTester.h @@ -0,0 +1,38 @@ +/* Summary Reader Tester + * + * From: https://github.com/PokemonAutomation/ + * + */ + +#ifndef PokemonAutomation_PokemonBDSP_SummaryReaderTester_H +#define PokemonAutomation_PokemonBDSP_SummaryReaderTester_H + +#include "CommonTools/Options/LanguageOCROption.h" +#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h" + +namespace PokemonAutomation{ +namespace NintendoSwitch{ +namespace PokemonBDSP{ + + +class SummaryReaderTester_Descriptor : public SingleSwitchProgramDescriptor{ +public: + SummaryReaderTester_Descriptor(); +}; + + +class SummaryReaderTester : public SingleSwitchProgramInstance{ +public: + SummaryReaderTester(); + + virtual void program(SingleSwitchProgramEnvironment& env, ProControllerContext& context) override; + +private: + OCR::LanguageOCROption LANGUAGE; +}; + + +} +} +} +#endif From 94d8618bd09950bc3b742c48cf4f939fca2258bc Mon Sep 17 00:00:00 2001 From: theAstrogoth Date: Mon, 10 Aug 2026 09:47:29 -0500 Subject: [PATCH 3/5] tweak menu detector to handle 'New' icon --- .../Inference/PokemonBDSP_MenuDetector.cpp | 24 ++++++++++++------- .../Inference/PokemonBDSP_MenuDetector.h | 17 +++++++++++-- 2 files changed, 31 insertions(+), 10 deletions(-) diff --git a/SerialPrograms/Source/PokemonBDSP/Inference/PokemonBDSP_MenuDetector.cpp b/SerialPrograms/Source/PokemonBDSP/Inference/PokemonBDSP_MenuDetector.cpp index 7133bfc814..12da43966e 100644 --- a/SerialPrograms/Source/PokemonBDSP/Inference/PokemonBDSP_MenuDetector.cpp +++ b/SerialPrograms/Source/PokemonBDSP/Inference/PokemonBDSP_MenuDetector.cpp @@ -14,14 +14,22 @@ namespace NintendoSwitch{ namespace PokemonBDSP{ +const double STRIPE_TOP = 0.110; +const double STRIPE_TOP_BELOW_BANNER = 0.170; +const double STRIPE_BOTTOM = 0.598; -MenuDetector::MenuDetector(Color color) +static ImageFloatBox menu_stripe(size_t index, bool skip_new_banner){ + double top = skip_new_banner ? STRIPE_TOP_BELOW_BANNER : STRIPE_TOP; + return ImageFloatBox(0.160 + 0.166 * (double)index, top, 0.015, STRIPE_BOTTOM - top); +} + +MenuDetector::MenuDetector(Color color, bool skip_new_banner) : m_color(color) - , m_line0(0.160 + 0.166 * 0, 0.110, 0.015, 0.488) - , m_line1(0.160 + 0.166 * 1, 0.110, 0.015, 0.488) - , m_line2(0.160 + 0.166 * 2, 0.110, 0.015, 0.488) - , m_line3(0.160 + 0.166 * 3, 0.110, 0.015, 0.488) - , m_line4(0.160 + 0.166 * 4, 0.110, 0.015, 0.488) + , m_line0(menu_stripe(0, skip_new_banner)) + , m_line1(menu_stripe(1, skip_new_banner)) + , m_line2(menu_stripe(2, skip_new_banner)) + , m_line3(menu_stripe(3, skip_new_banner)) + , m_line4(menu_stripe(4, skip_new_banner)) , m_cross(0.20, 0.15, 0.60, 0.37) {} @@ -63,8 +71,8 @@ bool MenuDetector::detect(const ImageViewRGB32& screen){ } -MenuWatcher::MenuWatcher(Color color) - : MenuDetector(color) +MenuWatcher::MenuWatcher(Color color, bool skip_new_banner) + : MenuDetector(color, skip_new_banner) , VisualInferenceCallback("MenuWatcher") {} void MenuWatcher::make_overlays(VideoOverlaySet& items) const{ diff --git a/SerialPrograms/Source/PokemonBDSP/Inference/PokemonBDSP_MenuDetector.h b/SerialPrograms/Source/PokemonBDSP/Inference/PokemonBDSP_MenuDetector.h index ed06ac9b37..2da359a3b9 100644 --- a/SerialPrograms/Source/PokemonBDSP/Inference/PokemonBDSP_MenuDetector.h +++ b/SerialPrograms/Source/PokemonBDSP/Inference/PokemonBDSP_MenuDetector.h @@ -19,7 +19,20 @@ namespace PokemonBDSP{ class MenuDetector : public StaticScreenDetector{ public: - MenuDetector(Color color = COLOR_RED); + // The menu is recognised by the white gaps between its entries. BDSP tags an + // entry with a red "NEW" banner the first time its contents change -- on the + // POKEMON entry once a starter is in hand, for instance -- and that banner sits + // directly over the second gap. is_white() allows a summed stddev of only 10 and + // the banner's edge takes it to 15, so the whole detector goes blind while the + // tag is present. + // + // "skip_new_banner" starts the gaps below the banner instead. It costs the top + // ~12% of the panel, which is white either way, so it only ever makes detection + // easier -- it cannot turn a screen the default accepts into one it rejects. + // + // Off by default so existing callers are unchanged. Any BDSP program that opens + // the menu while a NEW tag is showing wants it on. + MenuDetector(Color color = COLOR_RED, bool skip_new_banner = false); virtual void make_overlays(VideoOverlaySet& items) const override; virtual bool detect(const ImageViewRGB32& screen) override; @@ -37,7 +50,7 @@ class MenuDetector : public StaticScreenDetector{ class MenuWatcher : public MenuDetector, public VisualInferenceCallback{ public: - MenuWatcher(Color color = COLOR_RED); + MenuWatcher(Color color = COLOR_RED, bool skip_new_banner = false); virtual void make_overlays(VideoOverlaySet& items) const override; virtual bool process_frame(const ImageViewRGB32& frame, WallClock timestamp) override; From 810d7614c76adc189e4417c9e8c4be502c9ce47b Mon Sep 17 00:00:00 2001 From: theAstrogoth Date: Mon, 10 Aug 2026 09:47:44 -0500 Subject: [PATCH 4/5] update cmake --- SerialPrograms/cmake/SourceFiles.cmake | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/SerialPrograms/cmake/SourceFiles.cmake b/SerialPrograms/cmake/SourceFiles.cmake index c9d1e4978f..985274f34a 100644 --- a/SerialPrograms/cmake/SourceFiles.cmake +++ b/SerialPrograms/cmake/SourceFiles.cmake @@ -1413,6 +1413,8 @@ file(GLOB LIBRARY_SOURCES Source/PokemonBDSP/Inference/BoxSystem/PokemonBDSP_BoxShinyDetector.h Source/PokemonBDSP/Inference/BoxSystem/PokemonBDSP_IvJudgeReader.cpp Source/PokemonBDSP/Inference/BoxSystem/PokemonBDSP_IvJudgeReader.h + Source/PokemonBDSP/Inference/Rng/PokemonBDSP_SummaryReader.cpp + Source/PokemonBDSP/Inference/Rng/PokemonBDSP_SummaryReader.h Source/PokemonBDSP/Inference/PokemonBDSP_DialogDetector.cpp Source/PokemonBDSP/Inference/PokemonBDSP_DialogDetector.h Source/PokemonBDSP/Inference/PokemonBDSP_MapDetector.cpp @@ -1527,6 +1529,8 @@ file(GLOB LIBRARY_SOURCES Source/PokemonBDSP/Programs/TestPrograms/PokemonBDSP_ShinyEncounterTester.h Source/PokemonBDSP/Programs/TestPrograms/PokemonBDSP_SoundListener.cpp Source/PokemonBDSP/Programs/TestPrograms/PokemonBDSP_SoundListener.h + Source/PokemonBDSP/Programs/TestPrograms/PokemonBDSP_SummaryReaderTester.cpp + Source/PokemonBDSP/Programs/TestPrograms/PokemonBDSP_SummaryReaderTester.h Source/PokemonBDSP/Programs/Trading/PokemonBDSP_SelfBoxTrade.cpp Source/PokemonBDSP/Programs/Trading/PokemonBDSP_SelfBoxTrade.h Source/PokemonBDSP/Programs/Trading/PokemonBDSP_SelfTouchTrade.cpp From 5654476d31ebe8e615c4202c3630a90056feda02 Mon Sep 17 00:00:00 2001 From: theAstrogoth Date: Mon, 10 Aug 2026 16:15:30 -0500 Subject: [PATCH 5/5] remove unhelpful comments --- .../Inference/PokemonBDSP_MenuDetector.h | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/SerialPrograms/Source/PokemonBDSP/Inference/PokemonBDSP_MenuDetector.h b/SerialPrograms/Source/PokemonBDSP/Inference/PokemonBDSP_MenuDetector.h index 2da359a3b9..f7e5a0517f 100644 --- a/SerialPrograms/Source/PokemonBDSP/Inference/PokemonBDSP_MenuDetector.h +++ b/SerialPrograms/Source/PokemonBDSP/Inference/PokemonBDSP_MenuDetector.h @@ -19,19 +19,6 @@ namespace PokemonBDSP{ class MenuDetector : public StaticScreenDetector{ public: - // The menu is recognised by the white gaps between its entries. BDSP tags an - // entry with a red "NEW" banner the first time its contents change -- on the - // POKEMON entry once a starter is in hand, for instance -- and that banner sits - // directly over the second gap. is_white() allows a summed stddev of only 10 and - // the banner's edge takes it to 15, so the whole detector goes blind while the - // tag is present. - // - // "skip_new_banner" starts the gaps below the banner instead. It costs the top - // ~12% of the panel, which is white either way, so it only ever makes detection - // easier -- it cannot turn a screen the default accepts into one it rejects. - // - // Off by default so existing callers are unchanged. Any BDSP program that opens - // the menu while a NEW tag is showing wants it on. MenuDetector(Color color = COLOR_RED, bool skip_new_banner = false); virtual void make_overlays(VideoOverlaySet& items) const override;