summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/docs/crawl_options.txt109
-rw-r--r--crawl-ref/init.txt24
-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
25 files changed, 625 insertions, 224 deletions
diff --git a/crawl-ref/docs/crawl_options.txt b/crawl-ref/docs/crawl_options.txt
index 48aad68b97..5be8d756c9 100644
--- a/crawl-ref/docs/crawl_options.txt
+++ b/crawl-ref/docs/crawl_options.txt
@@ -34,32 +34,37 @@ The contents of this text are:
stair_item_brand
4-e Level Map Functions.
level_map_cursor_step, level_map_title, item_colour
-4-f Travel and Exploration.
+4-f Viewport Display Options.
+ view_max_width, view_max_height, view_lock_x,
+ view_lock_y, view_lock, center_on_scroll,
+ symmetric_scroll, scroll_margin_x, scroll_margin_y,
+ scroll_margin
+4-g Travel and Exploration.
travel_delay, travel_avoid_terrain,
travel_exclude_radius2, travel_stop_message,
explore_greedy, explore_stop, runrest_ignore_message,
runrest_ignore_poison, trapwalk_safe_hp, tc_reachable,
tc_dangerous, tc_excluded, tc_exclude_circle
-4-g Stashes.
+4-h Stashes.
stash_tracking, stash_filter
-4-h Command Enhancements.
+4-i Command Enhancements.
auto_list, lowercase_invocations, easy_open, easy_butcher,
easy_unequip, easy_confirm, easy_quit_item_prompts,
easy_exit_menu, default_autoprayer, sort_menus
-4-i Message and Display Improvements.
+4-j Message and Display Improvements.
hp_warning, mp_warning, hp_colour, mp_colour, always_greet,
terse_hand, delay_message_clear, menu_colour, message_colour,
increasing_skill_progress, show_inventory_weights,
show_turns
-4-j Missiles.
+4-k Missiles.
fire_items_start, fire_order
-4-k Message Channels.
+4-l Message Channels.
plain, prompt, god, pray, duration, danger, food, warning,
recovery, multiturn, talk, intrinsic_gain, mutation,
monster_spell, monster_enchant, monster_damage, rotten_meat
-4-l Inscriptions.
+4-m Inscriptions.
autoinscribe
-4-m Macro related Options.
+4-n Macro related Options.
flush.failure, flush.command, flush.message
5- Character Dump.
5-a Items and Kills.
@@ -481,7 +486,79 @@ item_colour = true
Colours items on level-map.
-4-f Travel and Exploration.
+4-f Viewport Display Options
+--------------------------------
+
+The viewport is the portion of the map that is displayed during normal
+play. The viewport is 33x17 by default, but if you use larger terminal
+sizes, you can set these options to make the game show a larger
+viewport. (These options are not fully available on DOS.)
+
+None of these options affects gameplay. In particular, your character's
+line-of-sight is unaffected by these options.
+
+view_max_width = 33
+ Sets the maximum width of the viewport (defaults to 33).
+ Making this larger will allow Crawl to show a wider viewport
+ on larger terminals.
+
+view_max_height = 17
+ Similar to view_max_width, but sets the viewport's maximum
+ height.
+
+* Note that using large viewports can slow the game down.
+
+view_lock_x = true
+ Keeps the player character centered horizontally in the
+ viewport, continuously scrolling the viewport to match the
+ PC's movements. If this is not set, the player character can
+ move horizontally within the viewport, and the viewport will
+ scroll only when the character's line-of-sight reaches the
+ left or right edge.
+
+view_lock_y = true
+ Keeps the character centered vertically in the viewport.
+
+view_lock = true
+ Aliased option that sets both view_lock_x and view_lock_y.
+
+center_on_scroll = false
+ If this is set, the viewport centers on the player character
+ whenever it scrolls (this option is irrelevant if view_lock_x
+ and view_lock_y are set).
+
+symmetric_scroll = true
+ If this is set, the viewport will scroll in a manner consistent
+ with the character movement that caused the scroll.
+
+ To illustrate, let's say the PC is at the lower edge of the
+ viewport, but is near the horizontal center. Now the PC moves
+ diagonally down and right, forcing the viewport to scroll up
+ one line. If symmetric_scroll is set, the viewport will also
+ scroll left one column to match the PC's diagonal movement. If
+ symmetric_scroll is not set, the viewport will only scroll up,
+ not horizontally. symmetric_scroll can be less disorienting
+ than free scrolling.
+
+ This option is not relevant if view_lock or center_on_scroll
+ are set.
+
+scroll_margin_x = 4
+ How far from the left or right edges scrolling starts. By
+ default, if the PC's circle of line-of-sight is closer than 4
+ squares from the edge, the viewport scrolls. If set at zero,
+ the viewport scrolls only when the LOS circle reaches the
+ viewport edge.
+
+scroll_margin_y = 4
+ How far from the top or bottom edges scrolling starts.
+
+scroll_margin = 4
+ An aliased option that sets both scroll_margin_x and
+ scroll_margin_y.
+
+
+4-g Travel and Exploration.
-------------------------------
travel_delay = 20
@@ -580,7 +657,7 @@ tc_exclude_circle = red
excluded_circle: the colour for travel exclusions apart from centre
-4-g Stashes.
+4-h Stashes.
----------------
stash_tracking = (all | explicit | dropped)
@@ -604,7 +681,7 @@ stash_tracking = (all | explicit | dropped)
squares. You can still use Ctrl-S and Ctrl-E as above.
-4-h Command Enhancements.
+4-i Command Enhancements.
-----------------------------
auto_list = true
@@ -741,7 +818,7 @@ sort_menus = [menu:](true | false | auto:X)[:sort_order]
any: All menus; this is the default when unspecified.
-4-i Messages and Display Enhancements.
+4-j Messages and Display Enhancements.
------------------------------------------
hp_warning = 10
@@ -827,7 +904,7 @@ show_turns = false
This option controls whether the turn counter (of turns elapsed) is
displayed in the main view.
-4-j Missiles.
+4-k Missiles.
-----------------
fire_items_start = a
@@ -847,7 +924,7 @@ fire_order = launcher, dart, stone, dagger, spear, handaxe, club
<See also pickup_thrown in A.4a.>
-4-k Message Channels.
+4-l Message Channels.
-------------------------
Crawl communicates to the players with its message window. Every message
@@ -892,7 +969,7 @@ Note that the template init.txt sets
in order to help new players. You may want to comment out this option, if
the messages are too verbose.
-4-l Inscriptions.
+4-m Inscriptions.
---------------------
In Crawl, items can be manually inscribed with the '{' command. This adds a
@@ -921,7 +998,7 @@ autoinscribe = <regex>:<inscription>
autoinscribe = wand of healing:!z
-4-m Macro related Options.
+4-n Macro related Options.
------------------------------
flush.failure = true
diff --git a/crawl-ref/init.txt b/crawl-ref/init.txt
index 48ec5cdc6e..82e76b8e8c 100644
--- a/crawl-ref/init.txt
+++ b/crawl-ref/init.txt
@@ -111,7 +111,15 @@ stab_brand = hi:blue
# level_map_title = false
# item_colour = false
-##### 4-f Travel and Exploration #################
+##### 4-f Viewport Options ###################
+# view_max_width = 33
+# view_max_height = 17
+# view_lock = false
+# center_on_scroll = true
+# symmetric_scroll = false
+# scroll_margin = 4
+
+##### 4-g Travel and Exploration #################
#
# travel_colour = false
# travel_delay = 20
@@ -135,12 +143,12 @@ stab_brand = hi:blue
# runrest_ignore_poison = 4:100
# trapwalk_safe_hp = dart:15, needle:25, spear:50
-##### 4-g Stashes ###############################
+##### 4-h Stashes ###############################
#
# stash_tracking = (all | explicit | dropped)
# stash_filter = 14, 4:21
-##### 4-h Command Enhancements ##################
+##### 4-i Command Enhancements ##################
#
# auto_list = false
# lowercase_invocations = false
@@ -153,7 +161,7 @@ stab_brand = hi:blue
# default_autoprayer = true
# sort_menus = pickup: true : basename, qualname, curse, qty
-##### 4-i Messages and Display Enhancements #####
+##### 4-j Messages and Display Enhancements #####
#
# hp_warning = 10
# mp_warning = 10
@@ -187,20 +195,20 @@ message_colour = lightcyan:LOW MAGIC WARNING
# message_colour = mute:(HP|Magic) restored
# message_colour = mute:warning:Not with.*(in view|monsters around)
-##### 4-j Firing Commands #######################
+##### 4-k Firing Commands #######################
#
# fire_items_start = a
# fire_order = launcher, dart, stone, dagger, spear, handaxe, club
-##### 4-k Channels ##############################
+##### 4-l Channels ##############################
#
# channel.multiturn = mute
-##### 4-l Inscriptions ##########################
+##### 4-m Inscriptions ##########################
#
# autoinscribe = royal jell:=g
-##### 4-m Macro related Options #################
+##### 4-n Macro related Options #################
#
# flush.failure = false
# flush.command = true
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
* *********************************************************************** */