Exemple #1
0
void menu_enter(void) {

	if (currentPointer->menu_function) currentPointer->menu_function();

	if (currentPointer->child)
	{

		switch (menu_get_level(currentPointer)) {
			case 0:
				lcd_row_pos_level_1 = lcd_row_pos;
				break;

			case 1:
				lcd_row_pos_level_2 = lcd_row_pos;
				break;
		}

		// switch...case can be replaced by:
		// lcd_row_pos_level[ menu_get_level(currentPointer) ] = lcd_row_pos;

		menu_index = 0;
		lcd_row_pos = 0;

		currentPointer = currentPointer->child;

		menu_refresh();
	}
}
Exemple #2
0
/*
 * Process these function after each TIMEOUT (default 3 seconds).
 * Order is important because some windows are on the top
 * of others.
 */
static void periodic(void)
{
	check_wtmp();
	update_load();		
	current->periodic();
	wnoutrefresh(main_win);
	wnoutrefresh(info_win.wd);
	sub_periodic();
	menu_refresh();
	box_refresh();
	info_refresh();
	doupdate();
}
Exemple #3
0
static void key_action(int key)
{
	int i, size;
	if(signal_sent) {
	    print_help();
	    signal_sent = 0;
	}
	/* 
	 * First, try to process the key by object (subwindow, menu) that
	 * could be on top.
	 */
	size = sizeof key_funct/sizeof(int (*)(int));
	for(i = 0; i < size; i++)
		if(key_funct[i](key)) goto SKIP; 
	
	if(current->keys(key)) goto SKIP;
	/* cursor movement */
	size = sizeof key_handlers/sizeof(struct key_handler);
	for(i = 0; i < size; i++) 
		if(key_handlers[i].c == key) {
			key_handlers[i].handler(current);
			if(can_draw()) pad_draw();
			goto SKIP;
		}
	switch(key) {
	case 'c':
		full_cmd ^= 1;
		current->redraw();
		break;
	case '/':
		m_search();
		break;			
	case KBD_F1:
		help();
		break;
	case KBD_ESC:
	case 'q':
		curses_end();
		exit(0);
	default: return;
	}
SKIP:
	dolog("%s: doing refresh\n", __FUNCTION__);
	wnoutrefresh(main_win);
	wnoutrefresh(info_win.wd);
	pad_refresh();
	menu_refresh();
	box_refresh();
	info_refresh();
	doupdate();
}
Exemple #4
0
void menu_prev(void) {

	currentPointer = currentPointer->prev;

	if (menu_index)
	{
		menu_index--;
		if (lcd_row_pos > 0) lcd_row_pos--;
	}
	else
	{
		menu_index = menu_get_index(currentPointer);

		if (menu_index >= LCD_ROWS - 1) lcd_row_pos = LCD_ROWS - 1;
		else lcd_row_pos = menu_index;
	}

	menu_refresh();
}
Exemple #5
0
void menu_back(void) {

	if (currentPointer->parent) {

		switch (menu_get_level(currentPointer)) {
			case 1:
				lcd_row_pos = lcd_row_pos_level_1;
				break;

			case 2:
				lcd_row_pos = lcd_row_pos_level_2;
				break;
			}

		currentPointer = currentPointer->parent;
		menu_index = menu_get_index(currentPointer);

		menu_refresh();

	}
}
Exemple #6
0
void menu_next(void) {

	if (currentPointer->next)
	{

		currentPointer = (*currentPointer).next;
		menu_index++;
		if (++lcd_row_pos > LCD_ROWS - 1) lcd_row_pos = LCD_ROWS - 1;
	}
	else
	{
		menu_index = 0;
		lcd_row_pos = 0;

		if (currentPointer->parent) currentPointer = (currentPointer->parent)->child;
		else currentPointer = &menu1;
	}

	menu_refresh();

}
Exemple #7
0
/* 
 * Run multiple menus at the same time.
 *
 * If popup is true, the screen is saved before the menu is drawn, and
 * restored afterwards. Each time a popup menu is redrawn, it resets the
 * screen before redrawing.
 */
