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
EOMCPVNQLX3IMLC46EAO67DPBH5KEG2FQTPBLGU62HIRWA3UQ7XQC KTNZIWQ7HRC2YKQEQ5SAM3UOYJPJY5JGWKMFGALBPRDZUJSFH2YQC B4X67DGLW77QLGPTMORE2EJ5K5VA3TWIU23HFUF4TZDODXQSFLRQC CTTZKXEF5P64ZO2UNJZIAKKZH7ZWZ54C5E27ATXKGZJFRJJC6FJAC SVKXVPIRSLANKYBFFZ5OTGQAB6GXSLSMGQEBWAE7ATSITBACOCFQC DTLQUII6XUFN6LMIOFGUX2MVWYJ22UKCFQGFXVR3CPTODFIEANNQC SCNVGV5WCDZK5OAJBYCAGSINHGIDANF3WXQCM5JVITL2I6RWMLMAC 2B4AQJIATJ4E7RFN6OTQITZNDBAPQ2VWWXLBCVYSORAFG2GIIDNQC CEK6M777MI5JVDC3KHE3JD3FETVSJ4VN6DGATBI5P3O6P5XHY4DAC XYJ5Y635KCRCTL2BFPP53NWQRK3NUHS6T3ARPIXV5A3CHWBW7VCQC KFULGQQOHWUTXOM3BXCCYPGGVGGY4Z6265XUFRCBPNLTZAEHJZSQC TZ643KHSE5CUPXFSQ7VYVOCM5MTQ7F4SENEYQX2RNFHGHLQVS3RQC GCIZIUXO5TYROKDUYB3HAY7H7MRDTJNM7HR7DGSH7KXDIZC2LCDAC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC GVCGKTH5IJ4VSQEIN4CRC7ZFVZW26JPIYNCPTO7GY66CSZZEW3ZQC ASFH3NFXSJ6AWVLIBJNTIC35HCOSHY42YQG2ELGPEYAULZUIRRRQC YIIILIV4ZPRIPWWT4GL7YWSJCUVH6RJJLXV4XIHY6SF3H7Y3EAYAC 5ASC3STDYCNLZFEBN6UTMUCGDETHBR2OCBZCF5VIAZ5RRWLOTDYQC 77H4BWWPPGLM3PLZH4QTAJRXIZTSDVNCOKZE223I437FN2UJ34RQC R22TTMI6WXWULC7ODKFF3QCB7MOTETQQ6IR4BUCUPOCQKQNCTT5AC Q5SFQO7ANODRI6OXKHPFQ4QWKGQ367S64DPURQW2TWK7ANTYO4NQC JR2RAQ523LOWNDYJNK6AZVKI6WVMI622PIV72XWOVZYPXPUKSQWAC UPJVSMMMHGRDUIJG4MZX6IBLQ4ODBF5Z3PF3RHDYTSAEOCVDZM5AC SH6NU4H5TG4O7CRXRHZ7MDHABZLWWXQ77NJDBHI7KCVHXHQYK46QC TV3ZC6WOZKSQQJQN26JIVKCHK6UK7WMDBYZDUYRWEAZ4JB4YVNAAC 74LQ7JXVLAFSHLI7LCBKFX47CNTYSKGUQSXNX5FCIUIGCC2JTR3QC LIBWXPN6HLJAIGEFJYLOL4HLIUD236U3WM5QPHIZ3DSB4CCUJERAC YWYXUCZKGNIAWAUKUESIPFCAL5HZOKOEWHUEUW7X4DMAX2HG2FSAC 22RFWMSJGG26Z2MQEEXGKVTFSTLREHQIG46WYOTMDRKI5YVMRNVAC CIPVRZGLOZHCERK6YPOBV3P2E4IAB4H6D5EHLRQE2O5E4P4VCBUAC 6HQB2N6N75R2RGKJFWRUN7WAC2PNGWQFXTII5DTRLTHZ2BOTMTVAC ID2OZJTHFXL74RVUCS3JCMDQEUHAXCQFZU7235VU6IEVAAUWD2FAC 2BCSCMJ5FRMEZNX7C4WIP3M6WSFFKTIG22C57VV4VXFJPXT6JBJAC SW3RLYFNRT3IJBK6LYKHKP2J2YDU7SXQWAJZX7U6S7ICYW43OMNQC MSQI3TH6T62JAXQGLL52QZCWAMC372TGB6ZNNRDGUGMJKBNNV2VAC SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC TJRYL3NXPW5IUGEV3YOC7JYWEXCZDBFPLT4AUG4P227WVKVB72ZAC UF4ODJOCV3ZL7DXRLLOFVWHUKKJX34FO4ZM6VJAWEJ3QVP3XZ2AAC RVST2QHYJ757ZHK4AUJ5NGPDZ44AD6RVFVXYPKQIBJXZBDNUCHXQC EHSY6DVGUMI6C67WKET3GDJVLWJWGYBYQONNDK5JVT7BCTHBEZVAC V6REAY6RCAG2QQ4BO54GHYOVTNCYHTLERJCIZJPSANXFBINZOTXAC XPCGZBHHSL6MB3ORMUJI64BAERU6AZTIY6RK56BBW7SNB3IK24IAC E5GFDGV5XJVVDZGWFQIIZ47FGGF7AEJLGGBWRUZ34HPLNFJTNLLQC NZFU5APXZZDBRYJGE57F43JKBBPWC33TIZNK6K4OZYSI47PFJMQQC 2ZFV5PKZU3HDHMLJWVWPPFV43NUNUON6YSAITHB26D7L4XIVWUHQC 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:");
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);
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);
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;
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);
//////////////////////////////////////////////////////////////////////////////// crawl_view_geometryconst 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();}
void player::moveto(const coord_def &c){x_pos = c.x;y_pos = c.y;crawl_view.set_player_at(c);}
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) );
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;}
FixedArray< unsigned int, 19, 19> show; // view window charFixedArray< unsigned short, 19, 19> show_col; // view window colour
FixedArray<unsigned, ENV_SHOW_DIAMETER, ENV_SHOW_DIAMETER>show; // view window charFixedArray<unsigned short, ENV_SHOW_DIAMETER, ENV_SHOW_DIAMETER>show_col; // view window colour
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());}};
// 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;
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,
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))));
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;
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;
##### 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 #################
4-f Travel and Exploration.
The viewport is the portion of the map that is displayed during normalplay. The viewport is 33x17 by default, but if you use larger terminalsizes, you can set these options to make the game show a largerviewport. (These options are not fully available on DOS.)None of these options affects gameplay. In particular, your character'sline-of-sight is unaffected by these options.view_max_width = 33Sets the maximum width of the viewport (defaults to 33).Making this larger will allow Crawl to show a wider viewporton larger terminals.view_max_height = 17Similar to view_max_width, but sets the viewport's maximumheight.* Note that using large viewports can slow the game down.view_lock_x = trueKeeps the player character centered horizontally in theviewport, continuously scrolling the viewport to match thePC's movements. If this is not set, the player character canmove horizontally within the viewport, and the viewport willscroll only when the character's line-of-sight reaches theleft or right edge.view_lock_y = trueKeeps the character centered vertically in the viewport.view_lock = trueAliased option that sets both view_lock_x and view_lock_y.center_on_scroll = falseIf this is set, the viewport centers on the player characterwhenever it scrolls (this option is irrelevant if view_lock_xand view_lock_y are set).symmetric_scroll = trueIf this is set, the viewport will scroll in a manner consistentwith the character movement that caused the scroll.To illustrate, let's say the PC is at the lower edge of theviewport, but is near the horizontal center. Now the PC movesdiagonally down and right, forcing the viewport to scroll upone line. If symmetric_scroll is set, the viewport will alsoscroll left one column to match the PC's diagonal movement. Ifsymmetric_scroll is not set, the viewport will only scroll up,not horizontally. symmetric_scroll can be less disorientingthan free scrolling.This option is not relevant if view_lock or center_on_scrollare set.scroll_margin_x = 4How far from the left or right edges scrolling starts. Bydefault, if the PC's circle of line-of-sight is closer than 4squares from the edge, the viewport scrolls. If set at zero,the viewport scrolls only when the LOS circle reaches theviewport edge.scroll_margin_y = 4How far from the top or bottom edges scrolling starts.scroll_margin = 4An aliased option that sets both scroll_margin_x andscroll_margin_y.4-g Travel and Exploration.