Angband
Data Structures | Macros | Typedefs | Functions | Variables
ui-term.h File Reference

Copyright (c) 1997 Ben Harrison. More...

#include "h-basic.h"
#include "ui-event.h"

Go to the source code of this file.

Data Structures

struct  term_win
 
struct  term
 

Macros

#define ANGBAND_TERM_MAX   8
 

Available Constants

More...
 
#define SCREEN_ROWS   (Term->hgt - ROW_MAP - 1)
 Number of text rows in each map screen, regardless of tile size. More...
 
#define SCREEN_HGT   ((int) (SCREEN_ROWS / tile_height))
 Number of grids in each screen (vertically) More...
 
#define SCREEN_WID   ((int)((Term->wid - COL_MAP - 1) / tile_width))
 Number of grids in each screen (horizontally) More...
 
#define ROW_MAP   1
 
#define COL_MAP   13
 
#define TERM_XTRA_EVENT   1 /* Process some pending events */
 Definitions for the "actions" of "Term_xtra()". More...
 
#define TERM_XTRA_FLUSH   2 /* Flush all pending events */
 
#define TERM_XTRA_CLEAR   3 /* Clear the entire window */
 
#define TERM_XTRA_SHAPE   4 /* Set cursor shape (optional) */
 
#define TERM_XTRA_FROSH   5 /* Flush one row (optional) */
 
#define TERM_XTRA_FRESH   6 /* Flush all rows (optional) */
 
#define TERM_XTRA_NOISE   7 /* Make a noise (optional) */
 
#define TERM_XTRA_BORED   9 /* Handle stuff when bored (optional) */
 
#define TERM_XTRA_REACT   10 /* React to global changes (optional) */
 
#define TERM_XTRA_ALIVE   11 /* Change the "hard" level (optional) */
 
#define TERM_XTRA_LEVEL   12 /* Change the "soft" level (optional) */
 
#define TERM_XTRA_DELAY   13 /* Delay some milliseconds (optional) */
 
#define PW_INVEN   0x00000001L /* Display inven/equip */
 Bit flags for the "window_flag" variable. More...
 
#define PW_EQUIP   0x00000002L /* Display equip/inven */
 
#define PW_PLAYER_0   0x00000004L /* Display player (basic) */
 
#define PW_PLAYER_1   0x00000008L /* Display player (extra) */
 
#define PW_PLAYER_2   0x00000010L /* Display player (compact) */
 
#define PW_MAP   0x00000020L /* Display dungeon map */
 
#define PW_MESSAGE   0x00000040L /* Display messages */
 
#define PW_OVERHEAD   0x00000080L /* Display overhead view */
 
#define PW_MONSTER   0x00000100L /* Display monster recall */
 
#define PW_OBJECT   0x00000200L /* Display object recall */
 
#define PW_MONLIST   0x00000400L /* Display monster list */
 
#define PW_STATUS   0x00000800L /* Display status */
 
#define PW_ITEMLIST   0x00001000L /* Display item list */
 
#define PW_MAPS   (PW_MAP | PW_OVERHEAD)
 
#define PW_MAX_FLAGS   16
 
#define KEYLOG_SIZE   8
 sketchy key logging pt. More...
 
#define term_screen   (angband_term[0])
 Hack – The main "screen". More...
 

Typedefs

typedef struct term_win term_win
 A term_win is a "window" for a Term. More...
 
typedef struct term term
 An actual "term" structure. More...
 

Functions

errr Term_xtra (int n, int v)
 

Available Functions

More...
 
void Term_queue_char (term *t, int x, int y, int a, wchar_t c, int ta, wchar_t tc)
 

Efficient routines

More...
 
void Term_big_queue_char (term *t, int x, int y, int a, wchar_t c, int a1, wchar_t c1)
 Queue a large-sized tile. More...
 
void Term_queue_chars (int x, int y, int n, int a, const wchar_t *s)
 Mentally draw some attr/chars at a given location. More...
 
errr Term_fresh (void)
 Actually perform all requested changes to the window. More...
 
errr Term_set_cursor (bool v)
 

Output routines

More...
 
errr Term_gotoxy (int x, int y)
 Place the cursor at a given location. More...
 
errr Term_draw (int x, int y, int a, wchar_t c)
 At a given location, place an attr/char Do not change the cursor position No visual changes until "Term_fresh()". More...
 
errr Term_addch (int a, wchar_t c)
 Using the given attr, add the given char at the cursor. More...
 
errr Term_addstr (int n, int a, const char *s)
 At the current location, using an attr, add a string. More...
 
errr Term_putch (int x, int y, int a, wchar_t c)
 Move to a location and, using an attr, add a char. More...
 
void Term_big_putch (int x, int y, int a, wchar_t c)
 Move to a location and, using an attr, add a big tile. More...
 
errr Term_putstr (int x, int y, int n, int a, const char *s)
 Move to a location and, using an attr, add a string. More...
 
errr Term_erase (int x, int y, int n)
 Place cursor at (x,y), and clear the next "n" chars. More...
 
errr Term_clear (void)
 Clear the entire window, and move to the top left corner. More...
 
errr Term_redraw (void)
 Redraw (and refresh) the whole window. More...
 
errr Term_redraw_section (int x1, int y1, int x2, int y2)
 Redraw part of a window. More...
 
errr Term_mark (int x, int y)
 Mark a spot as needing refresh (see "Term_fresh") More...
 
errr Term_get_cursor (bool *v)
 

Access routines

More...
 
errr Term_get_size (int *w, int *h)
 Extract the current window size. More...
 