ui_event menu_select_multi(int *active, menu_type **menus, int num, int notify, bool popup)
{
	ui_event in = EVENT_EMPTY;
	ui_event out = EVENT_EMPTY;
	bool no_act = FALSE;
	int i;

	assert(menus != NULL);
	assert(active != NULL);
	assert(num > 1);
	assert(*active < num);
	for (i = 0; i < num; i++) {
		assert(menus[i]->active.width != 0 && menus[i]->active.page_rows != 0);
	}

	notify |= (EVT_SELECT | EVT_ESCAPE);
	if (popup) {
		screen_save();
		button_backup_all(TRUE);
	}

	/* Stop on first unhandled event */
	//while (!(in.type & notify))
	//while (!(in & notify))
	while (!(in == EVT_SELECT) && !(in == EVT_ESCAPE))
	{
		out = EVENT_EMPTY;

		if (popup) {
			button_restore();
			screen_load();
			screen_save();
			button_backup_all(TRUE);
		}
		no_act = (menus[*active]->flags & MN_NO_ACTION) ? TRUE : FALSE;

		/* refresh all of the menus except the active one */
		for (i = 0; i < num; i++) {
			if (i != *active) {
				menu_refresh(menus[i], FALSE);
			}
		}
		/* refresh the active menu */
		menu_refresh(menus[*active], FALSE);

		//in = inkey_ex();
		in = inkey_m();

		/* Handle mouse & keyboard commands */
		//if (in.type == EVT_MOUSE) {
		if (in & 0x80) {
			//if (!no_act && menu_handle_action(menu, &in)) {
			//	continue;
			//}
			//menu_handle_mouse(menu, &in, &out);
			if (in == EVT_RESIZE) {
				/* resize all of the menus */
				for (i = 0; i < num; i++) {
					menu_calc_size(menus[i]);
					if (menus[i]->row_funcs->resize)
						menus[i]->row_funcs->resize(menus[i]);
				}
			} else {
				int mx,my;
				char p;

				/* check which menu the click was in */
				Term_peekmousepress(&p, &mx, &my);
				if (!rect_region_inside(&(menus[*active]->active), my, mx) ) {
					for (i = 0; i < num; i++) {
						if (rect_region_inside(&(menus[i]->active), my, mx)) {
							no_act = (menus[i]->flags & MN_NO_ACTION) ? TRUE : FALSE;
							*active = i;
						}
					}
				}

				/* handle the click in the active one */
				if (!no_act && menu_handle_action(menus[*active], &in)) {
					continue;
				}
				menu_handle_mouse(menus[*active], &in, &out);
			}
		//} else if (in.type == EVT_KBRD) {
		} else {
			/* see if we need to move between menus */
			/* handle the key press */
			if (!no_act && menus[*active]->cmd_keys &&
					//strchr(menu->cmd_keys, (char)in.key.code) &&
					strchr(menus[*active]->cmd_keys, (char)in) &&
					menu_handle_action(menus[*active], &in))
			{
				continue;
			}

			menu_handle_keypress(menus[*active], &in, &out);
		}// else if (in.type == EVT_RESIZE) {
		//	menu_calc_size(menu);
		//	if (menu->row_funcs->resize)
		//		menu->row_funcs->resize(menu);
		//}

		/* XXX should redraw menu here if cursor has moved */

		/* if we requested it, send move events out */
		if ((out == EVT_SELECT) && (menus[*active]->flags & MN_HANDLE_MOVE)
			&& !no_act && menu_handle_action(menus[*active], &out))
			continue;

		/* If we've selected an item, then send that event out */
		//if (out.type == EVT_SELECT && !no_act && menu_handle_action(menu, &out))
		if ((out == EVT_SELECT) && !no_act && menu_handle_action(menus[*active], &out))
			continue;

		/* needed because EVT_* types are composed of multiple flags where in
		 * angband they are one flag of an int, so the (notify & out) and
		 * (!(in & notify)) is only true for particular EVT_* values */
		/* Notify about the outgoing type */
		//if (notify & out.type) {
		//if (notify & out) {
		if ((out == EVT_SELECT) || (out == EVT_ESCAPE)) {
			if (popup) {
				button_restore();
				screen_load();
			}
			return out;
		}
	}

	if (popup) {
		button_restore();
		screen_load();
	}
	return in;
}
Exemple #8
0
/* 
 * Run a menu.
 *
 * If popup is true, the screen is saved before the menu is drawn, and
 * restored afterwards. Each time a popup menu is redrawn, it resets the
 * screen before redrawing.
 */
