@@ -141,81 +141,96 @@ void reapproach_bench_after_getting_up(SingleSwitchProgramEnvironment& env, ProC
141141void ShinyHunt_BenchSit::program (SingleSwitchProgramEnvironment& env, ProControllerContext& context){
142142 ShinyHunt_BenchSit_Descriptor::Stats& stats = env.current_stats <ShinyHunt_BenchSit_Descriptor::Stats>();
143143
144- while (true ){
145- float shiny_coefficient = 1.0 ;
146- PokemonLA::ShinySoundDetector shiny_detector (env.console , [&](float error_coefficient) -> bool {
147- // Warning: This callback will be run from a different thread than this function.
148- stats.shinies ++;
149- env.update_stats ();
150- shiny_coefficient = error_coefficient;
151- if (SHINY_DETECTED.ACTION != ShinySoundDetectedAction::NOTIFY_ON_FIRST_ONLY){
152- return true ;
144+ std::atomic<uint8_t > to_take_shiny_sound_video{0 };
145+ // Store shiny detection time as milliseconds since epoch for thread-safe access
146+ std::atomic<int64_t > shiny_detection_time_ms{0 };
147+
148+ // once shiny sound detector finds a shiny and user decides to take a video of it,
149+ // we need to take the video on Switch as part of the program loop.
150+ auto handle_shiny_sound_video_request = [&]() -> void {
151+ if (to_take_shiny_sound_video.load (std::memory_order_relaxed) && SHINY_DETECTED.TAKE_VIDEO ){
152+ // Calculate elapsed time since shiny detection
153+ int64_t detection_time_ms = shiny_detection_time_ms.load (std::memory_order_relaxed);
154+ WallDuration elapsed = current_time () - WallClock (Milliseconds (detection_time_ms));
155+ auto elapsed_ms = std::chrono::duration_cast<Milliseconds>(elapsed);
156+
157+ // Calculate remaining time to wait
158+ Milliseconds requested_delay = SHINY_DETECTED.SCREENSHOT_DELAY .get ();
159+ if (requested_delay > elapsed_ms){
160+ context.wait_for (requested_delay - elapsed_ms);
153161 }
162+ // Otherwise, take screenshot immediately (no additional wait needed)
154163
155- return stats.shinies == 1 ;
156- });
157-
158- int ret = run_until<ProControllerContext>(
159- env.console , context,
160- [&](ProControllerContext& context){
161- while (true ){
162- send_program_status_notification (env, NOTIFICATION_STATUS);
163- sit_on_bench (env.console , context);
164- stats.resets ++;
165- env.update_stats ();
166- Milliseconds duration = WALK_FORWARD_DURATION;
167- if (duration > Milliseconds::zero ()){
168- if (WALK_DIRECTION.current_value () == 0 ){ // forward
169- ssf_press_button (context, BUTTON_B, 0ms, 2 * duration, 0ms);
170- pbf_move_left_joystick (context, 128 , 0 , duration, 0ms);
171- pbf_move_left_joystick (context, 128 , 255 , duration + 500ms, 0ms);
172- } else if (WALK_DIRECTION.current_value () == 1 ){ // left
173- ssf_press_button (context, BUTTON_B, 0ms, duration, 0ms);
174- pbf_move_left_joystick (context, 0 , 128 , duration, 0ms);
175- pbf_press_button (context, BUTTON_L, 100ms, 400ms);
176- ssf_press_button (context, BUTTON_B, 0ms, duration, 0ms);
177- pbf_move_left_joystick (context, 128 , 255 , duration, 0ms);
178- pbf_move_left_joystick (context, 0 , 128 , 100ms, 0ms);
179- } else if (WALK_DIRECTION.current_value () == 2 ){ // right
180- ssf_press_button (context, BUTTON_B, 0ms, duration, 0ms);
181- pbf_move_left_joystick (context, 255 , 128 , duration, 0ms);
182- pbf_press_button (context, BUTTON_L, 100ms, 400ms);
183- ssf_press_button (context, BUTTON_B, 0ms, duration, 0ms);
184- pbf_move_left_joystick (context, 128 , 255 , duration, 0ms);
185- pbf_move_left_joystick (context, 255 , 128 , 100ms, 0ms);
186- }
187- }
188- else {
189- reapproach_bench_after_getting_up (env, context);
190- }
191- }
192- },
193- {{shiny_detector}}
194- );
164+ pbf_press_button (context, BUTTON_CAPTURE, 2 * TICKS_PER_SECOND, 0 );
165+ to_take_shiny_sound_video.store (0 , std::memory_order_relaxed);
166+ }
167+ };
195168
196- // This should never happen.
197- if (ret != 0 ){
198- continue ;
169+ PokemonLA::ShinySoundDetector shiny_detector (env.console , [&](float error_coefficient) -> bool {
170+ // Warning: This callback will be run from a different thread than this function.
171+ stats.shinies ++;
172+ env.update_stats ();
173+
174+ if ((SHINY_DETECTED.ACTION == ShinySoundDetectedAction::STOP_PROGRAM) || stats.shinies == 1 ){
175+ // Record the detection time for video delay calculation
176+ WallClock now = current_time ();
177+ int64_t now_ms = std::chrono::duration_cast<Milliseconds>(now.time_since_epoch ()).count ();
178+ shiny_detection_time_ms.store (now_ms, std::memory_order_relaxed);
179+
180+ SHINY_DETECTED.send_shiny_sound_notification (env, env.console , error_coefficient);
181+ to_take_shiny_sound_video.store (1 , std::memory_order_relaxed);
199182 }
200183
201- pbf_mash_button (context, BUTTON_B, 1000ms);
184+ return SHINY_DETECTED.ACTION == ShinySoundDetectedAction::STOP_PROGRAM;
185+ });
202186
203- bool exit = SHINY_DETECTED.on_shiny_sound (
204- env, env.console , context,
205- stats.shinies ,
206- shiny_coefficient
207- );
187+ run_until<ProControllerContext>(
188+ env.console , context,
189+ [&](ProControllerContext& context){
190+ while (true ){
191+ send_program_status_notification (env, NOTIFICATION_STATUS);
192+ sit_on_bench (env.console , context);
193+ handle_shiny_sound_video_request ();
194+ stats.resets ++;
195+ env.update_stats ();
196+ Milliseconds duration = WALK_FORWARD_DURATION;
197+ if (duration > Milliseconds::zero ()){
198+ if (WALK_DIRECTION.current_value () == 0 ){ // forward
199+ ssf_press_button (context, BUTTON_B, 0ms, 2 * duration, 0ms);
200+ pbf_move_left_joystick (context, 128 , 0 , duration, 0ms);
201+ pbf_move_left_joystick (context, 128 , 255 , duration + 500ms, 0ms);
202+ } else if (WALK_DIRECTION.current_value () == 1 ){ // left
203+ ssf_press_button (context, BUTTON_B, 0ms, duration, 0ms);
204+ pbf_move_left_joystick (context, 0 , 128 , duration, 0ms);
205+ pbf_press_button (context, BUTTON_L, 100ms, 400ms);
206+ ssf_press_button (context, BUTTON_B, 0ms, duration, 0ms);
207+ pbf_move_left_joystick (context, 128 , 255 , duration, 0ms);
208+ pbf_move_left_joystick (context, 0 , 128 , 100ms, 0ms);
209+ } else if (WALK_DIRECTION.current_value () == 2 ){ // right
210+ ssf_press_button (context, BUTTON_B, 0ms, duration, 0ms);
211+ pbf_move_left_joystick (context, 255 , 128 , duration, 0ms);
212+ pbf_press_button (context, BUTTON_L, 100ms, 400ms);
213+ ssf_press_button (context, BUTTON_B, 0ms, duration, 0ms);
214+ pbf_move_left_joystick (context, 128 , 255 , duration, 0ms);
215+ pbf_move_left_joystick (context, 255 , 128 , 100ms, 0ms);
216+ }
217+ }
218+ else {
219+ reapproach_bench_after_getting_up (env, context);
220+ }
208221
209- pbf_move_left_joystick (context, 128 , 255 , WALK_FORWARD_DURATION, 0ms);
222+ handle_shiny_sound_video_request ();
223+ }
224+ },
225+ {{shiny_detector}}
226+ );
210227
211- if (exit){
212- break ;
213- }
214- }
228+ // Shiny sound detected and user requested stopping the program when detected shiny sound
229+
230+ handle_shiny_sound_video_request ();
215231
216232 go_home (env.console , context);
217233 send_program_finished_notification (env, NOTIFICATION_PROGRAM_FINISH);
218-
219234}
220235
221236
0 commit comments