errr Term_locate (int *x, int *y)
 Extract the current cursor location. More...
 
errr Term_what (int x, int y, int *a, wchar_t *c)
 At a given location, determine the "current" attr and char Note that this refers to what will be on the window after the next call to "Term_fresh()". More...
 
errr Term_flush (void)
 

Input routines

More...
 
errr Term_mousepress (int x, int y, char button)
 Add a mouse event to the "queue". More...
 
errr Term_keypress (keycode_t k, byte mods)
 Add a keypress to the "queue". More...
 
errr Term_key_push (int k)
 Add a keypress to the FRONT of the "queue". More...
 
errr Term_event_push (const ui_event *ke)
 
errr Term_inkey (ui_event *ch, bool wait, bool take)
 Check for a pending keypress on the key queue. More...
 
errr Term_save (void)
 

Extra routines

More...
 
errr Term_load (void)
 Restore the "requested" contents (see above). More...
 
errr Term_resize (int w, int h)
 React to a new physical window size. More...
 
errr Term_activate (term *t)
 Activate a new Term (and deactivate the current Term) More...
 
errr term_nuke (term *t)
 Nuke a term. More...
 
errr term_init (term *t, int w, int h, int k)
 Initialize a term, using a window of the given size. More...
 
int big_pad (int col, int row, byte a, wchar_t c)
 Emit a 'graphical' symbol and a padding character if appropriate. More...
 

Variables

int log_i
 
int log_size
 
struct keypress keylog [KEYLOG_SIZE]
 
termTerm
 

Available Variables

More...
 
byte tile_width
 
byte tile_height
 
bool bigcurs
 Helper variables for large cursor. More...
 
bool smlcurs
 
termangband_term [ANGBAND_TERM_MAX]
 This file provides a generic, efficient, terminal window package, which can be used not only on standard terminal environments such as dumb terminals connected to a Unix box, but also in more modern "graphic" environments, such as the Macintosh or Unix/X11. More...
 
char angband_term_name [ANGBAND_TERM_MAX][16]
 The array[ANGBAND_TERM_MAX] of window names (modifiable?) More...
 
u32b window_flag [ANGBAND_TERM_MAX]
 

Detailed Description

Copyright (c) 1997 Ben Harrison.

This software may be copied and distributed for educational, research, and not for profit purposes provided that this copyright and statement are included in all such copies.

Macro Definition Documentation

◆ ANGBAND_TERM_MAX

#define ANGBAND_TERM_MAX   8

◆ COL_MAP

#define COL_MAP   13

◆ KEYLOG_SIZE

#define KEYLOG_SIZE   8

sketchy key logging pt.

1

Referenced by do_cmd_keylog(), and log_keypress().

◆ PW_EQUIP

#define PW_EQUIP   0x00000002L /* Display equip/inven */

◆ PW_INVEN

#define PW_INVEN   0x00000001L /* Display inven/equip */

Bit flags for the "window_flag" variable.

Referenced by subwindow_flag_changed(), textui_get_item(), textui_init(), and toggle_inven_equip().

◆ PW_ITEMLIST

#define PW_ITEMLIST   0x00001000L /* Display item list */

◆ PW_MAP

#define PW_MAP   0x00000020L /* Display dungeon map */

Referenced by subwindow_flag_changed().

◆ PW_MAPS

#define PW_MAPS   (PW_MAP | PW_OVERHEAD)

◆ PW_MAX_FLAGS

#define PW_MAX_FLAGS   16

Referenced by do_cmd_options_win().

◆ PW_MESSAGE

#define PW_MESSAGE   0x00000040L /* Display messages */

◆ PW_MONLIST

#define PW_MONLIST   0x00000400L /* Display monster list */

◆ PW_MONSTER

#define PW_MONSTER   0x00000100L /* Display monster recall */

◆ PW_OBJECT

#define PW_OBJECT   0x00000200L /* Display object recall */

◆ PW_OVERHEAD

#define PW_OVERHEAD   0x00000080L /* Display overhead view */

◆ PW_PLAYER_0

#define PW_PLAYER_0   0x00000004L /* Display player (basic) */

Referenced by subwindow_flag_changed().

◆ PW_PLAYER_1

#define PW_PLAYER_1   0x00000008L /* Display player (extra) */

Referenced by subwindow_flag_changed().

◆ PW_PLAYER_2

#define PW_PLAYER_2   0x00000010L /* Display player (compact) */

◆ PW_STATUS

#define PW_STATUS   0x00000800L /* Display status */

◆ ROW_MAP

#define ROW_MAP   1

◆ SCREEN_HGT

#define SCREEN_HGT   ((int) (SCREEN_ROWS / tile_height))

◆ SCREEN_ROWS

#define SCREEN_ROWS   (Term->hgt - ROW_MAP - 1)

Number of text rows in each map screen, regardless of tile size.

◆ SCREEN_WID

#define SCREEN_WID   ((int)((Term->wid - COL_MAP - 1) / tile_width))

◆ term_screen

#define term_screen   (angband_term[0])

Hack – The main "screen".

Referenced by inkey_ex(), textui_get_panel(), and textui_init().

◆ TERM_XTRA_ALIVE

#define TERM_XTRA_ALIVE   11 /* Change the "hard" level (optional) */

◆ TERM_XTRA_BORED

#define TERM_XTRA_BORED   9 /* Handle stuff when bored (optional) */

Referenced by Term_inkey(), and Term_xtra_nds().

◆ TERM_XTRA_CLEAR

#define TERM_XTRA_CLEAR   3 /* Clear the entire window */

