Skip to content

Commit a1de968

Browse files
authored
Refactor FRLG to use game cropping. (#1117)
* Refactor FRLG to use game cropping. * rebase
1 parent 64d8950 commit a1de968

13 files changed

Lines changed: 202 additions & 148 deletions

SerialPrograms/Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_DialogDetector.cpp

Lines changed: 84 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -26,46 +26,52 @@ namespace NintendoSwitch{
2626
namespace PokemonFRLG{
2727

2828
WhiteDialogDetector::WhiteDialogDetector(Color color)
29-
: m_right_box(0.844, 0.725, 0.005, 0.197)
30-
, m_top_box(0.151, 0.719, 0.698, 0.006)
31-
, m_bottom_box(0.152, 0.913, 0.692, 0.009)
29+
: m_right_box(0.923385, 0.748077, 0.00615385, 0.204577)
30+
, m_top_box(0.0704615, 0.741846, 0.859077, 0.00623077)
31+
, m_bottom_box(0.0716923, 0.943308, 0.851692, 0.00934615)
3232
{}
3333
void WhiteDialogDetector::make_overlays(VideoOverlaySet& items) const{
34-
items.add(COLOR_RED, m_right_box);
35-
items.add(COLOR_RED, m_top_box);
36-
items.add(COLOR_RED, m_bottom_box);
34+
const BoxOption& GAME_BOX = GameSettings::instance().GAME_BOX;
35+
items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_right_box));
36+
items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_top_box));
37+
items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_bottom_box));
3738
}
3839
bool WhiteDialogDetector::detect(const ImageViewRGB32& screen){
39-
ImageViewRGB32 right_image = extract_box_reference(screen, m_right_box);
40-
ImageViewRGB32 top_image = extract_box_reference(screen, m_top_box);
41-
ImageViewRGB32 bottom_image = extract_box_reference(screen, m_bottom_box);
40+
ImageViewRGB32 game_screen = extract_box_reference(screen, GameSettings::instance().GAME_BOX);
41+
42+
ImageViewRGB32 right_image = extract_box_reference(game_screen, m_right_box);
43+
ImageViewRGB32 top_image = extract_box_reference(game_screen, m_top_box);
44+
ImageViewRGB32 bottom_image = extract_box_reference(game_screen, m_bottom_box);
4245
if (is_white(right_image)
4346
&& is_white(top_image)
4447
&& is_white(bottom_image)
45-
){
48+
){
4649
return true;
4750
}
4851
return false;
4952
}
5053