ui_event menu_select(menu_type *menu, int notify, bool popup)
{
	ui_event in = EVENT_EMPTY;
	ui_event out = EVENT_EMPTY;
	bool no_act = (menu->flags & MN_NO_ACTION) ? TRUE : FALSE;

	assert(menu->active.width != 0 && menu->active.page_rows != 0);

	notify |= (EVT_SELECT | EVT_ESCAPE);
	if (popup) {
		screen_save();
		button_backup_all(TRUE);
	}

	/* Stop on first unhandled event */
	//while (!(in.type & notify))
	//while (!(in & notify))
	while (!(in == EVT_SELECT) && !(in == EVT_ESCAPE))
	{
		out = EVENT_EMPTY;

		menu_refresh(menu, popup);
		//in = inkey_ex();
		in = inkey_m();

		/* Handle mouse & keyboard commands */
		//if (in.type == EVT_MOUSE) {
		if (in & 0x80) {
			//if (!no_act && menu_handle_action(menu, &in)) {
			//	continue;
			//}
			//menu_handle_mouse(menu, &in, &out);
			if (in == EVT_RESIZE) {
				menu_calc_size(menu);
				if (menu->row_funcs->resize)
					menu->row_funcs->resize(menu);
			} else {
				if (!no_act && menu_handle_action(menu, &in)) {
					continue;
				}
				menu_handle_mouse(menu, &in, &out);
			}
		//} else if (in.type == EVT_KBRD) {
		} else {
			if (!no_act && menu->cmd_keys &&
					//strchr(menu->cmd_keys, (char)in.key.code) &&
					strchr(menu->cmd_keys, (char)in) &&
					menu_handle_action(menu, &in))
				continue;

			menu_handle_keypress(menu, &in, &out);
		}// else if (in.type == EVT_RESIZE) {
		//	menu_calc_size(menu);
		//	if (menu->row_funcs->resize)
		//		menu->row_funcs->resize(menu);
		//}

		/* XXX should redraw menu here if cursor has moved */

		/* if we requested it, send move events out */
		if ((out == EVT_SELECT) && (menu->flags & MN_HANDLE_MOVE)
			&& !no_act && menu_handle_action(menu, &out))
			continue;

		/* If we've selected an item, then send that event out */
		//if (out.type == EVT_SELECT && !no_act && menu_handle_action(menu, &out))
		if ((out == EVT_SELECT) && !no_act && menu_handle_action(menu, &out))
			continue;

		/* needed because EVT_* types are composed of multiple flags where in
		 * angband they are one flag of an int, so the (notify & out) and
		 * (!(in & notify)) is only true for particular EVT_* values */
		/* Notify about the outgoing type */
		//if (notify & out.type) {
		//if (notify & out) {
		if ((out == EVT_SELECT) || (out == EVT_ESCAPE)) {
			if (popup) {
				button_restore();
				screen_load();
			}
			return out;
		}
	}

	if (popup) {
		button_restore();
		screen_load();
	}
	return in;
}
Exemple #9
0
/*
 * This is called when we receive a request for a command in the birth 
 * process.

 * The birth process continues until we send a final character confirmation
 * command (or quit), so this is effectively called in a loop by the main
 * game.
 *
 * We're imposing a step-based system onto the main game here, so we need
 * to keep track of where we're up to, where each step moves on to, etc.
 */
