Beispiel #1
0
void generic_coil_at_max (struct sim_coil_state *c)
{
	unsigned int solno = c - coil_states;

#ifdef SOL_OUTHOLE
	if (solno == SOL_OUTHOLE)
		node_kick (&switch_nodes[MACHINE_OUTHOLE_SWITCH]);
#endif

#ifdef MACHINE_LAUNCH_SOLENOID
	if (solno == MACHINE_LAUNCH_SOLENOID)
		node_kick (&switch_nodes[MACHINE_SHOOTER_SWITCH]);
#endif

#ifdef MACHINE_KNOCKER_SOLENOID
	if (solno == MACHINE_KNOCKER_SOLENOID)
		simlog (SLC_DEBUG, "Thwack!");
#endif
}
Beispiel #2
0
/* Remove the head of the node queue. */
struct ball *node_remove (struct ball_node *node)
{
    unsigned int offset;
    struct ball *ball;

    if (node->count == 0)
    {
        simlog (SLC_DEBUG, "node_remove: no balls in %s", node->name);
        return NULL;
    }

    offset = node->head % node->size;
    ball = node->ball_queue[offset];
    if (!ball)
    {
        simlog (SLC_DEBUG, "node_remove: count=%d but ball is null?", node->count);
        return NULL;
    }

    node->head++;
    node->count--;
    ball->node = NULL;
    if (node->type->remove)
        node->type->remove (node, ball);
#ifdef CONFIG_UI
    ui_update_ball_tracker (ball->index, "Free");
#endif
    simlog (SLC_DEBUG, "node_remove: took %s from %s", ball->name, node->name);

    if (node->prev && node->prev->unlocked && node->prev->count != 0)
    {
        node_kick (node->prev);
    }

    return ball;
}
Beispiel #3
0
/** Main loop for handling the user interface. */
static void sim_interface_thread (void)
{
	char inbuf[2];
	struct key_binding *kb;
	int simulator_keys = 1;
	int toggle_mode = 1;

#ifndef CONFIG_UI_SDL
	/* Put stdin in raw mode so that 'enter' doesn't have to
	be pressed after each keystroke. */
	keybuffering (0);

	/* Let the system initialize before accepting keystrokes */
	task_sleep_sec (3);
#endif

	if (exec_file && exec_late_flag)
		exec_script_file (exec_file);

	for (;;)
	{
		task_yield ();
#ifdef CONFIG_GTK
		gtk_poll ();
#endif
#ifdef CONFIG_UI_SDL
		ui_refresh_all ();
		*inbuf = ui_poll_events ();
#else
		*inbuf = sim_getchar ();
#endif

		/* Try again if no character was read */
		if (*inbuf == '\0')
			continue;

		/* If switch simulation is turned off, then keystrokes
		are fed into the simulated serial port... meaning it is interpreted
		by the game program itself, and not the simulator.  Use the
		tilde to toggle between the two modes. */
		if (simulator_keys == 0)
		{
			/* Except tilde turns it off as usual. */
			if (*inbuf == '`')
			{
				simlog (SLC_DEBUG, "Input directed to switch matrix.");
				simulator_keys ^= 1;
			}
			else
			{
				wpc_key_press (*inbuf);
			}
			continue;
		}

		switch (*inbuf)
		{
			/* Carriage returns and line feeds are ignored so that you can
			put these commands into a script file. */
			case '\r':
			case '\n':
				break;

			case ':':
			{
				/* Read and execute a script command */
				char cmd[128];
				char *p = cmd;

				memset (p, 0, 128);
				ui_print_command (" ");
				for (;;)
				{
					*p = sim_getchar ();
					if (*p == '\x1B')
					{
						break;
					}
					else if (*p == '\010')
					{
						*p = '\0';
						p--;
					}
					else if ((*p == '\r') || (*p == '\n'))
					{
						*p = '\0';
						exec_script (cmd);
						break;
					}
					ui_print_command (cmd);
					p++;
				}
				ui_print_command ("");
				break;
			}

			case 'C':
				gdb_break ();
				break;

			case '{':
				signal_trace_start (signo_under_trace);
				break;

			case '}':
				signal_trace_stop (signo_under_trace);
				break;

			case 'q':
				node_kick (&open_node);
				break;

			case '`':
				/* The tilde toggles between keystrokes being treated as switches,
				and as input into the runtime debugger. */
				simulator_keys ^= 1;
				simlog (SLC_DEBUG, "Input directed to built-in debugger.");
				break;

			case '\x1b':
				sim_exit (0);
				break;

			case 'T':
				task_dump ();
				break;

			case '#':
				/* Treat '#' as a comment until end of line.
				This is useful for creating scripts. */
				do {
					*inbuf = sim_getchar ();
				} while (*inbuf != '\n');
				break;

			case '"':
				simlog (SLC_DEBUG, "next key will toggle, not press");
				toggle_mode = 0;
				break;

			default:
				/* For all other keystrokes, use the keymap table
				to turn the keystroke into a switch trigger. */
				kb = &keymaps[(int)*inbuf];
#ifdef MACHINE_SHOOTER_SWITCH
				if (kb->flags & KEY_SHOOTER)
				{
					node_kick (&shooter_node);
				}
				else
#endif
				if (kb->flags & KEY_NODE)
				{
					node_move (kb->node, &open_node);
				}
				else if (kb->flags & KEY_SW)
				{
					if ((switch_table[kb->sw].flags & SW_EDGE) || !toggle_mode)
					{
						simlog (SLC_DEBUG, "switch %d toggled", kb->sw);
						sim_switch_toggle (kb->sw);
						toggle_mode = 1;
					}
#if (MACHINE_FLIPTRONIC == 1)
					else if (kb->sw >= 72)
					{
						flipper_button_depress (kb->sw);
					}
#endif
					else
					{
						sim_switch_depress (kb->sw);
					}
				}
				else
					simlog (SLC_DEBUG, "invalid key '%c' pressed (0x%02X)",
						*inbuf, *inbuf);
			}
	}
}
Beispiel #4
0
void device_coil_at_max (struct sim_coil_state *c)
{
	node_kick (c->node);
}
Beispiel #5
0
/* Initialize the node graph for this machine.
	This creates the nodes that match the topology of the game, using
	some of the machine-specific parameters to guide things.
	Last, the ball trough is populated with all of the pinballs. */
