Example #1
0
/*
 * Helper function called only from "inkey()"
 */
static ui_event inkey_aux(int scan_cutoff)
{
	int w = 0;	

	ui_event ke;
	
	/* Wait for a keypress */
	if (scan_cutoff == SCAN_OFF)
	{
		(void)(Term_inkey(&ke, TRUE, TRUE));
	}
	else
	{
		w = 0;

		/* Wait only as long as macro activation would wait*/
		while (Term_inkey(&ke, FALSE, TRUE) != 0)
		{
			/* Increase "wait" */
			w++;

			/* Excessive delay */
			if (w >= scan_cutoff)
			{
				ui_event empty = EVENT_EMPTY;
				return empty;
			}

			/* Delay */
			Term_xtra(TERM_XTRA_DELAY, 10);
		}
	}

	return (ke);
}
Example #2
0
/*
 * (From the Angband Borg by Ben Harrison & Dr Andrew White)
 *
 * This function lets the automaton "steal" control from the user.
 *
 * The "z-term.c" file provides a special hook which we use to
 * bypass the standard "Term_flush()" and "Term_inkey()" functions
 * and replace them with the function below.
 *
 * The only way that the automaton can be stopped once it is started,
 * unless it dies or encounters an error, is to press any key.
 * This function checks for user input on a regular basic, and
 * when any is encountered, it relinquishes control gracefully.
 *
 * Note that this function hook automatically removes itself when
 * it realizes that it should no longer be active.  Note that this
 * may take place after the game has asked for the next keypress,
 * but the various "keypress" routines should be able to handle this.
 *
 * XXX XXX XXX We do not correctly handle the "take" flag
 */
char automaton_inkey_hack(int flush_first)
{
	int i;
    char ch;
    
	// paranoia
	if (!p_ptr->automaton)
	{
        stop_automaton();
        
		/* Nothing ready */
		return (ESCAPE);
	}
    
    // flush key buffer if requested
    if (flush_first)
    {
        // only flush if needed
        if (automaton_inkey(FALSE) != 0)
        {
            // Flush keys
            ////automaton_flush();   currently not actually doing this as it stops us queuing a 'y' for stepping on traps
        }
    }
    
	// check for manual user abort
	(void)Term_inkey(&ch, FALSE, TRUE);
    
    // if a key is hit, stop the automaton
    if (ch > 0)
    {
        stop_automaton();
        return (ESCAPE);
    }
    
	// check for a previously queued key, without taking it from the queue
	i = automaton_inkey(FALSE);
    
	// if it was empty and we need more keys
	if (!i)
	{
        // handle waiting for commands separately
        if (waiting_for_command)
        {
            // takes its turn by choosing some keys representing commands and queuing them
            automaton_turn();
            
            // pause for a moment so the user can see what is happening
            Term_xtra(TERM_XTRA_DELAY, 25 * op_ptr->delay_factor);
        }
        
        else
        {
            /* Hack -- Process events (do not wait) */
            (void)Term_xtra(TERM_XTRA_EVENT, FALSE);
            
            stop_automaton();
            return (ESCAPE);
        }
	}
    
	// check for a previously queued key, taking it from the queue
	i = automaton_inkey(TRUE);
    
	// deal with empty queue
	if (!i)
	{
		// exit
		return('\0');
	}
    
	// return the key chosen
	return (i);
}
Example #3
0
/*
 * Get a keypress from the user.
 *
 * This function recognizes a few "global parameters".  These are variables
 * which, if set to TRUE before calling this function, will have an effect
 * on this function, and which are always reset to FALSE by this function
 * before this function returns.  Thus they function just like normal
 * parameters, except that most calls to this function can ignore them.
 *
 * If "inkey_xtra" is TRUE, then all pending keypresses will be flushed.
 * This is set by flush(), which doesn't actually flush anything itself
 * but uses that flag to trigger delayed flushing.
 *
 * If "inkey_scan" is TRUE, then we will immediately return "zero" if no
 * keypress is available, instead of waiting for a keypress.
 *
 * If "inkey_flag" is TRUE, then we are waiting for a command in the main
 * map interface, and we shouldn't show a cursor.
 *
 * If we are waiting for a keypress, and no keypress is ready, then we will
 * refresh (once) the window which was active when this function was called.
 *
 * Note that "back-quote" is automatically converted into "escape" for
 * convenience on machines with no "escape" key.
 *
 * If "angband_term[0]" is not active, we will make it active during this
 * function, so that the various "main-xxx.c" files can assume that input
 * is only requested (via "Term_inkey()") when "angband_term[0]" is active.
 *
 * Mega-Hack -- This function is used as the entry point for clearing the
 * "signal_count" variable, and of the "character_saved" variable.
 *
 * Mega-Hack -- Note the use of "inkey_hack" to allow the "Borg" to steal
 * control of the keyboard from the user.
 */
