Skip to content

Commit 269aac2

Browse files
committed
added black screen detection during reset
1 parent a93d1bb commit 269aac2

File tree

4 files changed

+118
-15
lines changed

4 files changed

+118
-15
lines changed

SerialPrograms/Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_RNGManipulator.cpp

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

7-
#include "CommonFramework/Exceptions/OperationFailedException.h"
7+
#include "CommonFramework/Exceptions/OperationFailedException.h"
88
#include "CommonFramework/ProgramStats/StatsTracking.h"
99
#include "CommonFramework/Notifications/ProgramNotifications.h"
1010
#include "CommonFramework/ProgramStats/StatsTracking.h"
@@ -61,7 +61,7 @@ RNGManipulator::RNGManipulator()
6161
{Target::starters, "starters", "Bulbasaur / Squirtle / Charmander"},
6262
{Target::magikarp, "magikarp", "Magikarp"},
6363
// {Target::hitmon, "hitmon", "Hitmonlee / Hitmonchan"},
64-
// {Target::eevee, "eevee", "Eevee"},
64+
{Target::eevee, "eevee", "Eevee"},
6565
// {Target::lapras, "lapras", "Lapras"},
6666
// {Target::fossils, "fossils", "Omanyte / Kabuto / Aerodactyl"},
6767
{Target::sweetscent, "sweetscent", "Sweet Scent for wild encounters"},
@@ -147,15 +147,48 @@ void hard_reset(ProControllerContext& context){
147147
// press A to select game
148148
pbf_press_button(context, BUTTON_A, 200ms, 2300ms);
149149
// press A to select profile and immediately go back to the home screen
150-
pbf_press_button(context, BUTTON_A, 100ms, 100ms);
151-
pbf_press_button(context, BUTTON_HOME, 200ms, 2800ms);
150+
// pbf_press_button(context, BUTTON_A, 100ms, 100ms);
151+
// pbf_press_button(context, BUTTON_HOME, 200ms, 2800ms);
152152
pbf_press_button(context, BUTTON_A, 200ms, 0ms);
153153
}
154154

155155
void soft_reset(ProControllerContext& context){
156156
pbf_press_button(context, BUTTON_B | BUTTON_A | BUTTON_X | BUTTON_Y, 200ms, 0ms);
157157
}
158158

