FoV code now behaves, setlocale() handling now in display-nc.c
authorMartin Read <martin@blackswordsonics.com>
Mon, 23 Sep 2013 18:34:57 +0000 (19:34 +0100)
committerMartin Read <martin@blackswordsonics.com>
Mon, 23 Sep 2013 18:34:57 +0000 (19:34 +0100)
Makefile
display-nc.c
fov.c
main.c
map.c
map.h
monsters.c
victrix-abyssi.h

index 4688bf5..3ce605a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -8,8 +8,8 @@ include features.mk
 GAME:=victrix-abyssi
 MAJVERS:=1
 MINVERS:=0
-PRODUCTION_CFLAGS:=-c -Wall -Wstrict-prototypes -Wwrite-strings -Wmissing-prototypes -Wno-unused-but-set-variable -Wredundant-decls -Wunreachable-code -DMAJVERS=$(MAJVERS) -DMINVERS=$(MINVERS)
-DEVELOPMENT_CFLAGS:=-c -g -Wall -Wstrict-prototypes -Wwrite-strings -Wmissing-prototypes -Wno-unused-but-set-variable -Wredundant-decls -Wunreachable-code -Werror -DMAJVERS=$(MAJVERS) -DMINVERS=$(MINVERS)
+PRODUCTION_CFLAGS:=-std=gnu99 -c -Wall -Wstrict-prototypes -Wwrite-strings -Wmissing-prototypes -Wno-unused-but-set-variable -Wredundant-decls -Wunreachable-code -DMAJVERS=$(MAJVERS) -DMINVERS=$(MINVERS)
+DEVELOPMENT_CFLAGS:=-std=gnu99 -c -g -Wall -Wstrict-prototypes -Wwrite-strings -Wmissing-prototypes -Wno-unused-but-set-variable -Wredundant-decls -Wunreachable-code -Werror -DMAJVERS=$(MAJVERS) -DMINVERS=$(MINVERS)
 CFLAGS=$(PRODUCTION_CFLAGS)
 LINKFLAGS=-lm -lpanelw -lncursesw -g
 ARCHIVEDIR:=victrix-abyssi_$(MAJVERS).$(MINVERS)
index d19d296..c38b870 100644 (file)
@@ -32,8 +32,8 @@
 #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>
 
@@ -58,35 +58,79 @@ int map_updated;
 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);
 
@@ -104,37 +148,19 @@ static void draw_status_line(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)
@@ -154,12 +180,11 @@ 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]))
     {
@@ -178,7 +203,7 @@ void newsym(int y, int x)
     }
     else
     {
-       back_buffer[y][x] = ' ';
+       back_buffer[y][x] = &blank_tile;
     }
     if (ch != back_buffer[y][x])
     {
@@ -202,15 +227,15 @@ static void draw_world(void)
            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];
            }
        }
@@ -251,6 +276,25 @@ void display_update(void)
 
 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();
@@ -264,6 +308,35 @@ int display_init(void)
     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);
diff --git a/fov.c b/fov.c
index e52635e..8a5b672 100644 (file)
--- a/fov.c
+++ b/fov.c
@@ -54,7 +54,7 @@ static void compute_row(Radiance *rad, int octant, int radius, double inmost_slo
 
 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)
@@ -74,7 +74,7 @@ static inline double inner_slope(int rdl, int trn)
 
 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
@@ -107,30 +107,29 @@ static void compute_row(Radiance *rad, int octant, int radius, double inmost_slo
     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
             {
@@ -146,7 +145,10 @@ static void compute_row(Radiance *rad, int octant, int radius, double inmost_slo
                 {
                     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];
@@ -184,9 +186,9 @@ void resolve_radiance(Radiance *rad)
     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])
                 {
diff --git a/main.c b/main.c
index 4e9af86..ed4f03b 100644 (file)
--- a/main.c
+++ b/main.c
@@ -546,7 +546,7 @@ void main_loop(void)
     enum game_cmd cmd;
     int i;
     int action_speed;
-    print_msg("Welcome to Cave Chop, Princess %s.\n", u.name);
+    print_msg("Welcome to the Abyss, Princess %s.\n", u.name);
     print_msg("Press '?' for help.\n");
     while (!game_finished)
     {
diff --git a/map.c b/map.c
index 1af679b..6678267 100644 (file)
--- a/map.c
+++ b/map.c
@@ -143,7 +143,7 @@ void build_level(void)
     /* Snapshot the running RNG state, so that we can rebuild the map from
      * the saved RNG state at game reload. */
     memcpy(saved_state, rng_state, sizeof saved_state);
-    if (zero_die(7))
+    if (zero_die(2))
     {
         current_layout = LAYOUT_CAVE_INTRUSIONS;
     }
@@ -520,30 +520,19 @@ void inject_player(void)
 
 void explore_around(int y, int x)
 {
-    /*int y2, x2;*/
     compute_fov();
     touch_back_buffer();
-    /*
-    for (y2 = y - 10; y2 <= y + 10; y2++)
-    {
-        if ((y2 < 0) || (y2 >= DUN_HEIGHT))
-        {
-            continue;
-        }
-        for (x2 = x - 10; x2 <= x + 10; x2++)
-        {
-            if ((x2 < 0) || (x2 >= DUN_WIDTH))
-            {
-                continue;
-            }
-            if (!(mapflags[y2][x2] & MAPFLAG_EXPLORED))
-            {
-                mapflags[y2][x2] |= MAPFLAG_EXPLORED;
-            }
-            newsym(y2, x2);
-        }
-    }
-    */
+}
+
+bool terrain_opacity[NUM_TERRAINS] =
+{
+    true, true, true, false,
+    false, false, false, false
+};
+
+bool terrain_is_opaque(enum terrain_num terr)
+{
+    return terrain_opacity[terr];
 }
 
 /* map.c */
diff --git a/map.h b/map.h
index a9ddd36..e4277f1 100644 (file)
--- a/map.h
+++ b/map.h
@@ -38,7 +38,8 @@ enum terrain_num {
     // cheap hack: opaque terrain goes first, and walls very first.
     WALL = 0, HARDWALL, DOOR, FLOOR, ALTAR, STAIRS, LAVA, WATER
 };
-
+#define MAX_TERRAIN (WATER)
+#define NUM_TERRAINS (1 + MAX_TERRAIN)
 
 #define MAPFLAG_EXPLORED 0x00000001
 #define MAPFLAG_HARDWALL 0x00000002
@@ -85,7 +86,7 @@ extern void build_level(void);
 extern void populate_level(void);
 extern void inject_player(void);
 extern void explore_around(int y, int x);
-
+extern bool terrain_is_opaque(enum terrain_num terr);
 #endif
 
 /* map.h */
index c3696f5..7c273e7 100644 (file)
@@ -526,7 +526,6 @@ int mon_visible(int mon)
     }
     dy = monsters[mon].y - u.y;
     dx = monsters[mon].x - u.x;
-    /* Cave Chop FoV: The screen. */
     if (((dy > -11) && (dy < 11) && (dx > -11) && (dx < 11)))
     {
        return player_fov.affected[MAX_FOV_RADIUS + dy][MAX_FOV_RADIUS + dx];
index c17d6d4..59f4be1 100644 (file)
@@ -29,6 +29,8 @@
 #ifndef VICTRIX_ABYSSI_H
 #define VICTRIX_ABYSSI_H
 
+#define _GNU_SOURCE
+
 #include <stdlib.h>
 #include <stdint.h>
 #include <stdbool.h>