errr get_birth_command(bool wait)
{
	static enum birth_stage current_stage = BIRTH_RESET;
	static enum birth_stage prev;
	static enum birth_stage roller = BIRTH_RESET;
	enum birth_stage next = current_stage;

	switch (current_stage)
	{
		case BIRTH_RESET:
		{
			cmd_insert(CMD_BIRTH_RESET);

			roller = BIRTH_RESET;
			
			if (quickstart_allowed)
				next = BIRTH_QUICKSTART;
			else
				next = BIRTH_SEX_CHOICE;

			break;
		}

		case BIRTH_QUICKSTART:
		{
			display_player(0);
			next = get_quickstart_command();
			break;
		}

		case BIRTH_SEX_CHOICE:
		case BIRTH_CLASS_CHOICE:
		case BIRTH_RACE_CHOICE:
		case BIRTH_ROLLER_CHOICE:
		{
			menu_type *menu = &sex_menu;
			cmd_code command = CMD_CHOOSE_SEX;

			Term_clear();
			print_menu_instructions();

			if (current_stage > BIRTH_SEX_CHOICE)
			{
				menu_refresh(&sex_menu, FALSE);
				menu = &race_menu;
				command = CMD_CHOOSE_RACE;
			}
			
			if (current_stage > BIRTH_RACE_CHOICE)
			{
				menu_refresh(&race_menu, FALSE);
				menu = &class_menu;
				command = CMD_CHOOSE_CLASS;
			}

			if (current_stage > BIRTH_CLASS_CHOICE)
			{
				menu_refresh(&class_menu, FALSE);
				menu = &roller_menu;
				command = CMD_NULL;
			}
			
			next = menu_question(current_stage, menu, command);

			if (next == BIRTH_BACK)
				next = current_stage - 1;

			/* Make sure that the character gets reset before quickstarting */
			if (next == BIRTH_QUICKSTART) 
				next = BIRTH_RESET;

			break;
		}

		case BIRTH_POINTBASED:
		{
			roller = BIRTH_POINTBASED;
	
			if (prev > BIRTH_POINTBASED)
				point_based_start();

			next = point_based_command();

			if (next == BIRTH_BACK)
				next = BIRTH_ROLLER_CHOICE;

			if (next != BIRTH_POINTBASED)
				point_based_stop();

			break;
		}

		case BIRTH_ROLLER:
		{
			roller = BIRTH_ROLLER;
			next = roller_command(prev < BIRTH_ROLLER);
			if (next == BIRTH_BACK)
				next = BIRTH_ROLLER_CHOICE;

			break;
		}

		case BIRTH_NAME_CHOICE:
		{
			if (prev < BIRTH_NAME_CHOICE)
				display_player(0);

			next = get_name_command();
			if (next == BIRTH_BACK)
				next = roller;

			break;
		}

		case BIRTH_FINAL_CONFIRM:
		{
			if (prev < BIRTH_FINAL_CONFIRM)
				display_player(0);

			next = get_confirm_command();
			if (next == BIRTH_BACK)
				next = BIRTH_NAME_CHOICE;

			break;
		}

		default:
		{
			/* Remove dodgy compiler warning, */
		}
	}

	prev = current_stage;
	current_stage = next;

	return 0;
}
Exemple #10
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 = menu_priv(current_menu);
	ui_event 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 = "?=*\x18";	 /* ?, =, *, <ctl-X> */

	while (next == BIRTH_RESET)
	{
		/* Display the menu, wait for a selection of some sort to be made. */
		cx = menu_select(current_menu, EVT_KBRD, FALSE);

		/* 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_ESCAPE)
		{
			next = BIRTH_BACK;
		}
		else if (cx.type == EVT_SELECT)
		{
			if (current == BIRTH_ROLLER_CHOICE)
			{
				cmd_insert(CMD_FINALIZE_OPTIONS);

				if (current_menu->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);
					cmd_set_arg_choice(cmd_get_top(), 0, TRUE);
					next = current + 1;
				}
			}
			else
			{
				cmd_insert(choice_command);
				cmd_set_arg_choice(cmd_get_top(), 0, current_menu->cursor);
				next = current + 1;
			}
		}
		else if (cx.type == EVT_KBRD)
		{
			/* '*' chooses an option at random from those the game's provided. */
			if (cx.key.code == '*' && menu_data->allow_random) 
			{
				current_menu->cursor = randint0(current_menu->count);
				cmd_insert(choice_command);
				cmd_set_arg_choice(cmd_get_top(), 0, current_menu->cursor);

				menu_refresh(current_menu, FALSE);
				next = current + 1;
			}
			else if (cx.key.code == '=') 
			{
				do_cmd_options_birth();
				next = current;
			}
			else if (cx.key.code == KTRL('X')) 
			{
				cmd_insert(CMD_QUIT);
				next = BIRTH_COMPLETE;
			}
			else if (cx.key.code == '?')
			{
				do_cmd_help();
			}
		}
	}
	
	return next;
}
/*
 * Interactive group by.
 * Recognises inscriptions, graphical symbols, lore
 */
