#include <stdio.h>
#include <stdarg.h>
#include <string.h>
-// Not that we actually *use* ncursesw yet, but I want the capability there
-// when I do :)
+#include <stdlib.h>
+#include <locale.h>
#include <ncursesw/curses.h>
#include <ncursesw/panel.h>
int show_terrain;
int hard_redraw;
-chtype colour_attrs[15] =
+attr_t colour_attrs[15] =
{
0,
- COLOR_PAIR(DBCLR_D_GREY) | A_BOLD,
- COLOR_PAIR(DBCLR_RED),
- COLOR_PAIR(DBCLR_BLUE),
- COLOR_PAIR(DBCLR_GREEN),
- COLOR_PAIR(DBCLR_PURPLE),
- COLOR_PAIR(DBCLR_BROWN),
- COLOR_PAIR(DBCLR_CYAN),
+ 0 | A_BOLD,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
A_BOLD,
- COLOR_PAIR(DBCLR_RED) | A_BOLD,
- COLOR_PAIR(DBCLR_BLUE) | A_BOLD,
- COLOR_PAIR(DBCLR_GREEN) | A_BOLD,
- COLOR_PAIR(DBCLR_PURPLE) | A_BOLD,
- COLOR_PAIR(DBCLR_BROWN) | A_BOLD,
- COLOR_PAIR(DBCLR_CYAN) | A_BOLD
+ 0 | A_BOLD,
+ 0 | A_BOLD,
+ 0 | A_BOLD,
+ 0 | A_BOLD,
+ 0 | A_BOLD,
+ 0 | A_BOLD
};
+short colour_cpairs[15] =
+{
+ 0,
+ DBCLR_D_GREY,
+ DBCLR_RED,
+ DBCLR_BLUE,
+ DBCLR_GREEN,
+ DBCLR_PURPLE,
+ DBCLR_BROWN,
+ DBCLR_CYAN,
+ 0,
+ DBCLR_RED,
+ DBCLR_BLUE,
+ DBCLR_GREEN,
+ DBCLR_PURPLE,
+ DBCLR_BROWN,
+ DBCLR_CYAN,
+};
+
+wchar_t terrain_wchars[NUM_TERRAINS] =
+{
+ L'█', L'█', L'+', L'·', L'_', L'>', L'{', L'{'
+};
+
+short terrain_cpairs[NUM_TERRAINS] =
+{
+ DBCLR_BROWN, 0, 0, 0,
+ 0, 0, DBCLR_RED, DBCLR_BLUE
+};
+
+attr_t terrain_attrs[NUM_TERRAINS] =
+{
+ 0, 0, 0, 0,
+ 0, 0, 0, 0
+};
+
+cchar_t terrain_tiles[NUM_TERRAINS];
+
+cchar_t permobj_tiles[NUM_OF_PERMOBJS];
+
#define DISP_HEIGHT 21
#define DISP_WIDTH 21
-chtype back_buffer[DUN_HEIGHT][DUN_WIDTH];
-chtype front_buffer[DISP_HEIGHT][DISP_WIDTH];
+cchar_t permon_tiles[NUM_OF_PERMONS];
+
+cchar_t blank_tile;
+cchar_t player_tile;
+const cchar_t *back_buffer[DUN_HEIGHT][DUN_WIDTH];
+const cchar_t *front_buffer[DISP_HEIGHT][DISP_WIDTH];
/* Prototypes for static funcs */
-static chtype object_char(int object_id);
-static chtype monster_char(int monster_id);
-static chtype terrain_char(enum terrain_num terrain_type);
+static const cchar_t *object_char(int object_id);
+static const cchar_t *monster_char(int monster_id);
+static const cchar_t *terrain_char(enum terrain_num terrain_type);
static void draw_status_line(void);
static void draw_world(void);
mvwprintw(status_window, 1, 44, "Agility: %02d/%02d", u.agility - u.adam, u.agility);
}
-static chtype terrain_char(enum terrain_num terrain_type)
+static const cchar_t *terrain_char(enum terrain_num terrain_type)
{
- switch (terrain_type)
- {
- case STAIRS:
- return '>';
- case FLOOR:
- return '.';
- case HARDWALL:
- // return '#' | colour_attrs[DBCLR_PURPLE];
- case WALL:
- return '#' | colour_attrs[wall_colour];
- case DOOR:
- return '+';
- case WATER:
- return '{' | colour_attrs[DBCLR_BLUE];
- case LAVA:
- return '{' | colour_attrs[DBCLR_RED];
- default:
- return '*';
- }
+ return terrain_tiles + terrain_type;
}
-static chtype monster_char(int monster_id)
+static const cchar_t *monster_char(int monster_id)
{
- return (permons[monster_id].sym) | colour_attrs[permons[monster_id].colour];
+ return permon_tiles + monster_id;
}
-static chtype object_char(int object_id)
+static const cchar_t *object_char(int object_id)
{
- return permobjs[object_id].sym;
+ return permobj_tiles + object_id;
}
void touch_back_buffer(void)
void newsym(int y, int x)
{
- chtype ch;
-
+ const cchar_t *ch;
ch = back_buffer[y][x];
if ((y == u.y) && (x == u.x))
{
- back_buffer[y][x] = '@' | colour_attrs[you_colour];
+ back_buffer[y][x] = &player_tile;
}
else if ((!show_terrain) && (mapmonster[y][x] != -1) && mon_visible(mapmonster[y][x]))
{
}
else
{
- back_buffer[y][x] = ' ';
+ back_buffer[y][x] = &blank_tile;
}
if (ch != back_buffer[y][x])
{
if ((y < 0) || (x < 0) ||
(y >= DUN_HEIGHT) || (x >= DUN_WIDTH))
{
- if ((front_buffer[i][j] != ' ') || hard_redraw)
+ if ((front_buffer[i][j] != &blank_tile) || hard_redraw)
{
- mvwaddch(world_window, i, j, ' ');
+ mvwadd_wch(world_window, i, j, &blank_tile);
}
- front_buffer[i][j] = ' ';
+ front_buffer[i][j] = &blank_tile;
}
else if (hard_redraw || (front_buffer[i][j] != back_buffer[y][x]))
{
- mvwaddch(world_window, i, j, back_buffer[y][x]);
+ mvwadd_wch(world_window, i, j, back_buffer[y][x]);
front_buffer[i][j] = back_buffer[y][x];
}
}
int display_init(void)
{
+ int i;
+ const char *foo;
+ foo = getenv("LANG");
+ if (foo)
+ {
+ setlocale(LC_CTYPE, foo);
+ }
+ else
+ {
+ foo = getenv("LC_CTYPE");
+ if (foo)
+ {
+ setlocale(LC_CTYPE, foo);
+ }
+ else
+ {
+ setlocale(LC_CTYPE, "C.UTF-8");
+ }
+ }
initscr();
noecho();
cbreak();
init_pair(DBCLR_CYAN, COLOR_CYAN, COLOR_BLACK);
wall_colour = DBCLR_BROWN;
you_colour = DBCLR_WHITE;
+ {
+ wchar_t wch[2];
+ wch[0] = L'@';
+ wch[1] = 0;
+ setcchar(&player_tile, wch, 0, 0, NULL);
+ wch[0] = L' ';
+ setcchar(&blank_tile, wch, 0, 0, NULL);
+ }
+ for (i = 0; i < NUM_OF_PERMONS; ++i)
+ {
+ wchar_t wch[2];
+ wch[0] = permons[i].sym;
+ wch[1] = 0;
+ setcchar(permon_tiles + i, wch, colour_attrs[permons[i].colour], colour_cpairs[permons[i].colour], NULL);
+ }
+ for (i = 0; i < NUM_TERRAINS; ++i)
+ {
+ wchar_t wch[2];
+ wch[0] = terrain_wchars[i];
+ wch[1] = 0;
+ setcchar(terrain_tiles + i, wch, terrain_attrs[i], terrain_cpairs[i], NULL);
+ }
+ for (i = 0; i < NUM_OF_PERMOBJS; ++i)
+ {
+ wchar_t wch[2];
+ wch[0] = permobjs[i].sym;
+ wch[1] = 0;
+ setcchar(permobj_tiles + i, wch, 0, 0, NULL);
+ }
/* OK. We want a 21x21 viewport (player at centre), a 21x58 message
* window, and a 2x80 status line. */
status_window = newwin(2, 80, 22, 0);
static bool dflt_blk(int y, int x)
{
- return ((y <= 0) || (x <= 0) || (y >= DUN_HEIGHT - 1) || (x >= DUN_WIDTH - 1) || (terrain[y][x] < FLOOR));
+ return ((y <= 0) || (x <= 0) || (y >= DUN_HEIGHT - 1) || (x >= DUN_WIDTH - 1) || (terrain_is_opaque(terrain[y][x])));
}
static bool mark_explored(int y, int x, void *pvt)
static inline double inner_visible_slope(int rdl, int trn)
{
- return trn ? ((trn - 0.5) / (rdl - 0.5)) : 0.0;
+ return trn ? ((trn - 0.5) / (rdl + 0.5)) : 0.0;
}
/*! \fn
* \brief Return the outer (diagonal-wards) blocking limit of an octant-relative coordinate
bool block_flag = false;
int outer_idx;
int inner_idx;
+ double isl;
+ double ivs;
+ double ovs;
if (inmost_slope >= outmost_slope)
{
return;
}
- inner_idx = inmost_slope * radius;
+ inner_idx = 0.5 + (inmost_slope * radius);
outer_idx = 0.5 + (outmost_slope * radius);
dx = radius * rdl_dx[octant] + outer_idx * trn_dx[octant];
dy = radius * rdl_dy[octant] + outer_idx * trn_dy[octant];
for (trn = outer_idx; trn >= inner_idx; --trn)
{
- if (outer_visible_slope(radius, trn) < inmost_slope)
- {
- continue;
- }
- if (inner_visible_slope(radius, trn) > outmost_slope)
- {
- continue;
- }
+ isl = inner_slope(radius, trn);
rad->affected[MAX_FOV_RADIUS + dy][MAX_FOV_RADIUS + dx] = true;
if (block_flag)
{
if (rad->opaque_fun(dy + rad->centre_y, dx + rad->centre_x))
{
- outmost_slope = inner_slope(radius, trn);
+ if (outmost_slope > isl)
+ {
+ outmost_slope = isl;
+ }
}
else
{
{
compute_row(rad, octant, radius + 1, outer_slope(radius, trn), outmost_slope);
}
- outmost_slope = inner_slope(radius, trn);
+ if (outmost_slope > isl)
+ {
+ outmost_slope = isl;
+ }
}
}
dx -= trn_dx[octant];
switch (rad->order)
{
case Reo_ascending:
- for ((i = MAX_FOV_RADIUS - rad->radius), (y = rad->centre_y - rad->radius); y < rad->centre_y + rad->radius; ++y, ++i)
+ for ((i = MAX_FOV_RADIUS - rad->radius), (y = rad->centre_y - rad->radius); y <= rad->centre_y + rad->radius; ++y, ++i)
{
- for ((j = MAX_FOV_RADIUS - rad->radius), (x = rad->centre_x - rad->radius); x < rad->centre_x + rad->radius; ++x, ++j)
+ for ((j = MAX_FOV_RADIUS - rad->radius), (x = rad->centre_x - rad->radius); x <= rad->centre_x + rad->radius; ++x, ++j)
{
if (rad->affected[i][j])
{