Skip to content

Commit cece01d

Browse files
author
ig-14
committed
Fix LGPE date rolling menu navigation bugs
- Add verify_date_time_menu_selected() to ensure 'Date and Time' menu item is selected (not 'Time Zone') - Use single snapshot checks instead of continuous polling to avoid visual pulsing - Verify menu state before rolling date forward/backward in DailyItemFarmer - Prevents accidentally entering wrong menus (Time Zone, Region, etc.)
1 parent 9a503cf commit cece01d

File tree

3 files changed

+160
-71
lines changed

3 files changed

+160
-71
lines changed
Lines changed: 148 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,148 @@
1-
/* Auto Host Routines
2-
*
3-
* From: https://github.com/PokemonAutomation/
4-
*
5-
*/
6-
7-
#include "Controllers/SerialPABotBase/Connection/MessageConverter.h"
8-
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h"
9-
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h"
10-
#include "NintendoSwitch/Programs/NintendoSwitch_GameEntry.h"
11-
#include "NintendoSwitch/Programs/DateSpam/NintendoSwitch_HomeToDateTime.h"
12-
#include "PokemonLGPE_DateSpam.h"
13-
14-
namespace PokemonAutomation{
15-
namespace NintendoSwitch{
16-
namespace PokemonLGPE{
17-
18-
void roll_date_forward_1(JoyconContext& context){
19-
Milliseconds tv = context->timing_variation();
20-
Milliseconds unit = 24ms + tv;
21-
22-
pbf_press_button(context, BUTTON_A, 2*unit, unit);
23-
pbf_move_joystick(context, 128, 0, 2*unit, unit);
24-
pbf_press_button(context, BUTTON_A, 2*unit, unit);
25-
26-
pbf_move_joystick(context, 255, 128, 2*unit, unit);
27-
pbf_move_joystick(context, 128, 0, 2*unit, unit);
28-
pbf_move_joystick(context, 255, 128, 2*unit, unit);
29-
pbf_press_button(context, BUTTON_A, 2*unit, unit);
30-
pbf_move_joystick(context, 255, 128, 2*unit, unit);
31-
pbf_move_joystick(context, 255, 128, 2*unit, unit);
32-
pbf_press_button(context, BUTTON_A, 2*unit, unit);
33-
}
34-
35-
void roll_date_backward_N(JoyconContext& context, uint8_t skips){
36-
if (skips == 0){
37-
return;
38-
}
39-
40-
Milliseconds tv = context->timing_variation();
41-
Milliseconds unit = 24ms + tv;
42-
43-
pbf_press_button(context, BUTTON_A, 2*unit, unit);
44-
45-
for (uint8_t c = 0; c < skips - 1; c++){
46-
pbf_move_joystick(context, 128, 255, 2*unit, unit);
47-
}
48-
49-
pbf_press_button(context, BUTTON_A, 2*unit, unit);
50-
pbf_move_joystick(context, 255, 128, 2*unit, unit);
51-
52-
for (uint8_t c = 0; c < skips - 1; c++){
53-
pbf_move_joystick(context, 128, 255, 2*unit, unit);
54-
}
55-
56-
pbf_press_button(context, BUTTON_A, 2*unit, unit);
57-
pbf_move_joystick(context, 255, 128, 2*unit, unit);
58-
pbf_move_joystick(context, 255, 128, 2*unit, unit);
59-
pbf_press_button(context, BUTTON_A, 2*unit, unit);
60-
pbf_press_button(context, BUTTON_A, 2*unit, unit);
61-
}
62-
63-
64-
65-
66-
67-
}
68-
69-
}
70-
}
71-
1+
/* Auto Host Routines
2+
*
3+
* From: https://github.com/PokemonAutomation/
4+
*
5+
*/
6+
7+
#include "Common/Cpp/Time.h"
8+
#include "CommonFramework/Exceptions/OperationFailedException.h"
9+
#include "CommonFramework/ImageTools/ImageBoxes.h"
10+
#include "CommonTools/Async/InferenceRoutines.h"
11+
#include "Controllers/SerialPABotBase/Connection/MessageConverter.h"
12+
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_PushButtons.h"
13+
#include "NintendoSwitch/Commands/NintendoSwitch_Commands_Superscalar.h"
14+
#include "NintendoSwitch/Inference/NintendoSwitch_SelectedSettingDetector.h"
15+
#include "NintendoSwitch/Programs/NintendoSwitch_GameEntry.h"
16+
#include "NintendoSwitch/Programs/DateSpam/NintendoSwitch_HomeToDateTime.h"
17+
#include "PokemonLGPE_DateSpam.h"
18+
19+
namespace PokemonAutomation{
20+
namespace NintendoSwitch{
21+
namespace PokemonLGPE{
22+
23+
void verify_date_time_menu_selected(ConsoleHandle& console, JoyconContext& context){
24+
// Verify that "Date and Time" menu item is selected (not "Time Zone")
25+
// After home_to_date_time(..., true), we should be in the "Date and Time" menu screen
26+
// Menu items: "Synchronize Clock via Internet" (top), "Time Zone" (middle), "Date and Time" (bottom)
27+
// We need "Date and Time" (bottom) to be selected before rolling the date
28+
29+
context.wait_for_all_requests();
30+
context.wait_for(Milliseconds(300));
31+
32+
// Use single snapshot check instead of polling to avoid visual pulsing
33+
VideoSnapshot snapshot = console.video().snapshot();
34+
if (!snapshot){
35+
console.log("WARNING: No video available for menu verification. Proceeding anyway...", COLOR_RED);
36+
return;
37+
}
38+
39+
// Box positions based on Switch menu layout - "Date and Time" text is at bottom
40+
ImageFloatBox date_time_box(0.50, 0.78, 0.15, 0.03); // "Date and Time" menu item (bottom)
41+
ImageFloatBox time_zone_box(0.50, 0.70, 0.15, 0.03); // "Time Zone" menu item (middle)
42+
ImageFloatBox sync_clock_box(0.50, 0.62, 0.15, 0.03); // "Synchronize Clock via Internet" (top)
43+
44+
// Check once if "Date and Time" is selected (using snapshot timestamp, no polling)
45+
SelectedSettingWatcher date_time_watcher(date_time_box, time_zone_box, sync_clock_box);
46+
bool date_time_selected = date_time_watcher.process_frame(*snapshot, snapshot.timestamp());
47+
48+
if (date_time_selected){
49+
// Successfully detected "Date and Time" is selected
50+
console.log("Verified 'Date and Time' menu item is selected.");
51+
return;
52+
}
53+
54+
// "Date and Time" is not selected - navigate to it
55+
console.log("'Date and Time' not selected. Navigating to it...", COLOR_YELLOW);
56+
57+
Milliseconds tv = context->timing_variation();
58+
Milliseconds unit = 80ms + tv;
59+
60+
// Check if "Time Zone" is selected (middle option)
61+
SelectedSettingWatcher time_zone_watcher(time_zone_box, date_time_box, sync_clock_box);
62+
bool time_zone_selected = time_zone_watcher.process_frame(*snapshot, snapshot.timestamp());
63+
64+
if (time_zone_selected){
65+
// "Time Zone" is selected, need to go down one more to reach "Date and Time"
66+
console.log("'Time Zone' selected. Moving down one to 'Date and Time'...", COLOR_YELLOW);
67+
pbf_move_joystick(context, 128, 255, unit, unit);
68+
context.wait_for_all_requests();
69+
context.wait_for(Milliseconds(300));
70+
} else {
71+
// Might be on "Synchronize Clock via Internet" (top) - need to go down twice
72+
console.log("Top option selected. Moving down twice to 'Date and Time'...", COLOR_YELLOW);
73+
pbf_move_joystick(context, 128, 255, unit, unit);
74+
context.wait_for_all_requests();
75+
context.wait_for(Milliseconds(200));
76+
pbf_move_joystick(context, 128, 255, unit, unit);
77+
context.wait_for_all_requests();
78+
context.wait_for(Milliseconds(300));
79+
}
80+
81+
// Final quick check after navigation (single snapshot, no polling)
82+
context.wait_for_all_requests();
83+
context.wait_for(Milliseconds(200));
84+
snapshot = console.video().snapshot();
85+
if (snapshot){
86+
date_time_selected = date_time_watcher.process_frame(*snapshot, snapshot.timestamp());
87+
if (!date_time_selected){
88+
console.log("WARNING: Could not verify 'Date and Time' is selected after navigation. Proceeding anyway...", COLOR_RED);
89+
} else {
90+
console.log("Successfully navigated to 'Date and Time' menu item.");
91+
}
92+
}
93+
}
94+
95+
void roll_date_forward_1(JoyconContext& context){
96+
Milliseconds tv = context->timing_variation();
97+
Milliseconds unit = 24ms + tv;
98+
99+
pbf_press_button(context, BUTTON_A, 2*unit, unit);
100+
pbf_move_joystick(context, 128, 0, 2*unit, unit);
101+
pbf_press_button(context, BUTTON_A, 2*unit, unit);
102+
103+
pbf_move_joystick(context, 255, 128, 2*unit, unit);
104+
pbf_move_joystick(context, 128, 0, 2*unit, unit);
105+
pbf_move_joystick(context, 255, 128, 2*unit, unit);
106+
pbf_press_button(context, BUTTON_A, 2*unit, unit);
107+
pbf_move_joystick(context, 255, 128, 2*unit, unit);
108+
pbf_move_joystick(context, 255, 128, 2*unit, unit);
109+
pbf_press_button(context, BUTTON_A, 2*unit, unit);
110+
}
111+
112+
void roll_date_backward_N(JoyconContext& context, uint8_t skips){
113+
if (skips == 0){
114+
return;
115+
}
116+
117+
Milliseconds tv = context->timing_variation();
118+
Milliseconds unit = 24ms + tv;
119+
120+
pbf_press_button(context, BUTTON_A, 2*unit, unit);
121+
122+
for (uint8_t c = 0; c < skips - 1; c++){
123+
pbf_move_joystick(context, 128, 255, 2*unit, unit);
124+
}
125+
126+
pbf_press_button(context, BUTTON_A, 2*unit, unit);
127+
pbf_move_joystick(context, 255, 128, 2*unit, unit);
128+
129+
for (uint8_t c = 0; c < skips - 1; c++){
130+
pbf_move_joystick(context, 128, 255, 2*unit, unit);
131+
}
132+
133+
pbf_press_button(context, BUTTON_A, 2*unit, unit);
134+
pbf_move_joystick(context, 255, 128, 2*unit, unit);
135+
pbf_move_joystick(context, 255, 128, 2*unit, unit);
136+
pbf_press_button(context, BUTTON_A, 2*unit, unit);
137+
pbf_press_button(context, BUTTON_A, 2*unit, unit);
138+
}
139+
140+
141+
142+
143+
144+
}
145+
146+
}
147+
}
148+