static void display_knowledge(const char *title, int *obj_list,
							  int o_count, group_funcs g_funcs,
							  member_funcs o_funcs,
							  const char *otherfields)
{
	/* maximum number of groups to display */
	int max_group = g_funcs.maxnum < o_count ? g_funcs.maxnum : o_count;

	/* This could (should?) be (void **) */
	int *g_list, *g_offset;

	const char **g_names;

	int g_name_len = 8;			/* group name length, minumum is 8 */

	int grp_cnt = 0;			/* total number groups */

	int g_cur = 0, grp_old = -1;	/* group list positions */
	int o_cur = 0;				/* object list positions */
	int g_o_count = 0;			/* object count for group */
	int oid = -1;				/* object identifiers */

	region title_area = { 0, 0, 0, 4 };
	region group_region = { 0, 6, MISSING, -2 };
	region object_region = { MISSING, 6, 0, -2 };

	/* display state variables */
	bool tiles = (current_graphics_mode != NULL);
	bool tile_picker = FALSE;
	bool glyph_picker = FALSE;
	byte attr_top = 0;
	byte char_left = 0;

	int delay = 0;

	menu_type group_menu;
	menu_type object_menu;
	menu_iter object_iter =
		{ NULL, NULL, display_group_member, NULL, NULL };

	/* Panel state */
	/* These are swapped in parallel whenever the actively browsing " */
	/* changes */
	int *active_cursor = &g_cur, *inactive_cursor = &o_cur;
	menu_type *active_menu = &group_menu, *inactive_menu = &object_menu;
	int panel = 0;

	void *swapspace;
	bool do_swap = FALSE;

	bool flag = FALSE;
	bool redraw = TRUE;

	int browser_rows;
	int wid, hgt;
	int i;
	int prev_g = -1;

	int omode = OPT(rogue_like_commands);
	ui_event ke;

	/* Get size */
	Term_get_size(&wid, &hgt);
	browser_rows = hgt - 8;

	/* Disable the roguelike commands for the duration */
	OPT(rogue_like_commands) = FALSE;

	/* Determine if using tiles or not */
	if (tiles)
		tiles = (current_graphics_mode->grafID != 0);

	if (g_funcs.gcomp)
		sort(obj_list, o_count, sizeof(*obj_list), g_funcs.gcomp);

	/* Sort everything into group order */
	g_list = C_ZNEW(max_group + 1, int);
	g_offset = C_ZNEW(max_group + 1, int);

	for (i = 0; i < o_count; i++) {
		if (prev_g != g_funcs.group(obj_list[i])) {
			prev_g = g_funcs.group(obj_list[i]);
			g_offset[grp_cnt] = i;
			g_list[grp_cnt++] = prev_g;
		}
	}

	g_offset[grp_cnt] = o_count;
	g_list[grp_cnt] = -1;


	/* The compact set of group names, in display order */
	g_names = C_ZNEW(grp_cnt, const char *);

	for (i = 0; i < grp_cnt; i++) {
		int len;
		g_names[i] = g_funcs.name(g_list[i]);
		len = strlen(g_names[i]);
		if (len > g_name_len)
			g_name_len = len;
	}

	/* Reasonable max group name len */
	if (g_name_len >= 20)
		g_name_len = 20;

	object_region.col = g_name_len + 3;
	group_region.width = g_name_len;


	/* Leave room for the group summary information */
	if (g_funcs.summary)
		object_region.page_rows = -3;


	/* Set up the two menus */
	menu_init(&group_menu, MN_SKIN_SCROLL,
			  menu_find_iter(MN_ITER_STRINGS));
	menu_setpriv(&group_menu, grp_cnt, g_names);
	menu_layout(&group_menu, &group_region);

	menu_init(&object_menu, MN_SKIN_SCROLL, &object_iter);
	menu_setpriv(&object_menu, 0, &o_funcs);
	menu_layout(&object_menu, &object_region);

	o_funcs.is_visual = FALSE;

	/* Save screen */
	screen_save();
	clear_from(0);


	/* This is the event loop for a multi-region panel */
	/* Panels are -- text panels, two menus, and visual browser */
	/* with "pop-up menu" for lore */
	while ((!flag) && (grp_cnt)) {
		bool recall = FALSE;

		if (redraw) {
			/* Print the title bits */
			region_erase(&title_area);
			prt(format("Knowledge - %s", title), 2, 0);
			prt("Group", 4, 0);
			prt("Name", 4, g_name_len + 3);

			if (otherfields)
				prt(otherfields, 4, 46);


			/* Print dividers: horizontal and vertical */
			for (i = 0; i < 79; i++)
				Term_putch(i, 5, TERM_WHITE, '=');

			for (i = 0; i < browser_rows; i++)
				Term_putch(g_name_len + 1, 6 + i, TERM_WHITE, '|');


			/* Reset redraw flag */
			redraw = FALSE;
		}

		if (g_cur != grp_old) {
			grp_old = g_cur;
			o_cur = 0;
			g_o_count = g_offset[g_cur + 1] - g_offset[g_cur];
			menu_set_filter(&object_menu, obj_list + g_offset[g_cur],
							g_o_count);
			group_menu.cursor = g_cur;
			object_menu.cursor = 0;
		}

		/* HACK ... */
		if (!(tile_picker || glyph_picker)) {
			/* ... The object menu may be browsing the entire group... */
			o_funcs.is_visual = FALSE;
			menu_set_filter(&object_menu, obj_list + g_offset[g_cur],
							g_o_count);
			object_menu.cursor = o_cur;
		} else {
			/* ... or just a single element in the group. */
			o_funcs.is_visual = TRUE;
			menu_set_filter(&object_menu,
							obj_list + o_cur + g_offset[g_cur], 1);
			object_menu.cursor = 0;
		}

		oid = obj_list[g_offset[g_cur] + o_cur];

		/* Print prompt */
		{
			const char *pedit =
				(!o_funcs.xattr) ? "" : (!(attr_idx | char_idx) ?
										 ", 'c' to copy" :
										 ", 'c', 'p' to paste");
			const char *xtra =
				o_funcs.xtra_prompt ? o_funcs.xtra_prompt(oid) : "";
			const char *pvs = "";

			if (tile_picker)
				pvs = ", ENTER to accept";
			else if (glyph_picker)
				pvs = ", 'i' to insert, ENTER to accept";
			else if (o_funcs.xattr)
				pvs = ", 'v' for visuals";

			prt(format("<dir>%s%s%s, ESC", pvs, pedit, xtra), hgt - 1, 0);
		}

		if (do_swap) {
			do_swap = FALSE;
			swap(active_menu, inactive_menu);
			swap(active_cursor, inactive_cursor);
			panel = 1 - panel;
		}

		if (g_funcs.summary && !tile_picker && !glyph_picker) {
			g_funcs.summary(g_cur, obj_list, g_o_count, g_offset[g_cur],
							object_menu.active.row +
							object_menu.active.page_rows,
							object_region.col);
		}

		menu_refresh(inactive_menu, FALSE);
		menu_refresh(active_menu, FALSE);

		handle_stuff(p_ptr);

		if (tile_picker) {
			bigcurs = TRUE;
			display_tiles(g_name_len + 3, 7, browser_rows - 1,
						  wid - (g_name_len + 3), attr_top, char_left);
			place_tile_cursor(g_name_len + 3, 7, *o_funcs.xattr(oid),
							  (byte) * o_funcs.xchar(oid), attr_top,
							  char_left);
		}

		if (glyph_picker) {
			display_glyphs(g_name_len + 3, 7, browser_rows - 1,
						   wid - (g_name_len + 3), *o_funcs.xattr(oid),
						   *o_funcs.xchar(oid));
		}

		if (delay) {
			/* Force screen update */
			Term_fresh();

			/* Delay */
			Term_xtra(TERM_XTRA_DELAY, delay);

			delay = 0;
		}

		ke = inkey_ex();
		if (!tile_picker && !glyph_picker) {
			ui_event ke0 = EVENT_EMPTY;

			if (ke.type == EVT_MOUSE)
				menu_handle_mouse(active_menu, &ke, &ke0);
			else if (ke.type == EVT_KBRD)
				menu_handle_keypress(active_menu, &ke, &ke0);

			if (ke0.type != EVT_NONE)
				ke = ke0;
		}

		/* XXX Do visual mode command if needed */
		if (o_funcs.xattr && o_funcs.xchar) {
			if (tiles) {
				if (tile_picker_command(ke, &tile_picker, browser_rows - 1,
										wid - (g_name_len + 3), &attr_top,
										&char_left, o_funcs.xattr(oid),
										(byte *) o_funcs.xchar(oid),
										g_name_len + 3, 7, &delay))
					continue;
			} else {
				if (glyph_command(ke, &glyph_picker, browser_rows - 1,
								  wid - (g_name_len + 3),
								  o_funcs.xattr(oid), o_funcs.xchar(oid),
								  g_name_len + 3, 7))
					continue;
			}
		}

		switch (ke.type) {
		case EVT_KBRD:
			{
				if (ke.key.code == 'r' || ke.key.code == 'R')
					recall = TRUE;
				else if (o_funcs.xtra_act)
					o_funcs.xtra_act(ke.key, oid);

				break;
			}

		case EVT_MOUSE:
			{
				/* Change active panels */
				if (region_inside(&inactive_menu->boundary, &ke)) {
					swap(active_menu, inactive_menu);
					swap(active_cursor, inactive_cursor);
					panel = 1 - panel;
				}

				continue;
			}

		case EVT_ESCAPE:
			{
				if (panel == 1)
					do_swap = TRUE;
				else
					flag = TRUE;

				break;
			}

		case EVT_SELECT:
			{
				if (panel == 0)
					do_swap = TRUE;
				else if (panel == 1 && oid >= 0
						 && o_cur == active_menu->cursor)
					recall = TRUE;
				break;
			}

		case EVT_MOVE:
			{
				*active_cursor = active_menu->cursor;
				break;
			}

		default:
			{
				break;
			}
		}

		/* Recall on screen */
		if (recall) {
			if (oid >= 0)
				o_funcs.lore(oid);

			redraw = TRUE;
		}
	}

	/* Restore roguelike option */
	OPT(rogue_like_commands) = omode;

	/* Prompt */
	if (!grp_cnt)
		prt(format("No %s known.", title), 15, 0);

	FREE(g_names);
	FREE(g_offset);
	FREE(g_list);

	screen_load();
}
Exemple #12
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;
}
Exemple #13
0
/**
 * Deal with events on the get_item menu
 */
