Пример #1
0
/*
 * Place the cursor at the collect position for visual mode
 */
static void place_visual_list_cursor(int col, int row, byte a, byte c,
				     byte attr_top, byte char_left)
{
    int i = a - attr_top;
    int j = c - char_left;

    int x = col + actual_width(j);
    int y = row + actual_height(i);

    /* Place the cursor */
    Term_gotoxy(x, y);
}
Пример #2
0
/**
 * Show quiver missiles in full inventory
 */
static void item_menu_browser(int oid, void *data, const region *local_area)
{
	char tmp_val[80];
	int count, j, i = num_obj;
	int quiver_slots = (player->upkeep->quiver_cnt + z_info->quiver_slot_size - 1)
		/ z_info->quiver_slot_size;

	/* Set up to output below the menu */
	text_out_hook = text_out_to_screen;
	text_out_wrap = 0;
	text_out_indent = local_area->col - 1;
	text_out_pad = 1;
	prt("", local_area->row + local_area->page_rows, MAX(0, local_area->col - 1));
	Term_gotoxy(local_area->col, local_area->row + local_area->page_rows);

	/* If we're printing pack slots the quiver takes up */
	if (olist_mode & OLIST_QUIVER && player->upkeep->command_wrk == USE_INVEN) {
		/* Quiver may take multiple lines */
		for (j = 0; j < quiver_slots; j++, i++) {
			const char *fmt = "in Quiver: %d missile%s\n";
			char letter = I2A(i);

			/* Number of missiles in this "slot" */
			if (j == quiver_slots - 1)
				count = player->upkeep->quiver_cnt - (z_info->quiver_slot_size *
													  (quiver_slots - 1));
			else
				count = z_info->quiver_slot_size;

			/* Print the (disabled) label */
			strnfmt(tmp_val, sizeof(tmp_val), "%c) ", letter);
			text_out_c(COLOUR_SLATE, tmp_val, local_area->row + i, local_area->col);

			/* Print the count */
			strnfmt(tmp_val, sizeof(tmp_val), fmt, count,
					count == 1 ? "" : "s");
			text_out_c(COLOUR_L_UMBER, tmp_val, local_area->row + i, local_area->col + 3);
		}
	}

	/* Always print a blank line */
	prt("", local_area->row + i, MAX(0, local_area->col - 1));

	/* Blank out whole tiles */
	while ((tile_height > 1) && ((local_area->row + i) % tile_height != 0)) {
		i++;
		prt("", local_area->row + i, MAX(0, local_area->col - 1));
	}

	text_out_pad = 0;
	text_out_indent = 0;
}
Пример #3
0
/*
 * Move to a location and, using an attr, add a char
 */
errr Term_putch(int x, int y, byte a, char c)
{
	errr res;

	/* Move first */
	if ((res = Term_gotoxy(x, y)) != 0) return (res);

	/* Then add the char */
	if ((res = Term_addch(a, c)) != 0) return (res);

	/* Success */
	return (0);
}
Пример #4
0
/*
 * Move to a location and, using an attr, add a string
 */
errr Term_putstr(int x, int y, int n, byte a, cptr s)
{
	errr res;

	/* Move first */
	if ((res = Term_gotoxy(x, y)) != 0) return (res);

	/* Then add the string */
	if ((res = Term_addstr(n, a, s)) != 0) return (res);

	/* Success */
	return (0);
}
Пример #5
0
static enum birth_stage point_based_command(void)
{
	static int stat = 0;
	struct keypress ch;
	enum birth_stage next = BIRTH_POINTBASED;

	/* Place cursor just after cost of current stat */
	Term_gotoxy(COSTS_COL + 4, COSTS_ROW + stat);

	/* Get key */
	ch = inkey();
	
	if (ch.code == KTRL('X')) {
		quit(NULL);
	} else if (ch.code == ESCAPE) {
		/* Go back a step, or back to the start of this step */
		next = BIRTH_BACK;
	} else if (ch.code == 'r' || ch.code == 'R') {
		cmdq_push(CMD_RESET_STATS);
		cmd_set_arg_choice(cmdq_peek(), "choice", FALSE);
	} else if (ch.code == KC_ENTER) {
		/* Done */
		next = BIRTH_NAME_CHOICE;
	} else {
		int dir = target_dir(ch);

		/* Prev stat, looping round to the bottom when going off the top */
		if (dir == 8)
			stat = (stat + STAT_MAX - 1) % STAT_MAX;
		
		/* Next stat, looping round to the top when going off the bottom */
		if (dir == 2)
			stat = (stat + 1) % STAT_MAX;
		
		/* Decrease stat (if possible) */
		if (dir == 4) {
			cmdq_push(CMD_SELL_STAT);
			cmd_set_arg_choice(cmdq_peek(), "choice", stat);
		}
		
		/* Increase stat (if possible) */
		if (dir == 6) {
			cmdq_push(CMD_BUY_STAT);
			cmd_set_arg_choice(cmdq_peek(), "choice", stat);
		}
	}