ui_event inkey_ex(void)
{
	bool cursor_state;
	ui_event kk;
	ui_event ke = EVENT_EMPTY;

	bool done = FALSE;

	term *old = Term;

	/* Delayed flush */
	if (inkey_xtra) {
		Term_flush();
		inkey_next = NULL;
		inkey_xtra = FALSE;
	}

	/* Hack -- Use the "inkey_next" pointer */
	if (inkey_next && inkey_next->code)
	{
		/* Get next character, and advance */
		ke.key = *inkey_next++;

		/* Cancel the various "global parameters" */
		inkey_flag = FALSE;
		inkey_scan = 0;

		/* Accept result */
		return (ke);
	}

	/* Forget pointer */
	inkey_next = NULL;

#ifdef ALLOW_BORG

	/* Mega-Hack -- Use the special hook */
	if (inkey_hack)
	{
		ke.key = (*inkey_hack)(inkey_xtra);
		if (ke.key.type != EVT_NONE)
		{
			/* Cancel the various "global parameters" */
			inkey_flag = FALSE;
			inkey_scan = 0;
			ke.type = EVT_KBRD;

			/* Accept result */
			return (ke);
		}
	}

#endif /* ALLOW_BORG */


	/* Get the cursor state */
	(void)Term_get_cursor(&cursor_state);

	/* Show the cursor if waiting, except sometimes in "command" mode */
	if (!inkey_scan && (!inkey_flag || character_icky))
		(void)Term_set_cursor(TRUE);


	/* Hack -- Activate main screen */
	Term_activate(term_screen);


	/* Get a key */
	while (ke.type == EVT_NONE)
	{
		/* Hack -- Handle "inkey_scan == SCAN_INSTANT */
		if (inkey_scan == SCAN_INSTANT &&
				(0 != Term_inkey(&kk, FALSE, FALSE)))
			break;


		/* Hack -- Flush output once when no key ready */
		if (!done && (0 != Term_inkey(&kk, FALSE, FALSE)))
		{
			/* Hack -- activate proper term */
			Term_activate(old);

			/* Flush output */
			Term_fresh();

			/* Hack -- activate main screen */
			Term_activate(term_screen);

			/* Mega-Hack -- reset saved flag */
			character_saved = FALSE;

			/* Mega-Hack -- reset signal counter */
			signal_count = 0;

			/* Only once */
			done = TRUE;
		}


		/* Get a key (see above) */
		ke = inkey_aux(inkey_scan);

		/* Handle mouse buttons */
		if ((ke.type == EVT_MOUSE) && (OPT(mouse_buttons)))
		{
			/* Check to see if we've hit a button */
			/* Assuming text buttons here for now - this would have to
			 * change for GUI buttons */
			char key = button_get_key(ke.mouse.x, ke.mouse.y);

			if (key)
			{
				/* Rewrite the event */
				/* XXXmacro button implementation needs updating */
				ke.type = EVT_BUTTON;
				ke.key.code = key;
				ke.key.mods = 0;

				/* Done */
				break;
			}
		}

		/* Treat back-quote as escape */
		if (ke.key.code == '`')
			ke.key.code = ESCAPE;
	}


	/* Hack -- restore the term */
	Term_activate(old);


	/* Restore the cursor */
	Term_set_cursor(cursor_state);


	/* Cancel the various "global parameters" */
	inkey_flag = FALSE;
	inkey_scan = 0;

	/* Return the keypress */
	return (ke);
}
Example #4
0
/**
 * Get a keypress from the user.
 *
 * This function recognizes a few "global parameters".  These are variables
 * which, if set to true before calling this function, will have an effect
 * on this function, and which are always reset to false by this function
 * before this function returns.  Thus they function just like normal
 * parameters, except that most calls to this function can ignore them.
 *
 * If "inkey_xtra" is true, then all pending keypresses will be flushed.
 * This is set by flush(), which doesn't actually flush anything itself
 * but uses that flag to trigger delayed flushing.
 *
 * If "inkey_scan" is true, then we will immediately return "zero" if no
 * keypress is available, instead of waiting for a keypress.
 *
 * If "inkey_flag" is true, then we are waiting for a command in the main
 * map interface, and we shouldn't show a cursor.
 *
 * If we are waiting for a keypress, and no keypress is ready, then we will
 * refresh (once) the window which was active when this function was called.
 *
 * Note that "back-quote" is automatically converted into "escape" for
 * convenience on machines with no "escape" key.
 *
 * If "angband_term[0]" is not active, we will make it active during this
 * function, so that the various "main-xxx.c" files can assume that input
 * is only requested (via "Term_inkey()") when "angband_term[0]" is active.
 *
 * Mega-Hack -- This function is used as the entry point for clearing the
 * "signal_count" variable, and of the "character_saved" variable.
 *
 * Mega-Hack -- Note the use of "inkey_hack" to allow the "Borg" to steal
 * control of the keyboard from the user.
 */
