summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source
diff options
context:
space:
mode:
authordshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-06-04 06:53:25 +0000
committerdshaligram <dshaligram@c06c8d41-db1a-0410-9941-cceddc491573>2007-06-04 06:53:25 +0000
commita75a924ca5f67336d9e065ab307d976c4cd8fabc (patch)
tree052710fb2cac216521e398e8774426092426bf41 /crawl-ref/source
parentb53b7421dc0bda8dc3a4713cad64a6275132261c (diff)
downloadcrawl-ref-a75a924ca5f67336d9e065ab307d976c4cd8fabc.tar.gz
crawl-ref-a75a924ca5f67336d9e065ab307d976c4cd8fabc.zip
[1699948] Allow changing the viewport size if you're using a larger terminal
than 80x24. Also allow moving the PC around the viewport without scrolling the viewport if the viewport is large enough. This is not tested on DOS and Windows yet. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1524 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source')
-rw-r--r--crawl-ref/source/abyss.cc9
-rw-r--r--crawl-ref/source/acr.cc7
-rw-r--r--crawl-ref/source/defines.h3
-rw-r--r--crawl-ref/source/direct.cc55
-rw-r--r--crawl-ref/source/direct.h17
-rw-r--r--crawl-ref/source/dungeon.h14
-rw-r--r--crawl-ref/source/externs.h116
-rw-r--r--crawl-ref/source/files.cc7
-rw-r--r--crawl-ref/source/initfile.cc67
-rw-r--r--crawl-ref/source/libdos.cc14
-rw-r--r--crawl-ref/source/libunix.cc13
-rw-r--r--crawl-ref/source/libw32c.cc34
-rw-r--r--crawl-ref/source/message.cc10
-rw-r--r--crawl-ref/source/monplace.cc3
-rw-r--r--crawl-ref/source/output.cc44
-rw-r--r--crawl-ref/source/player.cc22
-rw-r--r--crawl-ref/source/spells1.cc3
-rw-r--r--crawl-ref/source/spells3.cc8
-rw-r--r--crawl-ref/source/spells4.cc8
-rw-r--r--crawl-ref/source/stuff.cc6
-rw-r--r--crawl-ref/source/tags.cc5
-rw-r--r--crawl-ref/source/view.cc249
-rw-r--r--crawl-ref/source/view.h2
23 files changed, 516 insertions, 200 deletions
diff --git a/crawl-ref/source/abyss.cc b/crawl-ref/source/abyss.cc
index 68b64edfcc..6dbf138ada 100644
--- a/crawl-ref/source/abyss.cc
+++ b/crawl-ref/source/abyss.cc
@@ -282,8 +282,7 @@ void area_shift(void)
}
}
- you.x_pos = 45;
- you.y_pos = 35;
+ you.moveto(45, 35);
generate_area(5, 5, (GXM - 5), (GYM - 5));
@@ -331,8 +330,7 @@ void abyss_teleport( bool new_area )
if (i < 100)
{
- you.x_pos = x;
- you.y_pos = y;
+ you.moveto(x, y);
return;
}
}
@@ -384,8 +382,7 @@ void abyss_teleport( bool new_area )
ASSERT( env.cloud_no == 0 );
- you.x_pos = 45;
- you.y_pos = 35;
+ you.moveto(45, 35);
generate_area( 10, 10, (GXM - 10), (GYM - 10) );
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index 67d99f71c9..9bb5a0abd7 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -894,7 +894,8 @@ static void input()
handle_delay();
- gotoxy(VIEW_CX, VIEW_CY);
+ const coord_def cwhere = grid2view(you.pos());
+ gotoxy(cwhere.x, cwhere.y);
if ( you_are_delayed() )
{
@@ -1127,6 +1128,7 @@ void process_command( command_type cmd )
{
mpr("Clearing level map.");
clear_map();
+ crawl_view.set_player_at(you.pos(), true);
}
break;
@@ -1347,6 +1349,7 @@ void process_command( command_type cmd )
#endif
plox[0] = 0;
show_map(plox, true);
+ crawl_view.set_player_at(you.pos(), true);
redraw_screen();
if (plox[0] > 0)
start_travel(plox[0], plox[1]);
@@ -1450,7 +1453,7 @@ void process_command( command_type cmd )
#endif
case CMD_SAVE_GAME:
- if (yesno("Save game and exit?", true, 'n'))
+ if (yesno("Save game and exit? ", true, 'n'))
save_game(true);
break;
diff --git a/crawl-ref/source/defines.h b/crawl-ref/source/defines.h
index 9ce64087e6..5b8bb6200c 100644
--- a/crawl-ref/source/defines.h
+++ b/crawl-ref/source/defines.h
@@ -109,6 +109,9 @@
#define Y_ABYSS_WIDTH (Y_ABYSS_2 - Y_ABYSS_1 + 1)
#define Y_ABYSS_CENTER (Y_ABYSS_1 + Y_ABYSS_WIDTH / 2)
+#define LOS_RADIUS 8
+#define ENV_SHOW_OFFSET (LOS_RADIUS + 1)
+#define ENV_SHOW_DIAMETER (ENV_SHOW_OFFSET * 2 + 1)
#define LOS_SX 8
#define LOS_EX 25
#define LOS_SY 1
diff --git a/crawl-ref/source/direct.cc b/crawl-ref/source/direct.cc
index 59429c4349..5bf61db694 100644
--- a/crawl-ref/source/direct.cc
+++ b/crawl-ref/source/direct.cc
@@ -85,8 +85,8 @@ static char find_square_wrapper( int tx, int ty,
bool wrap = false,
int los = LOS_ANY);
-static char find_square( unsigned char xps, unsigned char yps,
- FixedVector<char, 2> &mfp, char direction,
+static char find_square( int xps, int yps,
+ FixedVector<char, 2> &mfp, int direction,
bool (*targ)(int, int, int),
int mode = TARG_ANY,
bool wrap = false,
@@ -827,8 +827,9 @@ static void describe_oos_square(int x, int y)
bool in_vlos(int x, int y)
{
- return in_los_bounds(x, y)
- && (env.show[x - LOS_SX][y] || (x == VIEW_CX && y == VIEW_CY));
+ return in_los_bounds(x, y)
+ && (env.show(view2show(coord_def(x, y)))
+ || coord_def(x, y) == grid2view(you.pos()));
}
bool in_vlos(const coord_def &pos)
@@ -838,13 +839,7 @@ bool in_vlos(const coord_def &pos)
bool in_los(int x, int y)
{
- const int tx = x + VIEW_CX - you.x_pos,
- ty = y + VIEW_CY - you.y_pos;
-
- if (!in_los_bounds(tx, ty))
- return (false);
-
- return (x == you.x_pos && y == you.y_pos) || env.show[tx - LOS_SX][ty];
+ return (in_vlos(grid2view(coord_def(x, y))));
}
static bool find_monster( int x, int y, int mode )
@@ -929,12 +924,12 @@ static int next_los(int dir, int los, bool wrap)
bool in_viewport_bounds(int x, int y)
{
- return (x >= VIEW_SX && x <= VIEW_EX && y >= VIEW_SY && y <= VIEW_EY);
+ return crawl_view.in_view_viewport(coord_def(x, y));
}
bool in_los_bounds(int x, int y)
{
- return !(x > LOS_EX || x < LOS_SX || y > LOS_EY || y < LOS_SY);
+ return crawl_view.in_view_los(coord_def(x, y));
}
//---------------------------------------------------------------
@@ -951,8 +946,8 @@ bool in_los_bounds(int x, int y)
// monsters will be targeted.
//
//---------------------------------------------------------------
-static char find_square( unsigned char xps, unsigned char yps,
- FixedVector<char, 2> &mfp, char direction,
+static char find_square( int xps, int yps,
+ FixedVector<char, 2> &mfp, int direction,
bool (*find_targ)( int x, int y, int mode ),
int mode, bool wrap, int los )
{
@@ -961,8 +956,8 @@ static char find_square( unsigned char xps, unsigned char yps,
int temp_xps = xps;
int temp_yps = yps;
- char x_change = 0;
- char y_change = 0;
+ int x_change = 0;
+ int y_change = 0;
bool onlyVis = false, onlyHidden = false;
@@ -977,8 +972,8 @@ static char find_square( unsigned char xps, unsigned char yps,
{
// We've been told to flip between visible/hidden, so we
// need to find what we're currently on.
- const bool vis = (env.show[xps - 8][yps]
- || (xps == VIEW_CX && yps == VIEW_CY));
+ const bool vis = (env.show(view2show(coord_def(xps, yps)))
+ || view2grid(coord_def(xps, yps)) == you.pos());
if (wrap && (vis != (los == LOS_FLIPVH)) == (direction == 1))
{
@@ -1001,9 +996,17 @@ static char find_square( unsigned char xps, unsigned char yps,
onlyVis = (los & LOS_VISIBLE);
onlyHidden = (los & LOS_HIDDEN);
- const int minx = VIEW_SX, maxx = VIEW_EX,
- miny = VIEW_SY - VIEW_Y_DIFF, maxy = VIEW_EY + VIEW_Y_DIFF,
- ctrx = VIEW_CX, ctry = VIEW_CY;
+ int radius = 0;
+ if (crawl_view.viewsz.x > crawl_view.viewsz.y)
+ radius = crawl_view.viewsz.x - LOS_RADIUS - 1;
+ else
+ radius = crawl_view.viewsz.y - LOS_RADIUS - 1;
+
+ const coord_def vyou = grid2view(you.pos());
+
+ const int minx = vyou.x - radius, maxx = vyou.x + radius,
+ miny = vyou.y - radius, maxy = vyou.y + radius,
+ ctrx = vyou.x, ctry = vyou.y;
while (temp_xps >= minx - 1 && temp_xps <= maxx
&& temp_yps <= maxy && temp_yps >= miny - 1)
@@ -1135,17 +1138,17 @@ static char find_square( unsigned char xps, unsigned char yps,
//if (!in_los_bounds(temp_xps, temp_yps))
// continue;
- if (temp_xps < minx - 1 || temp_xps > maxx
- || temp_yps < VIEW_SY || temp_yps > VIEW_EY)
+ if (!crawl_view.in_grid_viewport(coord_def(targ_x, targ_y)))
continue;
- if (targ_x < 1 || targ_x >= GXM || targ_y < 1 || targ_y >= GYM)
+ if (!in_bounds(targ_x, targ_y))
continue;
if ((onlyVis || onlyHidden) && onlyVis != in_los(targ_x, targ_y))
continue;
- if (find_targ(targ_x, targ_y, mode)) {
+ if (find_targ(targ_x, targ_y, mode))
+ {
mfp[0] = temp_xps;
mfp[1] = temp_yps;
return (1);
diff --git a/crawl-ref/source/direct.h b/crawl-ref/source/direct.h
index 460b14527a..973000e8de 100644
--- a/crawl-ref/source/direct.h
+++ b/crawl-ref/source/direct.h
@@ -42,32 +42,37 @@ std::vector<dungeon_feature_type> features_by_desc(const text_pattern &pattern);
inline int view2gridX(int vx)
{
- return (you.x_pos + vx - VIEW_CX);
+ return (crawl_view.vgrdc.x + vx - crawl_view.view_centre().x);
}
inline int view2gridY(int vy)
{
- return (you.y_pos + vy - VIEW_CY);
+ return (crawl_view.vgrdc.y + vy - crawl_view.view_centre().y);
}
inline coord_def view2grid(const coord_def &pos)
{
- return coord_def( view2gridX(pos.x), view2gridY(pos.y) );
+ return pos - crawl_view.view_centre() + crawl_view.vgrdc;
}
inline int grid2viewX(int gx)
{
- return (gx - you.x_pos + VIEW_CX);
+ return (gx - crawl_view.vgrdc.x + crawl_view.view_centre().x);
}
inline int grid2viewY(int gy)
{
- return (gy - you.y_pos + VIEW_CY);
+ return (gy - crawl_view.vgrdc.y + crawl_view.view_centre().y);
}
inline coord_def grid2view(const coord_def &pos)
{
- return coord_def( grid2viewX(pos.x), grid2viewY(pos.y) );
+ return (pos - crawl_view.vgrdc + crawl_view.view_centre());
+}
+
+inline coord_def view2show(const coord_def &pos)
+{
+ return (pos - crawl_view.vlos1 + coord_def(1, 1));
}
#endif
diff --git a/crawl-ref/source/dungeon.h b/crawl-ref/source/dungeon.h
index 226be99c82..172cea7061 100644
--- a/crawl-ref/source/dungeon.h
+++ b/crawl-ref/source/dungeon.h
@@ -56,6 +56,11 @@ struct dgn_region
return dgn_region(left, top, right - left + 1, bottom - top + 1);
}
+ static dgn_region absolute(const coord_def &c1, const coord_def &c2)
+ {
+ return dgn_region(c1.x, c1.y, c2.x, c2.y);
+ }
+
static bool between(int val, int low, int high)
{
return (val >= low && val <= high);
@@ -63,8 +68,13 @@ struct dgn_region
bool contains(const coord_def &p) const
{
- return (p.x >= pos.x && p.x < pos.x + size.x
- && p.y >= pos.y && p.y < pos.y + size.y);
+ return contains(p.x, p.y);
+ }
+
+ bool contains(int xp, int yp) const
+ {
+ return (xp >= pos.x && xp < pos.x + size.x
+ && yp >= pos.y && yp < pos.y + size.y);
}
bool fully_contains(const coord_def &p) const
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index cc73ba5a5c..635d853f6a 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -277,19 +277,30 @@ struct coord_def
y -= other.y;
return (*this);
}
+
+ const coord_def &operator /= (int div)
+ {
+ x /= div;
+ y /= div;
+ return (*this);
+ }
coord_def operator + (const coord_def &other) const
{
coord_def copy = *this;
- copy += other;
- return (copy);
+ return (copy += other);
}
coord_def operator - (const coord_def &other) const
{
coord_def copy = *this;
- copy -= other;
- return (copy);
+ return (copy -= other);
+ }
+
+ coord_def operator / (int div) const
+ {
+ coord_def copy = *this;
+ return (copy /= div);
}
int abs() const
@@ -756,6 +767,11 @@ public:
bool operator < (const player &p) const;
public:
+ // Low-level move the player to (x, y). Use these functions instead of
+ // changing x_pos and y_pos directly.
+ void moveto(int x, int y);
+ void moveto(const coord_def &c);
+
bool in_water() const;
bool can_swim() const;
bool is_levitating() const;
@@ -1141,8 +1157,10 @@ struct crawl_environment
FixedArray< unsigned short, GXM, GYM > map; // discovered terrain
FixedArray< map_colour, GXM, GYM > map_col; // map colours
- FixedArray< unsigned int, 19, 19> show; // view window char
- FixedArray< unsigned short, 19, 19> show_col; // view window colour
+ FixedArray<unsigned, ENV_SHOW_DIAMETER, ENV_SHOW_DIAMETER>
+ show; // view window char
+ FixedArray<unsigned short, ENV_SHOW_DIAMETER, ENV_SHOW_DIAMETER>
+ show_col; // view window colour
FixedVector< cloud_struct, MAX_CLOUDS > cloud; // cloud list
unsigned char cloud_no;
@@ -1227,6 +1245,72 @@ struct system_environment
extern system_environment SysEnv;
+struct crawl_view_geometry
+{
+public:
+ coord_def termsz; // Size of the terminal.
+ coord_def viewp; // Left-top pos of viewport.
+ coord_def viewsz; // Size of the viewport (play area).
+ coord_def hudp; // Left-top pos of status area.
+ coord_def hudsz; // Size of the status area.
+ coord_def msgp; // Left-top pos of the message pane.
+ coord_def msgsz; // Size of the message pane.
+
+ coord_def vgrdc; // What grid pos is at the centre of the view
+ // usually you.pos().
+
+ coord_def viewhalfsz;
+
+ coord_def glos1, glos2; // LOS limit grid coords (inclusive)
+ coord_def vlos1, vlos2; // LOS limit viewport coords (inclusive)
+
+ static const int message_min_lines = 7;
+ static const int hud_min_width = 41;
+ static const int hud_min_gutter = 3;
+ static const int hud_max_gutter = 6;
+
+private:
+ coord_def last_player_pos;
+
+public:
+ crawl_view_geometry();
+ void init_geometry();
+
+ void init_view();
+ void set_player_at(const coord_def &c, bool force_centre = false);
+
+ coord_def view_centre() const
+ {
+ return viewp + viewhalfsz;
+ }
+
+ bool in_grid_los(const coord_def &c) const
+ {
+ return (c.x >= glos1.x && c.x <= glos2.x
+ && c.y >= glos1.y && c.y <= glos2.y);
+ }
+
+ bool in_view_los(const coord_def &c) const
+ {
+ return (c.x >= vlos1.x && c.x <= vlos2.x
+ && c.y >= vlos1.y && c.y <= vlos2.y);
+ }
+
+ bool in_view_viewport(const coord_def &c) const
+ {
+ return (c.x >= viewp.x && c.y >= viewp.y
+ && c.x < viewp.x + viewsz.x
+ && c.y < viewp.y + viewsz.y);
+ }
+
+ bool in_grid_viewport(const coord_def &c) const
+ {
+ return in_view_viewport(c - vgrdc + view_centre());
+ }
+};
+
+extern crawl_view_geometry crawl_view;
+
struct message_filter
{
int channel; // Use -1 to match any channel.
@@ -1349,6 +1433,26 @@ public:
bool messaging; // Check for messages.
#endif
+ int view_max_width;
+ int view_max_height;
+
+ // The view lock variables force centering the viewport around the PC @
+ // at all times (the default). If view locking is not enabled, the viewport
+ // scrolls only when the PC hits the edge of it.
+ bool view_lock_x;
+ bool view_lock_y;
+
+ // For an unlocked viewport, this will center the viewport when scrolling.
+ bool center_on_scroll;
+
+ // If symmetric_scroll is set, for diagonal moves, if the view
+ // scrolls at all, it'll scroll diagonally.
+ bool symmetric_scroll;
+
+ // How far from the viewport edge is scrolling forced.
+ int scroll_margin_x;
+ int scroll_margin_y;
+
bool autopickup_on;
bool autoprayer_on;
diff --git a/crawl-ref/source/files.cc b/crawl-ref/source/files.cc
index 4a3c39c44d..2e4ec6c9d9 100644
--- a/crawl-ref/source/files.cc
+++ b/crawl-ref/source/files.cc
@@ -810,8 +810,7 @@ static void place_player_on_stair(branch_type old_branch, int stair_taken)
}
const coord_def where_to_go = find_nearby_stair(stair_taken, find_first);
- you.x_pos = where_to_go.x;
- you.y_pos = where_to_go.y;
+ you.moveto(where_to_go);
}
static void close_level_gates()
@@ -999,9 +998,9 @@ bool load( int stair_taken, load_mode_type load_mode, bool was_a_labyrinth,
}
else if (load_mode != LOAD_RESTART_GAME && you.level_type == LEVEL_ABYSS)
{
- you.x_pos = 45;
- you.y_pos = 35;
+ you.moveto(45, 35);
}
+ crawl_view.set_player_at(you.pos(), true);
// This should fix the "monster occuring under the player" bug?
if (mgrd[you.x_pos][you.y_pos] != NON_MONSTER)
diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc
index 401dfda212..30e9619699 100644
--- a/crawl-ref/source/initfile.cc
+++ b/crawl-ref/source/initfile.cc
@@ -555,6 +555,17 @@ void game_options::reset_options()
messaging = true;
#endif
+ view_max_width = VIEW_EX;
+ view_max_height = VIEW_EY;
+
+ view_lock_x = true;
+ view_lock_y = true;
+
+ center_on_scroll = false;
+ symmetric_scroll = true;
+ scroll_margin_x = 4;
+ scroll_margin_y = 4;
+
autopickup_on = true;
autoprayer_on = false;
@@ -1855,6 +1866,62 @@ void game_options::read_option_line(const std::string &str, bool runscript)
messaging = read_bool(field, messaging);
}
#endif
+ else if (key == "view_max_width")
+ {
+ view_max_width = atoi(field.c_str());
+ if (view_max_width < VIEW_EX)
+ view_max_width = VIEW_EX;
+ else if (view_max_width > GXM + 1)
+ view_max_width = GXM + 1;
+ }
+ else if (key == "view_max_height")
+ {
+ view_max_height = atoi(field.c_str());
+ if (view_max_height < VIEW_EY)
+ view_max_height = VIEW_EY;
+ else if (view_max_height > GYM + 1)
+ view_max_height = GYM + 1;
+ }
+ else if (key == "view_lock_x")
+ {
+ view_lock_x = read_bool(field, view_lock_x);
+ }
+ else if (key == "view_lock_y")
+ {
+ view_lock_y = read_bool(field, view_lock_y);
+ }
+ else if (key == "view_lock")
+ {
+ const bool lock = read_bool(field, true);
+ view_lock_x = view_lock_y = lock;
+ }
+ else if (key == "center_on_scroll")
+ {
+ center_on_scroll = read_bool(field, center_on_scroll);
+ }
+ else if (key == "symmetric_scroll")
+ {
+ symmetric_scroll = read_bool(field, symmetric_scroll);
+ }
+ else if (key == "scroll_margin_x")
+ {
+ scroll_margin_x = atoi(field.c_str());
+ if (scroll_margin_x < 0)
+ scroll_margin_x = 0;
+ }
+ else if (key == "scroll_margin_y")
+ {
+ scroll_margin_y = atoi(field.c_str());
+ if (scroll_margin_y < 0)
+ scroll_margin_y = 0;
+ }
+ else if (key == "scroll_margin")
+ {
+ int scrollmarg = atoi(field.c_str());
+ if (scrollmarg < 0)
+ scrollmarg = 0;
+ scroll_margin_x = scroll_margin_y = scrollmarg;
+ }
else if (key == "use_notes")
{
use_notes = read_bool( field, use_notes );
diff --git a/crawl-ref/source/libdos.cc b/crawl-ref/source/libdos.cc
index 2db3422868..8c197e1c8e 100644
--- a/crawl-ref/source/libdos.cc
+++ b/crawl-ref/source/libdos.cc
@@ -28,7 +28,8 @@ void init_libdos()
void clear_message_window()
{
- window(1, VIEW_EY + 1, get_number_of_cols(), get_number_of_lines());
+ window(crawl_view.msgp.x, crawl_view.msgp.y,
+ get_number_of_cols(), get_number_of_lines());
clrscr();
window(1, 1, get_number_of_cols(), get_number_of_lines());
}
@@ -38,8 +39,9 @@ static void scroll_message_window()
const int x = wherex(), y = wherey();
textcolor(LIGHTGREY);
- movetext(1, VIEW_EY + 2, get_number_of_cols(), get_number_of_lines(),
- 1, VIEW_EY + 1);
+ movetext(crawl_view.msgp.x, crawl_view.msgp.y + 1,
+ get_number_of_cols(), get_number_of_lines(),
+ crawl_view.msgp.x, crawl_view.msgp.y);
gotoxy(1, get_number_of_lines());
clreol();
@@ -48,19 +50,19 @@ static void scroll_message_window()
gotoxy(x, y - 1);
}
-extern int get_message_window_height();
void message_out(int which_line, int colour, const char *s, int firstcol,
bool newline)
{
if (!firstcol)
firstcol = Options.delay_message_clear? 2 : 1;
- gotoxy(firstcol, which_line + VIEW_EY + 1);
+ gotoxy(firstcol + crawl_view.msgp.x - 1,
+ which_line + crawl_view.msgp.y);
textcolor(colour);
cprintf("%s", s);
- if (newline && which_line == get_message_window_height() - 1)
+ if (newline && which_line == crawl_view.msgsz.y - 1)
scroll_message_window();
}
diff --git a/crawl-ref/source/libunix.cc b/crawl-ref/source/libunix.cc
index 79f91d17b7..b9d9342e92 100644
--- a/crawl-ref/source/libunix.cc
+++ b/crawl-ref/source/libunix.cc
@@ -234,10 +234,8 @@ static void handle_hangup(int)
static WINDOW *Message_Window;
static void setup_message_window()
{
- extern int get_message_window_height();
-
- Message_Window = newwin( get_message_window_height(), get_number_of_cols(),
- VIEW_EY, 0 );
+ Message_Window = newwin( crawl_view.msgsz.y, crawl_view.msgsz.x,
+ crawl_view.msgp.y - 1, crawl_view.msgp.x - 1 );
if (!Message_Window)
{
fprintf(stderr, "Unable to create message window!");
@@ -258,8 +256,6 @@ void clear_message_window()
void message_out(int which_line, int color, const char *s, int firstcol,
bool newline)
{
- extern int get_message_window_height();
-
wattrset( Message_Window, curs_fg_attr(color) );
if (!firstcol)
@@ -269,7 +265,7 @@ void message_out(int which_line, int color, const char *s, int firstcol,
mvwaddstr(Message_Window, which_line, firstcol, s);
- if (newline && which_line == get_message_window_height() - 1)
+ if (newline && which_line == crawl_view.msgsz.y - 1)
{
int x, y;
getyx(Message_Window, y, x);
@@ -282,7 +278,7 @@ void message_out(int which_line, int color, const char *s, int firstcol,
{
int x, y;
getyx(Message_Window, y, x);
- move(y + VIEW_EY, x);
+ move(y + crawl_view.msgp.y - 1, crawl_view.msgp.x - 1 + x);
}
wrefresh(Message_Window);
@@ -327,6 +323,7 @@ void unixcurses_startup( void )
scrollok(stdscr, TRUE);
+ crawl_view.init_geometry();
setup_message_window();
}
diff --git a/crawl-ref/source/libw32c.cc b/crawl-ref/source/libw32c.cc
index c111aa5251..2797568046 100644
--- a/crawl-ref/source/libw32c.cc
+++ b/crawl-ref/source/libw32c.cc
@@ -559,11 +559,12 @@ void textcolor(int c)
void clear_message_window()
{
- PCHAR_INFO pci = screen + SCREENINDEX(0, VIEW_EY);
+ PCHAR_INFO pci = screen + SCREENINDEX(crawl_view.msgp.x - 1,
+ crawl_view.msgp.y - 1);
const int ncols = get_number_of_cols();
for (int x = 0; x < ncols; x++)
{
- for (int y = 0; y < get_message_window_height(); y++)
+ for (int y = 0; y < crawl_view.msgsz.y; y++)
{
pci->Char.AsciiChar = ' ';
pci->Attributes = 0;
@@ -574,39 +575,37 @@ void clear_message_window()
COORD source;
SMALL_RECT target;
- source.X = 0;
- source.Y = VIEW_EY;
- target.Left = 0;
- target.Top = VIEW_EY;
+ source.X = crawl_view.msgp.x - 1;
+ source.Y = crawl_view.msgp.y - 1;
+ target.Left = crawl_view.msgp.x - 1;
+ target.Top = crawl_view.msgp.y - 1;
target.Right = get_number_of_cols() - 1;
target.Bottom = get_number_of_lines() - 1;
WriteConsoleOutput(outbuf, screen, screensize, source, &target);
}
-extern int get_message_window_height();
static void scroll_message_buffer()
{
- memmove( screen + SCREENINDEX(0, VIEW_EY),
- screen + SCREENINDEX(0, VIEW_EY + 1),
- get_message_window_height() * get_number_of_cols()
- * sizeof(*screen) );
+ memmove( screen + SCREENINDEX(crawl_view.msgp.x - 1, crawl_view.msgp.y - 1),
+ screen + SCREENINDEX(crawl_view.msgp.x - 1, crawl_view.msgp.y),
+ crawl_view.msgsz.y * get_number_of_cols() * sizeof(*screen) );
}
static void scroll_message_window()
{
SMALL_RECT scroll_rectangle, clip_rectangle;
- scroll_rectangle.Left = 0;
- scroll_rectangle.Top = VIEW_EY + 1;
+ scroll_rectangle.Left = crawl_view.msgp.x - 1;
+ scroll_rectangle.Top = crawl_view.msgp.y;
scroll_rectangle.Right = get_number_of_cols() - 1;
scroll_rectangle.Bottom = get_number_of_lines() - 1;
clip_rectangle = scroll_rectangle;
- clip_rectangle.Top = VIEW_EY;
+ clip_rectangle.Top = crawl_view.msgp.y - 1;
COORD new_origin;
- new_origin.X = 0;
- new_origin.Y = VIEW_EY;
+ new_origin.X = crawl_view.msgp.x;
+ new_origin.Y = crawl_view.msgp.y - 1;
CHAR_INFO fill;
fill.Char.AsciiChar = ' ';
@@ -629,7 +628,8 @@ void message_out(int which_line, int colour, const char *s, int firstcol,
if (!firstcol)
firstcol = Options.delay_message_clear? 2 : 1;
- gotoxy(firstcol, which_line + VIEW_EY + 1);
+ gotoxy(firstcol - 1 + crawl_view.viewp.x,
+ which_line + crawl_view.viewp.y);
textcolor(colour);
cprintf("%s", s);
diff --git a/crawl-ref/source/message.cc b/crawl-ref/source/message.cc
index b0a1e98159..a82d5ffd07 100644
--- a/crawl-ref/source/message.cc
+++ b/crawl-ref/source/message.cc
@@ -459,7 +459,7 @@ static void mpr_check_patterns(const std::string& message, int channel,
static void mpr_store_messages(const std::string& message,
int channel, int param)
{
- const int num_lines = get_message_window_height();
+ const int num_lines = crawl_view.msgsz.y;
// Prompt lines are presumably shown to / seen by the player accompanied
// by a request for input, which should do the equivalent of a more(); to
@@ -516,7 +516,7 @@ static int prepare_message(const std::string& imsg, int channel, int param)
{
mpr_check_patterns(imsg, channel, param);
flush_input_buffer( FLUSH_ON_MESSAGE );
- const int num_lines = get_message_window_height();
+ const int num_lines = crawl_view.msgsz.y;
if (New_Message_Count == num_lines - 1)
more();
@@ -610,7 +610,7 @@ void formatted_message_history(const std::string st, int channel, int param)
flush_input_buffer( FLUSH_ON_MESSAGE );
- const int num_lines = get_message_window_height();
+ const int num_lines = crawl_view.msgsz.y;
if (New_Message_Count == num_lines - 1)
more();
@@ -652,13 +652,13 @@ void more(void)
char keypress = 0;
if (Options.tutorial_left)
- message_out(get_message_window_height() - 1,
+ message_out(crawl_view.msgsz.y - 1,
LIGHTGREY,
"--more-- "
"Press Ctrl-P to reread old messages",
2, false);
else
- message_out(get_message_window_height() - 1,
+ message_out(crawl_view.msgsz.y - 1,
LIGHTGREY, "--more--", 2, false);
do
diff --git a/crawl-ref/source/monplace.cc b/crawl-ref/source/monplace.cc
index 41c23abd48..463217bd98 100644
--- a/crawl-ref/source/monplace.cc
+++ b/crawl-ref/source/monplace.cc
@@ -372,8 +372,7 @@ bool place_monster(int &id, int mon_type, int power, char behaviour,
int tpy = py;
px = you.x_pos;
py = you.y_pos;
- you.x_pos = tpx;
- you.y_pos = tpy;
+ you.moveto(tpx, tpy);
}
proxOK = (pval > 0);
diff --git a/crawl-ref/source/output.cc b/crawl-ref/source/output.cc
index f113605a5b..9439c2f9e8 100644
--- a/crawl-ref/source/output.cc
+++ b/crawl-ref/source/output.cc
@@ -65,7 +65,7 @@ void update_message_status()
{
textcolor(LIGHTBLUE);
- gotoxy(75, 2);
+ gotoxy(crawl_view.hudp.x + 35, 2);
if (SysEnv.have_messages)
cprintf("(msg)");
else
@@ -88,7 +88,7 @@ void update_turn_count()
// FIXME: Create some kind of layout manager class so we can
// templatise the heads-up display layout and stop hardcoding
// these coords.
- gotoxy(61, 10);
+ gotoxy(crawl_view.hudp.x + 21, 10);
textcolor(LIGHTGREY);
// Show the turn count starting from 1. You can still quit on turn 0.
@@ -99,6 +99,8 @@ void print_stats(void)
{
textcolor(LIGHTGREY);
+ const int xcol = crawl_view.hudp.x;
+
// Displayed evasion is now tied to dex.
if (you.redraw_dexterity)
you.redraw_evasion = true;
@@ -122,7 +124,7 @@ void print_stats(void)
}
}
- gotoxy(44, 3);
+ gotoxy(xcol + 4, 3);
cprintf( "%d", you.hp );
@@ -157,7 +159,7 @@ void print_stats(void)
break;
}
}
- gotoxy(47, 4);
+ gotoxy(xcol + 7, 4);
cprintf( "%d", you.magic_points);
@@ -183,7 +185,7 @@ void print_stats(void)
if (you.max_strength > 72)
you.max_strength = 72;
- gotoxy(45, 7);
+ gotoxy(xcol + 5, 7);
if (you.might)
textcolor(LIGHTBLUE); // no end of effect warning
@@ -216,7 +218,7 @@ void print_stats(void)
if (you.max_intel > 72)
you.max_intel = 72;
- gotoxy(45, 8);
+ gotoxy(xcol + 5, 8);
if (you.intel < you.max_intel)
textcolor(YELLOW);
@@ -245,7 +247,7 @@ void print_stats(void)
if (you.max_dex > 72)
you.max_dex = 72;
- gotoxy(45, 9);
+ gotoxy(xcol + 5, 9);
if (you.dex < you.max_dex)
textcolor(YELLOW);
@@ -266,7 +268,7 @@ void print_stats(void)
if (you.redraw_armour_class)
{
- gotoxy(44, 5);
+ gotoxy(xcol + 4, 5);
if (you.duration[DUR_STONEMAIL])
dur_colour( BLUE, (you.duration[DUR_STONEMAIL] <= 6) );
@@ -276,7 +278,7 @@ void print_stats(void)
cprintf( "%d ", player_AC() );
textcolor( LIGHTGREY );
- gotoxy(50, 5);
+ gotoxy(xcol + 10, 5);
if (you.duration[DUR_CONDENSATION_SHIELD]) //jmf: added 24mar2000
textcolor( LIGHTBLUE ); // no end of effect warning
@@ -289,7 +291,7 @@ void print_stats(void)
if (you.redraw_evasion)
{
- gotoxy(44, 6);
+ gotoxy(xcol + 4, 6);
if (you.duration[DUR_FORESCRY])
textcolor(LIGHTBLUE); // no end of effect warning
@@ -302,14 +304,14 @@ void print_stats(void)
if (you.redraw_gold)
{
- gotoxy(46, 10);
+ gotoxy(xcol + 6, 10);
cprintf( "%-8d", you.gold );
you.redraw_gold = 0;
}
if (you.redraw_experience)
{
- gotoxy(52, 11);
+ gotoxy(xcol + 12, 11);
#if DEBUG_DIAGNOSTICS
cprintf( "%d/%lu (%d/%d)",
@@ -330,14 +332,14 @@ void print_stats(void)
if (you.wield_change)
{
- gotoxy(40, 13);
+ gotoxy(xcol, 13);
#ifdef UNIX
clear_to_end_of_line();
#else
cprintf(" ");
#endif
- gotoxy(40, 13);
+ gotoxy(xcol, 13);
if (you.equip[EQ_WEAPON] != -1)
{
@@ -381,13 +383,13 @@ void print_stats(void)
if (you.redraw_status_flags & REDRAW_LINE_1_MASK)
{
- gotoxy(40, 14);
+ gotoxy(xcol, 14);
#ifdef UNIX
clear_to_end_of_line();
#else
cprintf( " " );
- gotoxy(40, 14);
+ gotoxy(xcol, 14);
#endif
switch (you.burden_state)
@@ -442,13 +444,13 @@ void print_stats(void)
if (you.redraw_status_flags & REDRAW_LINE_2_MASK)
{
- gotoxy(40, 15);
+ gotoxy(xcol, 15);
#ifdef UNIX
clear_to_end_of_line();
#else
cprintf( " " );
- gotoxy(40, 15);
+ gotoxy(xcol, 15);
#endif
// Max length of this line = 8 * 5 - 1 = 39
@@ -534,13 +536,13 @@ void print_stats(void)
if (you.redraw_status_flags & REDRAW_LINE_3_MASK)
{
- gotoxy(40, 16);
+ gotoxy(xcol, 16);
#ifdef UNIX
clear_to_end_of_line();
#else
cprintf( " " );
- gotoxy(40, 16);
+ gotoxy(xcol, 16);
#endif
// Max length of this line = 7 * 5 + 3 - 1 = 37
@@ -615,7 +617,7 @@ void print_stats(void)
#if DEBUG_DIAGNOSTICS
// debug mode GPS
- gotoxy(40, 17);
+ gotoxy(xcol, 17);
cprintf( "Position (%2d,%2d)", you.x_pos, you.y_pos );
#endif
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index 2542bf2da0..175db38a74 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -221,8 +221,7 @@ bool move_player_to_grid( int x, int y, bool stepped, bool allow_shift,
}
// have to move now so fall_into_a_pool will work
- you.x_pos = x;
- you.y_pos = y;
+ you.moveto(x, y);
viewwindow( true, false );
@@ -271,8 +270,7 @@ bool move_player_to_grid( int x, int y, bool stepped, bool allow_shift,
}
// move the player to location
- you.x_pos = x;
- you.y_pos = y;
+ you.moveto(x, y);
viewwindow( true, false );
@@ -3248,7 +3246,7 @@ void redraw_skill(const char your_name[kNameLen], const char class_name[80])
print_it[40] = 0;
- gotoxy(40, 1);
+ gotoxy(crawl_view.hudp.x, 1);
textcolor( LIGHTGREY );
cprintf( "%s", print_it );
@@ -5253,3 +5251,17 @@ bool player::is_icy() const
{
return (attribute[ATTR_TRANSFORMATION] == TRAN_ICE_BEAST);
}
+
+void player::moveto(int x, int y)
+{
+ x_pos = x;
+ y_pos = y;
+ crawl_view.set_player_at(coord_def(x, y));
+}
+
+void player::moveto(const coord_def &c)
+{
+ x_pos = c.x;
+ y_pos = c.y;
+ crawl_view.set_player_at(c);
+}
diff --git a/crawl-ref/source/spells1.cc b/crawl-ref/source/spells1.cc
index 555c81ebf1..536260e79a 100644
--- a/crawl-ref/source/spells1.cc
+++ b/crawl-ref/source/spells1.cc
@@ -152,8 +152,7 @@ void random_blink(bool allow_partial_control, bool override_abyss)
mpr("You blink.");
succ = true;
- you.x_pos = tx;
- you.y_pos = ty;
+ you.moveto(tx, ty);
if (you.level_type == LEVEL_ABYSS)
{
diff --git a/crawl-ref/source/spells3.cc b/crawl-ref/source/spells3.cc
index 548aa5de9f..8394a1c4f6 100644
--- a/crawl-ref/source/spells3.cc
+++ b/crawl-ref/source/spells3.cc
@@ -662,8 +662,7 @@ static bool teleport_player( bool allow_control, bool new_abyss_area )
if (is_controlled)
{
- you.x_pos = plox[0];
- you.y_pos = plox[1];
+ you.moveto(plox[0], plox[1]);
if ((grd[you.x_pos][you.y_pos] != DNGN_FLOOR
&& grd[you.x_pos][you.y_pos] != DNGN_SHALLOW_WATER)
@@ -693,7 +692,12 @@ static bool teleport_player( bool allow_control, bool new_abyss_area )
&& grd[you.x_pos][you.y_pos] != DNGN_SHALLOW_WATER)
|| mgrd[you.x_pos][you.y_pos] != NON_MONSTER
|| env.cgrid[you.x_pos][you.y_pos] != EMPTY_CLOUD);
+
+ // Necessary to update the view centre.
+ you.moveto(you.pos());
}
+ crawl_view.set_player_at(you.pos(), true);
+
return !is_controlled;
}
diff --git a/crawl-ref/source/spells4.cc b/crawl-ref/source/spells4.cc
index 55c9379973..2d19836752 100644
--- a/crawl-ref/source/spells4.cc
+++ b/crawl-ref/source/spells4.cc
@@ -1490,10 +1490,7 @@ static int spell_swap_func(int x, int y, int pow, int message)
int old_y = defender->y;
if (swap_places( defender ))
- {
- you.x_pos = old_x;
- you.y_pos = old_y;
- }
+ you.moveto(old_x, old_y);
}
return 1;
@@ -3038,8 +3035,7 @@ static int quadrant_blink(int x, int y, int pow, int garbage)
break;
}
- you.x_pos = tx;
- you.y_pos = ty;
+ you.moveto(tx, ty);
return 1;
}
diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc
index af677759ce..e948dbbcdd 100644
--- a/crawl-ref/source/stuff.cc
+++ b/crawl-ref/source/stuff.cc
@@ -334,6 +334,8 @@ void cio_init()
init_libdos();
#endif
+ crawl_view.init_geometry();
+
io_inited = true;
}
@@ -1050,9 +1052,9 @@ void zap_los_monsters()
{
losight(env.show, grd, you.x_pos, you.y_pos);
- for (int y = LOS_SY; y <= LOS_EY; ++y)
+ for (int y = crawl_view.vlos1.y; y <= crawl_view.vlos2.y; ++y)
{
- for (int x = LOS_SX; x <= LOS_EX; ++x)
+ for (int x = crawl_view.vlos1.x; x <= crawl_view.vlos2.x; ++x)
{
if (!in_vlos(x, y))
continue;
diff --git a/crawl-ref/source/tags.cc b/crawl-ref/source/tags.cc
index d88f2dcda1..bbfc298549 100644
--- a/crawl-ref/source/tags.cc
+++ b/crawl-ref/source/tags.cc
@@ -1042,8 +1042,9 @@ static void tag_read_you(struct tagHeader &th, char minorVersion)
you.base_magic_points = unmarshallShort(th);
you.base_magic_points2 = unmarshallShort(th);
- you.x_pos = unmarshallShort(th);
- you.y_pos = unmarshallShort(th);
+ const int x = unmarshallShort(th);
+ const int y = unmarshallShort(th);
+ you.moveto(x, y);
unmarshallString(th, you.class_name, 30);
diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc
index d253e2349e..c03decd6ff 100644
--- a/crawl-ref/source/view.cc
+++ b/crawl-ref/source/view.cc
@@ -28,6 +28,7 @@
#include <string.h>
#include <cmath>
+#include <sstream>
#ifdef DOS
#include <conio.h>
@@ -41,6 +42,7 @@
#include "debug.h"
#include "delay.h"
#include "direct.h"
+#include "dungeon.h"
#include "initfile.h"
#include "insult.h"
#include "itemprop.h"
@@ -76,6 +78,7 @@ static FixedVector<feature_def, NUM_FEATURES> Feature;
typedef unsigned short screen_buffer_t;
+crawl_view_geometry crawl_view;
FixedArray < unsigned int, 20, 19 > Show_Backup;
unsigned char show_green;
@@ -92,11 +95,6 @@ static int get_item_dngn_code(const item_def &item);
static void set_show_backup( int ex, int ey );
static int get_viewobj_flags(int viewobj);
-int get_message_window_height()
-{
- return (get_number_of_lines() - VIEW_EY);
-}
-
unsigned get_envmap_char(int x, int y)
{
return static_cast<unsigned char>(
@@ -1977,25 +1975,27 @@ void draw_border(void)
clrscr();
redraw_skill( you.your_name, player_title() );
- gotoxy(40, 2);
+ const int xcol = crawl_view.hudp.x;
+
+ gotoxy(xcol, 2);
cprintf( "%s %s", species_name( you.species, you.experience_level ),
(you.wizard ? "*WIZARD*" : "" ) );
- gotoxy(40, 3); cprintf("HP:");
- gotoxy(40, 4); cprintf("Magic:");
- gotoxy(40, 5); cprintf("AC:");
- gotoxy(40, 6); cprintf("EV:");
- gotoxy(40, 7); cprintf("Str:");
- gotoxy(40, 8); cprintf("Int:");
- gotoxy(40, 9); cprintf("Dex:");
- gotoxy(40, 10); cprintf("Gold:");
+ gotoxy(xcol, 3); cprintf("HP:");
+ gotoxy(xcol, 4); cprintf("Magic:");
+ gotoxy(xcol, 5); cprintf("AC:");
+ gotoxy(xcol, 6); cprintf("EV:");
+ gotoxy(xcol, 7); cprintf("Str:");
+ gotoxy(xcol, 8); cprintf("Int:");
+ gotoxy(xcol, 9); cprintf("Dex:");
+ gotoxy(xcol, 10); cprintf("Gold:");
if (Options.show_turns)
{
- gotoxy(55, 10);
+ gotoxy(xcol + 15, 10);
cprintf("Turn:");
}
- gotoxy(40, 11); cprintf("Experience:");
- gotoxy(40, 12); cprintf("Level");
+ gotoxy(xcol, 11); cprintf("Experience:");
+ gotoxy(xcol, 12); cprintf("Level");
} // end draw_border()
// Determines if the given feature is present at (x, y) in _grid_ coordinates.
@@ -3549,9 +3549,6 @@ std::string screenshot( bool fullscreen )
{
UNUSED( fullscreen );
- const int X_SIZE = VIEW_WIDTH;
- const int Y_SIZE = VIEW_HEIGHT;
-
// [ds] Screenshots need to be straight ASCII. We will now proceed to force
// the char and feature tables back to ASCII.
FixedVector<unsigned char, NUM_DCHAR_TYPES> char_table_bk;
@@ -3564,35 +3561,32 @@ std::string screenshot( bool fullscreen )
int firstpopline = -1;
int lastpopline = -1;
- char lines[Y_SIZE][X_SIZE + 1];
- for (int count_y = 0; count_y < Y_SIZE; count_y++)
+ std::vector<std::string> lines(crawl_view.viewsz.y);
+ for (int count_y = 1; count_y <= crawl_view.viewsz.y; count_y++)
{
int lastnonspace = -1;
- for (int count_x = 0; count_x < X_SIZE; count_x++)
+ for (int count_x = 1; count_x <= crawl_view.viewsz.x; count_x++)
{
// in grid coords
- const int gx = count_x + you.x_pos - 16;
- const int gy = count_y + you.y_pos - 8;
-
- int ch = (!map_bounds(gx, gy))
- ? 0
- : (count_x < 8 || count_x > 24)
- ? get_envmap_char(gx, gy)
- : (gx == you.x_pos && gy == you.y_pos)
- ? you.symbol
- : get_screen_glyph(gx, gy);
+ const coord_def gc = view2grid(coord_def(count_x, count_y));
+ int ch =
+ (!map_bounds(gc)) ? 0
+ : (!crawl_view.in_grid_los(gc)) ? get_envmap_char(gc.x, gc.y)
+ : (gc == you.pos()) ? you.symbol
+ : get_screen_glyph(gc.x, gc.y);
+
if (ch && !isprint(ch))
{
// [ds] Evil hack time again. Peek at grid, use that character.
- int object = grd[gx][gy];
+ int object = grd(gc);
unsigned short glych, glycol = 0;
if (object == DNGN_SECRET_DOOR)
- object = grid_secret_door_appearance( gx, gy );
+ object = grid_secret_door_appearance( gc.x, gc.y );
- get_symbol( gx, gy, object, &glych, &glycol );
+ get_symbol( gc.x, gc.y, object, &glych, &glycol );
ch = glych;
}
@@ -3612,17 +3606,17 @@ std::string screenshot( bool fullscreen )
firstpopline = count_y;
}
- lines[count_y][count_x] = ch;
+ lines[count_y - 1] += ch;
}
- lines[count_y][lastnonspace + 1] = 0;
+ lines[count_y - 1].erase(lastnonspace + 1);
}
// Restore char and feature tables
Options.char_table = char_table_bk;
init_feature_table();
- std::string ss;
+ std::ostringstream ss;
if (firstpopline != -1 && lastpopline != -1)
{
if (firstnonspace == -1)
@@ -3630,17 +3624,14 @@ std::string screenshot( bool fullscreen )
for (int i = firstpopline; i <= lastpopline; ++i)
{
- char *curr = lines[i];
-
- while (*curr && curr - lines[i] < firstnonspace)
- curr++;
-
- ss += curr;
- ss += EOL;
+ const std::string &ref = lines[i - 1];
+ if (firstnonspace < (int) ref.length())
+ ss << ref.substr(firstnonspace);
+ ss << EOL;
}
}
- return (ss);
+ return (ss.str());
}
static int viewmap_flash_colour()
@@ -3667,11 +3658,9 @@ static int viewmap_flash_colour()
//---------------------------------------------------------------
void viewwindow(bool draw_it, bool do_updates)
{
- const int X_SIZE = VIEW_WIDTH;
- const int Y_SIZE = VIEW_HEIGHT;
- const int BUFFER_SIZE = 1550;
-
- FixedVector < screen_buffer_t, BUFFER_SIZE > buffy;
+ std::vector<screen_buffer_t> buffy(
+ crawl_view.viewsz.y * crawl_view.viewsz.x * 2);
+
int count_x, count_y;
losight( env.show, grd, you.x_pos, you.y_pos ); // must be done first
@@ -3700,31 +3689,32 @@ void viewwindow(bool draw_it, bool do_updates)
if (flash_colour == BLACK)
flash_colour = viewmap_flash_colour();
- for (count_y = 0; count_y < Y_SIZE; count_y++)
+ for (count_y = 1; count_y <= crawl_view.viewsz.y; count_y++)
{
- for (count_x = 0; count_x < X_SIZE; count_x++)
+ for (count_x = 1; count_x <= crawl_view.viewsz.x; count_x++)
{
// in grid coords
- const int gx = count_x + you.x_pos - 16;
- const int gy = count_y + you.y_pos - 8;
+ const int gx = view2gridX(count_x);
+ const int gy = view2gridY(count_y);
if (Options.tutorial_left && in_bounds(gx, gy)
- && count_x >= 8 && count_x <= 24)
+ && crawl_view.in_grid_los(coord_def(gx, gy)))
{
const int ex = gx - you.x_pos + 9;
const int ey = gy - you.y_pos + 9;
- int object = env.show[ex][ey];
-
+ const int object = env.show[ex][ey];
if (object)
{
if (is_feature('>',gx,gy))
learned_something_new(TUT_SEEN_STAIRS,gx,gy);
else if (is_feature('_',gx,gy))
learned_something_new(TUT_SEEN_ALTAR,gx,gy);
- else if (grd[gx][gy] == DNGN_CLOSED_DOOR && see_grid( gx, gy ))
+ else if (grd[gx][gy] == DNGN_CLOSED_DOOR
+ && see_grid( gx, gy ))
learned_something_new(TUT_SEEN_DOOR,gx,gy);
- else if (grd[gx][gy] == DNGN_ENTER_SHOP && see_grid( gx, gy ))
+ else if (grd[gx][gy] == DNGN_ENTER_SHOP
+ && see_grid( gx, gy ))
learned_something_new(TUT_SEEN_SHOP,gx,gy);
}
}
@@ -3736,7 +3726,7 @@ void viewwindow(bool draw_it, bool do_updates)
buffy[bufcount] = 0;
buffy[bufcount + 1] = DARKGREY;
}
- else if (count_x < 8 || count_x > 24)
+ else if (!crawl_view.in_grid_los(coord_def(gx, gy)))
{
// outside the env.show area
buffy[bufcount] = get_envmap_char( gx, gy );
@@ -3875,12 +3865,11 @@ void viewwindow(bool draw_it, bool do_updates)
// avoiding unneeded draws when running
if (!you.running || (you.running < 0 && Options.travel_delay > -1))
{
- gotoxy( 1, 1 );
-
bufcount = 0;
- for (count_y = 0; count_y < Y_SIZE; count_y++)
+ for (count_y = 0; count_y < crawl_view.viewsz.y; count_y++)
{
- for (count_x = 0; count_x < X_SIZE; count_x++)
+ gotoxy( crawl_view.viewp.x, crawl_view.viewp.y + count_y );
+ for (count_x = 0; count_x < crawl_view.viewsz.x; count_x++)
{
#ifdef USE_CURSES
buffy[bufcount] = cset_adjust( buffy[bufcount] );
@@ -3889,8 +3878,6 @@ void viewwindow(bool draw_it, bool do_updates)
putch( buffy[bufcount] );
bufcount += 2;
}
-
- gotoxy( 1, count_y + 2 );
}
}
@@ -3899,3 +3886,129 @@ void viewwindow(bool draw_it, bool do_updates)
#endif
}
} // end viewwindow()
+
+//////////////////////////////////////////////////////////////////////////////
+// crawl_view_geometry
+
+const int crawl_view_geometry::message_min_lines;
+const int crawl_view_geometry::hud_min_width;
+const int crawl_view_geometry::hud_min_gutter;
+const int crawl_view_geometry::hud_max_gutter;
+
+crawl_view_geometry::crawl_view_geometry()
+ : termsz(80, 24), viewp(1, 1), viewsz(33, 17),
+ hudp(40, 1), hudsz(41, 17),
+ msgp(1, viewp.y + viewsz.y), msgsz(80, 7)
+{
+}
+
+void crawl_view_geometry::init_view()
+{
+ set_player_at(you.pos(), true);
+}
+
+void crawl_view_geometry::set_player_at(const coord_def &c, bool centre)
+{
+ if (centre)
+ {
+ vgrdc = c;
+ }
+ else
+ {
+ const coord_def oldc = vgrdc;
+ const int xmarg =
+ Options.scroll_margin_x + LOS_RADIUS <= viewhalfsz.x
+ ? Options.scroll_margin_x
+ : viewhalfsz.x - LOS_RADIUS;
+ const int ymarg =
+ Options.scroll_margin_y + LOS_RADIUS <= viewhalfsz.y
+ ? Options.scroll_margin_y
+ : viewhalfsz.y - LOS_RADIUS;
+
+ if (Options.view_lock_x)
+ vgrdc.x = c.x;
+ else if (c.x - LOS_RADIUS < vgrdc.x - viewhalfsz.x + xmarg)
+ vgrdc.x = c.x - LOS_RADIUS + viewhalfsz.x - xmarg;
+ else if (c.x + LOS_RADIUS > vgrdc.x + viewhalfsz.x - xmarg)
+ vgrdc.x = c.x + LOS_RADIUS - viewhalfsz.x + xmarg;
+
+ if (Options.view_lock_y)
+ vgrdc.y = c.y;
+ else if (c.y - LOS_RADIUS < vgrdc.y - viewhalfsz.y + ymarg)
+ vgrdc.y = c.y - LOS_RADIUS + viewhalfsz.y - ymarg;
+ else if (c.y + LOS_RADIUS > vgrdc.y + viewhalfsz.y - ymarg)
+ vgrdc.y = c.y + LOS_RADIUS - viewhalfsz.y + ymarg;
+
+ if (vgrdc != oldc && Options.center_on_scroll)
+ vgrdc = c;
+
+ if (!Options.center_on_scroll && Options.symmetric_scroll
+ && !Options.view_lock_x
+ && !Options.view_lock_y
+ && (c - last_player_pos).abs() == 2
+ && (vgrdc - oldc).abs() == 1)
+ {
+ const coord_def dp = c - last_player_pos;
+ const coord_def dc = vgrdc - oldc;
+ if ((dc.x == dp.x) != (dc.y == dp.y))
+ vgrdc = oldc + dp;
+ }
+ }
+
+ glos1 = c - coord_def(LOS_RADIUS, LOS_RADIUS);
+ glos2 = c + coord_def(LOS_RADIUS, LOS_RADIUS);
+
+ vlos1 = glos1 - vgrdc + view_centre();
+ vlos2 = glos2 - vgrdc + view_centre();
+
+ last_player_pos = c;
+}
+
+void crawl_view_geometry::init_geometry()
+{
+ termsz = coord_def( get_number_of_cols(), get_number_of_lines() );
+
+ // If the terminal is too small, exit with an error.
+ if (termsz.x < 80 || termsz.y < 24)
+ end(1, false, "Terminal too small (%d,%d), need at least (80,24)",
+ termsz.x, termsz.y);
+
+
+ int freeheight = termsz.y - message_min_lines;
+
+ // Make the viewport as tall as possible.
+ viewsz.y = freeheight < Options.view_max_height?
+ freeheight : Options.view_max_height;
+
+ // Make sure we're odd-sized.
+ if (!(viewsz.y % 2))
+ --viewsz.y;
+
+ // The message pane takes all lines not used by the viewport.
+ msgp = coord_def(1, viewsz.y + 1);
+ msgsz = coord_def(termsz.x, termsz.y - viewsz.y);
+
+ int freewidth = termsz.x - (hud_min_width + hud_min_gutter);
+ // Make the viewport as wide as possible.
+ viewsz.x = freewidth < Options.view_max_width?
+ freewidth : Options.view_max_width;
+
+ if (!(viewsz.x % 2))
+ --viewsz.x;
+
+ // The hud appears after the viewport + gutter.
+ hudp = coord_def(viewsz.x + 1 + hud_min_gutter, 1);
+
+ // HUD size never changes, but we may increase the gutter size (up to
+ // the current max of 6).
+ if (hudp.x + hudsz.x - 1 < termsz.x)
+ {
+ const int hudmarg = termsz.x - (hudp.x + hudsz.x - 1);
+ const int hud_increase_max = hud_max_gutter - hud_min_gutter;
+ hudp.x += hudmarg > hud_increase_max? hud_increase_max : hudmarg;
+ }
+
+ viewhalfsz = viewsz / 2;
+
+ init_view();
+}
diff --git a/crawl-ref/source/view.h b/crawl-ref/source/view.h
index c303619497..ce31141055 100644
--- a/crawl-ref/source/view.h
+++ b/crawl-ref/source/view.h
@@ -23,8 +23,6 @@
void init_char_table(char_set_type set);
void init_feature_table();
-int get_message_window_height();
-
/* ***********************************************************************
* called from: dump_screenshot - chardump
* *********************************************************************** */