void node_init (void)
{
    unsigned int i;

    /* Create nodes for all playfield switches.  Not all of these will
    be used necessarily.  The default is for all switches to drain to the
    open playfield.  The switch will remain active for 100ms before it moves. */
    for (i=0; i < NUM_SWITCHES; i++)
    {
        struct ball_node *node = switch_nodes + i;
        node->name = names_of_switches[i];
        node->type = &switch_type_node;
        node->index = i;
        node->unlocked = 1;
        node->size = 1;
        node_join (node, &open_node, 100);
    }

    /* Create nodes for the ball devices.  Trough leads to shooter;
    everything else leads to the open playfield as for the switches. */
    for (i=0; i < MAX_DEVICES; i++)
    {
        device_nodes[i].type = &device_type_node;
        device_nodes[i].index = i;
        device_nodes[i].size = device_properties_table[i].sw_count;
        device_nodes[i].name = device_properties_table[i].name;
        device_nodes[i].unlocked = 0;
#if defined(DEVNO_TROUGH) && defined(MACHINE_SHOOTER_SWITCH)
        if (i == DEVNO_TROUGH)
            node_join (&device_nodes[i], &shooter_node, 50);
        else
#endif
            node_join (&device_nodes[i], &open_node, 0);
    }

    /* The outhole and the shooter switches, initialized above, can
    actually hold more pinballs than 1; they just queue up undetected.
    They are also unlocked, meaning that they stay there until something
    forces them to move on. */
#ifdef MACHINE_OUTHOLE_SWITCH
    outhole_node.size = MAX_BALLS_PER_NODE;
    outhole_node.unlocked = 0;
    node_join (&outhole_node, &trough_node, 100);
#endif
#ifdef MACHINE_SHOOTER_SWITCH
    shooter_node.size = MAX_BALLS_PER_NODE;
    shooter_node.unlocked = 0;
    node_join (&shooter_node, &open_node, 0);
#endif

    /* Initialize the open playfield node, which feeds into the trough
    (or outhole if present). */
    open_node.name = "Playfield";
    open_node.type = &open_type_node;
    open_node.size = MAX_BALLS_PER_NODE;
    open_node.unlocked = 0;
#ifdef drain_node
    node_join (&open_node, &drain_node, 0);
#endif

    /* Fixup the graph in a machine-specific way */
#ifdef CONFIG_MACHINE_SIM
    mach_node_init ();
#endif

#ifdef DEVNO_TROUGH
    /* Create the pinballs and dump them into the trough.
    	Actually, we dump them onto the playfield and force them to drain.
    	This lets us install more balls than the trough can hold, as if
    	you just dropped them onto the playfield. */
    for (i=0; i < sim_installed_balls; i++)
    {
        the_ball[i].node = NULL;
        strcpy (the_ball[i].name, "Ball X");
        the_ball[i].name[5] = i + '0';
        the_ball[i].index = i;
        the_ball[i].flags = 0;

        node_insert (&open_node, &the_ball[i]);
        node_kick (&open_node);
    }
#endif
}
Beispiel #6
0
void node_kick_delayed (struct ball_node *node)
{
    node_kick (node);
}