	return next;
}
Пример #6
0
/*
 * Display a "small-scale" map of the dungeon.
 *
 * Note that the "player" is always displayed on the map.
 */
void do_cmd_view_map(void)
{
	int cy, cx;
	byte w, h;
	const char *prompt = "Hit any key to continue";
	if (Term->view_map_hook) {
		(*(Term->view_map_hook))(Term);
		return;
	}
	/* Save screen */
	screen_save();

	/* Note */
	prt("Please wait...", 0, 0);

	/* Flush */
	Term_fresh();

	/* Clear the screen */
	Term_clear();

	/* store the tile multipliers */
	w = tile_width;
	h = tile_height;
	tile_width = 1;
	tile_height = 1;

	/* Display the map */
	display_map(&cy, &cx);

	/* Show the prompt */
	put_str(prompt, Term->hgt - 1, Term->wid / 2 - strlen(prompt) / 2);

	/* Highlight the player */
	Term_gotoxy(cx, cy);

	/* Get any key */
	(void)anykey();

	/* Restore the tile multipliers */
	tile_width = w;
	tile_height = h;

	/* Load screen */
	screen_load();
}
Пример #7
0
/**
 * Show spell long description when browsing
 */
static void curse_menu_browser(int oid, void *data, const region *loc)
{
	int *choice = data;

	/* Redirect output to the screen */
	text_out_hook = text_out_to_screen;
	text_out_wrap = 0;
	text_out_indent = loc->col - 1;
	text_out_pad = 1;

	Term_gotoxy(loc->col, loc->row + loc->page_rows);
	text_out("\n%s\n", curses[choice[oid]].desc);

	/* XXX */
	text_out_pad = 0;
	text_out_indent = 0;
}
Пример #8
0
/* Show the birth instructions on an otherwise blank screen */	
static void print_menu_instructions(void)
{
	/* Clear screen */
	Term_clear();
	
	/* Output to the screen */
	text_out_hook = text_out_to_screen;
	
	/* Indent output */
	text_out_indent = QUESTION_COL;
	Term_gotoxy(QUESTION_COL, HEADER_ROW);
	
	/* Display some helpful information */
	text_out_e(BIRTH_MENU_HELPTEXT);
	
	/* Reset text_out() indentation */
	text_out_indent = 0;
}
Пример #9
0
/*
 * Hack -- Display the "name" and "attr/chars" of a monster race
 */
static void roff_top(int r_idx)
{
	monster_race *r_ptr = &r_info[r_idx];

	byte a1, a2;
	char c1, c2;


	/* Get the chars */
	c1 = r_ptr->d_char;
	c2 = r_ptr->x_char;

	/* Get the attrs */
	a1 = r_ptr->d_attr;
	a2 = r_ptr->x_attr;


	/* Clear the top line */
	Term_erase(0, 0, 255);

	/* Reset the cursor */
	Term_gotoxy(0, 0);

	/* A title (use "The" for non-uniques) */
	if (!(r_ptr->flags1 & RF1_UNIQUE))
	{
		Term_addstr(-1, TERM_WHITE, "The ");
	}

	/* Dump the name */
	Term_addstr(-1, TERM_WHITE, (r_name + r_ptr->name));

	/* Append the "standard" attr/char info */
	Term_addstr(-1, TERM_WHITE, " ('");
	Term_addch(a1, c1);
	Term_addstr(-1, TERM_WHITE, "')");

	/* Append the "optional" attr/char info */
	Term_addstr(-1, TERM_WHITE, "/('");
	Term_addch(a2, c2);
	if (use_bigtile && (a2 & 0x80)) Term_addch(255, -1);
	Term_addstr(-1, TERM_WHITE, "'):");

}
Пример #10
0
/*
 * Display glyph and colours
 */
static void display_glyphs(int col, int row, int height, int width, byte a,
						   wchar_t c)
{
	int i;
	int x, y;

	/* Clear the display lines */
	for (i = 0; i < height; i++)
		Term_erase(col, row + i, width);

	/* Prompt */
	prt("Choose colour:", row + height / 2, col);
	Term_locate(&x, &y);
	for (i = 0; i < MAX_COLORS; i++)
		big_pad(x + i, y, i, c);

	/* Place the cursor */
	Term_gotoxy(x + a, y);
}
Пример #11
0
/**
 * Move the cursor to a given map location.
 */
static void move_cursor_relative_map(int y, int x)
{
	int ky, kx;

	term *old;

	int j;

	/* Scan windows */
	for (j = 0; j < ANGBAND_TERM_MAX; j++) {
		term *t = angband_term[j];

		/* No window */
		if (!t) continue;

		/* No relevant flags */
		if (!(window_flag[j] & (PW_MAPS))) continue;

		/* Location relative to panel */
		ky = y - t->offset_y;

		if (tile_height > 1)
			ky = tile_height * ky;

		/* Verify location */
		if ((ky < 0) || (ky >= t->hgt)) continue;

		/* Location relative to panel */
		kx = x - t->offset_x;

		if (tile_width > 1)
			kx = tile_width * kx;

		/* Verify location */
		if ((kx < 0) || (kx >= t->wid)) continue;

		/* Go there */
		old = Term;
		Term_activate(t);
		(void)Term_gotoxy(kx, ky);
		Term_activate(old);
	}
}
Пример #12
0
/**
 * Show spell long description when browsing
 */