Referenced by Term_fresh(), and Term_xtra_nds().

◆ TERM_XTRA_DELAY

#define TERM_XTRA_DELAY   13 /* Delay some milliseconds (optional) */

◆ TERM_XTRA_EVENT

#define TERM_XTRA_EVENT   1 /* Process some pending events */

Definitions for the "actions" of "Term_xtra()".

These values may be used as the first parameter of "Term_xtra()", with the second parameter depending on the "action" itself. Many of the actions shown below are optional on at least one platform.

The "TERM_XTRA_EVENT" action uses "v" to "wait" for an event The "TERM_XTRA_SHAPE" action uses "v" to "show" the cursor The "TERM_XTRA_FROSH" action uses "v" for the index of the row The "TERM_XTRA_ALIVE" action uses "v" to "activate" (or "close") The "TERM_XTRA_LEVEL" action uses "v" to "resume" (or "suspend") The "TERM_XTRA_DELAY" action uses "v" as a "millisecond" value

The other actions do not need a "v" code, so "zero" is used.

Referenced by Term_inkey(), and Term_xtra_nds().

◆ TERM_XTRA_FLUSH

#define TERM_XTRA_FLUSH   2 /* Flush all pending events */

Referenced by Term_flush(), and Term_xtra_nds().

◆ TERM_XTRA_FRESH

#define TERM_XTRA_FRESH   6 /* Flush all rows (optional) */

Referenced by Term_fresh(), and Term_xtra_nds().

◆ TERM_XTRA_FROSH

#define TERM_XTRA_FROSH   5 /* Flush one row (optional) */

Referenced by Term_fresh(), and Term_xtra_nds().

◆ TERM_XTRA_LEVEL

#define TERM_XTRA_LEVEL   12 /* Change the "soft" level (optional) */

Referenced by Term_activate(), and Term_xtra_nds().

◆ TERM_XTRA_NOISE

#define TERM_XTRA_NOISE   7 /* Make a noise (optional) */

◆ TERM_XTRA_REACT

#define TERM_XTRA_REACT   10 /* React to global changes (optional) */

◆ TERM_XTRA_SHAPE

#define TERM_XTRA_SHAPE   4 /* Set cursor shape (optional) */

Referenced by Term_fresh(), and Term_xtra_nds().

Typedef Documentation

◆ term

typedef struct term term

An actual "term" structure.

  • Extra "user" info (used by application)
  • Extra "data" info (used by implementation)
  • Flag "user_flag" An extra "user" flag (used by application)
  • Flag "data_flag" An extra "data" flag (used by implementation)
  • Flag "active_flag" This "term" is "active"
  • Flag "mapped_flag" This "term" is "mapped"
  • Flag "total_erase" This "term" should be fully erased
  • Flag "fixed_shape" This "term" is not allowed to resize
  • Flag "icky_corner" This "term" has an "icky" corner grid
  • Flag "soft_cursor" This "term" uses a "software" cursor
  • Flag "always_pict" Use the "Term_pict()" routine for all text
  • Flag "higher_pict" Use the "Term_pict()" routine for special text
  • Flag "always_text" Use the "Term_text()" routine for invisible text
  • Flag "unused_flag" Reserved for future use
  • Flag "never_bored" Never call the "TERM_XTRA_BORED" action
  • Flag "never_frosh" Never call the "TERM_XTRA_FROSH" action
  • Value "attr_blank" Use this "attr" value for "blank" grids
  • Value "char_blank" Use this "char" value for "blank" grids
  • Flag "complex_input" Distinguish between Enter/^m/^j, Tab/^i, etc.
  • Ignore this pointer
  • Keypress Queue – various data
  • Keypress Queue – pending keys
  • Window Width (max 255)
  • Window Height (max 255)
  • Minimum modified row
  • Maximum modified row
  • Minimum modified column (per row)
  • Maximum modified column (per row)
  • Displayed screen image
  • Requested screen image
  • Temporary screen image
  • Memorized screen image
  • Hook for init-ing the term
  • Hook for nuke-ing the term
  • Hook for extra actions
  • Hook for placing the cursor
  • Hook for drawing some blank spaces
  • Hook for drawing a string of chars using an attr
  • Hook for drawing a sequence of special attr/char pairs

◆ term_win

typedef struct term_win term_win

A term_win is a "window" for a Term.

  • Cursor Useless/Visible codes
  • Cursor Location (see "Useless")
  • Array[h] – Access to the attribute array
  • Array[h] – Access to the character array
  • Array[h*w] – Attribute array
  • Array[h*w] – Character array
  • next screen saved
  • hook to be called on screen size change

Note that the attr/char pair at (x,y) is a[y][x]/c[y][x] and that the row of attr/chars at (0,y) is a[y]/c[y]

Function Documentation

◆ big_pad()

int big_pad ( int  col,
int  row,
byte  a,
wchar_t  c 
)

Emit a 'graphical' symbol and a padding character if appropriate.

References Term_big_putch(), Term_putch(), tile_height, and tile_width.

Referenced by display_feature(), display_glyphs(), display_monster(), display_object(), display_tiles(), display_trap(), and proj_display().

◆ Term_activate()

errr Term_activate ( term t)

Activate a new Term (and deactivate the current Term)

This function is extremely important, and also somewhat bizarre. It is the only function that should "modify" the value of "Term".

To "create" a valid "term", one should do "term_init(t)", then set the various flags and hooks, and then do "Term_activate(t)".

References term::active_flag, term::init_hook, term::mapped_flag, Term_xtra(), and TERM_XTRA_LEVEL.

