@@ -312,6 +312,206 @@ bool openedgame_to_gamemenu(
312312
313313
314314
315+ void move_to_user (JoyconContext& context, uint8_t user_slot){
316+ if (user_slot != 0 ){
317+ // Move to correct user.
318+ for (uint8_t c = 0 ; c < 9 ; c++){ // Extra iteration in case one gets dropped.
319+ pbf_move_joystick (context, 0 , 128 , 160ms, 160ms);
320+ }
321+ for (uint8_t c = 1 ; c < user_slot; c++){
322+ pbf_move_joystick (context, 0 , 128 , 160ms, 160ms);
323+ }
324+ }
325+ }
326+
327+ void start_game_from_home_with_inference (
328+ VideoStream& stream, JoyconContext& context,
329+ uint8_t game_slot,
330+ uint8_t user_slot,
331+ Milliseconds start_game_wait
332+ ){
333+ context.wait_for_all_requests ();
334+ {
335+ HomeWatcher detector;
336+ int ret = run_until<JoyconContext>(
337+ stream, context,
338+ [](JoyconContext& context){
339+ pbf_mash_button (context, BUTTON_B, 10000ms);
340+ },
341+ { detector }
342+ );
343+ if (ret == 0 ){
344+ stream.log (" Detected Home screen." );
345+ }else {
346+ OperationFailedException::fire (
347+ ErrorReport::SEND_ERROR_REPORT,
348+ " start_game_from_home_with_inference(): Failed to detect Home screen after 10 seconds." ,
349+ stream
350+ );
351+ }
352+ context.wait_for (std::chrono::milliseconds (100 ));
353+ }
354+
355+ if (game_slot != 0 ){
356+ ssf_press_button (context, BUTTON_HOME, ConsoleSettings::instance ().SETTINGS_TO_HOME_DELAY0 , 160ms);
357+ for (uint8_t c = 1 ; c < game_slot; c++){
358+ pbf_move_joystick (context, 255 , 128 , 160ms, 0ms);
359+ }
360+ context.wait_for_all_requests ();
361+ }
362+
363+ pbf_press_button (context, BUTTON_A, 160ms, 840ms);
364+
365+ while (true ){
366+ HomeWatcher home (std::chrono::milliseconds (2000 ));
367+ StartGameUserSelectWatcher user_select (COLOR_GREEN);
368+ UpdateMenuWatcher update_menu (COLOR_PURPLE);
369+ CheckOnlineWatcher check_online (COLOR_CYAN);
370+ BlackScreenWatcher black_screen (COLOR_BLUE);
371+ context.wait_for_all_requests ();
372+ int ret = wait_until (
373+ stream, context,
374+ std::chrono::seconds (30 ),
375+ {
376+ home,
377+ user_select,
378+ update_menu,
379+ check_online,
380+ black_screen,
381+ }
382+ );
383+
384+ // Wait for screen to stabilize.
385+ context.wait_for (std::chrono::milliseconds (100 ));
386+
387+ switch (ret){
388+ case 0 :
389+ stream.log (" Detected home screen (again)." , COLOR_RED);
390+ pbf_press_button (context, BUTTON_A, 160ms, 840ms);
391+ break ;
392+ case 1 :
393+ stream.log (" Detected user-select screen." );
394+ move_to_user (context, user_slot);
395+ pbf_press_button (context, BUTTON_A, 80ms, start_game_wait);
396+ break ;
397+ case 2 :
398+ stream.log (" Detected update menu." , COLOR_RED);
399+ pbf_move_joystick (context, 128 , 0 , 50ms, 0ms);
400+ pbf_press_button (context, BUTTON_A, 160ms, 840ms);
401+ break ;
402+ case 3 :
403+ stream.log (" Detected check online." , COLOR_RED);
404+ context.wait_for (std::chrono::seconds (1 ));
405+ break ;
406+ case 4 :
407+ stream.log (" Detected black screen. Game started..." );
408+ return ;
409+ default :
410+ OperationFailedException::fire (
411+ ErrorReport::SEND_ERROR_REPORT,
412+ " start_game_from_home_with_inference(): No recognizable state after 30 seconds." ,
413+ stream
414+ );
415+ }
416+ }
417+ }
418+
419+ void start_game_from_home (
420+ VideoStream& stream, JoyconContext& context,
421+ bool tolerate_update_menu,
422+ uint8_t game_slot,
423+ uint8_t user_slot,
424+ Milliseconds start_game_mash
425+ ){
426+ context.wait_for_all_requests ();
427+ if (stream.video ().snapshot ()){
428+ stream.log (" start_game_from_home(): Video capture available. Using inference..." );
429+ start_game_from_home_with_inference (stream, context, game_slot, user_slot, start_game_mash);
430+ return ;
431+ }else {
432+ stream.log (" start_game_from_home(): Video capture not available." , COLOR_RED);
433+ }
434+
435+ if (game_slot != 0 ){
436+ ssf_press_button (context, BUTTON_HOME, ConsoleSettings::instance ().SETTINGS_TO_HOME_DELAY0 , 160ms);
437+ for (uint8_t c = 1 ; c < game_slot; c++){
438+ pbf_move_joystick (context, 255 , 128 , 80ms, 0ms);
439+ }
440+ }
441+
442+ if (tolerate_update_menu){
443+ if (ConsoleSettings::instance ().START_GAME_REQUIRES_INTERNET ){
444+ throw UserSetupError (
445+ stream.logger (),
446+ " Cannot have both \" Tolerate Update Menu\" and \" Start Game Requires Internet\" enabled at the same time without video feedback."
447+ );
448+ }
449+
450+ // If the update menu isn't there, these will get swallowed by the opening
451+ // animation for the select user menu.
452+ pbf_press_button (context, BUTTON_A, 80ms, 1400ms); // Choose game
453+ pbf_move_joystick (context, 128 , 255 , 100ms, 0ms); // Skip the update window.
454+ move_to_user (context, user_slot);
455+ }
456+
457+ // cout << "START_GAME_REQUIRES_INTERNET = " << ConsoleSettings::instance().START_GAME_REQUIRES_INTERNET << endl;
458+ if (!ConsoleSettings::instance ().START_GAME_REQUIRES_INTERNET && user_slot == 0 ){
459+ // Mash your way into the game.
460+ pbf_mash_button (context, BUTTON_A, start_game_mash);
461+ }else {
462+ pbf_press_button (context, BUTTON_A, 80ms, 1400ms); // Enter select user menu.
463+ move_to_user (context, user_slot);
464+ ssf_press_button (context, BUTTON_A, 160ms); // Enter game
465+
466+ // Switch to mashing ZL instead of A to get into the game.
467+ // Mash your way into the game.
468+ Milliseconds duration = start_game_mash;
469+ if (ConsoleSettings::instance ().START_GAME_REQUIRES_INTERNET ){
470+ // Need to wait a bit longer for the internet check.
471+ duration += ConsoleSettings::instance ().START_GAME_INTERNET_CHECK_DELAY0 ;
472+ }
473+ // pbf_mash_button(context, BUTTON_ZL, duration);
474+ pbf_wait (context, duration);
475+ }
476+ context.wait_for_all_requests ();
477+ }
478+
479+ bool openedgame_to_gamemenu (
480+ VideoStream& stream, JoyconContext& context,
481+ Milliseconds timeout
482+ ){
483+ {
484+ stream.log (" Waiting to load game..." );
485+ GameLoadingDetector detector (false );
486+ int ret = wait_until (
487+ stream, context,
488+ timeout,
489+ {{detector}}
490+ );
491+ if (ret < 0 ){
492+ stream.log (" Timed out waiting to enter game." , COLOR_RED);
493+ return false ;
494+ }
495+ }
496+ {
497+ stream.log (" Waiting for game menu..." );
498+ GameLoadingDetector detector (true );
499+ int ret = wait_until (
500+ stream, context,
501+ timeout,
502+ {{detector}}
503+ );
504+ if (ret < 0 ){
505+ stream.log (" Timed out waiting for game menu." , COLOR_RED);
506+ return false ;
507+ }
508+ }
509+ return true ;
510+ }
511+
512+
513+
514+
315515
316516
317517
0 commit comments