static void  gain_spec_menu_browser(int oid, void *data, const region *loc)
{
    struct spec_menu_data *d = data;
    
    /* Redirect output to the screen */
    text_out_hook = text_out_to_screen;
    text_out_wrap = 0;
    text_out_indent = loc->col - 1;
    text_out_pad = 1;
    
    
    clear_from(loc->row + loc->page_rows);
    Term_gotoxy(loc->col, loc->row + loc->page_rows);
    text_out_to_screen(TERM_DEEP_L_BLUE, (char *) abilities[d->specialties[oid]].desc);
    
    /* XXX */
    text_out_pad = 0;
    text_out_indent = 0;
}
Пример #13
0
/**
 * Show spell long description when browsing
 */
static void spell_menu_browser(int oid, void *data, const region * loc)
{
	struct spell_menu_data *d = data;
	int spell = d->spells[oid];
	const magic_type *s_ptr = &mp_ptr->info[spell];

	/* Redirect output to the screen */
	text_out_hook = text_out_to_screen;
	text_out_wrap = 0;
	text_out_indent = loc->col - 1;
	text_out_pad = 1;

	Term_gotoxy(loc->col, loc->row + loc->page_rows);
	text_out_c(TERM_DEEP_L_BLUE,
			   format("\n%s\n", s_info[s_ptr->index].text));

	/* XXX */
	text_out_pad = 0;
	text_out_indent = 0;
}
Пример #14
0
/**
 * Show spell long description when browsing
 */
static void curse_menu_browser(int oid, void *data, const region *loc)
{
	struct curse_menu_data *choice = data;
	char buf[80];

	/* Redirect output to the screen */
	text_out_hook = text_out_to_screen;
	text_out_wrap = 0;
	text_out_indent = loc->col - 1;
	text_out_pad = 1;

	Term_gotoxy(loc->col, loc->row + loc->page_rows);
	my_strcpy(buf, curses[choice[oid].index].desc, sizeof(buf));
	my_strcap(buf);
	text_out(" %s.\n", buf);

	/* XXX */
	text_out_pad = 0;
	text_out_indent = 0;
}
Пример #15
0
/**
 * Show spell long description when browsing
 */
static void spell_menu_browser(int oid, void *data, const region *loc)
{
	struct spell_menu_data *d = data;
	int spell_index = d->spells[oid];

	if (d->show_description) {
		/* Redirect output to the screen */
		text_out_hook = text_out_to_screen;
		text_out_wrap = 0;
		text_out_indent = loc->col - 1;
		text_out_pad = 1;

		Term_gotoxy(loc->col, loc->row + loc->page_rows);
		text_out("\n%s\n", spell_by_index(spell_index)->text);

		/* XXX */
		text_out_pad = 0;
		text_out_indent = 0;
	}
}
Пример #16
0
/**
 * Show specialty long description when browsing
 */
static void view_spec_menu_browser(int oid, void *data, const region *loc)
{
	ability *choices = data;

	/* Redirect output to the screen */
	text_out_hook = text_out_to_screen;
	text_out_wrap = 0;
	text_out_indent = loc->col - 1;
	text_out_pad = 1;

	clear_from(loc->row + loc->page_rows);
	Term_gotoxy(loc->col, loc->row + loc->page_rows);
	if (choices[oid].index == PF_MAX)
	    text_out_c(TERM_L_BLUE, "\n%s\n", race_other_desc);
	else
	    text_out_c(TERM_L_BLUE, "\n%s\n", (char *)choices[oid].desc);

	/* XXX */
	text_out_pad = 0;
	text_out_indent = 0;
}
Пример #17
0
/**
 * Show quiver missiles in full inventory
 */