Referenced by do_cmd_redraw(), flush_subwindow(), inkey_ex(), move_cursor_relative_map(), pre_turn_refresh(), subwindow_set_flags(), term_data_link(), textui_init(), toggle_inven_equip(), update_equip_subwindow(), update_inven_subwindow(), update_itemlist_subwindow(), update_messages_subwindow(), update_minimap_subwindow(), update_monlist_subwindow(), update_monster_subwindow(), update_object_subwindow(), update_player0_subwindow(), update_player1_subwindow(), and update_player_compact_subwindow().

◆ Term_addch()

errr Term_addch ( int  a,
wchar_t  c 
)

Using the given attr, add the given char at the cursor.

We return "-2" if the character is "illegal". XXX XXX

We return "-1" if the cursor is currently unusable.

We queue the given attr/char for display at the current cursor location, and advance the cursor to the right, marking it as unusable and returning "1" if it leaves the screen, and otherwise returning "0".

So when this function, or the following one, return a positive value, future calls to either function will return negative ones.

References term_win::cu, term_win::cx, term_win::cy, term::scr, Term_queue_char(), w, and term::wid.

Referenced by cmd_sub_entry(), display_resistance_panel(), draw_path(), load_path(), Term_putch(), and text_out_to_screen().

◆ Term_addstr()

errr Term_addstr ( int  n,
int  a,
const char *  buf 
)

At the current location, using an attr, add a string.

We also take a length "n", using negative values to imply the largest possible value, and then we use the minimum of this length and the "actual" length of the string as the actual number of characters to attempt to display, never displaying more characters than will actually fit, since we do NOT attempt to "wrap" the cursor at the screen edge.

We return "-1" if the cursor is currently unusable. We return "N" if we were "only" able to write "N" chars, even if all of the given characters fit on the screen, and mark the cursor as unusable for future attempts.

So when this function, or the preceding one, return a positive value, future calls to either function will return negative ones.

References term_win::cu, term_win::cx, term_win::cy, term::scr, Term_queue_chars(), text_mbstowcs(), w, and term::wid.

Referenced by c_prt(), cmd_sub_entry(), keymap_get_trigger(), Term_putstr(), and ui_keymap_query().

◆ Term_big_putch()

void Term_big_putch ( int  x,
int  y,
int  a,
wchar_t  c 
)

Move to a location and, using an attr, add a big tile.

References COLOUR_WHITE, Term_putch(), tile_height, tile_width, and void().

Referenced by big_pad(), and display_map().

◆ Term_big_queue_char()

void Term_big_queue_char ( term t,
int  x,
int  y,
int  a,
wchar_t  c,
int  a1,
wchar_t  c1 
)

◆ Term_clear()

errr Term_clear ( void  )

◆ Term_draw()

errr Term_draw ( int  x,
int  y,
int  a,
wchar_t  c 
)

At a given location, place an attr/char Do not change the cursor position No visual changes until "Term_fresh()".

References h, term::hgt, Term_queue_char(), w, and term::wid.

◆ Term_erase()

errr Term_erase ( int  x,
int  y,
int  n 
)

◆ Term_event_push()

errr Term_event_push ( const ui_event ke)

◆ Term_flush()

errr Term_flush ( void  )


Input routines

Flush and forget the input

References term::key_head, term::key_tail, Term_xtra(), and TERM_XTRA_FLUSH.

Referenced by do_cmd_redraw(), and inkey_ex().

◆ Term_fresh()

errr Term_fresh ( void  )

Actually perform all requested changes to the window.

If absolutely nothing has changed, not even temporarily, or if the current "Term" is not mapped, then this function will return 1 and do absolutely nothing.

Note that when "soft_cursor" is true, we erase the cursor (if needed) whenever anything has changed, and redraw it (if needed) after all of the screen updates are complete. This will induce a small amount of "cursor flicker" but only when the screen has been updated. If the screen is updated and then restored, you may still get this flicker.

When "soft_cursor" is not true, we make the cursor invisible before doing anything else if it is supposed to be invisible by the time we are done, and we make it visible after moving it to its final location after all of the screen updates are complete.

Note that "Term_xtra(TERM_XTRA_CLEAR,0)" must erase the entire screen, including the cursor, if needed, and may place the cursor anywhere.

Note that "Term_xtra(TERM_XTRA_FROSH,y)" will be always be called after any row "y" has been "flushed", unless the "Term->never_frosh" flag is set, and "Term_xtra(TERM_XTRA_FRESH,0)" will be called after all of the rows have been "flushed".

Note the use of three different functions to handle the actual flush, based on the settings of the "Term->always_pict" and "Term->higher_pict" flags (see below).

The three helper functions (above) work by collecting similar adjacent grids into stripes, and then sending each stripe to "Term->pict_hook", "Term->text_hook", or "Term->wipe_hook", based on the settings of the "Term->always_pict" and "Term->higher_pict" flags, which select which of the helper functions to call to flush each row.

The helper functions currently "skip" any grids which already contain the desired contents. This may or may not be the best method, especially when the desired content fits nicely into the current stripe. For example, it might be better to go ahead and queue them while allowed, but keep a count of the "trailing skipables", then, when time to flush, or when a "non skippable" is found, force a flush if there are too many skippables.

Perhaps an "initialization" stage, where the "text" (and "attr") buffers are "filled" with information, converting "blanks" into a convenient representation, and marking "skips" with "zero chars", and then some "processing" is done to determine which chars to skip.

