static void lock_and_outhole_monitor (void) { /* Wait for balls to settle/amode to start before emptying * locks/outhole */ task_sleep_sec (3); while (!in_live_game) { if (switch_poll (SW_LOCK_LOWER)) { device_request_kick (device_entry (DEVNO_LOCK)); } if (switch_poll (SW_OUTHOLE)) { sol_request (SOL_OUTHOLE); } if (!switch_poll (SW_AUTOFIRE2)) { callset_invoke (clear_autofire); } /* Wait for the balls to be cleared before starting again */ task_sleep_sec (3); } task_exit (); }
/** * Serve a new ball to the manual shooter lane. * This function is the preferred method to serve a ball to a manual * plunger at the beginning of a ball and after a ball lock. * It is not used for autoplunges. */ void serve_ball (void) { #ifdef DEVNO_TROUGH valid_playfield = FALSE; callset_invoke (serve_ball); effect_update_request (); device_request_kick (device_entry (DEVNO_TROUGH)); #endif /* DEVNO_TROUGH */ } //end of function
void pb_test_enter (void) { sound_send (SND_TEST_ENTER); switch (pb_test_command) { case KICK_TROUGH: device_request_kick (device_entry (DEVNO_TROUGH)); break; case KICK_LOCK: device_request_kick (device_entry (DEVNO_LOCK)); break; case RELEASE_GUMBALL: gumball_release (); break; case LOAD_GUMBALL: gumball_load_from_trough (); break; } }
/** Requests that a device 'unlock' a ball. */ void device_unlock_ball (device_t *dev) { if (dev->max_count > 0) { dbprintf ("Unlock ball in devno %d\n", dev->devno); device_disable_lock (dev); device_request_kick (dev); } else nonfatal (ERR_UNLOCK_EMPTY_DEVICE); }
/** * Autolaunch a new ball into play from the trough. This is the * preferred API to use by ballsavers. */ void serve_ball_auto (void) { #ifdef DEVNO_TROUGH /* Fall back to manual ball serve if there is no autoplunger. */ if (!have_auto_serve_p ()) serve_ball (); else { set_valid_playfield (); /* TZ's autoplunger is a little different, so it is handled specially. */ #if defined(MACHINE_TZ) autofire_add_ball (); #else device_request_kick (device_entry (DEVNO_TROUGH)); #endif } //end of else #endif /* DEVNO_TROUGH */ } //end of function
/** Request that a new ball be autolaunched into play. */ void autofire_add_ball (void) { autofire_request_count++; if (!in_game || switch_poll_logical (SW_FAR_LEFT_TROUGH)) { /* For special situations. If not in game, the kick_attempt hook won't be called to open for trough. If far left trough is set, the kick will appear failed because the trough count won't change (even though a ball was successfully kicked). In these cases, do it manually. However, you get no retry capability here. */ autofire_open_for_trough (); /* Wait for divertor to open */ task_sleep_sec (2); sol_request (SOL_BALL_SERVE); } else { /* The normal way to kick a ball from the trough. * dev_trough_kick_attempt will be called next */ device_request_kick (device_entry (DEVNO_TROUGH)); } }
/** Probes all devices to see if any balls are present that * shouldn't be. Balls are kicked as necessary. * * For example, this clears out the balls of a lockup device * at the end of a game. * * This is always done as a background task, because it may * take some time and this function waits for any kicked * balls to successfully exit before it returns. */ void device_probe (void) { devicenum_t devno; U8 kicks; dbprintf ("Probing devices\n"); /* Keep track of the number of times we actually had to kick a device; equivalently, this is the number of times we sleep waiting for the kick to have an effect. After so long, if things aren't right, just give up. */ kicks = 0; probe_from_beginning: if (kicks >= 10) goto probe_exit; for (devno = 0; devno < NUM_DEVICES; devno++) { device_t *dev = device_entry (devno); /* Recount the number of balls in the device, and reset * other device data. */ device_recount (dev); dev->previous_count = dev->actual_count; dev->kicks_needed = 0; dev->kick_errors = 0; task_kill_gid (DEVICE_GID(devno)); /* If there are more balls in the device than ought to be, * schedule the extras to be emptied. Then rescan from * the beginning again. */ dev->max_count = dev->props->init_max_count; if (dev->actual_count > dev->max_count) { kicks++; device_request_kick (dev); task_sleep_sec (2); goto probe_from_beginning; } #if 0 /* TODO */ else if (dev->actual_count < dev->max_count) { /* The device normally holds more balls than are present in it. If possible, launch a ball here. (For example, ST:TNG or Whodunnit.) */ } #endif } probe_exit: /* At this point, all kicks have been made, but balls may be on the playfield heading for the trough. We still should wait until 'missing_balls' goes (hopefully) to zero. We'll wait for up to 10 seconds, but exit sooner if we find all balls before then. */ task_sleep_sec (4); if (missing_balls != 0) { task_sleep_sec (2); if (missing_balls != 0) { task_sleep_sec (2); if (missing_balls != 0) { task_sleep_sec (2); } } } dbprintf ("Checking globals after probe\n"); device_update_globals (); dbprintf ("\nDevices initialized.\n"); device_debug_all (); task_exit (); }