Example #1
0
/** Add a virtual ball to the device, not seen by any switches.
 * For example, TZ's gumball machine does not have individual switches
 * counting how many balls are inside it.  The machine code has other
 * means of knowing when a ball enters the device.
 */
void device_add_virtual (device_t *dev)
{
	dev->virtual_count++;

	/* After updating the virtual count, always invoke the
	device switch handler, as if some counting switch changed.
	This will take care of throwing the 'enter' event and updating
	the number of live balls, serving another ball if it is locked
	here, etc. */
	device_sw_handler (dev->devno);
}
Example #2
0
/*
 * The entry point for processing a switch transition.  It performs
 * some of the common switch handling logic before calling all
 * event handlers.  Then it also performs some common post-processing.
 * This function runs in a separate task context for each switch that
 * needs to be processed.
 */
void switch_sched_task (void)
{
	const U8 sw = (U8)task_get_arg ();
	const switch_info_t * const swinfo = switch_lookup (sw);

	/* Ignore any switch that doesn't have a processing function.
	   This shouldn't ever happen if things are working correctly, but it
		was observed on PIC games when the PIC code is broken and reporting
		bad switch returns.  genmachine ensures that all defined switches
		have a non-null value (null_function if nothing needs to be done) */
	if (swinfo->fn == 0)
		goto cleanup;

	/* For test mode : this lets it see what was the last switch
	 * to be scheduled.  Used by the Switch Edges test. */
	sw_last_scheduled = sw;

	log_event (SEV_INFO, MOD_SWITCH, EV_SW_SCHEDULE, sw);

	/* Don't service switches marked SW_IN_GAME if we're
	 * not presently in a game */
	if ((swinfo->flags & SW_IN_GAME) && !in_game)
		goto cleanup;

	/* Don't service switches not marked SW_IN_TEST, unless we're
	 * actually in test mode */
	if (!(swinfo->flags & SW_IN_TEST) && in_test)
		goto cleanup;

	/* If the switch has an associated lamp, then flicker the lamp when
	 * the switch triggers. */
	if ((swinfo->lamp != 0) && in_live_game)
	{
		task_pid_t tp = task_create_gid (GID_SWITCH_LAMP_PULSE,
			switch_lamp_pulse);

		lamp_pulse_data_t *cdata = task_init_class_data (tp, lamp_pulse_data_t);
		cdata->swinfo = swinfo;
	}

	/* If we're in a live game and the switch declares a standard
	 * sound, then make it happen. */
	if ((swinfo->sound != 0) && in_live_game)
		sound_send (swinfo->sound);

#ifdef DEBUGGER
	if (swinfo->fn != null_function && sw < 72)
	{
		dbprintf ("SW: ");
		sprintf_far_string (names_of_switches + sw);
		dbprintf1 ();
#ifdef DEBUG_SWITCH_NUMBER
		dbprintf (" (%d) ", sw);
#endif
		dbprintf ("\n");
	}
#endif

	/* If the switch declares a processing function, call it. */
	if (swinfo->fn)
		callset_pointer_invoke (swinfo->fn);

	/* Declare this as a hardware event that affects the random number
	generator. */
	random_hw_event ();

	/* If a switch is marked SW_PLAYFIELD and we're in a game,
	 * then call the global playfield switch handler and check for
	 * valid playfield.  Also, reset the ball search timer so that
	 * it doesn't expire.
	 */
	if ((swinfo->flags & SW_PLAYFIELD) && in_game)
	{
		callset_invoke (any_pf_switch);

		/* If valid playfield was not asserted yet, then see if this
		 * switch validates it.  Most playfield switches do this right
		 * away, but for some switches, like special solenoids (jets
		 * or slings), which could repeatedly trigger if misaligned,
		 * count the activations and validate only when some number
		 * of different switches have triggered.  Device counting
		 * switches are ignored here, but an 'enter' event will
		 * set it. */
		if (!valid_playfield)
		{
			if (swinfo->flags & SW_NOVALID)
			{
				if (!SW_HAS_DEVICE (swinfo))
					try_validate_playfield (sw);
			}
			else
				set_valid_playfield ();
		}
		ball_search_timer_reset ();
	}

cleanup:
	/* If the switch is part of a device, then let the device
	 * subsystem process the event.  Note this will always occur
	 * regardless of any of the above conditions checked. */
	if (SW_HAS_DEVICE (swinfo))
		device_sw_handler (SW_GET_DEVICE (swinfo));

	task_exit ();
}