/**
 * Display the options and redraw afterward.
 */
void do_cmd_xxx_options(void)
{
	do_cmd_options();
	do_cmd_redraw();
}
Exemple #2
0
/*
 * Generic "get choice from menu" function
 */
static int get_player_choice(birth_menu *choices, int num, int def, int col, int wid, void (*hook)(birth_menu))
{
	int top = 0, next;
	int i, dir;
	char c;
	char buf[300];
	bool done = FALSE;
	int hgt;
	byte attr;
	int cur = (def) ? def : 0; 

	/* Autoselect if able */
	//if (num == 1) done = TRUE;

	/* Clear */
	for (i = TABLE_ROW; i < DESCRIPTION_ROW + 4; i++)
	{
		/* Clear */
		Term_erase(col, i, Term->wid - wid);
	}

	/* Choose */
	while (TRUE)
	{
		hgt = Term->hgt - TABLE_ROW - 1;

		/* Redraw the list */
		for (i = 0; ((i + top < num) && (i <= hgt)); i++)
		{
			if (i + top < 26)
			{
				strnfmt(buf, sizeof(buf), "%c) %s", I2A(i + top), choices[i + top].name);
			}
			else
			{
				/* ToDo: Fix the ASCII dependency */
				strnfmt(buf, sizeof(buf), "%c) %s", 'A' + (i + top - 26), choices[i + top].name);
			}

			/* Clear */
			Term_erase(col, i + TABLE_ROW, wid);

			/* Display */
			if (i == (cur - top))
			{
				/* Highlight the current selection */
				if (choices[i + top].ghost) attr = TERM_BLUE;
				else attr = TERM_L_BLUE;
			}
			else
			{
				if (choices[i + top].ghost) attr = TERM_SLATE;
				else attr = TERM_WHITE;
			}

			Term_putstr(col, i + TABLE_ROW, wid, attr, buf);
		}

		Term_erase(0, DESCRIPTION_ROW + 0, 255);
		Term_erase(0, DESCRIPTION_ROW + 1, 255);
		Term_erase(0, DESCRIPTION_ROW + 2, 255);
		Term_erase(0, DESCRIPTION_ROW + 3, 255);
		Term_erase(0, DESCRIPTION_ROW + 4, 255);
		
		if (choices[cur+top].text != NULL)
		{

			/* Indent output by 2 character, and wrap at column 70 */
			text_out_wrap = 70;
			text_out_indent = 2;

			/* History */
			Term_gotoxy(text_out_indent, DESCRIPTION_ROW);
			text_out_to_screen(TERM_L_WHITE, choices[cur+top].text);

			/* Reset text_out() vars */
			text_out_wrap = 0;
			text_out_indent = 0;
		}
		
		else
		{
			/* Extra info */
//			Term_putstr(QUESTION_COL, DESCRIPTION_ROW, -1, TERM_L_WHITE,
//						"Your sex has no gameplay effect.");
			
		}

		if (done) return (cur);

		/* Display auxiliary information if any is available. */
		if (hook) hook(choices[cur]);


		/* Move the cursor */
		put_str("", TABLE_ROW + cur - top, col);

		hide_cursor = TRUE;
		c = inkey();
		hide_cursor = FALSE;

		/* Exit the game */
		if ((c == 'Q') || (c == 'q'))	quit(NULL);

		/* Hack - go back */
		if ((c == ESCAPE)|| (c == '4')) return (INVALID_CHOICE);

		/* Make a choice */
		if ((c == '\n') || (c == '\r') || (c == '6')) return (cur);

		/* Random choice */
		if (c == '*')
		{
			/* Ensure legal choice */
			do { cur = rand_int(num); } while (choices[cur].ghost);

			/* Done */
			done = TRUE;
		}

		/* Alphabetic choice */
		else if (isalpha(c))
		{

			/* Options */
			if ((c == 'O') || (c == 'o'))
			{
				do_cmd_options();
			}

			else
			{
				int choice;

				if (islower(c)) choice = A2I(c);
				else choice = c - 'A' + 26;
				
				/* Validate input */
				if ((choice > -1) && (choice < num) && !(choices[choice].ghost))
				{
					cur = choice;
					
					/* Done */
					done = TRUE;
				}
				else if (choices[choice].ghost)
				{
					bell("Your race cannot choose that house.");
				}
				else
				{
					bell("Illegal response to question!");
				}
			}
		}

		/* Move */
		else if (isdigit(c))
		{
			/* Get a direction from the key */
			dir = target_dir(c);

			/* Going up? */
			if (dir == 8)
			{
				next = -1;
				for (i = 0; i < cur; i++)
				{
					if (!(choices[i].ghost))
					{
						next = i;
					}
				}
				
				/* Move selection */
				if (next != -1) cur = next;
				/* if (cur != 0) cur--; */

				/* Scroll up */
				if ((top > 0) && ((cur - top) < 4))	top--;		
			}

			/* Going down? */
			if (dir == 2)
			{
				next = -1;
				for (i = num - 1; i > cur; i--)
				{
					if (!(choices[i].ghost))
					{
						next = i;
					}
				}
				
				/* Move selection */
				if (next != -1) cur = next;
				/* if (cur != (num - 1)) cur++; */

				/* Scroll down */
				if ((top + hgt < (num - 1)) && ((top + hgt - cur) < 4)) top++;
			}
		}

		/* Invalid input */
		else bell("Illegal response to question!");

		/* If choice is off screen, move it to the top */
		if ((cur < top) || (cur > top + hgt)) top = cur;
	}

	return (INVALID_CHOICE);
}
Exemple #3
0
/*
 * Generic "get choice from menu" function
 */
