Пример #1
0
/**
 * Make a solenoid request, and wait for it to finish before returning.
 *
 * This is one of the 2 topmost APIs that starts a solenoid pulse
 * (see also sol_request_async).
 *
 * By default, sol_request behaves identically to sol_request_async, with
 * the addition of the alloc and free calls around it.  However, machines
 * can override this behavior by catching the 'sol_request' event, and
 * doing something different.  The handler should inspect the value of
 * sol_pulsing to see which solenoid is being pulsed, it should call
 * sol_free() just before returning, and finally it should return FALSE.
 */
void sol_request (U8 sol)
{
	sol_alloc (sol);
	if (callset_invoke_boolean (sol_request))
	{
		sol_req_start (sol);
		sol_free (sol);
	}
}
Пример #2
0
/** Called by the trough when a ball has entered it.
 * The intent is to signal that there is one less live ball than before.
 */
void device_remove_live (void)
{
	/* If any balls were missing, and now one is rediscovered in the
	 * trough, then just hold onto it.  This condition was seen when
	 * the game thought 1 ball was in play, but 2 were on the playfield. */
	if (missing_balls > live_balls)
	{
		callset_invoke (missing_ball_found);
		missing_balls--;
	}
	else if (live_balls > 0)
	{
		/* Decrement the count of balls in play.  Now what? */
		live_balls--;
		if (in_game && !in_bonus)
		{
			/* Notify that the ball count changed */
			callset_invoke (ball_count_change);

			/* See if this qualifies as a ball drain.  Any event receiver
			can return FALSE here if it is not to be treated as a drain;
			e.g., when a ballsaver is active.  In these cases, the
			event function is also responsible for putting the ball
			back into play. */
			if (!callset_invoke_boolean (ball_drain))
				return;

			/* OK, at this point, it is a true ball drain event.
			See how many balls are in play now. */
			switch (live_balls
#ifdef DEVNO_TROUGH
				 + device_entry (DEVNO_TROUGH)->kicks_needed
#endif
				)
			{
				case 0:
					/* With zero balls in play, this is end of ball.
					This function usually does not return; it will stop just about
					every task running to reset for the next ball. */
					end_ball ();
					return;

				case 1:
					/* Multiball modes like to know when single ball play resumes. */
					callset_invoke (single_ball_play);
					break;
				default:
					break;
			}
		}
	}
}
Пример #3
0
/**
 * See if a factory reset is needed.  The 'init_ok' event is
 * thrown and any catchers can return FALSE if a factory reset
 * should occur.  The accept button must be pressed afterwards
 * to confirm.
 */
void factory_reset_if_required (void)
{
	if (!callset_invoke_boolean (init_ok))
	{
		dmd_alloc_low_clean ();
		font_render_string_center (&font_mono5, 64, 10, "FACTORY SETTINGS");
		font_render_string_center (&font_mono5, 64, 20, "RESTORED");
		dmd_show_low ();
		factory_reset ();
		task_sleep_sec (4);
		warm_reboot ();
	}
}
Пример #4
0
/**
 * See if a factory reset is needed.  The 'init_ok' event is
 * thrown and any catchers can return FALSE if a factory reset
 * should occur.  The accept button must be pressed afterwards
 * to confirm.
 */
void factory_reset_if_required (void)
{
	if (!callset_invoke_boolean (init_ok))
	{
		deff_stop (DEFF_SYSTEM_RESET);
#ifdef CONFIG_DMD_OR_ALPHA
		dmd_alloc_low_clean ();
		font_render_string_center (&font_mono5, 64, 10, "FACTORY SETTINGS");
		font_render_string_center (&font_mono5, 64, 20, "RESTORED");
		dmd_show_low ();
#endif
		factory_reset ();
		task_sleep_sec (4);
		warm_reboot ();
	}
}
Пример #5
0
/*
 * 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;
}
Пример #6
0
/** Requests that a device allow a ball lock. */
void device_lock_ball (device_t *dev)
{
#ifdef DEVNO_TROUGH
	device_t *trough = device_entry (DEVNO_TROUGH);
#endif

	/* If the device is already locking as many balls
	as it can hold, then trying to lock another ball here
	is an error. */
	if (dev->max_count >= dev->size)
		fatal (ERR_LOCK_FULL_DEVICE);

	dbprintf ("Lock ball in devno %d\n", dev->devno);

	/* Update count of balls that will be held here. */
	device_enable_lock (dev);

	/* Say that there is one less active ball on the
	playfield now, assuming a ball is still physically present */
	if (device_kickable_count (dev))
		live_balls--;

	/* If the trough is not empty, we can serve another ball from the
	trough to continue play.  Otherwise, it will have to come from
	somewhere else.  The default is to serve it from the same device,
	but this can be overriden by the 'empty_trough_kick' event. */
#ifdef DEVNO_TROUGH
	if (trough->actual_count > 0)
	{
		serve_ball ();
	}
	else
#endif
	{
		if (!callset_invoke_boolean (empty_trough_kick))
			device_unlock_ball (dev);
	}
}
Пример #7
0
/**
 * Start a solenoid request now.
 * The state machine must be in IDLE.  This call puts it
 * into PENDING state.
 */
void sol_req_start (U8 sol)
{
	sol_pulsing = sol;

	/* Normally, just start sol_req_start_specific with default parameters.
	But provide a hook that can override them.  Any machine that wants finer
	control should declare one event handler named 'sol_pulse', which can
	inspect the solenoid number in 'sol_pulsing' and decide if special handling
	is needed.  It can call sol_req_start_specific() with different values.
	If it does, it should return FALSE and then the default call here is
	skipped.
		Reasons for providing this: 1) some devices may need more than just
	a quick pulse; it may require a sequence of pulses of different sizes.
	(It is safe to do this in the caller's context, without spawning a new
	task, if it is a ball device, since that is always done synchronously.)
	2) Device retries can kick harder on subsequent tries if the first try
	doesn't work.  You can inspect dev->kick_errors to see how many failed
	attempts have already occurred. */
	if (callset_invoke_boolean (sol_pulse))
	{
		sol_req_start_specific (sol, sol_get_duty (sol), sol_get_time (sol));
	}
}