5154
AdvanceWhiteDialogDetector::AdvanceWhiteDialogDetector(Color color)
52-
: m_dialog_box(0.145, 0.727, 0.707, 0.193)
53-
, m_right_box(0.844, 0.725, 0.005, 0.197)
54-
, m_top_box(0.151, 0.719, 0.698, 0.006)
55-
, m_bottom_box(0.152, 0.913, 0.692, 0.009)
55+
: m_dialog_box(0.0630769, 0.750154, 0.870154, 0.200423)
56+
, m_right_box(0.923385, 0.748077, 0.00615385, 0.204577)
57+
, m_top_box(0.0704615, 0.741846, 0.859077, 0.00623077)
58+
, m_bottom_box(0.0716923, 0.943308, 0.851692, 0.00934615)
5659
{}
5760
void AdvanceWhiteDialogDetector::make_overlays(VideoOverlaySet& items) const{
58-
items.add(COLOR_RED, m_dialog_box);
59-
items.add(COLOR_RED, m_right_box);
60-
items.add(COLOR_RED, m_top_box);
61-
items.add(COLOR_RED, m_bottom_box);
61+
const BoxOption& GAME_BOX = GameSettings::instance().GAME_BOX;
62+
items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_dialog_box));
63+
items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_right_box));
64+
items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_top_box));
65+
items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_bottom_box));
6266
}
6367
bool AdvanceWhiteDialogDetector::detect(const ImageViewRGB32& screen){
68+
ImageViewRGB32 game_screen = extract_box_reference(screen, GameSettings::instance().GAME_BOX);
69+
6470
const bool replace_color_within_range = false;
6571

6672
//Filter out background
6773
ImageRGB32 filtered_region = filter_rgb32_range(
68-
extract_box_reference(screen, m_dialog_box),
74+
extract_box_reference(game_screen, m_dialog_box),
6975
combine_rgb(164, 0, 0), combine_rgb(255, 114, 87), Color(0), replace_color_within_range
7076
);
7177
ImageStats stats = image_stats(filtered_region);
@@ -77,118 +83,129 @@ bool AdvanceWhiteDialogDetector::detect(const ImageViewRGB32& screen){
7783
cout << stats.average.b << endl;
7884
*/
7985

80-
ImageViewRGB32 right_image = extract_box_reference(screen, m_right_box);
81-
ImageViewRGB32 top_image = extract_box_reference(screen, m_top_box);
82-
ImageViewRGB32 bottom_image = extract_box_reference(screen, m_bottom_box);
86+
ImageViewRGB32 right_image = extract_box_reference(game_screen, m_right_box);
87+
ImageViewRGB32 top_image = extract_box_reference(game_screen, m_top_box);
88+
ImageViewRGB32 bottom_image = extract_box_reference(game_screen, m_bottom_box);
8389

8490
if (is_white(right_image)
8591
&& is_white(top_image)
8692
&& is_white(bottom_image)
8793
&& (stats.average.r > stats.average.b + 180)
8894
&& (stats.average.r > stats.average.g + 180)
89-
)
90-
{
95+
){
9196
return true;
9297
}
9398
return false;
9499
}
95100

96101
SelectionDialogDetector::SelectionDialogDetector(Color color)
97-
: m_right_box(0.844, 0.725, 0.005, 0.197)
98-
, m_top_box(00.151, 0.719, 0.698, 0.006)
99-
, m_bottom_box(0.152, 0.913, 0.692, 0.009)
100-
, m_selection_box(0.813, 0.436, 0.013, 0.195)
102+
: m_right_box(0.923385, 0.748077, 0.00615385, 0.204577)
103+
, m_top_box(0.0704615, 0.741846, 0.859077, 0.00623077)
104+
, m_bottom_box(0.0716923, 0.943308, 0.851692, 0.00934615)
105+
, m_selection_box(0.885231, 0.447962, 0.016, 0.2025)
101106
{}
102107
void SelectionDialogDetector::make_overlays(VideoOverlaySet& items) const{
103-
items.add(COLOR_RED, m_right_box);
104-
items.add(COLOR_RED, m_top_box);
105-
items.add(COLOR_RED, m_bottom_box);
106-
items.add(COLOR_RED, m_selection_box);
108+
const BoxOption& GAME_BOX = GameSettings::instance().GAME_BOX;
109+
items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_right_box));
110+
items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_top_box));
111+
items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_bottom_box));
112+
items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_selection_box));
107113
}
108114
bool SelectionDialogDetector::detect(const ImageViewRGB32& screen){
109-
ImageViewRGB32 right_image = extract_box_reference(screen, m_right_box);
110-
ImageViewRGB32 top_image = extract_box_reference(screen, m_top_box);
111-
ImageViewRGB32 bottom_image = extract_box_reference(screen, m_bottom_box);
112-
ImageViewRGB32 selection_image = extract_box_reference(screen, m_selection_box);
115+
ImageViewRGB32 game_screen = extract_box_reference(screen, GameSettings::instance().GAME_BOX);
116+
117+
ImageViewRGB32 right_image = extract_box_reference(game_screen, m_right_box);
118+
ImageViewRGB32 top_image = extract_box_reference(game_screen, m_top_box);
119+
ImageViewRGB32 bottom_image = extract_box_reference(game_screen, m_bottom_box);
120+
ImageViewRGB32 selection_image = extract_box_reference(game_screen, m_selection_box);
113121
if (is_white(right_image)
114122
&& is_white(top_image)
115123
&& is_white(bottom_image)
116124
&& is_white(selection_image)
117-
){
125+
){
118126
return true;
119127
}
120128
return false;
121129
}
122130