SerialPrograms/Source/PokemonLGPE/Commands/PokemonLGPE_DateSpam.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,22 @@
99

1010
#include "CommonFramework/Tools/VideoStream.h"
1111
#include "NintendoSwitch/Controllers/NintendoSwitch_Joycon.h"
12+
#include "NintendoSwitch/NintendoSwitch_ConsoleHandle.h"
1213

1314
namespace PokemonAutomation{
1415
namespace NintendoSwitch{
1516
namespace PokemonLGPE{
1617

18+
// Verify that "Date and Time" menu item is selected (not "Time Zone") before rolling date
19+
// If wrong menu item is selected, navigate to correct it
20+
void verify_date_time_menu_selected(ConsoleHandle& console, JoyconContext& context);
21+
1722
void roll_date_forward_1 (JoyconContext& context);
1823
void roll_date_backward_N (JoyconContext& context, uint8_t skips);
1924

2025
}
2126

2227
}
28+
2329
}
2430
#endif

SerialPrograms/Source/PokemonLGPE/Programs/Farming/PokemonLGPE_DailyItemFarmer.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,9 @@ void DailyItemFarmer::program(SingleSwitchProgramEnvironment& env, CancellableSc
182182
context.wait_for(1000ms);
183183

184184
home_to_date_time(env.console, context, true);
185+
186+
// Verify "Date and Time" menu item is selected before rolling date
187+
verify_date_time_menu_selected(env.console, context);
185188

186189
env.log("Rolling date back.");
187190
roll_date_backward_N(context, MAX_YEAR);
@@ -218,6 +221,9 @@ void DailyItemFarmer::program(SingleSwitchProgramEnvironment& env, CancellableSc
218221
#endif
219222

220223
home_to_date_time(env.console, context, true);
224+
225+
// Verify "Date and Time" menu item is selected before rolling date
226+
verify_date_time_menu_selected(env.console, context);
221227

222228
if (year >= MAX_YEAR){
223229
env.log("Rolling date back.");

0 commit comments

Comments
 (0)