int get_player_choice(cptr *choices, int num, int col, int wid,
                             cptr helpfile, void (*hook) (cptr))
{
	int top = 0, cur = 0;
	/* int bot = 13; */
	int i, dir;
	char c;
	char buf[80];
	bool done = FALSE;
	int hgt;


	/* Autoselect if able */
	if (num == 1) done = TRUE;

	/* Clear */
	for (i = TABLE_ROW; i < Term->hgt; i++)
	{
		/* Clear */
		Term_erase(col, i, Term->wid - wid);
	}

	/* Choose */
	while (TRUE)
	{
		/*
		 * Note to Melkor: What happens when the screen is resized?
		 * There is no 'redraw' hook at this point... 
		 * (That is why the original code restricted itself to what
		 * would fit in the smallest possible screen.) -SF-
		 */
		hgt = Term->hgt - TABLE_ROW - 1;

		/* Redraw the list */
		for (i = 0; ((i + top < num) && (i <= hgt)); i++)
		{
			if (i + top < 26)
			{
				strnfmt(buf, 80, "%c) %s", I2A(i + top), choices[i + top]);
			}
			else
			{
				/* ToDo: Fix the ASCII dependency */
				strnfmt(buf, 80, "%c) %s", 'A' + (i + top - 26), choices[i + top]);
			}

			/* Clear */
			Term_erase(col, i + TABLE_ROW, wid);

			/* Display */
			if (i == (cur - top))
			{
				/* Highlight the current selection */
				put_fstr(col, i + TABLE_ROW, CLR_L_BLUE "%s", buf);
			}
			else
			{
				put_fstr(col, i + TABLE_ROW, buf);
			}
		}

		if (done) return (cur);

		/* Display auxiliary information if any is available. */
		if (hook) hook(choices[cur]);

		/* Move the cursor */
		Term_gotoxy(col, TABLE_ROW + cur - top);

		c = inkey();

		if (c == KTRL('X'))
		{
			quit(NULL);
		}
		if (c == ESCAPE)
		{
			/* Mega Hack - go back. */
			return (INVALID_CHOICE);
		}
		if (c == '*')
		{
			/* Select at random */
			cur = randint0(num);

			/* Move it onto the screen */
			if ((cur < top) || (cur > top + hgt))
			{
				top = cur;
			}

			/* Done */
			done = TRUE;
		}
		else if (c == '?')
		{
			(void)show_file(helpfile, NULL, 0, 0);
		}
		else if (c == '=')
		{
			do_cmd_options(OPT_FLAG_BIRTH | OPT_FLAG_SERVER | OPT_FLAG_PLAYER);
		}
		else if ((c == '\n') || (c == '\r'))
		{
			/* Done */
			return (cur);
		}
		else if (isdigit(c))
		{
			/* Get a direction from the key */
			dir = get_keymap_dir(c);

			/* Going up? */
			if (dir == 8)
			{
				if (cur != 0)
				{
					/* Move selection */
					cur--;
				}

				if ((top > 0) && ((cur - top) < 4))
				{
					/* Scroll up */
					top--;
				}
			}

			/* Going down? */
			if (dir == 2)
			{
				if (cur != (num - 1))
				{
					/* Move selection */
					cur++;
				}

				if ((top + hgt < (num - 1)) && ((top + hgt - cur) < 4))
				{
					/* Scroll down */
					top++;
				}
			}
		}
		else if (isalpha(c))
		{
			int choice;

			if (islower(c))
			{
				choice = A2I(c);
			}
			else
			{
				choice = c - 'A' + 26;
			}

			/* Validate input */
			if ((choice > -1) && (choice < num))
			{
				cur = choice;

				/* Move it onto the screen */
				if ((cur < top) || (cur > top + hgt))
				{
					top = cur;
				}

				/* Done */
				done = TRUE;
			}
			else
			{
				/* Invalid input */
				bell("Illegal birth choice!");
			}
		}
	}

	return (INVALID_CHOICE);
}
Exemple #4
0
/* Allow the user to select from the current menu, and return the
   corresponding command to the game.  Some actions are handled entirely
   by the UI (displaying help text, for instance). */