static void item_menu_browser(int oid, void *data, const region *area)
{
	char tmp_val[80];
	int count, j, i = num_obj;
	int quiver_slots = (player->upkeep->quiver_cnt + z_info->stack_size - 1)
		/ z_info->stack_size;

	/* Set up to output below the menu */
	text_out_hook = text_out_to_screen;
	text_out_wrap = 0;
	text_out_indent = area->col - 1;
	text_out_pad = 1;
	prt("", area->row + area->page_rows, MAX(0, area->col - 1));
	Term_gotoxy(area->col, area->row + area->page_rows);

	/* Quiver may take multiple lines */
	for (j = 0; j < quiver_slots; j++, i++) {
		const char *fmt = "in Quiver: %d missile%s\n";
		char letter = I2A(i);

		/* Number of missiles in this "slot" */
		if (j == quiver_slots - 1)
			count = player->upkeep->quiver_cnt - (z_info->stack_size *
													  (quiver_slots - 1));
		else
			count = z_info->stack_size;

		/* Print the (disabled) label */
		strnfmt(tmp_val, sizeof(tmp_val), "%c) ", letter);
		text_out_c(COLOUR_SLATE, tmp_val, area->row + i, area->col);

		/* Print the count */
		strnfmt(tmp_val, sizeof(tmp_val), fmt, count,
				count == 1 ? "" : "s");
		text_out_c(COLOUR_L_UMBER, tmp_val, area->row + i, area->col + 3);
	}

	text_out_pad = 0;
	text_out_indent = 0;
}
Пример #18
0
static void mon_lore(int oid)
{
	/* Update the monster recall window */
	monster_race_track(default_join[oid].oid);
	handle_stuff(p_ptr);

	/* Save the screen */
	screen_save();

	/* Describe */
	text_out_hook = text_out_to_screen;

	/* Recall monster */
	roff_top(default_join[oid].oid);
	Term_gotoxy(0, 2);
	describe_monster(default_join[oid].oid, FALSE);

	text_out_c(TERM_L_BLUE, "\n[Press any key to continue]\n");
	(void) anykey();

	/* Load the screen */
	screen_load();
}
Пример #19
0
static void class_help(int i, void *db, const region *l)
{
	int j;

	/* Output to the screen */
	text_out_hook = text_out_to_screen;

	/* Indent output */
	text_out_indent = CLASS_AUX_COL;
	Term_gotoxy(CLASS_AUX_COL, TABLE_ROW);

	for (j = 0; j < A_MAX; j++)
	{
		text_out_e("%s%+d%+8d%+8d\n", stat_names_reduced[j], p_info[p_ptr->prace].r_adj[j], c_info[i].c_adj[j],
					  (p_info[p_ptr->prace].r_adj[j] + c_info[i].c_adj[j]));
	}

	text_out_e("Hit die: %6d%8d\n", c_info[i].c_mhp, p_info[p_ptr->prace].r_mhp + c_info[i].c_mhp);
	text_out_e("Experience: %3d%%%7d%%", c_info[i].c_exp, + (p_info[p_ptr->prace].r_exp + c_info[i].c_exp));

	/* Reset text_out() indentation */
	text_out_indent = 0;
}
Пример #20
0
static void race_help(int i, void *db, const region *l)
{
	int j;

	/* Output to the screen */
	text_out_hook = text_out_to_screen;

	/* Indent output */
	text_out_indent = RACE_AUX_COL;
	Term_gotoxy(RACE_AUX_COL, TABLE_ROW);

	for (j = 0; j < A_MAX; j++)
	{
		text_out_e("%s%+d\n", stat_names_reduced[j], p_info[i].r_adj[j]);
	}

	text_out_e("Hit die: %d\n", p_info[i].r_mhp);
	text_out_e("Experience: %d%%\n", p_info[i].r_exp);
	text_out_e("Infravision: %d ft", p_info[i].infra * 10);

	/* Reset text_out() indentation */
	text_out_indent = 0;
}
Пример #21
0
/*
 * Hack -- describe the given monster race in the current "term" window
 */
void display_roff(int r_idx)
{
    int y;

    /* Erase the window */
    for (y = 0; y < Term->hgt; y++)
    {
        /* Erase the line */
        Term_erase(0, y, 255);
    }

    /* Begin recall */
    Term_gotoxy(0, 1);

    /* Output to the screen */
    text_out_hook = text_out_to_screen;

    /* Recall monster */
    describe_monster(r_idx, FALSE);

    /* Describe monster */
    roff_top(r_idx);
}
Пример #22
0
void display_player_xtra_info(void)
{
	size_t i;
	for (i = 0; i < N_ELEMENTS(panels); i++) {
		struct panel *p = panels[i].panel();
		display_panel(p, panels[i].align_left, &panels[i].bounds);
		panel_free(p);
	}

	/* Indent output by 1 character, and wrap at column 72 */
	text_out_wrap = 72;
	text_out_indent = 1;

	/* History */
	Term_gotoxy(text_out_indent, 19);
	text_out_to_screen(COLOUR_WHITE, player->history);

	/* Reset text_out() vars */
	text_out_wrap = 0;
	text_out_indent = 0;

	return;
}
Пример #23
0
static void display_columns(menu_type *menu, int cursor, int *top, rect_region *loc)
{
	int c, r;
	int w, h;
	int n = menu->filter_list ? menu->filter_count : menu->count;
	int col = loc->col;
	int row = loc->row;
	int rows_per_page = loc->page_rows;
	int cols = (n + rows_per_page - 1) / rows_per_page;
	int colw = 23;

	Term_get_size(&w, &h);

	if (menu->column_width > 0) {
		colw = menu->column_width;
	} else
	if ((colw * cols) > (w - col))
		colw = (w - col) / cols;

	for (c = 0; c < cols; c++)
	{
		for (r = 0; r < rows_per_page; r++)
		{
			int pos = c * rows_per_page + r;
			bool is_cursor = (pos == cursor);

			if (pos < n)
				display_menu_row(menu, pos, 0, is_cursor,
						row + r, col + c * colw, colw);
		}
	}

	if (menu->cursor >= 0)
		Term_gotoxy(col + (cursor / rows_per_page) * colw,
				row + (cursor % rows_per_page) - *top);
}
Пример #24
0
/* Display current view of a skin */
static void display_scrolling(menu_type *menu, int cursor, int *top, rect_region *loc)
{
	int col = loc->col;
	int row = loc->row;
	int rows_per_page = loc->page_rows;
	int n = menu->filter_list ? menu->filter_count : menu->count;
	int i;

	/* Keep a certain distance from the top when possible */
	if ((cursor <= *top) && (*top > 0))
		*top = cursor - 1;

	/* Keep a certain distance from the bottom when possible */
	if (cursor >= *top + (rows_per_page - 1))
		*top = cursor - (rows_per_page - 1) + 1;

	/* Limit the top to legal places */
	*top = MIN(*top, n - rows_per_page);
	*top = MAX(*top, 0);

	for (i = 0; i < rows_per_page; i++)
	{
		/* Blank all lines */
		Term_erase(col, row + i, loc->width);
		if (i < n)
		{
			/* Redraw the line if it's within the number of menu items */
			bool is_curs = (i == cursor - *top);
			display_menu_row(menu, i + *top, *top, is_curs, row + i, col,
							loc->width);
		}
	}

	if (menu->cursor >= 0)
		Term_gotoxy(col, row + cursor - *top);
}
Пример #25
0
/*
 * Hack -- describe the given monster race in the current "term" window
 */
