Skip to content

Commit 17fd9af

Browse files
committed
use inference for home_to_date_time
1 parent 614877a commit 17fd9af

File tree

3 files changed

+259
-1
lines changed

3 files changed

+259
-1
lines changed

SerialPrograms/Source/NintendoSwitch/DevPrograms/TestProgramSwitch.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@
121121
#include "PokemonSV/Inference/Picnics/PokemonSV_SandwichHandDetector.h"
122122
#include "PokemonSwSh/MaxLair/Inference/PokemonSwSh_MaxLair_Detect_PokemonSwapMenu.h"
123123
#include "CommonTools/Images/ImageFilter.h"
124-
124+
#include "NintendoSwitch/Programs/NintendoSwitch_Navigation.h"
125125

126126
#include <QPixmap>
127127
#include <QVideoFrame>
@@ -315,11 +315,22 @@ void TestProgram::program(MultiSwitchProgramEnvironment& env, CancellableScope&
315315
ProControllerContext context(scope, console.pro_controller());
316316
VideoOverlaySet overlays(overlay);
317317

318+
319+
#if 1
320+
ImageFloatBox box(0.060, 0.75, 0.02, 0.08);
321+
ImageFloatBox system_settings(0.685, 0.69, 0.05, 0.03);
322+
ImageFloatBox other_setting1(0.615, 0.69, 0.05, 0.03);
323+
ImageFloatBox other_setting2(0.545, 0.69, 0.05, 0.03);
324+
cout << is_setting_selected(console, context, system_settings, other_setting1, other_setting2) << endl;
325+
#endif
326+
327+
#if 0
318328
// std::terminate();
319329
ImageRGB32 image("20250503-121259857603.png");
320330

321331
image = filter_rgb32_brightness(image, COLOR_RED, false, 0x00ffff01, 0, 200);
322332
image.save("temp.png");
333+
#endif
323334

324335

325336
#if 0

SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_Navigation.cpp

Lines changed: 235 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,247 @@
77
#include "Controllers/ControllerTypes.h"
88
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h"
99
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h"
10+
#include "CommonFramework/ImageTools/ImageStats.h"
11+
#include "CommonFramework/VideoPipeline/VideoFeed.h"
12+
#include "CommonFramework/VideoPipeline/VideoOverlayScopes.h"
1013
#include "NintendoSwitch_Navigation.h"
1114

15+
#include <cmath>
16+
1217
namespace PokemonAutomation{
1318
namespace NintendoSwitch{
1419

1520

21+
bool is_white_theme(VideoStream& stream, ProControllerContext& context){
22+
context.wait_for_all_requests();
23+
VideoSnapshot snapshot = stream.video().snapshot();
24+
ImageFloatBox window_top(0.60, 0.02, 0.35, 0.05);
25+
ImageStats stats_window_top = image_stats(extract_box_reference(snapshot, window_top));
26+
bool white_theme = stats_window_top.average.sum() > 600;
27+
return white_theme;
28+
}
29+
30+
bool is_setting_selected(VideoStream& stream, ProControllerContext& context, ImageFloatBox selected_box, ImageFloatBox unselected_box1, ImageFloatBox unselected_box2){
31+
VideoOverlaySet overlays(stream.overlay());
32+
overlays.add(COLOR_RED, selected_box);
33+
overlays.add(COLOR_BLUE, unselected_box1);
34+
overlays.add(COLOR_BLUE, unselected_box2);
35+
context.wait_for(Milliseconds(100));
36+
context.wait_for_all_requests();
37+
VideoSnapshot snapshot = stream.video().snapshot();
38+
39+
ImageStats stats_unselected_box1 = image_stats(extract_box_reference(snapshot, unselected_box1));
40+
double unselected1_average_sum = stats_unselected_box1.average.sum();
41+
stream.log("unselected_average_sum1: " + std::to_string(unselected1_average_sum));
42+
43+
ImageStats stats_unselected_box2 = image_stats(extract_box_reference(snapshot, unselected_box2));
44+
double unselected2_average_sum = stats_unselected_box2.average.sum();
45+
stream.log("unselected_average_sum2: " + std::to_string(unselected2_average_sum));
46+
47+
double average_sum_unselected_diff = std::abs(unselected1_average_sum - unselected2_average_sum);
48+
49+
ImageStats stats_selected_box = image_stats(extract_box_reference(snapshot, selected_box));
50+
double selected_average_sum = stats_selected_box.average.sum();
51+
stream.log("selected_average_sum: " + std::to_string(selected_average_sum));
52+
53+
if (is_white_theme(stream, context)){ // light mode
54+
// unselected should be brighter than selected
55+
return selected_average_sum < std::min(unselected1_average_sum, unselected2_average_sum) - average_sum_unselected_diff - 20 ;
56+
}else{ // dark mode
57+
// selected should be brighter than unselected
58+
return selected_average_sum > std::max(unselected1_average_sum, unselected2_average_sum) + average_sum_unselected_diff + 20;
59+
}
60+
}
61+
62+
void home_to_date_time(VideoStream& stream, ProControllerContext& context, bool to_date_change, bool fast){
63+
switch (context->performance_class()){
64+
case ControllerPerformanceClass::SerialPABotBase_Wired_125Hz:{
65+
ssf_issue_scroll(context, SSF_SCROLL_RIGHT, 4);
66+
ssf_issue_scroll(context, SSF_SCROLL_RIGHT, 4);
67+
ssf_issue_scroll(context, SSF_SCROLL_RIGHT, 4);
68+
69+
// Down twice in case we drop one.
70+
ssf_issue_scroll(context, SSF_SCROLL_DOWN, 3);
71+
ssf_issue_scroll(context, SSF_SCROLL_DOWN, 4);
72+
73+
ssf_issue_scroll(context, SSF_SCROLL_LEFT, 0);
74+
75+
76+
77+
// Two A presses in case we drop the 1st one.
78+
ssf_press_button(context, BUTTON_A, 3);
79+
ssf_press_button(context, BUTTON_A, 3);
80+
81+
// Just button mash it. lol
82+
{
83+
auto iterations = Milliseconds(1200) / 24ms + 1;
84+
do{
85+
ssf_issue_scroll(context, SSF_SCROLL_DOWN, 24ms);
86+
}while (--iterations);
87+
}
88+
89+
// Scroll left and press A to exit the sleep menu if we happened to
90+
// land there.
91+
ssf_issue_scroll(context, SSF_SCROLL_LEFT, 3);
92+
ssf_press_button(context, BUTTON_A, 3);
93+
94+
{
95+
auto iterations = Milliseconds(312) / 24ms + 1;
96+
do{
97+
ssf_issue_scroll(context, SSF_SCROLL_RIGHT, 24ms);
98+
}while (--iterations);
99+
}
100+
101+
ssf_issue_scroll(context, SSF_SCROLL_DOWN, 3);
102+
ssf_issue_scroll(context, SSF_SCROLL_DOWN, 3);
103+
ssf_issue_scroll(context, SSF_SCROLL_DOWN, 10);
104+
ssf_press_dpad(context, DPAD_DOWN, 45, 40);
105+
ssf_issue_scroll(context, SSF_SCROLL_DOWN, 3);
106+
ssf_issue_scroll(context, SSF_SCROLL_DOWN, 3);
107+
108+
if (!to_date_change){
109+
// Triple up this A press to make sure it gets through.
110+
ssf_press_button(context, BUTTON_A, 3);
111+
ssf_press_button(context, BUTTON_A, 3);
112+
ssf_press_button(context, BUTTON_A, 45);
113+
return;
114+
}
115+
116+
// Triple up this A press to make sure it gets through.
117+
ssf_press_button(context, BUTTON_A, 3);
118+
ssf_press_button(context, BUTTON_A, 3);
119+
ssf_press_button(context, BUTTON_A, 3);
120+
{
121+
auto iterations = Milliseconds(250) / 24ms + 1;
122+
do{
123+
ssf_issue_scroll(context, SSF_SCROLL_DOWN, 24ms);
124+
}while (--iterations);
125+
}
126+
// ssf_issue_scroll(context, SSF_SCROLL_DOWN, 0);
127+
128+
// Left scroll in case we missed landed in the language change or sleep
129+
// confirmation menus.
130+
ssf_issue_scroll(context, SSF_SCROLL_LEFT, 0ms);
131+
132+
break;
133+
}
134+
case ControllerPerformanceClass::SerialPABotBase_Wireless_ESP32:{
135+
Milliseconds tv = context->timing_variation();
136+
Milliseconds unit = 24ms + tv;
137+
138+
ssf_issue_scroll(context, SSF_SCROLL_RIGHT, unit);
139+
ssf_issue_scroll(context, SSF_SCROLL_RIGHT, unit);
140+
ssf_issue_scroll(context, SSF_SCROLL_RIGHT, unit);
141+
142+
// Down twice in case we drop one.
143+
ssf_issue_scroll(context, SSF_SCROLL_DOWN, unit);
144+
ssf_issue_scroll(context, SSF_SCROLL_DOWN, unit);
145+
146+
ssf_issue_scroll(context, SSF_SCROLL_LEFT, 0ms, 2*unit, unit);
147+
148+
// Press A multiple times to make sure one goes through.
149+
pbf_press_button(context, BUTTON_A, 2*unit, unit);
150+
pbf_press_button(context, BUTTON_A, 2*unit, unit);
151+
pbf_press_button(context, BUTTON_A, 2*unit, unit);
152+
153+
// Just button mash it. lol
154+
{
155+
auto iterations = Milliseconds(1100) / unit + 1;
156+
do{
157+
ssf_issue_scroll(context, SSF_SCROLL_DOWN, unit);
158+
}while (--iterations);
159+
}
160+
161+
// Scroll left and press A to exit the sleep menu if we happened to
162+
// land there.
163+
ssf_issue_scroll(context, SSF_SCROLL_LEFT, unit);
164+
ssf_press_button(context, BUTTON_A, unit, 2*unit, unit);
165+
166+
{
167+
auto iterations = Milliseconds(312) / unit + 1;
168+
do{
169+
ssf_issue_scroll(context, SSF_SCROLL_RIGHT, unit);
170+
}while (--iterations);
171+
}
172+
173+
ssf_issue_scroll(context, SSF_SCROLL_DOWN, unit);
174+
ssf_issue_scroll(context, SSF_SCROLL_DOWN, unit);
175+
ssf_issue_scroll(context, SSF_SCROLL_DOWN, 400ms, 2*unit, unit);
176+
ssf_press_dpad(context, DPAD_DOWN, 360ms, 304ms);
177+
ssf_issue_scroll(context, SSF_SCROLL_DOWN, unit);
178+
ssf_issue_scroll(context, SSF_SCROLL_DOWN, unit);
179+
180+
if (!to_date_change){
181+
// Triple up this A press to make sure it gets through.
182+
ssf_press_button(context, BUTTON_A, unit);
183+
ssf_press_button(context, BUTTON_A, unit);
184+
ssf_press_button(context, BUTTON_A, 360ms, 2*unit, unit);
185+
return;
186+
}
187+
188+
// Triple up this A press to make sure it gets through.
189+
ssf_press_button(context, BUTTON_A, unit);
190+
ssf_press_button(context, BUTTON_A, unit);
191+
ssf_press_button(context, BUTTON_A, unit);
192+
{
193+
auto iterations = Milliseconds(250) / unit + 1;
194+
do{
195+
ssf_issue_scroll(context, SSF_SCROLL_DOWN, unit);
196+
}while (--iterations);
197+
}
198+
199+
// Left scroll in case we missed landed in the language change or sleep
200+
// confirmation menus.
201+
ssf_issue_scroll(context, SSF_SCROLL_LEFT, 0ms, 2*unit, unit);
202+
203+
break;
204+
}
205+
default:{
206+
// Slow version for tick-imprecise controllers.
207+
208+
Milliseconds tv = context->timing_variation();
209+
// ssf_do_nothing(context, 1500ms);
210+
211+
ssf_issue_scroll_ptv(context, SSF_SCROLL_RIGHT);
212+
ssf_issue_scroll_ptv(context, SSF_SCROLL_RIGHT);
213+
ssf_issue_scroll_ptv(context, SSF_SCROLL_RIGHT);
214+
215+
// Down twice in case we drop one.
216+
ssf_issue_scroll_ptv(context, SSF_SCROLL_DOWN);
217+
// ssf_issue_scroll_ptv(context, SSF_SCROLL_DOWN);
218+
219+
ssf_issue_scroll_ptv(context, SSF_SCROLL_LEFT);
220+
221+
// Press A multiple times to make sure one goes through.
222+
ssf_mash1_button(context, BUTTON_A, 200ms);
223+
ssf_issue_scroll_ptv(context, SSF_SCROLL_DOWN, 2500ms, 2500ms);
224+
ssf_issue_scroll_ptv(context, SSF_SCROLL_RIGHT, 500ms, 500ms);
225+
226+
ssf_issue_scroll_ptv(context, SSF_SCROLL_DOWN);
227+
ssf_issue_scroll_ptv(context, SSF_SCROLL_DOWN);
228+
ssf_issue_scroll(context, SSF_SCROLL_DOWN, 500ms, tv, tv);
229+
ssf_press_right_joystick(context, 128, 224, 1000ms, 300ms, tv);
230+
// ssf_issue_scroll(context, SSF_SCROLL_DOWN, 1000ms, 250ms, tv); // Scroll down
231+
ssf_issue_scroll_ptv(context, SSF_SCROLL_DOWN);
232+
ssf_issue_scroll_ptv(context, SSF_SCROLL_DOWN);
233+
234+
if (!to_date_change){
235+
ssf_press_button_ptv(context, BUTTON_A);
236+
return;
237+
}
238+
239+
ssf_press_button_ptv(context, BUTTON_A, 1000ms);
240+
ssf_issue_scroll_ptv(context, SSF_SCROLL_DOWN);
241+
ssf_issue_scroll_ptv(context, SSF_SCROLL_DOWN);
242+
}
243+
}
244+
245+
246+
247+
}
248+
249+
250+
16251

17252
void home_to_date_time(ProControllerContext& context, bool to_date_change, bool fast){
18253
switch (context->performance_class()){

SerialPrograms/Source/NintendoSwitch/Programs/NintendoSwitch_Navigation.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,26 @@
77
#ifndef PokemonAutomation_NintendoSwitch_Navigation_H
88
#define PokemonAutomation_NintendoSwitch_Navigation_H
99

10+
#include "CommonFramework/ImageTools/ImageBoxes.h"
11+
#include "CommonFramework/Tools/VideoStream.h"
1012
#include "NintendoSwitch/Controllers/NintendoSwitch_ProController.h"
1113
#include "NintendoSwitch/Controllers/NintendoSwitch_Joycon.h"
1214

1315
namespace PokemonAutomation{
1416
namespace NintendoSwitch{
1517

18+
// return true if the Switch Settings uses White theme
19+
// assumes we are currently in the Switch Settings.
20+
bool is_white_theme(VideoStream& stream, ProControllerContext& context);
1621

22+
// return true if the area within the selected_box is highlighted, compared with the area within unselected_box
23+
// This compares the brightness of the selected_box with the unselected_box.
24+
// selected_box: the box where we expect the screen should be highlighted
25+
// unselected_box 1 and 2: the boxes where we expect the screen should NOT be highlighted. These acts as the control, for comparison.
26+
// the average sum of selected_box should be greater than the absolute difference of average sum between unselected_box 1 and 2.
27+
bool is_setting_selected(VideoStream& stream, ProControllerContext& context, ImageFloatBox selected_box, ImageFloatBox unselected_box1, ImageFloatBox unselected_box2);
1728

29+
void home_to_date_time(VideoStream& stream, ProControllerContext& context, bool to_date_change, bool fast);
1830
void home_to_date_time(ProControllerContext& context, bool to_date_change, bool fast);
1931

2032
//Joycon must not be sideways

0 commit comments

Comments
 (0)