123131
BattleDialogDetector::BattleDialogDetector(Color color)
124-
: m_dialog_top_box(0.124, 0.727, 0.752, 0.009)
125-
, m_dialog_right_box(0.871, 0.736, 0.005, 0.179)
132+
: m_dialog_top_box(0.0372308, 0.750154, 0.925538, 0.00934615)
133+
, m_dialog_right_box(0.956615, 0.7595, 0.00615385, 0.185885)
126134
{}
127135
void BattleDialogDetector::make_overlays(VideoOverlaySet& items) const{
128-
items.add(COLOR_RED, m_dialog_top_box);
129-
items.add(COLOR_RED, m_dialog_right_box);
136+
const BoxOption& GAME_BOX = GameSettings::instance().GAME_BOX;
137+
items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_dialog_top_box));
138+
items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_dialog_right_box));
130139
}
131140
bool BattleDialogDetector::detect(const ImageViewRGB32& screen){
132-
ImageViewRGB32 dialog_top_image = extract_box_reference(screen, m_dialog_top_box);
133-
ImageViewRGB32 dialog_right_image = extract_box_reference(screen, m_dialog_right_box);
141+
ImageViewRGB32 game_screen = extract_box_reference(screen, GameSettings::instance().GAME_BOX);
142+
143+
ImageViewRGB32 dialog_top_image = extract_box_reference(game_screen, m_dialog_top_box);
144+
ImageViewRGB32 dialog_right_image = extract_box_reference(game_screen, m_dialog_right_box);
134145

135146
if (is_solid(dialog_top_image, { 0.176, 0.357, 0.467 }, 0.25, 20)
136147
&& is_solid(dialog_right_image, { 0.176, 0.357, 0.467 }, 0.25, 20)
137-
){
148+
){
138149
return true;
139150
}
140151
return false;
141152
}
142153

143154

144155
BattleMenuDetector::BattleMenuDetector(Color color)
145-
: m_menu_top_box(0.523, 0.720, 0.357, 0.008) //top of the white dialog box
146-
, m_menu_right_box(0.875, 0.729, 0.005, 0.193)
147-
, m_dialog_top_box(0.123, 0.726, 0.373, 0.013)
148-
, m_dialog_right_box(0.492, 0.739, 0.005, 0.172) //right side, closest to the menu
156+
: m_menu_top_box(0.528308, 0.742885, 0.439385, 0.00830769) //top of the white dialog box
157+
, m_menu_right_box(0.961538, 0.752231, 0.00615385, 0.200423)
158+
, m_dialog_top_box(0.036, 0.749115, 0.459077, 0.0135)
159+
, m_dialog_right_box(0.490154, 0.762615, 0.00615385, 0.178615) //right side, closest to the menu
149160
{}
150161
void BattleMenuDetector::make_overlays(VideoOverlaySet& items) const{
151-
items.add(COLOR_RED, m_menu_top_box);
152-
items.add(COLOR_RED, m_menu_right_box);
153-
items.add(COLOR_RED, m_dialog_top_box);
154-
items.add(COLOR_RED, m_dialog_right_box);
162+
const BoxOption& GAME_BOX = GameSettings::instance().GAME_BOX;
163+
items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_menu_top_box));
164+
items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_menu_right_box));
165+
items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_dialog_top_box));
166+
items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_dialog_right_box));
155167
}
156168
bool BattleMenuDetector::detect(const ImageViewRGB32& screen){
169+
ImageViewRGB32 game_screen = extract_box_reference(screen, GameSettings::instance().GAME_BOX);
170+
157171
//Menu is white
158-
ImageViewRGB32 menu_top_image = extract_box_reference(screen, m_menu_top_box);
159-
ImageViewRGB32 menu_right_image = extract_box_reference(screen, m_menu_right_box);
172+
ImageViewRGB32 menu_top_image = extract_box_reference(game_screen, m_menu_top_box);
173+
ImageViewRGB32 menu_right_image = extract_box_reference(game_screen, m_menu_right_box);
160174

161175
//Background dialog is teal
162-
ImageViewRGB32 dialog_top_image = extract_box_reference(screen, m_dialog_top_box);
163-
ImageViewRGB32 dialog_right_image = extract_box_reference(screen, m_dialog_right_box);
176+
ImageViewRGB32 dialog_top_image = extract_box_reference(game_screen, m_dialog_top_box);
177+
ImageViewRGB32 dialog_right_image = extract_box_reference(game_screen, m_dialog_right_box);
164178

165179
if (is_white(menu_top_image)
166180
&& is_white(menu_right_image)
167181
&& is_solid(dialog_top_image, { 0.176, 0.357, 0.467 }, 0.25, 20) //40, 81, 106 teal
168182
&& is_solid(dialog_right_image, { 0.176, 0.357, 0.467 }, 0.25, 20)
169-
){
183+
){
170184
return true;
171185
}
172186
return false;
173187
}
174188

175189