Currently, the helper functions are optimal for systems which prefer to "print a char + move a char + print a char" to "print three chars", and for applications that do a lot of "detailed" color printing.

In the two "queue" functions, total "non-changes" are "pre-skipped". The helper functions must also handle situations in which the contents of a grid are changed, but then changed back to the original value, and situations in which two grids in the same row are changed, but the grids between them are unchanged.

If the "Term->always_pict" flag is set, then "Term_fresh_row_pict()" will be used instead of "Term_fresh_row_text()". This allows all the modified grids to be collected into stripes of attr/char pairs, which are then sent to the "Term->pict_hook" hook, which can draw these pairs in whatever way it would like.

If the "Term->higher_pict" flag is set, then "Term_fresh_row_both()" will be used instead of "Term_fresh_row_text()". This allows all the "special" attr/char pairs (in which both the attr and char have the high-bit set) to be sent (one pair at a time) to the "Term->pict_hook" hook, which can draw these pairs in whatever way it would like.

Normally, the "Term_wipe()" function is used only to display "blanks" that were induced by "Term_clear()" or "Term_erase()", and then only if the "attr_blank" and "char_blank" fields have not been redefined to use "white space" instead of the default "black space". Actually, the "Term_wipe()" function is used to display all "black" text, such as the default "spaces" created by "Term_clear()" and "Term_erase()".

Note that the "Term->always_text" flag will disable the use of the "Term_wipe()" function hook entirely, and force all text, even text drawn in the color "black", to be explicitly drawn. This is useful for machines which implement "Term_wipe()" by just drawing spaces.

Note that the "Term->always_pict" flag will disable the use of the "Term_wipe()" function entirely, and force everything, even text drawn in the attr "black", to be explicitly drawn.

Note that if no "black" text is ever drawn, and if "attr_blank" is not "zero", then the "Term_wipe" hook will never be used, even if the "Term->always_text" flag is not set.

This function does nothing unless the "Term" is "mapped", which allows certain systems to optimize the handling of "closed" windows.

On systems with a "soft" cursor, we must explicitly erase the cursor before flushing the output, if needed, to prevent a "jumpy" refresh. The actual method for this is horrible, but there is very little that we can do to simplify it efficiently. XXX XXX XXX

On systems with a "hard" cursor, we will "hide" the cursor before flushing the output, if needed, to avoid a "flickery" refresh. It would be nice to always hide the cursor during the refresh, but this might be expensive (and/or ugly) on some machines.

The "Term->icky_corner" flag is used to avoid calling "Term_wipe()" or "Term_pict()" or "Term_text()" on the bottom right corner of the window, which might induce "scrolling" or other nasty stuff on old dumb terminals. This flag is handled very efficiently. We assume that the "Term_curs()" call will prevent placing the cursor in the corner, if needed, though I doubt such placement is ever a problem. Currently, the use of "Term->icky_corner" and "Term->soft_cursor" together may result in undefined behavior.

References term_win::a, term::always_pict, term::always_text, term::attr_blank, bigcurs, term::bigcurs_hook, term_win::c, cc, term::char_blank, term_win::cu, term::curs_hook, term_win::cv, term_win::cx, term_win::cy, h, term::hgt, term::higher_pict, term::icky_corner, term::mapped_flag, term::never_frosh, term::old, term::pict_hook, term::saved, term::scr, smlcurs, term::soft_cursor, term_win::ta, term_win::tc, Term_curs_hack(), Term_fresh_row_both(), Term_fresh_row_pict(), Term_fresh_row_text(), Term_pict_hack(), Term_text_hack(), Term_wipe_hack(), Term_xtra(), TERM_XTRA_CLEAR, TERM_XTRA_FRESH, TERM_XTRA_FROSH, TERM_XTRA_SHAPE, term::text_hook, tile_height, tile_width, term::total_erase, void(), w, term::wid, term::wipe_hook, term::x1, term::x2, term::y1, and term::y2.

Referenced by bell_message(), display_bolt(), display_explosion(), display_knowledge(), display_missile(), do_cmd_redraw(), do_cmd_view_map(), flush_subwindow(), handle_signal_abort(), handle_signal_simple(), handle_signal_suspend(), idle_update(), inkey_ex(), load_path(), new_level_display_update(), pre_turn_refresh(), refresh(), save_game(), show_scores(), show_splashscreen(), splashscreen_note(), subwindow_set_flags(), Term_redraw(), Term_redraw_section(), textui_target_closest(), toggle_inven_equip(), ui_leave_init(), update_equip_subwindow(), update_inven_subwindow(), update_itemlist_subwindow(), update_maps(), update_messages_subwindow(), update_minimap_subwindow(), update_monlist_subwindow(), update_monster_subwindow(), update_object_subwindow(), update_player0_subwindow(), update_player1_subwindow(), update_player_compact_subwindow(), and wiz_statistics().

◆ Term_get_cursor()

errr Term_get_cursor ( bool *  v)


Access routines

Extract the cursor visibility

References term_win::cv, and term::scr.

Referenced by inkey_ex(), and textui_target_closest().

◆ Term_get_size()

errr Term_get_size ( int w,
int h 
)

◆ Term_gotoxy()

errr Term_gotoxy ( int  x,
int  y 
)

◆ term_init()

errr term_init ( term t,
int  w,
int  h,
int  k 
)

Initialize a term, using a window of the given size.

Also prepare the "input queue" for "k" keypresses By default, the cursor starts out "invisible" By default, we "erase" using "black spaces"

