/* * Check if timers should be paused. * * Returns TRUE if timers should not run for some reason. * Returns FALSE if timers should continue to run. */ bool system_timer_pause (void) { if (!in_game || in_bonus || !valid_playfield) return TRUE; if (timer_lock_count) return TRUE; if (global_flag_test (GLOBAL_FLAG_BALL_AT_PLUNGER) && single_ball_play ()) return TRUE; if (global_flag_test (GLOBAL_FLAG_COIN_DOOR_OPENED)) return TRUE; if (config_timed_game) { extern U8 timed_game_suspend_count; if (timer_find_gid (GID_TIMED_GAME_PAUSED)) return TRUE; if (timed_game_suspend_count) return TRUE; } if (device_holdup_count ()) return TRUE; if (ball_search_timed_out ()) return TRUE; if (timer_find_gid (GID_BALLSAVE_EXTENDED)) return TRUE; /* Machines can extend the meaning of timer pause by defining an 'allow timers' event. It should return FALSE if timers should be paused for some reason. */ if (!callset_invoke_boolean (allow_timers)) return TRUE; #ifdef MACHINE_TZ if (mpf_active) return TRUE; #endif return FALSE; }
/** * Periodically check to see if effects need updating. */ CALLSET_ENTRY (effect_update, idle_every_100ms, start_ball, end_ball) { if (sys_init_complete && !in_test) { /* Update devices frequently */ if (in_game && !ball_search_timed_out ()) callset_invoke (device_update); /* Less frequently, update background display, music, and lamps. Normally this is done every 500ms. If effect_update_request() is called, then it will occur on the next 100ms interval. */ if (effect_update_counter == 0) { task_recreate_gid_while (GID_EFFECT_UPDATE, effect_update_task, TASK_DURATION_INF); update_complete (); } else { --effect_update_counter; } } }
/** A monitor task that checks whether or not a ball search is necessary. This task periodically bumps a counter, which is normally reset as scoring switches are triggered. If the counter reaches a threshold, and ball search is allowed to run, then it is initiated. This task is also responsible for incrementing the ball time statistic, when ball search is not necessary. */ void ball_search_monitor_task (void) { ball_search_timer_reset (); while (in_game) { task_sleep (TIME_1S); /* Step the ball search timer as long as a game * is in progess. But don't allow a ball search in * some situations: * * - ball is on the shooter switch * - either flipper button is held */ if (in_live_game && !in_bonus && (live_balls || !valid_playfield) #ifdef MACHINE_SHOOTER_SWITCH && !switch_poll_logical (MACHINE_SHOOTER_SWITCH) #endif && !switch_poll_logical (SW_LEFT_BUTTON) && !switch_poll_logical (SW_RIGHT_BUTTON)) { ball_time++; ball_search_timer_step (); if (ball_search_timed_out ()) { ball_search_count = 0; while (ball_search_timer != 0) { if ((ball_search_count >= 5) && chase_ball_enabled ()) { /* If chase ball is enabled, after the 5th ball search we will force endball. */ audit_increment (&system_audits.chase_balls); end_ball (); return; } else { /* Perform a ball search */ ball_search_run (); } /* After the third ball search, cancel the tilt lamp effect, to help the player find the missing ball. */ if (ball_search_count == 3) leff_stop (LEFF_TILT); if (ball_search_count < 10) { /* Delay a small amount for the first few ball searches */ task_sleep_sec (12); } else { /* Delay longer after many ball searches */ task_sleep_sec (20); } /* After a while, just give up -- but don't do that in tournament mode or on free play; this is just to keep a location game from cycling continuously. */ if (ball_search_count >= 25 && !price_config.free_play && !system_config.tournament_mode) { fatal (ERR_BALL_SEARCH_TIMEOUT); } } /* A ball was seen -- clear the counter and exit */ ball_search_count = 0; } } } task_exit (); }