176190
AdvanceBattleDialogDetector::AdvanceBattleDialogDetector(Color color)
177-
: m_dialog_box(0.123, 0.725, 0.753, 0.197)
178-
, m_dialog_top_box(0.124, 0.727, 0.752, 0.009)
179-
, m_dialog_right_box(0.871, 0.736, 0.005, 0.179)
191+
: m_dialog_box(0.036, 0.748077, 0.926769, 0.204577)
192+
, m_dialog_top_box(0.0372308, 0.750154, 0.925538, 0.00934615)
193+
, m_dialog_right_box(0.956615, 0.7595, 0.00615385, 0.185885)
180194
{}
181195
void AdvanceBattleDialogDetector::make_overlays(VideoOverlaySet& items) const{
182-
items.add(COLOR_RED, m_dialog_box);
183-
items.add(COLOR_RED, m_dialog_top_box);
184-
items.add(COLOR_RED, m_dialog_right_box);
196+
const BoxOption& GAME_BOX = GameSettings::instance().GAME_BOX;
197+
items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_dialog_box));
198+
items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_dialog_top_box));
199+
items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_dialog_right_box));
185200
}
186201
bool AdvanceBattleDialogDetector::detect(const ImageViewRGB32& screen){
202+
ImageViewRGB32 game_screen = extract_box_reference(screen, GameSettings::instance().GAME_BOX);
203+
187204
const bool replace_color_within_range = false;
188205

189206
//Filter out background
190207
ImageRGB32 filtered_region = filter_rgb32_range(
191-
extract_box_reference(screen, m_dialog_box),
208+
extract_box_reference(game_screen, m_dialog_box),
192209
combine_rgb(164, 0, 0), combine_rgb(255, 114, 87), Color(0), replace_color_within_range
193210
);
194211
ImageStats stats = image_stats(filtered_region);
@@ -200,15 +217,14 @@ bool AdvanceBattleDialogDetector::detect(const ImageViewRGB32& screen){
200217
cout << stats.average.b << endl;
201218
*/
202219

203-
ImageViewRGB32 dialog_top_image = extract_box_reference(screen, m_dialog_top_box);
204-
ImageViewRGB32 dialog_right_image = extract_box_reference(screen, m_dialog_right_box);
220+
ImageViewRGB32 dialog_top_image = extract_box_reference(game_screen, m_dialog_top_box);
221+
ImageViewRGB32 dialog_right_image = extract_box_reference(game_screen, m_dialog_right_box);
205222

206223
if (is_solid(dialog_top_image, { 0.176, 0.357, 0.467 }, 0.25, 20)
207224
&& is_solid(dialog_right_image, { 0.176, 0.357, 0.467 }, 0.25, 20)
208225
&& (stats.average.r > stats.average.b + 180)
209226
&& (stats.average.r > stats.average.g + 180)
210-
)
211-
{
227+
){
212228
return true;
213229
}
214230
return false;

SerialPrograms/Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_DialogDetector.h

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,51 @@
88
#define PokemonAutomation_PokemonFRLG_DialogDetector_H
99

1010
#include <chrono>
11-
#include <atomic>
12-
#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h"
1311
#include "Common/Cpp/Color.h"
1412
#include "CommonFramework/ImageTools/ImageBoxes.h"
13+
#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h"
1514
#include "CommonTools/VisualDetector.h"
15+
#include "CommonTools/VisualDetectors/BlackScreenDetector.h"
1616
#include "CommonTools/InferenceCallbacks/VisualInferenceCallback.h"
17+
#include "PokemonFRLG/PokemonFRLG_Settings.h"
1718

1819
namespace PokemonAutomation{
1920
class CancellableScope;
2021
class VideoFeed;
2122
namespace NintendoSwitch{
2223
namespace PokemonFRLG{
2324

25+
26+
class WhiteScreenOverWatcher : public PokemonAutomation::WhiteScreenOverWatcher{
27+
public:
28+
WhiteScreenOverWatcher(Color color = COLOR_RED)
29+
: PokemonAutomation::WhiteScreenOverWatcher(
30+
color,
31+
GameSettings::instance().GAME_BOX.inner_to_outer({0.231692, 0.0616538, 0.551385, 0.9045})
32+
)
33+
{}
34+
};
35+
class BlackScreenWatcher : public PokemonAutomation::BlackScreenWatcher{
36+
public:
37+
BlackScreenWatcher(Color color = COLOR_RED)
38+
: PokemonAutomation::BlackScreenWatcher(
39+
color,
40+
GameSettings::instance().GAME_BOX.inner_to_outer({0.231692, 0.0616538, 0.551385, 0.9045})
41+
)
42+
{}
43+
};
44+
class BlackScreenOverWatcher : public PokemonAutomation::BlackScreenOverWatcher{
45+
public:
46+
BlackScreenOverWatcher(Color color = COLOR_RED)
47+
: PokemonAutomation::BlackScreenOverWatcher(
48+
color,
49+
GameSettings::instance().GAME_BOX.inner_to_outer({0.231692, 0.0616538, 0.551385, 0.9045})
50+
)
51+
{}
52+
};
53+
54+
55+
2456
// When given a choice popup, there is no advance arrow.
2557
// FRLG doesn't have an advance arrow on the final line of dialog when speaking to an npc!
2658

SerialPrograms/Source/PokemonFRLG/Inference/Dialogs/PokemonFRLG_PrizeSelectDetector.cpp

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

7-
#include "CommonTools/Images/SolidColorTest.h"
8-
#include "CommonTools/Images/ImageFilter.h"
97
#include "CommonFramework/ImageTools/ImageBoxes.h"
10-
#include "CommonFramework/ImageTypes/ImageRGB32.h"
118
#include "CommonFramework/ImageTools/ImageStats.h"
129
#include "CommonFramework/ImageTypes/ImageViewRGB32.h"
1310
#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h"
1411
#include "CommonTools/Images/SolidColorTest.h"
12+
#include "CommonTools/Images/ImageFilter.h"
1513
#include "CommonTools/Images/WaterfillUtilities.h"
16-
#include "CommonTools/ImageMatch/WaterfillTemplateMatcher.h"
17-
#include "CommonFramework/VideoPipeline/VideoOverlay.h"
14+
#include "PokemonFRLG/PokemonFRLG_Settings.h"
1815
#include "PokemonFRLG_PrizeSelectDetector.h"
1916

2017
namespace PokemonAutomation{
2118
namespace NintendoSwitch{
2219
namespace PokemonFRLG{
2320

2421
PrizeSelectDetector::PrizeSelectDetector(Color color)
25-
: m_right_box(0.812, 0.726, 0.013, 0.169)
26-
, m_top_box(0.175, 0.715, 0.649, 0.005)
27-
, m_bottom_box(0.177, 0.896, 0.645, 0.008)
28-
, m_selection_box(0.667, 0.514, 0.173, 0.058)
22+
: m_right_box(0.884, 0.749115, 0.016, 0.1755)
23+
, m_top_box(0.1, 0.737692, 0.798769, 0.00519231)
24+
, m_bottom_box(0.102462, 0.925654, 0.793846, 0.00830769)
25+
, m_selection_box(0.705538, 0.528962, 0.212923, 0.0602308)
2926
{}
3027
void PrizeSelectDetector::make_overlays(VideoOverlaySet& items) const{
31-
items.add(COLOR_RED, m_right_box);
32-
items.add(COLOR_RED, m_top_box);
33-
items.add(COLOR_RED, m_bottom_box);
34-
items.add(COLOR_RED, m_selection_box);
28+
const BoxOption& GAME_BOX = GameSettings::instance().GAME_BOX;
29+
items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_right_box));
30+
items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_top_box));
31+
items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_bottom_box));
32+
items.add(COLOR_RED, GAME_BOX.inner_to_outer(m_selection_box));
3533
}
3634
bool PrizeSelectDetector::detect(const ImageViewRGB32& screen){
37-
ImageViewRGB32 right_image = extract_box_reference(screen, m_right_box);
38-
ImageViewRGB32 top_image = extract_box_reference(screen, m_top_box);
39-
ImageViewRGB32 bottom_image = extract_box_reference(screen, m_bottom_box);
40-
ImageViewRGB32 selection_image = extract_box_reference(screen, m_selection_box);
35+
ImageViewRGB32 game_screen = extract_box_reference(screen, GameSettings::instance().GAME_BOX);
36+
37+
ImageViewRGB32 right_image = extract_box_reference(game_screen, m_right_box);
38+
ImageViewRGB32 top_image = extract_box_reference(game_screen, m_top_box);
39+
ImageViewRGB32 bottom_image = extract_box_reference(game_screen, m_bottom_box);
40+
ImageViewRGB32 selection_image = extract_box_reference(game_screen, m_selection_box);
4141
if (is_solid(right_image, { 0.25, 0.38, 0.369 })
4242
&& is_solid(top_image, { 0.25, 0.38, 0.369 })
4343
&& is_solid(bottom_image, { 0.25, 0.38, 0.369 })
4444
&& is_solid(selection_image, { 0.25, 0.38, 0.369 })
45-
){
45+
){
4646
return true;
4747
}
4848
return false;

0 commit comments

Comments
 (0)