References term::attr_blank, term::char_blank, h, term::hgt, term::key_head, term::key_queue, term::key_size, term::key_tail, mem_zalloc(), term::old, term::saved, term::scr, term_win_init(), term::total_erase, w, term::wid, term::x1, term::x2, term::y1, and term::y2.

Referenced by term_data_link().

◆ Term_inkey()

errr Term_inkey ( ui_event ch,
bool  wait,
bool  take 
)

Check for a pending keypress on the key queue.

Store the keypress, if any, in "ch", and return "0". Otherwise store "zero" in "ch", and return "1".

Wait for a keypress if "wait" is true.

Remove the keypress if "take" is true.

References term::key_head, term::key_queue, term::key_size, term::key_tail, log_keypress(), term::never_bored, Term_xtra(), TERM_XTRA_BORED, and TERM_XTRA_EVENT.

Referenced by inkey_aux(), and inkey_ex().

◆ Term_key_push()

errr Term_key_push ( int  k)

Add a keypress to the FRONT of the "queue".

References keypress::code, EVT_KBRD, ui_event::key, keypress::mods, Term_event_push(), and ui_event::type.

◆ Term_keypress()

errr Term_keypress ( keycode_t  k,
byte  mods 
)

◆ Term_load()

errr Term_load ( void  )

Restore the "requested" contents (see above).

Every "Term_save()" should match exactly one "Term_load()"

References h, term::hgt, term::mem, mem_free(), term_win::next, term::saved, term::scr, term_win_copy(), term_win_nuke(), void(), w, term::wid, term::x1, term::x2, term::y1, and term::y2.

Referenced by screen_load().

◆ Term_locate()

errr Term_locate ( int x,
int y 
)

Extract the current cursor location.

References term_win::cu, term_win::cx, term_win::cy, and term::scr.

Referenced by askfor_aux(), display_glyphs(), text_out_to_screen(), and update_messages_subwindow().

◆ Term_mark()

errr Term_mark ( int  x,
int  y 
)

Mark a spot as needing refresh (see "Term_fresh")

References term_win::a, term_win::c, term::old, term_win::ta, and term_win::tc.

◆ Term_mousepress()

errr Term_mousepress ( int  x,
int  y,
char  button 
)

◆ term_nuke()

errr term_nuke ( term t)

◆ Term_putch()

errr Term_putch ( int  x,
int  y,
int  a,
wchar_t  c 
)

◆ Term_putstr()

errr Term_putstr ( int  x,
int  y,
int  n,
int  a,
const char *  s 
)

◆ Term_queue_char()

void Term_queue_char ( term t,
int  x,
int  y,
int  a,
wchar_t  c,
int  ta,
wchar_t  tc 
)


Efficient routines

Mentally draw an attr/char at a given location

Assumes given location and values are valid.

References term_win::a, term_win::c, term::scr, term_win::ta, term_win::tc, term::x1, term::x2, term::y1, and term::y2.

Referenced by display_map(), print_rel(), print_rel_map(), prt_map(), prt_map_aux(), Term_addch(), Term_big_queue_char(), Term_draw(), and update_maps().

◆ Term_queue_chars()

void Term_queue_chars ( int  x,
int  y,
int  n,
int  a,
const wchar_t *  s 
)

Mentally draw some attr/chars at a given location.

Assumes that (x,y) is a valid location, that the first "n" characters of the string "s" are all valid (non-zero), and that (x+n-1,y) is also a valid location, so the first "n" characters of "s" can all be added starting at (x,y) without causing any illegal operations.

References term_win::a, term_win::c, term::scr, term_win::ta, term_win::tc, term::x1, term::x2, term::y1, and term::y2.

Referenced by Term_addstr().

◆ Term_redraw()

errr Term_redraw ( void  )

◆ Term_redraw_section()

errr Term_redraw_section ( int  x1,
int  y1,
int  x2,
int  y2 
)

Redraw part of a window.

References term_win::a, term_win::c, term::hgt, i, term::old, Term_fresh(), term::wid, term::x1, term::x2, term::y1, and term::y2.

Referenced by textui_target_closest().

◆ Term_resize()

errr Term_resize ( int  w,
int  h 
)

◆ Term_save()

errr Term_save ( void  )


Extra routines

Save the "requested" screen into the "memorized" screen

Every "Term_save()" should match exactly one "Term_load()"

References h, term::hgt, term::mem, mem_zalloc(), term_win::next, term::saved, term::scr, term_win_copy(), term_win_init(), w, and term::wid.

Referenced by screen_save().

◆ Term_set_cursor()

errr Term_set_cursor ( bool  v)


Output routines

Set the cursor visibility

References term_win::cv, and term::scr.

Referenced by inkey_ex(), textui_get_command(), textui_init(), and textui_target_closest().

◆ Term_what()

errr Term_what ( int  x,
int  y,
int a,
wchar_t *  c 
)

At a given location, determine the "current" attr and char Note that this refers to what will be on the window after the next call to "Term_fresh()".

It may or may not already be there.

References term_win::a, term_win::c, h, term::hgt, term::scr, w, and term::wid.

Referenced by draw_path(), html_screenshot(), text_out_to_screen(), and write_character_dump().

◆ Term_xtra()

errr Term_xtra ( int  n,
int  v 
)

Variable Documentation

◆ angband_term

term* angband_term[ANGBAND_TERM_MAX]

This file provides a generic, efficient, terminal window package, which can be used not only on standard terminal environments such as dumb terminals connected to a Unix box, but also in more modern "graphic" environments, such as the Macintosh or Unix/X11.

Each "window" works like a standard "dumb terminal", that is, it can display a two dimensional array of grids containing colored textual symbols, plus an optional cursor, and it can be used to get keypress events from the user.