void display_roff(const int r_idx, const monster_lore *l_ptr)
{
	monster_race *r_ptr = &r_info[r_idx];
	int y;

	/* Erase the window */
	for (y = 0; y < Term->hgt; y++)
	{
		/* Erase the line */
		Term_erase(0, y, 255);
	}

	/* Begin recall */
	Term_gotoxy(0, 1);

	/* Output to the screen */
	text_out_hook = text_out_to_screen;

	/* Recall monster */
	describe_monster_race(r_ptr, l_ptr, FALSE);

	/* Describe monster */
	roff_top(r_idx, 0);
}
Пример #26
0
/*
 *  Do glyph picker command -- Change glyphs
 */
static bool glyph_command(ui_event ke, bool * glyph_picker_ptr,
						  int height, int width, byte * cur_attr_ptr,
						  wchar_t * cur_char_ptr, int col, int row)
{
	static byte attr_old = 0;
	static char char_old = 0;

	/* Get mouse movement */
	if (ke.type == EVT_MOUSE) {
		byte a = *cur_attr_ptr;

		int mx = logical_width(ke.mouse.x - col);

		if (ke.mouse.y != row + height / 2)
			return FALSE;

		if ((mx >= 0) && (mx < MAX_COLORS) && (ke.mouse.button == 1)) {
			/* Set the visual */
			*cur_attr_ptr = a = mx - 14;

			/* Accept change */
			remove_tiles(col, row, glyph_picker_ptr, width, height);

			return TRUE;
		}

		else {
			return FALSE;
		}
	}

	if (ke.type != EVT_KBRD)
		return FALSE;


	switch (ke.key.code) {
	case ESCAPE:
		{
			if (*glyph_picker_ptr) {
				/* Cancel change */
				*cur_attr_ptr = attr_old;
				*cur_char_ptr = char_old;
				remove_tiles(col, row, glyph_picker_ptr, width, height);

				return TRUE;
			}

			break;
		}

	case KC_ENTER:
		{
			if (*glyph_picker_ptr) {
				/* Accept change */
				remove_tiles(col, row, glyph_picker_ptr, width, height);
				return TRUE;
			}

			break;
		}

	case 'V':
	case 'v':
		{
			if (!*glyph_picker_ptr) {
				*glyph_picker_ptr = TRUE;

				attr_old = *cur_attr_ptr;
				char_old = *cur_char_ptr;
			} else {
				/* Cancel change */
				*cur_attr_ptr = attr_old;
				*cur_char_ptr = char_old;
				remove_tiles(col, row, glyph_picker_ptr, width, height);
			}

			return TRUE;
		}

	case 'i':
	case 'I':
		{
			if (*glyph_picker_ptr) {
				char code_point[6];
				bool res = FALSE;

				/* Ask the user for a code point */
				Term_gotoxy(col, row + height / 2 + 2);
				res = get_string("(up to 5 hex digits):", code_point, 5);

				/* Process input */
				if (res) {
					unsigned long int point =
						strtoul(code_point, (char **) NULL, 16);
					*cur_char_ptr = (wchar_t) point;
					return TRUE;
				}
			}

			break;


		}

	default:
		{
			int d = target_dir(ke.key);
			byte a = *cur_attr_ptr;

			if (!*glyph_picker_ptr)
				break;

			/* Horizontal only */
			if (ddy[d] != 0)
				break;

			/* Horizontal movement */
			if (ddx[d] != 0) {
				a += ddx[d] + BASIC_COLORS;
				a = a % BASIC_COLORS;
				*cur_attr_ptr = a;
			}


			/* We need to always eat the input even if it is clipped,
			 * otherwise it will be interpreted as a change object
			 * selection command with messy results.
			 */
			return TRUE;
		}
	}


	/* Glyph picker command is not used */
	return FALSE;
}
Пример #27
0
/*
 * Print some (colored) text to the screen at the current cursor position,
 * automatically "wrapping" existing text (at spaces) when necessary to
 * avoid placing any text into the last column, and clearing every line
 * before placing any text in that line.  Also, allow "newline" to force
 * a "wrap" to the next line.  Advance the cursor as needed so sequential
 * calls to this function will work correctly.
 *
 * Once this function has been called, the cursor should not be moved
 * until all the related "text_out()" calls to the window are complete.
 *
 * This function will correctly handle any width up to the maximum legal
 * value of 256, though it works best for a standard 80 character width.
 */
