Skip to content

Commit 59beefa

Browse files
committed
more dialog infra, improve audio starter reset
FeedbackType update, finally got audio working
1 parent 6643e9d commit 59beefa

File tree

9 files changed

+116
-53
lines changed

9 files changed

+116
-53
lines changed

SerialPrograms/Source/CommonFramework/Globals.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ enum class FeedbackType{
6969
NONE,
7070
OPTIONAL_, // Naming conflict with macro.
7171
REQUIRED,
72-
AUDIO,
7372
VIDEO_AUDIO,
73+
VIDEO_AUDIO_GBA,
7474
};
7575

7676

SerialPrograms/Source/CommonFramework/Panels/UI/PanelElements.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,13 +81,8 @@ CollapsibleGroupBox* make_panel_header(
8181
header
8282
);
8383
break;
84-
case FeedbackType::AUDIO:
85-
text = new QLabel(
86-
"<font color=\"green\">(This program requires audio feedback. Please make sure you choose the correct audio device.)</font>",
87-
header
88-
);
89-
break;
9084
case FeedbackType::VIDEO_AUDIO:
85+
case FeedbackType::VIDEO_AUDIO_GBA:
9186
text = new QLabel(
9287
"<font color=\"green\">(This program requires video and audio feedback. Please make sure you choose the correct capture device, as well as the correct audio device.)</font>",
9388
header

SerialPrograms/Source/PokemonRSE/Inference/Dialogs/PokemonRSE_DialogDetector.cpp

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,18 @@
55
*/
66

77
#include "CommonFramework/ImageTools/SolidColorTest.h"
8+
#include "CommonFramework/ImageTools/ImageBoxes.h"
9+
#include "CommonFramework/ImageTools/ImageFilter.h"
10+
#include "CommonFramework/ImageTypes/ImageRGB32.h"
11+
#include "CommonFramework/ImageTools/ImageStats.h"
12+
#include "CommonFramework/ImageTypes/ImageViewRGB32.h"
813
#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h"
914
#include "PokemonRSE_DialogDetector.h"
1015

16+
#include <iostream>
17+
using std::cout;
18+
using std::endl;
19+
1120
namespace PokemonAutomation{
1221
namespace NintendoSwitch{
1322
namespace PokemonRSE{
@@ -29,11 +38,11 @@ bool DialogDetector::detect(const ImageViewRGB32& screen) const{
2938
}
3039
return false;
3140
}
32-
41+
*/
3342

3443
BattleDialogDetector::BattleDialogDetector(Color color)
35-
: m_left_box(0.155, 0.727, 0.015, 0.168)
36-
, m_right_box(0.837, 0.729, 0.008, 0.161)
44+
: m_left_box(0.158, 0.725, 0.011, 0.176)
45+
, m_right_box(0.827, 0.722, 0.013, 0.178)
3746
{}
3847
void BattleDialogDetector::make_overlays(VideoOverlaySet& items) const{
3948
items.add(COLOR_RED, m_left_box);
@@ -42,12 +51,12 @@ void BattleDialogDetector::make_overlays(VideoOverlaySet& items) const{
4251
bool BattleDialogDetector::detect(const ImageViewRGB32& screen) const{
4352
ImageViewRGB32 left_image = extract_box_reference(screen, m_left_box);
4453
ImageViewRGB32 right_image = extract_box_reference(screen, m_right_box);
45-
if (is_solid(left_image, { 0.25, 0.38, 0.369 }) && is_solid(right_image, { 0.25, 0.38, 0.369 })){
54+
if (is_solid(left_image, { 0.335, 0.331, 0.332 }) && is_solid(right_image, { 0.335, 0.331, 0.332 })){
4655
return true;
4756
}
4857
return false;
4958
}
50-
*/
59+
5160

5261
BattleMenuDetector::BattleMenuDetector(Color color)
5362
: m_left_box(0.155, 0.727, 0.015, 0.168)
@@ -67,6 +76,36 @@ bool BattleMenuDetector::detect(const ImageViewRGB32& screen) const{
6776
}
6877

6978

79+
AdvanceDialogDetector::AdvanceDialogDetector(Color color)
80+
: m_dialog_box(0.156, 0.715, 0.686, 0.193)
81+
{}
82+
void AdvanceDialogDetector::make_overlays(VideoOverlaySet& items) const{
83+
items.add(COLOR_RED, m_dialog_box);
84+
}
85+
bool AdvanceDialogDetector::detect(const ImageViewRGB32& screen) const{
86+
const bool replace_color_within_range = false;
87+
88+
//Filter out background
89+
ImageRGB32 filtered_region = filter_rgb32_range(
90+
extract_box_reference(screen, m_dialog_box),
91+
combine_rgb(185, 0, 1), combine_rgb(255, 32, 33), Color(0), replace_color_within_range
92+
);
93+
ImageStats stats = image_stats(filtered_region);
94+
95+
/*
96+
filtered_region.save("./filtered_only.png");
97+
cout << stats.average.r << endl;
98+
cout << stats.average.g << endl;
99+
cout << stats.average.b << endl;
100+
*/
101+
102+
if ((stats.average.r > stats.average.b + 200) && (stats.average.r > stats.average.g + 200)){
103+
return true;
104+
}
105+
return false;
106+
}
107+
108+
70109

71110
}
72111
}

SerialPrograms/Source/PokemonRSE/Inference/Dialogs/PokemonRSE_DialogDetector.h

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ class DialogWatcher : public DetectorToFinder<DialogDetector>{
4141
: DetectorToFinder("DialogWatcher", std::chrono::milliseconds(250), color)
4242
{}
4343
};
44-
45-
44+
*/
4645

4746
// Battle dialog boxes are teal
4847
class BattleDialogDetector : public StaticScreenDetector{
@@ -62,10 +61,9 @@ class BattleDialogWatcher : public DetectorToFinder<BattleDialogDetector>{
6261
: DetectorToFinder("BattleDialogWatcher", std::chrono::milliseconds(250), color)
6362
{}
6463
};
65-
*/
6664

6765

68-
// Battle menu is up when it is white on the left and teal on the right
66+
// Battle menu is up when it is white on the right and teal on the left
6967
class BattleMenuDetector : public StaticScreenDetector{
7068
public:
7169
BattleMenuDetector(Color color);
@@ -86,10 +84,27 @@ class BattleMenuWatcher : public DetectorToFinder<BattleMenuDetector>{
8684

8785

8886

89-
// advancedialogdetector Detect that the dialog arrow is in the dialog box by filtering for the red arrow
87+
// Detect the red advancement arrow by filtering for red.
88+
// This works for now, I don't think there's colored text?
89+
// TODO: Change this to detect that the dialog arrow is in the dialog box by filtering for the red arrow
90+
class AdvanceDialogDetector : public StaticScreenDetector{
91+
public:
92+
AdvanceDialogDetector(Color color);
9093

91-
// when given a choice popup, there is no advance arrow
94+
virtual void make_overlays(VideoOverlaySet& items) const override;
95+
virtual bool detect(const ImageViewRGB32& screen) const override;
9296

97+
private:
98+
ImageFloatBox m_dialog_box;
99+
};
100+
class AdvanceDialogWatcher : public DetectorToFinder<AdvanceDialogDetector>{
101+
public:
102+
AdvanceDialogWatcher(Color color)
103+
: DetectorToFinder("AdvanceDialogWatcher", std::chrono::milliseconds(250), color)
104+
{}
105+
};
106+
107+
// when given a choice popup, there is no advance arrow
93108

94109

95110
}

SerialPrograms/Source/PokemonRSE/Inference/PokemonRSE_ShinyNumberDetector.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,20 @@
1313
#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h"
1414
#include "PokemonRSE_ShinyNumberDetector.h"
1515

16-
#include <iostream>
17-
using std::cout;
18-
using std::endl;
16+
//#include <iostream>
17+
//using std::cout;
18+
//using std::endl;
1919

2020
namespace PokemonAutomation{
2121
namespace NintendoSwitch{
2222
namespace PokemonRSE{
2323

24-
ShinyNumberDetector::ShinyNumberDetector()
24+
ShinyNumberDetector::ShinyNumberDetector(Color color)
2525
: m_box_number(0.136, 0.156, 0.123, 0.072)
2626
{}
27-
27+
void ShinyNumberDetector::make_overlays(VideoOverlaySet& items) const{
28+
items.add(COLOR_RED, m_box_number);
29+
}
2830
bool ShinyNumberDetector::read(Logger& logger, const ImageViewRGB32& frame){
2931
const bool replace_color_within_range = true;
3032

SerialPrograms/Source/PokemonRSE/Inference/PokemonRSE_ShinyNumberDetector.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@ namespace PokemonRSE{
1919
// Number is easier to check as background as scan lines.
2020
class ShinyNumberDetector{
2121
public:
22-
ShinyNumberDetector();
22+
ShinyNumberDetector(Color color);
2323

24+
virtual void make_overlays(VideoOverlaySet& items) const;
2425
bool read(Logger& logger, const ImageViewRGB32& frame);
2526

2627
private:

SerialPrograms/Source/PokemonRSE/PokemonRSE_Panels.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,10 @@ std::vector<PanelEntry> PanelListFactory::make_panels() const{
3434

3535
ret.emplace_back("---- Shiny Hunting ----");
3636
ret.emplace_back(make_single_switch_program<StarterReset_Descriptor, StarterReset>());
37+
ret.emplace_back(make_single_switch_program<AudioStarterReset_Descriptor, AudioStarterReset>());
3738

3839

3940
if (PreloadSettings::instance().DEVELOPER_MODE){
40-
ret.emplace_back("---- WIP: Shiny Hunting (Audio only) ----");
41-
ret.emplace_back(make_single_switch_program<AudioStarterReset_Descriptor, AudioStarterReset>());
42-
4341
ret.emplace_back("---- Developer Tools ----");
4442
ret.emplace_back(make_single_switch_program<SoundListener_Descriptor, SoundListener>());
4543
}

SerialPrograms/Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_AudioStarterReset.cpp

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "CommonFramework/Tools/StatsTracking.h"
1313
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h"
1414
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h"
15+
#include "PokemonRSE/Inference/Dialogs/PokemonRSE_DialogDetector.h"
1516
#include "PokemonRSE/Inference/Sounds/PokemonRSE_ShinySoundDetector.h"
1617
#include "PokemonRSE/PokemonRSE_Navigation.h"
1718
#include "PokemonRSE_AudioStarterReset.h"
@@ -23,10 +24,10 @@ namespace PokemonRSE{
2324
AudioStarterReset_Descriptor::AudioStarterReset_Descriptor()
2425
: SingleSwitchProgramDescriptor(
2526
"PokemonRSE:AudioStarterReset",
26-
"Pokemon RSE", "[RS] Starter Reset - Audio only",
27+
"Pokemon RSE", "[RS] Starter Reset",
2728
"ComputerControl/blob/master/Wiki/Programs/PokemonRSE/AudioStarterReset.md",
28-
"Soft reset for a shiny starter. Ruby and Sapphire only. WIP, audio recognition does not work well.",
29-
FeedbackType::AUDIO,
29+
"Soft reset for a shiny starter. Ruby and Sapphire only.",
30+
FeedbackType::VIDEO_AUDIO_GBA,
3031
AllowCommandsWhenRunning::DISABLE_COMMANDS,
3132
PABotBaseLevel::PABOTBASE_12KB
3233
)
@@ -101,8 +102,12 @@ void AudioStarterReset::program(SingleSwitchProgramEnvironment& env, BotBaseCont
101102

102103
/*
103104
* Settings: Text Speed fast.
105+
* Full screen, no filter? The device I'm using to test has similar looking output, but I don't have switch online+.
106+
* If on a retro handheld, make sure the screen matches that of NSO+ and that there is an overlay to avoid the black border check.
107+
*
104108
* Setup: Stand in front of the Professor's bag and save the game.
105109
*
110+
*
106111
* Required to fight, so have to do the SR method instead of run away
107112
* Soft reset programs are only for Ruby/Sapphire, as Emerald has the 0 seed issue.
108113
*
@@ -137,29 +142,33 @@ void AudioStarterReset::program(SingleSwitchProgramEnvironment& env, BotBaseCont
137142
break;
138143
}
139144
pbf_mash_button(context, BUTTON_A, 540);
145+
context.wait_for_all_requests();
140146
env.log("Starter selected. Checking for shiny Poochyena.");
141147

142-
143-
int ret = run_until(
148+
AdvanceDialogWatcher pooch_appeared(COLOR_YELLOW);
149+
int res = run_until(
144150
env.console, context,
145-
[&](BotBaseContext& context){
146-
//Wait for battle to start and for Pooch battle cry
147-
pbf_wait(context, POOCH_WAIT);
148-
149-
context.wait_for_all_requests();
150-
151+
[&](BotBaseContext& context) {
152+
int ret = wait_until(
153+
env.console, context,
154+
std::chrono::seconds(20),
155+
{{pooch_detector}}
156+
);
157+
pooch_detector.throw_if_no_sound();
158+
if (ret == 0){
159+
env.log("Shiny Poochyena detected!");
160+
stats.poochyena++;
161+
send_program_status_notification(env, NOTIFICATION_SHINY_POOCH, "Shiny Poochyena found.");
162+
}
163+
else {
164+
env.log("Poochyena is not shiny.");
165+
}
151166
},
152-
{{pooch_detector}}
167+
{{pooch_appeared}}
153168
);
154-
pooch_detector.throw_if_no_sound();
155-
if (ret == 0){
156-
env.log("Shiny Poochyena detected!");
157-
stats.poochyena++;
158-
send_program_status_notification(env, NOTIFICATION_SHINY_POOCH, "Shiny Poochyena found.");
159-
}
160-
else {
161-
env.log("Poochyena is not shiny.");
162-
}
169+
if (res == 0) {
170+
env.log("Advance arrow detected. Pressing A.");
171+
} //res != if pooch is shiny
163172

164173
ShinySoundDetector starter_detector(env.console, [&](float error_coefficient) -> bool{
165174
return true;
@@ -201,7 +210,7 @@ void AudioStarterReset::program(SingleSwitchProgramEnvironment& env, BotBaseCont
201210
stats.resets++;
202211
}
203212

204-
//TODO: if system set to nintendo switch, have go home when done option
213+
//if system set to nintendo switch, have go home when done option?
205214

206215
send_program_finished_notification(env, NOTIFICATION_PROGRAM_FINISH);
207216
}

SerialPrograms/Source/PokemonRSE/Programs/ShinyHunting/PokemonRSE_StarterReset.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,10 @@ namespace PokemonRSE{
2525
StarterReset_Descriptor::StarterReset_Descriptor()
2626
: SingleSwitchProgramDescriptor(
2727
"PokemonRSE:StarterReset",
28-
"Pokemon RSE", "[RS] Starter Reset",
28+
"Pokemon RSE", "[RS] Starter Reset - Video only",
2929
"ComputerControl/blob/master/Wiki/Programs/PokemonRSE/StarterReset.md",
3030
"Soft reset for a shiny starter. Ruby and Sapphire only.",
31-
FeedbackType::REQUIRED,
31+
FeedbackType::VIDEO_AUDIO_GBA,
3232
AllowCommandsWhenRunning::DISABLE_COMMANDS,
3333
PABotBaseLevel::PABOTBASE_12KB
3434
)
@@ -88,6 +88,9 @@ void StarterReset::program(SingleSwitchProgramEnvironment& env, BotBaseContext&
8888

8989
/*
9090
* Settings: Text Speed fast.
91+
* Full screen, no filter? The device I'm using to test has similar looking output, but I don't have switch online+.
92+
* If on a retro handheld, make sure the screen matches that of NSO+ and that there is an overlay to avoid the black border check.
93+
*
9194
* Setup: Stand in front of the Professor's bag and save the game.
9295
*
9396
* Required to fight, so have to do the SR method instead of run away
@@ -147,13 +150,14 @@ void StarterReset::program(SingleSwitchProgramEnvironment& env, BotBaseContext&
147150
pbf_press_dpad(context, DPAD_DOWN, 40, 80);
148151
pbf_press_button(context, BUTTON_A, 40, 80);
149152

153+
//Check second party member - used for testing with hacked in shiny starter
150154
//pbf_press_dpad(context, DPAD_DOWN, 40, 80);
151155

152156
pbf_wait(context, 125);
153157
context.wait_for_all_requests();
154158

155159
VideoSnapshot screen = env.console.video().snapshot();
156-
ShinyNumberDetector shiny_checker;
160+
ShinyNumberDetector shiny_checker(COLOR_YELLOW);
157161
shiny_starter = shiny_checker.read(env.console.logger(), screen);
158162

159163
if (shiny_starter) {
@@ -173,7 +177,7 @@ void StarterReset::program(SingleSwitchProgramEnvironment& env, BotBaseContext&
173177
}
174178
}
175179

176-
//TODO: if system set to nintendo switch, have go home when done option
180+
//if system set to nintendo switch, have go home when done option?
177181

178182
send_program_finished_notification(env, NOTIFICATION_PROGRAM_FINISH);
179183
}

0 commit comments

Comments
 (0)