159+
uint64_t wait_for_copyright_text(SingleSwitchProgramEnvironment& env, ProControllerContext& context){
160+
// wait for copyright text to appear
161+
BlackScreenWatcher black_screen(COLOR_RED);
162+
context.wait_for_all_requests();
163+
int black_ret = wait_until(
164+
env.console, context, 2000ms,
165+
{black_screen}
166+
);
167+
if (black_ret != 0){
168+
OperationFailedException::fire(
169+
ErrorReport::SEND_ERROR_REPORT,
170+
"Black screen not detected after starting game.",
171+
env.console
172+
);
173+
}
174+
BlackScreenOverWatcher copyright_detected(COLOR_RED);
175+
context.wait_for_all_requests();
176+
WallClock start_time = current_time();
177+
int ret = wait_until(
178+
env.console, context, 2000ms,
179+
{copyright_detected}
180+
);
181+
if (ret != 0){
182+
OperationFailedException::fire(
183+
ErrorReport::SEND_ERROR_REPORT,
184+
"Black screen detected for more than 2 seconds.",
185+
env.console
186+
);
187+
}
188+
auto elapsed = current_time() - start_time;
189+
return std::chrono::duration_cast<std::chrono::milliseconds>(elapsed).count();
190+
}
191+
159192
void set_seed_after_delay(ProControllerContext& context, SimpleIntegerOption<uint64_t>& SEED_DELAY){
160193
// wait on title screen for the specified delay
161194
pbf_wait(context, std::chrono::milliseconds(SEED_DELAY - 200));
@@ -194,6 +227,16 @@ void collect_magikarp_after_delay(ProControllerContext& context, uint64_t& DOUBL
194227
pbf_press_button(context, BUTTON_B, 200ms, 1300ms);
195228
}
196229

230+
231+
void collect_eevee_after_delay(ProControllerContext& context, uint64_t& DOUBLE_DELAY){
232+
// No dialogue to advance through -- just wait
233+
pbf_wait(context, std::chrono::milliseconds(DOUBLE_DELAY - 4000));
234+
// Interact with the pokeball
235+
pbf_press_button(context, BUTTON_A, 200ms, 3800ms);
236+
// Decline nickname
237+
pbf_press_button(context, BUTTON_B, 200ms, 1300ms);
238+
}
239+
197240
void go_to_starter_summary(ProControllerContext& context){
198241
// Navigate to summary (1st party slot)
199242
pbf_press_button(context, BUTTON_PLUS, 200ms, 800ms);
@@ -227,15 +270,17 @@ bool use_sweet_scent(SingleSwitchProgramEnvironment& env, ProControllerContext&
227270
pbf_press_button(context, BUTTON_A, 200ms, 800ms);
228271
context.wait_for_all_requests();
229272
BlackScreenWatcher battle_entered(COLOR_RED);
230-
run_until<ProControllerContext>(
231-
env.console, context,
232-
[](ProControllerContext& context) {
233-
while (true){
234-
pbf_wait(context, 100ms);
235-
}
236-
},
237-
{ battle_entered }
273+
int ret = wait_until(
274+
env.console, context, 10000ms,
275+
{battle_entered}
238276
);
277+
if (ret != 0){
278+
OperationFailedException::fire(
279+
ErrorReport::SEND_ERROR_REPORT,
280+
"Sweet Scent failed to initiate encounter.",
281+
env.console
282+
);
283+
}
239284
bool encounter_shiny = handle_encounter(env.console, context, false);
240285
return encounter_shiny;
241286
}
@@ -292,8 +337,8 @@ void RNGManipulator::program(SingleSwitchProgramEnvironment& env, ProControllerC
292337
while (!shiny_found){
293338
LOAD_DELAY = uint64_t((LOAD_ADVANCES)/ FRAMERATE * 1000);
294339
DOUBLE_DELAY = uint64_t((DOUBLE_ADVANCES)/ FRAMERATE * 500);
295-
env.log("Load screen delay: " + std::to_string(LOAD_DELAY));
296-
env.log("In-game delay: " + std::to_string(DOUBLE_DELAY));
340+
env.log("Load screen delay: " + std::to_string(LOAD_DELAY) + "ms");
341+
env.log("In-game delay: " + std::to_string(DOUBLE_DELAY) + "ms");
297342
if (RESET_TYPE == ResetType::hard){
298343
hard_reset(context);
299344
}else if (RESET_TYPE == ResetType::soft){
@@ -306,6 +351,9 @@ void RNGManipulator::program(SingleSwitchProgramEnvironment& env, ProControllerC
306351
);
307352
}
308353

354+
uint64_t STARTUP_DELAY = wait_for_copyright_text(env, context);
355+
env.log("Sstartup delay: " + std::to_string(STARTUP_DELAY) + "ms");
356+
309357
set_seed_after_delay(context, SEED_DELAY);
310358
load_game_after_delay(context, LOAD_DELAY);
311359

@@ -333,6 +381,19 @@ void RNGManipulator::program(SingleSwitchProgramEnvironment& env, ProControllerC
333381

334382
screen = env.console.video().snapshot();
335383

384+
ShinySymbolDetector shiny_checker(COLOR_YELLOW);
385+
shiny_found = shiny_checker.read(env.console.logger(), screen);
386+
}else if (TARGET == Target::eevee) {
387+
collect_eevee_after_delay(context, DOUBLE_DELAY);
388+
go_to_summary(context);
389+
if (TAKE_PICTURES){
390+
take_summary_pictures(context);
391+
}
392+
context.wait_for_all_requests();
393+
env.log("Eevee collected.");
394+
395+
screen = env.console.video().snapshot();
396+
336397
ShinySymbolDetector shiny_checker(COLOR_YELLOW);
337398
shiny_found = shiny_checker.read(env.console.logger(), screen);
338399
}else if (TARGET == Target::sweetscent){

SerialPrograms/Source/PokemonFRLG/Programs/ShinyHunting/PokemonFRLG_RNGManipulator.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class RNGManipulator : public SingleSwitchProgramInstance{
4242
starters,
4343
magikarp,
4444
// hitmon,
45-
// eevee,
45+
eevee,
4646
// lapras,
4747
// fossils,
4848
sweetscent,

SerialPrograms/Source/PokemonFRLG/Programs/TestPrograms/PokemonFRLG_StatsChecker.cpp

Whitespace-only changes.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/* Stats Checker
2+
*
3+
* From: https://github.com/PokemonAutomation/
4+
*
5+
*/
6+
7+
#ifndef PokemonAutomation_PokemonFRLG_StatsChecker_H
8+
#define PokemonAutomation_PokemonFRLG_StatsChecker_H
9+
10+
#include "Common/Cpp/Options/BooleanCheckBoxOption.h"
11+
#include "CommonFramework/Notifications/EventNotificationsTable.h"
12+
#include "NintendoSwitch/NintendoSwitch_SingleSwitchProgram.h"
13+
#include "NintendoSwitch/Options/NintendoSwitch_GoHomeWhenDoneOption.h"
14+
15+
namespace PokemonAutomation{
16+
namespace NintendoSwitch{
17+
namespace PokemonFRLG{
18+
19+
class StatsChecker_Descriptor : public SingleSwitchProgramDescriptor{
20+
public:
21+
StatsChecker_Descriptor();
22+
};
23+
24+
class StatsChecker : public SingleSwitchProgramInstance{
25+
public:
26+
StatsChecker();
27+
virtual void program(SingleSwitchProgramEnvironment& env, ProControllerContext &context) override;
28+
29+
virtual void start_program_border_check(
30+
VideoStream& stream,
31+
FeedbackType feedback_type
32+
) override{}
33+
34+
};
35+
36+
}
37+
}
38+
}
39+
#endif
40+
41+
42+

0 commit comments

Comments
 (0)