In fact, this package can simply be used, if desired, to support programs which will look the same on a dumb terminal as they do on a graphic platform such as the Macintosh.

This package was designed to help port the game "Angband" to a wide variety of different platforms. Angband, like many other games in the "rogue-like" heirarchy, requires, at the minimum, the ability to display "colored textual symbols" in a standard 80x24 "window", such as that provided by most dumb terminals, and many old personal computers, and to check for "keypresses" from the user. The major concerns were thus portability and efficiency, so Angband could be easily ported to many different systems, with minimal effort, and yet would run quickly on each of these systems, no matter what kind of underlying hardware/software support was being used.

It is important to understand the differences between the older "dumb terminals" and the newer "graphic interface" machines, since this package was designed to work with both types of systems.

New machines: waiting for a keypress is complex checking for a keypress is often cheap changing "colors" may be expensive the "color" of a "blank" is rarely important moving the "cursor" is relatively cheap use a "software" cursor (only moves when requested) drawing characters normally will not erase old ones drawing a character on the cursor often erases it may have fast routines for "clear a region" the bottom right corner is usually not special

Old machines: waiting for a keypress is simple checking for a keypress is often expensive changing "colors" is usually cheap the "color" of a "blank" may be important moving the "cursor" may be expensive use a "hardware" cursor (moves during screen updates) drawing new symbols automatically erases old ones characters may only be drawn at the cursor location drawing a character on the cursor will move the cursor may have fast routines for "clear entire window" may have fast routines for "clear to end of line" the bottom right corner is often dangerous

This package provides support for multiple windows, each of an arbitrary size (up to 255x255), each with its own set of flags, and its own hooks to handle several low-level procedures which differ from platform to platform. Then the main program simply creates one or more "term" structures, setting the various flags and hooks in a manner appropriate for the current platform, and then it can use the various "term" structures without worrying about the underlying platform.

This package allows each "grid" in each window to hold an attr/char pair, with each ranging from 0 to 255, and makes very few assumptions about the meaning of any attr/char values. Normally, we assume that "attr 0" is "black", with the semantics that "black" text should be sent to "Term_wipe()" instead of "Term_text()", but this sematics is modified if either the "always_pict" or the "always_text" flags are set. We assume that "char 0" is "dangerous", since placing such a "char" in the middle of a string "terminates" the string, and usually we prevent its use.

Finally, we use a special attr/char pair, defaulting to "attr 0" and "char 32", also known as "black space", when we "erase" or "clear" any window, but this pair can be redefined to any pair, including the standard "white space", or the bizarre "emptiness" ("attr 0" and "char 0"), as long as various obscure restrictions are met.

This package provides several functions which allow a program to interact with the "term" structures. Most of the functions allow the program to "request" certain changes to the current "term", such as moving the cursor, drawing an attr/char pair, erasing a region of grids, hiding the cursor, etc. Then there is a special function which causes all of the "pending" requests to be performed in an efficient manner. There is another set of functions which allow the program to query the "requested state" of the current "term", such as asking for the cursor location, or what attr/char is at a given location, etc. There is another set of functions dealing with "keypress" events, which allows the program to ask if the user has pressed any keys, or to forget any keys the user pressed. There is a pair of functions to allow this package to memorize the contents of the current "term", and to restore these contents at a later time. There is a special function which allows the program to specify which "term" structure should be the "current" one. At the lowest level, there is a set of functions which allow a new "term" to be initialized or destroyed, and which allow this package, or a program, to access the special "hooks" defined for the current "term", and a set of functions which those "hooks" can use to inform this package of the results of certain occurances, for example, one such function allows this package to learn about user keypresses, detected by one of the special "hooks".

We provide, among other things, the functions "Term_keypress()" to "react" to keypress events, and "Term_redraw()" to redraw the entire window, plus "Term_resize()" to note a new size.

Note that the current "term" contains two "window images". One of these images represents the "requested" contents of the "term", and the other represents the "actual" contents of the "term", at the time of the last performance of pending requests. This package uses these two images to determine the "minimal" amount of work needed to make the "actual" contents of the "term" match the "requested" contents of the "term". This method is not perfect, but it often reduces the amount of work needed to perform the pending requests, which thus increases the speed of the program itself. This package promises that the requested changes will appear to occur either "all at once" or in a "top to bottom" order. In addition, a "cursor" is maintained, and this cursor is updated along with the actual window contents.

Currently, the "Term_fresh()" routine attempts to perform the "minimum" number of physical updates, in terms of total "work" done by the hooks Term_wipe(), Term_text(), and Term_pict(), making use of the fact that adjacent characters of the same color can both be drawn together using the "Term_text()" hook, and that "black" text can often be sent to the "Term_wipe()" hook instead of the "Term_text()" hook, and if something is already displayed in a window, then it is not necessary to display it again. Unfortunately, this may induce slightly non-optimal results in some cases, in particular, those in which, say, a string of ten characters needs to be written, but the fifth character has already been displayed. Currently, this will cause the "Term_text()" routine to be called once for each half of the string, instead of once for the whole string, which, on some machines, may be non-optimal behavior.

The new formalism includes a "displayed" screen image (old) which is actually seen by the user, a "requested" screen image (scr) which is being prepared for display, a "memorized" screen image (mem) which is used to save and restore screen images, and a "temporary" screen image (tmp) which is currently unused.

Several "flags" are available in each "term" to allow the underlying visual system (which initializes the "term" structure) to "optimize" the performance of this package for the given system, or to request certain behavior which is helpful/required for the given system.