static enum birth_stage menu_question(enum birth_stage current, menu_type *current_menu, cmd_code choice_command)
{
	struct birthmenu_data *menu_data = current_menu->menu_data;
	int cursor = current_menu->cursor;
	ui_event_data cx;

	enum birth_stage next = BIRTH_RESET;

	/* Print the question currently being asked. */
	clear_question();
	Term_putstr(QUESTION_COL, QUESTION_ROW, -1, TERM_YELLOW, menu_data->hint);

	current_menu->cmd_keys = "?=*\r\n\x18";	 /* ?, ,= *, \n, <ctl-X> */

	while (next == BIRTH_RESET)
	{
		button_kill_all();
		button_add("[ENTER]", '\r');
		if (menu_data->allow_random) button_add("[RANDOM]", '*');
		button_add("[ESCAPE]", ESCAPE);
		button_add("[OPTIONS]", '=');
		button_add("[HELP]", '?');
		button_add("[QUIT]", '\x18');  /* CTRL-X */
		event_signal(EVENT_MOUSEBUTTONS);

		/* Display the menu, wait for a selection of some sort to be made. */
		cx = menu_select(current_menu, &cursor, EVT_CMD);

		/* As all the menus are displayed in "hierarchical" style, we allow
		   use of "back" (left arrow key or equivalent) to step back in
		   the proces as well as "escape". */
		if (cx.type == EVT_BACK || cx.type == EVT_ESCAPE || cx.key == ESCAPE)
		{
			next = BIRTH_BACK;
		}
		/* '\xff' or DEFINED_XFF is a mouse selection, '\r' a keyboard one. */
		else if (cx.key == DEFINED_XFF || cx.key == '\r')
		{
			if (current == BIRTH_ROLLER_CHOICE)
			{
				if (cursor)
				{
					/* Do a first roll of the stats */
					cmd_insert(CMD_ROLL_STATS);
					next = current + 2;
				}
				else
				{
					/*
					 * Make sure we've got a point-based char to play with.
					 * We call point_based_start here to make sure we get
					 * an update on the points totals before trying to
					 * display the screen.  The call to CMD_RESET_STATS
					 * forces a rebuying of the stats to give us up-to-date
					 * totals.  This is, it should go without saying, a hack.
					 */
					point_based_start();
					cmd_insert(CMD_RESET_STATS, TRUE);
					next = current + 1;
				}
			}
			else
			{
				cmd_insert(choice_command, cursor);
				next = current + 1;
			}
		}
		/* '*' chooses an option at random from those the game's provided. */
		else if (cx.key == '*' && menu_data->allow_random)
		{
			current_menu->cursor = randint0(current_menu->count);
			cmd_insert(choice_command, current_menu->cursor);

			menu_refresh(current_menu);
			next = current + 1;
		}
		else if (cx.key == '=')
		{
			do_cmd_options();
			next = current;
		}
		else if (cx.key == KTRL('X'))
		{
			cmd_insert(CMD_QUIT);
			next = BIRTH_COMPLETE;
		}
		else if (cx.key == '?')
		{
			do_cmd_help();
		}
	}

	return next;
}