bool get_item_action(menu_type *menu, const ui_event *event, int oid)
{
    bool refresh = FALSE;
    struct object_menu_data *choice = menu_priv(menu);
    char key = event->key.code;
    int i, k;
    char *selections = (char *) menu->selections;

    if (event->type == EVT_SELECT)
    {
	selection = choice[oid].key;
	return FALSE;
    }

    if (event->type == EVT_KBRD)
    {
	if (key == '/')
	{
	    /* Toggle to inventory */
	    if ((item_mode & USE_INVEN) && (p_ptr->command_wrk != USE_INVEN)) 
	    {
		p_ptr->command_wrk = USE_INVEN;
		build_obj_list(0, i2, NULL, olist_mode);
		refresh = TRUE;
	    }
	    
	    /* Toggle to equipment */
	    else if ((item_mode & USE_EQUIP) && 
		     (p_ptr->command_wrk != USE_EQUIP)) 
	    {
		p_ptr->command_wrk = USE_EQUIP;
		build_obj_list(INVEN_WIELD, e2, NULL, olist_mode);
		refresh = TRUE;
	    }
	    
	    /* No toggle allowed */
	    else 
	    {
		bell("Cannot switch item selector!");
	    }
	}

	else if (key == '-')
	{
	    /* No toggle allowed */
	    if (f1 > f2) {
		bell("Cannot select floor!");
	    }
	    /* Toggle to floor */
	    else 
	    {
		p_ptr->command_wrk = (USE_FLOOR);
		build_obj_list(0, f2, floor_list, olist_mode);
		refresh = TRUE;
	    }
	}

	else if ((key >= '0') && (key <= '9'))
	{
	    /* Look up the tag */
	    if (!get_tag(&k, key, item_cmd, item_mode & QUIVER_TAGS)) 
	    {
		bell("Illegal object choice (tag)!");
		return TRUE;
	    }

	    /* Match the item */
	    for (i = 0; i < menu->count; i++)
	    {
		if (choice[i].object == &p_ptr->inventory[k]) {
		    Term_keypress(choice[i].key, 0);
		    return TRUE;
		}
	    }
	}
	    

	if (refresh)
	{
	    /* Load screen */
	    screen_load();
	    Term_fresh();
	    
	    /* Save screen */
	    screen_save();
	    
	    /* Show the prompt */
	    item_prompt(item_mode);
	    
	    menu_setpriv(menu, num_obj, items);
	    for (i = 0; i < num_obj; i++)
		selections[i] = items[i].key;
	    area.page_rows = menu->count + 1;
	    menu_layout(menu, &area);
	    menu_refresh(menu, TRUE);
	    redraw_stuff(p_ptr);
	}
	
	return FALSE;

    }

    return TRUE;
}
Exemple #14
0
/**
 * This is called when we receive a request for a command in the birth 
 * process.

 * The birth process continues until we send a final character confirmation
 * command (or quit), so this is effectively called in a loop by the main
 * game.
 *
 * We're imposing a step-based system onto the main game here, so we need
 * to keep track of where we're up to, where each step moves on to, etc.
 */