void text_out_to_screen(byte a, const char *str)
{
	int x, y;

	int wid, h;

	int wrap;

	const wchar_t *s;
	wchar_t buf[1024];

	/* Obtain the size */
	(void)Term_get_size(&wid, &h);

	/* Obtain the cursor */
	(void)Term_locate(&x, &y);

	/* Copy to a rewriteable string */
	Term_mbstowcs(buf, str, 1024);
	
	/* Use special wrapping boundary? */
	if ((text_out_wrap > 0) && (text_out_wrap < wid))
		wrap = text_out_wrap;
	else
		wrap = wid;

	/* Process the string */
	for (s = buf; *s; s++)
	{
		wchar_t ch;

		/* Force wrap */
		if (*s == L'\n')
		{
			/* Wrap */
			x = text_out_indent;
			y++;

			/* Clear line, move cursor */
			Term_erase(x, y, 255);

			x += text_out_pad;
			Term_gotoxy(x, y);

			continue;
		}

		/* Clean up the char */
		ch = (iswprint(*s) ? *s : L' ');

		/* Wrap words as needed */
		if ((x >= wrap - 1) && (ch != L' '))
		{
			int i, n = 0;

			byte av[256];
			wchar_t cv[256];

			/* Wrap word */
			if (x < wrap)
			{
				/* Scan existing text */
				for (i = wrap - 2; i >= 0; i--)
				{
					/* Grab existing attr/char */
					Term_what(i, y, &av[i], &cv[i]);

					/* Break on space */
					if (cv[i] == L' ') break;

					/* Track current word */
					n = i;
				}
			}

			/* Special case */
			if (n == 0) n = wrap;

			/* Clear line */
			Term_erase(n, y, 255);

			/* Wrap */
			x = text_out_indent;
			y++;

			/* Clear line, move cursor */
			Term_erase(x, y, 255);

			x += text_out_pad;
			Term_gotoxy(x, y);

			/* Wrap the word (if any) */
			for (i = n; i < wrap - 1; i++)
			{
				/* Dump */
				Term_addch(av[i], cv[i]);

				/* Advance (no wrap) */
				if (++x > wrap) x = wrap;
			}
		}

		/* Dump */
		Term_addch(a, ch);

		/* Advance */
		if (++x > wrap) x = wrap;
	}
}
Пример #28
0
/*
 * Get some input at the cursor location.
 *
 * The buffer is assumed to have been initialized to a default string.
 * Note that this string is often "empty" (see below).
 *
 * The default buffer is displayed in yellow until cleared, which happens
 * on the first keypress, unless that keypress is Return.
 *
 * Normal chars clear the default and append the char.
 * Backspace clears the default or deletes the final char.
 * Return accepts the current buffer contents and returns TRUE.
 * Escape clears the buffer and the window and returns FALSE.
 *
 * Note that 'len' refers to the size of the buffer.  The maximum length
 * of the input is 'len-1'.
 *
 * 'keypress_h' is a pointer to a function to handle keypresses, altering
 * the input buffer, cursor position and suchlike as required.  See
 * 'askfor_aux_keypress' (the default handler if you supply NULL for
 * 'keypress_h') for an example.
 */