The "soft_cursor" flag indicates the use of a "soft" cursor, which only moves when explicitly requested,and which is "erased" when any characters are drawn on top of it. This flag is used for all "graphic" systems which handle the cursor by "drawing" it.

The "icky_corner" flag indicates that the bottom right "corner" of the windows are "icky", and "printing" anything there may induce "messy" behavior, such as "scrolling". This flag is used for most old "dumb terminal" systems.

The "term" structure contains the following function "hooks":

Term->init_hook = Init the term Term->nuke_hook = Nuke the term Term->xtra_hook = Perform extra actions Term->curs_hook = Draw (or Move) the cursor Term->bigcurs_hook = Draw (or Move) the big cursor (bigtile mode) Term->wipe_hook = Draw some blank spaces Term->text_hook = Draw some text in the window Term->pict_hook = Draw some attr/chars in the window

The "Term->xtra_hook" hook provides a variety of different functions, based on the first parameter (which should be taken from the various TERM_XTRA_* defines) and the second parameter (which may make sense only for some first parameters). It is available to the program via the "Term_xtra()" function, though some first parameters are only "legal" when called from inside this package.

The "Term->curs_hook" hook provides this package with a simple way to "move" or "draw" the cursor to the grid "x,y", depending on the setting of the "soft_cursor" flag. Note that the cursor is never redrawn if "nothing" has happened to the screen (even temporarily). This hook is required.

The "Term->wipe_hook" hook provides this package with a simple way to "erase", starting at "x,y", the next "n" grids. This hook assumes that the input is valid. This hook is required, unless the setting of the "always_pict" or "always_text" flags makes it optional.

The "Term->text_hook" hook provides this package with a simple way to "draw", starting at "x,y", the "n" chars contained in "cp", using the attr "a". This hook assumes that the input is valid, and that "n" is between 1 and 256 inclusive, but it should NOT assume that the contents of "cp" are null-terminated. This hook is required, unless the setting of the "always_pict" flag makes it optional.

The "Term->pict_hook" hook provides this package with a simple way to "draw", starting at "x,y", the "n" attr/char pairs contained in the arrays "ap" and "cp". This hook assumes that the input is valid, and that "n" is between 1 and 256 inclusive, but it should NOT assume that the contents of "cp" are null-terminated. This hook is optional, unless the setting of the "always_pict" or "higher_pict" flags make it required. Note that recently, this hook was changed from taking a int "a" and a char "c" to taking a length "n", an array of ints "ap" and an array of chars "cp". Old implementations of this hook should now iterate over all "n" attr/char pairs. The two new arrays "tap" and "tcp" can contain the attr/char pairs of the terrain below the values in "ap" and "cp". These values can be used to implement transparency when using graphics by drawing the terrain values as a background and the "ap", "cp" values in the foreground.

The game "Angband" uses a set of files called "main-xxx.c", for various "xxx" suffixes. Most of these contain a function called "init_xxx()", that will prepare the underlying visual system for use with Angband, and then create one or more "term" structures, using flags and hooks appropriate to the given platform, so that the "main()" function can call one (or more) of the "init_xxx()" functions, as appropriate, to prepare the required "term" structs (one for each desired sub-window), and these "init_xxx()" functions are called from a centralized "main()" function in "main.c". Other "main-xxx.c" systems contain their own "main()" function which, in addition to doing everything needed to initialize the actual program, also does everything that the normal "init_xxx()" functions would do.

The game "Angband" defines, in addition to "attr 0", all of the attr codes from 1 to 15, using definitions in "defines.h", and thus the "main-xxx.c" files used by Angband must handle these attr values correctly. Also, they must handle all other attr values, though they may do so in any way they wish, for example, by always taking every attr code mod 16. Many of the "main-xxx.c" files use "white space" ("attr 1" / "char 32") to "erase" or "clear" any window, for efficiency.

See "main-xxx.c" for a simple skeleton file which can be used to create a "visual system" for a new platform when porting Angband. The array[ANGBAND_TERM_MAX] of window pointers

Referenced by adjust_panel_help(), change_panel(), display_player(), do_cmd_redraw(), init_nds(), move_cursor_relative_map(), option_dump(), pre_turn_refresh(), print_rel_map(), prt_map_aux(), quit_hook(), subwindow_flag_changed(), subwindow_set_flags(), subwindows_set_flags(), textui_get_item(), toggle_inven_equip(), ui_enter_world(), ui_leave_world(), update_maps(), update_minimap_subwindow(), and verify_panel_int().

◆ angband_term_name

char angband_term_name[ANGBAND_TERM_MAX][16]

The array[ANGBAND_TERM_MAX] of window names (modifiable?)

ToDo: Make the names independent of ANGBAND_TERM_MAX.

Referenced by do_cmd_options_win(), and option_dump().

◆ bigcurs

bool bigcurs

Helper variables for large cursor.

Referenced by display_knowledge(), remove_tiles(), Term_fresh(), and tile_picker_command().

◆ keylog

struct keypress keylog[KEYLOG_SIZE]

Referenced by do_cmd_keylog(), and log_keypress().

◆ log_i

int log_i

Referenced by do_cmd_keylog(), and log_keypress().

◆ log_size

int log_size

Referenced by do_cmd_keylog(), and log_keypress().

◆ smlcurs

bool smlcurs

◆ Term

term* Term

◆ tile_height

byte tile_height

◆ tile_width

byte tile_width

◆ window_flag

u32b window_flag[ANGBAND_TERM_MAX]