int textui_do_birth(void)
{
	enum birth_stage current_stage = BIRTH_RESET;
	enum birth_stage prev;
	enum birth_stage roller = BIRTH_RESET;
	enum birth_stage next = current_stage;

	bool done = FALSE;

	cmdq_push(CMD_BIRTH_INIT);
	cmdq_execute(CMD_BIRTH);

	while (!done) {

		switch (current_stage)
		{
			case BIRTH_RESET:
			{
				cmdq_push(CMD_BIRTH_RESET);

				roller = BIRTH_RESET;
				
				if (quickstart_allowed)
					next = BIRTH_QUICKSTART;
				else
					next = BIRTH_RACE_CHOICE;

				break;
			}

			case BIRTH_QUICKSTART:
			{
				display_player(0);
				next = textui_birth_quickstart();
				if (next == BIRTH_COMPLETE)
					done = TRUE;
				break;
			}

			case BIRTH_CLASS_CHOICE:
			case BIRTH_RACE_CHOICE:
			case BIRTH_ROLLER_CHOICE:
			{
				struct menu *menu = &race_menu;
				cmd_code command = CMD_CHOOSE_RACE;

				Term_clear();
				print_menu_instructions();

				if (current_stage > BIRTH_RACE_CHOICE) {
					menu_refresh(&race_menu, FALSE);
					menu = &class_menu;
					command = CMD_CHOOSE_CLASS;
				}

				if (current_stage > BIRTH_CLASS_CHOICE) {
					menu_refresh(&class_menu, FALSE);
					menu = &roller_menu;
				}

				next = menu_question(current_stage, menu, command);

				if (next == BIRTH_BACK)
					next = current_stage - 1;

				/* Make sure the character gets reset before quickstarting */
				if (next == BIRTH_QUICKSTART) 
					next = BIRTH_RESET;

				break;
			}

			case BIRTH_POINTBASED:
			{
				roller = BIRTH_POINTBASED;
		
				if (prev > BIRTH_POINTBASED)
					point_based_start();

				next = point_based_command();

				if (next == BIRTH_BACK)
					next = BIRTH_ROLLER_CHOICE;

				if (next != BIRTH_POINTBASED)
					point_based_stop();

				break;
			}

			case BIRTH_ROLLER:
			{
				roller = BIRTH_ROLLER;
				next = roller_command(prev < BIRTH_ROLLER);
				if (next == BIRTH_BACK)
					next = BIRTH_ROLLER_CHOICE;

				break;
			}

			case BIRTH_NAME_CHOICE:
			{
				if (prev < BIRTH_NAME_CHOICE)
					display_player(0);

				next = get_name_command();
				if (next == BIRTH_BACK)
					next = roller;

				break;
			}

			case BIRTH_HISTORY_CHOICE:
			{
				if (prev < BIRTH_HISTORY_CHOICE)
					display_player(0);

				next = get_history_command();
				if (next == BIRTH_BACK)
					next = BIRTH_NAME_CHOICE;

				break;
			}

			case BIRTH_FINAL_CONFIRM:
			{
				if (prev < BIRTH_FINAL_CONFIRM)
					display_player(0);

				next = get_confirm_command();
				if (next == BIRTH_BACK)
					next = BIRTH_HISTORY_CHOICE;

				if (next == BIRTH_COMPLETE)
					done = TRUE;

				break;
			}

			default:
			{
				/* Remove dodgy compiler warning, */
			}
		}

		prev = current_stage;
		current_stage = next;

		/* Execute whatever commands have been sent */
		cmdq_execute(CMD_BIRTH);
	}

	return 0;
}