bool askfor_aux(char *buf, size_t len, bool (*keypress_h)(char *, size_t, size_t *, size_t *, struct keypress, bool))
{
	int y, x;

	size_t k = 0;		/* Cursor position */
	size_t nul = 0;		/* Position of the null byte in the string */

	struct keypress ch = { 0 };

	bool done = FALSE;
	bool firsttime = TRUE;

	if (keypress_h == NULL)
	{
		keypress_h = askfor_aux_keypress;
	}

	/* Locate the cursor */
	Term_locate(&x, &y);


	/* Paranoia */
	if ((x < 0) || (x >= 80)) x = 0;


	/* Restrict the length */
	if (x + len > 80) len = 80 - x;

	/* Truncate the default entry */
	buf[len-1] = '\0';

	/* Get the position of the null byte */
	nul = strlen(buf);

	/* Display the default answer */
	Term_erase(x, y, (int)len);
	Term_putstr(x, y, -1, TERM_YELLOW, buf);

	/* Process input */
	while (!done)
	{
		/* Place cursor */
		Term_gotoxy(x + k, y);

		/* Get a key */
		ch = inkey();

		/* Let the keypress handler deal with the keypress */
		done = keypress_h(buf, len, &k, &nul, ch, firsttime);

		/* Update the entry */
		Term_erase(x, y, (int)len);
		Term_putstr(x, y, -1, TERM_WHITE, buf);

		/* Not the first time round anymore */
		firsttime = FALSE;
	}

	/* Done */
	return (ch.code != ESCAPE);
}
Пример #29
0
static void display_resistance_panel(const struct player_flag_record *rec,
									size_t size, const region *bounds) 
{
	size_t i;
	int j;
	int col = bounds->col;
	int row = bounds->row;
	int res_cols = 5 + 2 + player->body.count;

	Term_putstr(col, row++, res_cols, COLOUR_WHITE, "      abcdefghijkl@");
	for (i = 0; i < size - 3; i++, row++) {
		byte name_attr = COLOUR_WHITE;
		Term_gotoxy(col + 6, row);

		/* Repeated extraction of flags is inefficient but more natural */
		for (j = 0; j <= player->body.count; j++) {
			bitflag f[OF_SIZE];
			byte attr = COLOUR_WHITE | (j % 2) * 8; /* alternating columns */
			char sym = '.';
			bool res = false, imm = false, vul = false, rune = false;
			bool timed = false;
			bool known = false;

			/* Object or player info? */
			if (j < player->body.count) {
				int index = 0;
				struct object *obj = slot_object(player, j);
				struct curse_data *curse = obj ? obj->curses : NULL;

				while (obj) {
					/* Wipe flagset */
					of_wipe(f);

					/* Get known properties */
					object_flags_known(obj, f);
					if (rec[i].element != -1) {
						known = object_element_is_known(obj, rec[i].element);
					} else if (rec[i].flag != -1) {
						known = object_flag_is_known(obj, rec[i].flag);
					} else {
						known = true;
					}

					/* Get resistance, immunity and vulnerability info */
					if (rec[i].mod != -1) {
						if (obj->modifiers[rec[i].mod] != 0) {
							res = true;
						}
						rune = (player->obj_k->modifiers[rec[i].mod] == 1);
					} else if (rec[i].flag != -1) {
						if (of_has(f, rec[i].flag)) {
							res = true;
						}
						rune = of_has(player->obj_k->flags, rec[i].flag);
					} else if (rec[i].element != -1) {
						if (known) {
							if (obj->el_info[rec[i].element].res_level == 3) {
								imm = true;
							}
							if (obj->el_info[rec[i].element].res_level == 1) {
								res = true;
							}
							if (obj->el_info[rec[i].element].res_level == -1) {
								vul = true;
							}
						}
						rune = (player->obj_k->el_info[rec[i].element].res_level == 1);
					}

					/* Move to any unprocessed curse object */
					if (curse) {
						index++;
						obj = NULL;
						while (index < z_info->curse_max) {
							if (curse[index].power) {
								obj = curses[index].obj;
								break;
							} else {
								index++;
							}
						}
					} else {
						obj = NULL;
					}
				}
			} else {
				player_flags(player, f);
				known = true;

				/* Timed flags only in the player column */
				if (rec[i].tmd_flag >= 0) {
	 				timed = player->timed[rec[i].tmd_flag] ? true : false;
					/* There has to be one special case... */
					if ((rec[i].tmd_flag == TMD_AFRAID) &&
						(player->timed[TMD_TERROR]))
						timed = true;
				}

				/* Set which (if any) symbol and color are used */
				if (rec[i].mod != -1) {
					int k;

					/* Shape modifiers */
					for (k = 0; k < OBJ_MOD_MAX; k++) {
						res = (player->shape->modifiers[i] > 0);
						vul = (player->shape->modifiers[i] > 0);
					}

					/* Messy special cases */
					if (rec[i].mod == OBJ_MOD_INFRA)
						res |= (player->race->infra > 0);
					if (rec[i].mod == OBJ_MOD_TUNNEL)
						res |= (player->race->r_skills[SKILL_DIGGING] > 0);
				} else if (rec[i].flag != -1) {
					res = of_has(f, rec[i].flag);
					res |= (of_has(player->shape->flags, rec[i].flag) &&
							of_has(player->obj_k->flags, rec[i].flag));
				} else if (rec[i].element != -1) {
					int el = rec[i].element;
					imm = (player->race->el_info[el].res_level == 3) ||
						((player->shape->el_info[el].res_level == 3) &&
						 (player->obj_k->el_info[el].res_level));
					res = (player->race->el_info[el].res_level == 1) ||
						((player->shape->el_info[el].res_level == 1) &&
						 (player->obj_k->el_info[el].res_level));
					vul = (player->race->el_info[el].res_level == -1) ||
						((player->shape->el_info[el].res_level == -1) &&
						 (player->obj_k->el_info[el].res_level));
				}
			}

			/* Colour the name appropriately */
			if (imm) {
				name_attr = COLOUR_GREEN;
			} else if (res && (name_attr != COLOUR_GREEN)) {
				name_attr = COLOUR_L_BLUE;
			} else if (vul && (name_attr != COLOUR_GREEN)) {
				name_attr = COLOUR_RED;
			}

			/* Set the symbols and print them */
			if (vul) {
				sym = '-';
			} else if (imm) {
				sym = '*';
			} else if (res) {
				sym = '+';
			} else if (timed) {
				sym = '!';
				attr = COLOUR_L_GREEN;
			} else if ((j < player->body.count) && slot_object(player, j) &&
					   !known && !rune) {
				sym = '?';
			}

			Term_addch(attr, sym);
		}

		/* Check if the rune is known */
		if (((rec[i].mod >= 0) &&
			 (player->obj_k->modifiers[rec[i].mod] == 0))
			|| ((rec[i].flag >= 0) &&
				!of_has(player->obj_k->flags, rec[i].flag))
			|| ((rec[i].element >= 0) &&
				(player->obj_k->el_info[rec[i].element].res_level == 0))) {
			name_attr = COLOUR_SLATE;
		}

		Term_putstr(col, row, 6, name_attr, format("%5s:", rec[i].name));
	}
	Term_putstr(col, row++, res_cols, COLOUR_WHITE, "      abcdefghijkl@");

	/* Equippy */
	display_player_equippy(row++, col + 6);
}
Пример #30
0
static void display_resistance_panel(const struct player_flag_record *rec,
									size_t size, const region *bounds) 
{
	size_t i;
	int j;
	int col = bounds->col;
	int row = bounds->row;
	int res_cols = 5 + 2 + player->body.count;

	Term_putstr(col, row++, res_cols, COLOUR_WHITE, "      abcdefghijkl@");
	for (i = 0; i < size - 3; i++, row++) {
		byte name_attr = COLOUR_WHITE;
		Term_gotoxy(col + 6, row);

		/* Repeated extraction of flags is inefficient but more natural */
		for (j = 0; j <= player->body.count; j++) {
			struct object *obj;
			bitflag f[OF_SIZE];

			byte attr = COLOUR_WHITE | (j % 2) * 8; /* alternating columns */
			char sym = '.';

			bool res = false, imm = false, vul = false, rune = false;
			bool timed = false;
			bool known = false;

			/* Wipe flagset */
			of_wipe(f);

			/* Get the object or player info */
			obj = j < player->body.count ? slot_object(player, j) : NULL;
			if (j < player->body.count && obj) {
				/* Get known properties */
				object_flags_known(obj, f);
				if (rec[i].element != -1)
					known = object_element_is_known(obj, rec[i].element);
				else if (rec[i].flag != -1)
					known = object_flag_is_known(obj, rec[i].flag);
				else
					known = true;
			} else if (j == player->body.count) {
				player_flags(player, f);
				known = true;

				/* Timed flags only in the player column */
				if (rec[i].tmd_flag >= 0) {
	 				timed = player->timed[rec[i].tmd_flag] ? true : false;
					/* There has to be one special case... */
					if ((rec[i].tmd_flag == TMD_AFRAID) &&
						(player->timed[TMD_TERROR]))
						timed = true;
				}
			}

			/* Set which (if any) symbol and color are used */
			if (rec[i].mod != -1) {
				if (j != player->body.count)
					res = (obj && (obj->modifiers[rec[i].mod] != 0));
				else {
					/* Messy special cases */
					if (rec[i].mod == OBJ_MOD_INFRA)
						res = (player->race->infra > 0);
					if (rec[i].mod == OBJ_MOD_TUNNEL)
						res = (player->race->r_skills[SKILL_DIGGING] > 0);
				}
				rune = (player->obj_k->modifiers[rec[i].mod] == 1);
			} else if (rec[i].flag != -1) {
				res = of_has(f, rec[i].flag);
				rune = of_has(player->obj_k->flags, rec[i].flag);
			} else if (rec[i].element != -1) {
				if (j != player->body.count) {
					imm = obj && known &&
						(obj->el_info[rec[i].element].res_level == 3);
					res = obj && known &&
						(obj->el_info[rec[i].element].res_level == 1);
					vul = obj && known &&
						(obj->el_info[rec[i].element].res_level == -1);
				} else {
					imm = player->race->el_info[rec[i].element].res_level == 3;
					res = player->race->el_info[rec[i].element].res_level == 1;
					vul = player->race->el_info[rec[i].element].res_level == -1;
				}
				rune = (player->obj_k->el_info[rec[i].element].res_level == 1);
			}

			/* Set the symbols and print them */
			if (imm) name_attr = COLOUR_GREEN;
			else if (!rune) name_attr = COLOUR_SLATE;
			else if (res && (name_attr != COLOUR_GREEN))
				name_attr = COLOUR_L_BLUE;

			if (vul) sym = '-';
			else if (imm) sym = '*';
			else if (res) sym = '+';
			else if (timed) { sym = '!'; attr = COLOUR_L_GREEN; }
			else if ((j < player->body.count) && obj && !known && !rune)
				sym = '?';

			Term_addch(attr, sym);
		}
		Term_putstr(col, row, 6, name_attr, format("%5s:", rec[i].name));
	}
	Term_putstr(col, row++, res_cols, COLOUR_WHITE, "      abcdefghijkl@");

	/* Equippy */
	display_player_equippy(row++, col + 6);
}