ui_event inkey_ex(void)
{
    bool cursor_state;
    ui_event kk;
    ui_event ke = EVENT_EMPTY;

    bool done = false;

    term *old = Term;

    /* Delayed flush */
    if (inkey_xtra) {
        Term_flush();
        inkey_next = NULL;
        inkey_xtra = false;
    }

    /* Hack -- Use the "inkey_next" pointer */
    while (inkey_next && inkey_next->code) {
        /* Get next character, and advance */
        ke.key = *inkey_next++;

        /* Cancel the various "global parameters" */
        inkey_flag = false;
        inkey_scan = 0;

        /* Peek at the key, and see if we want to skip more prompts */
        if (ke.key.code == '(') {
            keymap_auto_more = true;
            /* Since we are not returning this char, make sure the
             * next key below works well */
            if (!inkey_next || !inkey_next->code) {
                ke.type = EVT_NONE;
                break;
            }
            continue;
        } else if (ke.key.code == ')') {
            keymap_auto_more = false;
            /* Since we are not returning this char, make sure the
             * next key below works well */
            if (!inkey_next || !inkey_next->code) {
                ke.type = EVT_NONE;
                break;
            }
            continue;
        }

        /* Accept result */
        return (ke);
    }

    /* make sure that the flag to skip more prompts is off */
    keymap_auto_more = false;

    /* Forget pointer */
    inkey_next = NULL;

    /* Get the cursor state */
    (void)Term_get_cursor(&cursor_state);

    /* Show the cursor if waiting, except sometimes in "command" mode */
    if (!inkey_scan && (!inkey_flag || screen_save_depth ||
                        (OPT(show_target) && target_sighted())))
        (void)Term_set_cursor(true);


    /* Hack -- Activate main screen */
    Term_activate(term_screen);


    /* Get a key */
    while (ke.type == EVT_NONE) {
        /* Hack -- Handle "inkey_scan == SCAN_INSTANT */
        if (inkey_scan == SCAN_INSTANT &&
                (0 != Term_inkey(&kk, false, false)))
            break;


        /* Hack -- Flush output once when no key ready */
        if (!done && (0 != Term_inkey(&kk, false, false))) {
            /* Hack -- activate proper term */
            Term_activate(old);

            /* Flush output */
            Term_fresh();

            /* Hack -- activate main screen */
            Term_activate(term_screen);

            /* Mega-Hack -- reset saved flag */
            character_saved = false;

            /* Mega-Hack -- reset signal counter */
            signal_count = 0;

            /* Only once */
            done = true;
        }


        /* Get a key (see above) */
        ke = inkey_aux(inkey_scan);

        if (inkey_scan && ke.type == EVT_NONE)
            /* The keypress timed out. We need to stop here. */
            break;

        /* Treat back-quote as escape */
        if (ke.key.code == '`')
            ke.key.code = ESCAPE;
    }

    /* Hack -- restore the term */
    Term_activate(old);

    /* Restore the cursor */
    Term_set_cursor(cursor_state);

    /* Cancel the various "global parameters" */
    inkey_flag = false;
    inkey_scan = 0;

    /* Return the keypress */
    return (ke);
}