/** * Redraw (on the screen) the current map panel * * Note the inline use of "light_spot()" for efficiency. * * The main screen will always be at least 24x80 in size. */ void prt_map(void) { int a, ta; wchar_t c, tc; struct grid_data g; int y, x; int vy, vx; int ty, tx; /* Redraw map sub-windows */ prt_map_aux(); /* Assume screen */ ty = Term->offset_y + SCREEN_HGT; tx = Term->offset_x + SCREEN_WID; /* Dump the map */ for (y = Term->offset_y, vy = ROW_MAP; y < ty; vy+=tile_height, y++) for (x = Term->offset_x, vx = COL_MAP; x < tx; vx+=tile_width, x++) { /* Check bounds */ if (!square_in_bounds(cave, loc(x, y))) continue; /* Determine what is there */ map_info(loc(x, y), &g); grid_data_as_text(&g, &a, &c, &ta, &tc); /* Hack -- Queue it */ Term_queue_char(Term, vx, vy, a, c, ta, tc); if ((tile_width > 1) || (tile_height > 1)) Term_big_queue_char(Term, vx, vy, a, c, COLOUR_WHITE, L' '); } }
/** * Display an attr/char pair at the given map location * * Note the inline use of "panel_contains()" for efficiency. * * Note the use of "Term_queue_char()" for efficiency. * * The main screen will always be at least 24x80 in size. */ void print_rel(wchar_t c, byte a, int y, int x) { int ky, kx; int vy, vx; /* Print on map sub-windows */ print_rel_map(c, a, y, x); /* Location relative to panel */ ky = y - Term->offset_y; /* Verify location */ if ((ky < 0) || (ky >= SCREEN_HGT)) return; /* Location relative to panel */ kx = x - Term->offset_x; /* Verify location */ if ((kx < 0) || (kx >= SCREEN_WID)) return; /* Get right position */ vx = COL_MAP + (tile_width * kx); vy = ROW_MAP + (tile_height * ky); /* Hack -- Queue it */ Term_queue_char(Term, vx, vy, a, c, 0, 0); if ((tile_width > 1) || (tile_height > 1)) Term_big_queue_char(Term, vx, vy, a, c, 0, 0); }
/* * 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 unuable 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. */ errr Term_addch(byte a, char c) { int w = Term->wid; /* Handle "unusable" cursor */ if (Term->scr->cu) return ( -1); /* Paranoia -- no illegal chars */ if (!c) return ( -2); /* Queue the given character for display */ Term_queue_char(Term->scr->cx, Term->scr->cy, a, c); /* Advance the cursor */ Term->scr->cx++; /* Success */ if (Term->scr->cx < w) return (0); /* Note "Useless" cursor */ Term->scr->cu = 1; /* Note "Useless" cursor */ return (1); }
static void prt_map_aux(void) { int a, ta; wchar_t c, tc; struct grid_data g; int y, x; int vy, vx; int ty, tx; 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; /* Assume screen */ ty = t->offset_y + (t->hgt / tile_height); tx = t->offset_x + (t->wid / tile_width); /* Dump the map */ for (y = t->offset_y, vy = 0; y < ty; vy++, y++) { if (vy + tile_height - 1 >= t->hgt) continue; for (x = t->offset_x, vx = 0; x < tx; vx++, x++) { /* Check bounds */ if (!square_in_bounds(cave, loc(x, y))) continue; if (vx + tile_width - 1 >= t->wid) continue; /* Determine what is there */ map_info(loc(x, y), &g); grid_data_as_text(&g, &a, &c, &ta, &tc); Term_queue_char(t, vx, vy, a, c, ta, tc); if ((tile_width > 1) || (tile_height > 1)) Term_big_queue_char(t, vx, vy, 255, -1, 0, 0); } } } }
/** * Display an attr/char pair at the given map location * * Note the inline use of "panel_contains()" for efficiency. * * Note the use of "Term_queue_char()" for efficiency. */ static void print_rel_map(wchar_t c, byte a, int y, int x) { int ky, kx; 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; if (ky + 1 >= t->hgt) continue; } /* 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; if (kx + 1 >= t->wid) continue; } /* Verify location */ if ((kx < 0) || (kx >= t->wid)) continue; /* Hack -- Queue it */ Term_queue_char(t, kx, ky, a, c, 0, 0); if ((tile_width > 1) || (tile_height > 1)) Term_big_queue_char(Term, kx, ky, a, c, 0, 0); } }
/* * At a given location, place an attr/char * Do not change the cursor position * No visual changes until "Term_fresh()". */ errr Term_draw(int x, int y, byte a, char c) { int w = Term->wid; int h = Term->hgt; /* Verify location */ if ((x < 0) || (x >= w)) return ( -1); if ((y < 0) || (y >= h)) return ( -1); /* Paranoia -- illegal char */ if (!c) return ( -2); /* Queue it for later */ Term_queue_char(x, y, a, c); /* Success */ return (0); }
/** * Display a "small-scale" map of the dungeon in the active Term. * * Note that this function must "disable" the special lighting effects so * that the "priority" function will work. * * Note the use of a specialized "priority" function to allow this function * to work with any graphic attr/char mappings, and the attempts to optimize * this function where possible. * * If "cy" and "cx" are not NULL, then returns the screen location at which * the player was displayed, so the cursor can be moved to that location, * and restricts the horizontal map size to SCREEN_WID. Otherwise, nothing * is returned (obviously), and no restrictions are enforced. */ void display_map(int *cy, int *cx) { int map_hgt, map_wid; int row, col; int x, y; struct grid_data g; int a, ta; wchar_t c, tc; byte tp; struct monster_race *race = &r_info[0]; /* Priority array */ byte **mp = mem_zalloc(cave->height * sizeof(byte*)); for (y = 0; y < cave->height; y++) mp[y] = mem_zalloc(cave->width * sizeof(byte)); /* Desired map height */ map_hgt = Term->hgt - 2; map_wid = Term->wid - 2; /* Prevent accidents */ if (map_hgt > cave->height) map_hgt = cave->height; if (map_wid > cave->width) map_wid = cave->width; /* Prevent accidents */ if ((map_wid < 1) || (map_hgt < 1)) { for (y = 0; y < cave->height; y++) mem_free(mp[y]); mem_free(mp); return; } /* Nothing here */ a = COLOUR_WHITE; c = L' '; ta = COLOUR_WHITE; tc = L' '; /* Draw a box around the edge of the term */ window_make(0, 0, map_wid + 1, map_hgt + 1); /* Analyze the actual map */ for (y = 0; y < cave->height; y++) for (x = 0; x < cave->width; x++) { row = (y * map_hgt / cave->height); col = (x * map_wid / cave->width); if (tile_width > 1) col = col - (col % tile_width); if (tile_height > 1) row = row - (row % tile_height); /* Get the attr/char at that map location */ map_info(loc(x, y), &g); grid_data_as_text(&g, &a, &c, &ta, &tc); /* Get the priority of that attr/char */ tp = f_info[g.f_idx].priority; /* Stuff on top of terrain gets higher priority */ if ((a != ta) || (c != tc)) tp = 20; /* Save "best" */ if (mp[row][col] < tp) { /* Hack - make every grid on the map lit */ g.lighting = LIGHTING_LIT; grid_data_as_text(&g, &a, &c, &ta, &tc); Term_queue_char(Term, col + 1, row + 1, a, c, ta, tc); if ((tile_width > 1) || (tile_height > 1)) Term_big_queue_char(Term, col + 1, row + 1, 255, -1, 0, 0); /* Save priority */ mp[row][col] = tp; } } /*** Display the player ***/ /* Player location */ row = (player->grid.y * map_hgt / cave->height); col = (player->grid.x * map_wid / cave->width); if (tile_width > 1) col = col - (col % tile_width); if (tile_height > 1) row = row - (row % tile_height); /* Get the "player" tile */ ta = monster_x_attr[race->ridx]; tc = monster_x_char[race->ridx]; /* Draw the player */ Term_putch(col + 1, row + 1, ta, tc); if ((tile_width > 1) || (tile_height > 1)) Term_big_putch(col + 1, row + 1, ta, tc); /* Return player location */ if (cy != NULL) (*cy) = row + 1; if (cx != NULL) (*cx) = col + 1; for (y = 0; y < cave->height; y++) mem_free(mp[y]); mem_free(mp); }