summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/acr.cc6
-rw-r--r--crawl-ref/source/defines.h3
-rw-r--r--crawl-ref/source/externs.h20
-rw-r--r--crawl-ref/source/initfile.cc6
-rw-r--r--crawl-ref/source/libunix.cc53
-rw-r--r--crawl-ref/source/stuff.cc7
-rw-r--r--crawl-ref/source/view.cc26
-rw-r--r--crawl-ref/source/view.h2
8 files changed, 101 insertions, 22 deletions
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index d121b1cef0..7d8ca311bc 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -912,12 +912,18 @@ static void input()
return;
}
+ if (crawl_state.terminal_resized)
+ handle_terminal_resize();
+
{
// Enable the cursor to read input. The cursor stays on while
// the command is being processed, so subsidiary prompts
// shouldn't need to turn it on explicitly.
cursor_control con(true);
+
+ crawl_state.waiting_for_comand = true;
command_type cmd = get_next_cmd();
+ crawl_state.waiting_for_comand = false;
// [dshaligram] If get_next_cmd encountered a Lua macro
// binding, your turn may be ended by the first invoke of the
diff --git a/crawl-ref/source/defines.h b/crawl-ref/source/defines.h
index 70c24277e5..b5a11f26af 100644
--- a/crawl-ref/source/defines.h
+++ b/crawl-ref/source/defines.h
@@ -113,7 +113,8 @@
#define ENV_SHOW_OFFSET (LOS_RADIUS + 1)
#define ENV_SHOW_DIAMETER (ENV_SHOW_OFFSET * 2 + 1)
-#define VIEW_MIN_WIDTH 33
+#define VIEW_BASE_WIDTH 33
+#define VIEW_MIN_WIDTH 17
#define VIEW_MIN_HEIGHT 17
// max traps per level
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index b8571bf5dc..18c85f65df 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -1182,9 +1182,14 @@ struct crawl_environment
extern struct crawl_environment env;
-// Track stuff for SIGHUP handling.
+// Track various aspects of Crawl game state.
struct game_state
{
+ bool waiting_for_comand; // True when the game is waiting for a command.
+ bool terminal_resized; // True if the term was resized and we need to
+ // take action to handle it.
+
+ bool io_inited; // Is curses or the equivalent initialised?
bool need_save; // Set to true when game has started.
bool saving_game; // Set to true while in save_game.
bool updating_scores; // Set to true while updating hiscores.
@@ -1195,11 +1200,14 @@ struct game_state
bool unicode_ok; // Is unicode support available?
std::string (*glyph2strfn)(unsigned glyph);
- int (*multibyte_strlen)(const std::string &s);
-
- game_state() : need_save(false), saving_game(false),
- updating_scores(false), shopping(false), seen_hups(0),
- unicode_ok(false), glyph2strfn(NULL), multibyte_strlen(NULL)
+ int (*multibyte_strlen)(const std::string &s);
+ void (*terminal_resize_handler)();
+
+ game_state() : waiting_for_comand(false), terminal_resized(false),
+ io_inited(false), need_save(false), saving_game(false),
+ updating_scores(false), shopping(false), seen_hups(0),
+ unicode_ok(false), glyph2strfn(NULL), multibyte_strlen(NULL),
+ terminal_resize_handler(NULL)
{
}
};
diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc
index 6687b09a48..cdf8a4f810 100644
--- a/crawl-ref/source/initfile.cc
+++ b/crawl-ref/source/initfile.cc
@@ -559,7 +559,7 @@ void game_options::reset_options()
messaging = true;
#endif
- view_max_width = VIEW_MIN_WIDTH;
+ view_max_width = VIEW_BASE_WIDTH;
view_max_height = VIEW_MIN_HEIGHT;
view_lock_x = true;
@@ -567,8 +567,8 @@ void game_options::reset_options()
center_on_scroll = false;
symmetric_scroll = true;
- scroll_margin_x = 4;
- scroll_margin_y = 4;
+ scroll_margin_x = 2;
+ scroll_margin_y = 2;
autopickup_on = true;
autoprayer_on = false;
diff --git a/crawl-ref/source/libunix.cc b/crawl-ref/source/libunix.cc
index 133eb70620..a1d8b5e0ce 100644
--- a/crawl-ref/source/libunix.cc
+++ b/crawl-ref/source/libunix.cc
@@ -46,6 +46,8 @@
#include "enum.h"
#include "externs.h"
#include "files.h"
+#include "stuff.h"
+#include "view.h"
#ifdef UNICODE_GLYPHS
#include <wchar.h>
@@ -192,6 +194,8 @@ static int unix_multibyte_strlen(const std::string &s)
}
#endif
+static void unix_handle_terminal_resize();
+
static void termio_init()
{
tcgetattr(0, &def_term);
@@ -217,12 +221,16 @@ static void termio_init()
crawl_state.multibyte_strlen = unix_multibyte_strlen;
}
#endif
+
+ crawl_state.terminal_resize_handler = unix_handle_terminal_resize;
}
-int getch_ck() {
+int getch_ck()
+{
int c = getch();
- switch (c) {
+ switch (c)
+ {
// [dshaligram] MacOS ncurses returns 127 for backspace.
case 127:
case KEY_BACKSPACE: return CK_BKSP;
@@ -239,8 +247,17 @@ int getch_ck() {
}
}
-#if defined(USE_UNIX_SIGNALS) && defined(SIGHUP_SAVE)
+#if defined(USE_UNIX_SIGNALS)
+static void handle_sigwinch(int)
+{
+ if (crawl_state.waiting_for_comand)
+ handle_terminal_resize();
+ else
+ crawl_state.terminal_resized = true;
+}
+
+#ifdef SIGHUP_SAVE
/* [ds] This SIGHUP handling is primitive and far from safe, but it
* should be better than nothing. Feel free to get rigorous on this.
*/
@@ -265,8 +282,9 @@ static void handle_hangup(int)
exit(1);
}
}
+#endif // SIGHUP_SAVE
-#endif // USE_UNIX_SIGNALS && SIGHUP_SAVE
+#endif // USE_UNIX_SIGNALS
static WINDOW *Message_Window;
static void setup_message_window()
@@ -275,14 +293,23 @@ static void setup_message_window()
crawl_view.msgp.y - 1, crawl_view.msgp.x - 1 );
if (!Message_Window)
{
- fprintf(stderr, "Unable to create message window!");
- exit(1);
+ if (crawl_state.need_save)
+ save_game(true);
+
+ // Never reaches here unless the game didn't need saving.
+ end(1, false, "Unable to create message window!");
}
scrollok(Message_Window, true);
idlok(Message_Window, true);
}
+static void unix_handle_terminal_resize()
+{
+ unixcurses_shutdown();
+ unixcurses_startup();
+}
+
void clear_message_window()
{
wattrset( Message_Window, curs_fg_attr(LIGHTGREY) );
@@ -337,6 +364,8 @@ void unixcurses_startup( void )
#ifdef SIGHUP_SAVE
signal(SIGHUP, handle_hangup);
#endif
+
+ signal(SIGWINCH, handle_sigwinch);
#endif
@@ -366,6 +395,12 @@ void unixcurses_startup( void )
void unixcurses_shutdown()
{
+ if (Message_Window)
+ {
+ delwin(Message_Window);
+ Message_Window = NULL;
+ }
+
// resetty();
endwin();
@@ -379,6 +414,12 @@ void unixcurses_shutdown()
#ifdef SIGINT
signal(SIGINT, SIG_DFL);
#endif
+
+#ifdef SIGHUP_SAVE
+ signal(SIGHUP, SIG_DFL);
+#endif
+
+ signal(SIGWINCH, SIG_DFL);
#endif
}
diff --git a/crawl-ref/source/stuff.cc b/crawl-ref/source/stuff.cc
index 0d42444864..c40d737fd9 100644
--- a/crawl-ref/source/stuff.cc
+++ b/crawl-ref/source/stuff.cc
@@ -302,10 +302,9 @@ int random2limit(int max, int limit)
return sum;
} // end random2limit()
-static bool io_inited = false;
void cio_init()
{
- io_inited = true;
+ crawl_state.io_inited = true;
#ifdef UNIX
unixcurses_startup();
@@ -329,7 +328,7 @@ void cio_init()
void cio_cleanup()
{
- if (!io_inited)
+ if (!crawl_state.io_inited)
return;
#ifdef UNIX
@@ -342,7 +341,7 @@ void cio_cleanup()
msg::deinitalise_mpr_streams();
- io_inited = false;
+ crawl_state.io_inited = false;
}
void end(int exit_code, bool print_error, const char *format, ...)
diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc
index 1b34462ffb..fe384a5809 100644
--- a/crawl-ref/source/view.cc
+++ b/crawl-ref/source/view.cc
@@ -4131,11 +4131,10 @@ 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)
+ if ((termsz.x < 80 || termsz.y < 24) && !crawl_state.need_save)
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.
@@ -4146,6 +4145,10 @@ void crawl_view_geometry::init_geometry()
if (!(viewsz.y % 2))
--viewsz.y;
+ // If the view is too short, force it to minimum height.
+ if (viewsz.y < VIEW_MIN_HEIGHT)
+ viewsz.y = VIEW_MIN_HEIGHT;
+
// 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);
@@ -4158,6 +4161,9 @@ void crawl_view_geometry::init_geometry()
if (!(viewsz.x % 2))
--viewsz.x;
+ if (viewsz.x < VIEW_MIN_WIDTH)
+ viewsz.x = VIEW_MIN_WIDTH;
+
// The hud appears after the viewport + gutter.
hudp = coord_def(viewsz.x + 1 + hud_min_gutter, 1);
@@ -4174,3 +4180,19 @@ void crawl_view_geometry::init_geometry()
init_view();
}
+
+////////////////////////////////////////////////////////////////////////////
+// Term resize handling (generic).
+
+void handle_terminal_resize(bool redraw)
+{
+ crawl_state.terminal_resized = false;
+
+ if (crawl_state.terminal_resize_handler)
+ (*crawl_state.terminal_resize_handler)();
+ else
+ crawl_view.init_geometry();
+
+ if (redraw)
+ redraw_screen();
+}
diff --git a/crawl-ref/source/view.h b/crawl-ref/source/view.h
index b562359b7b..e031388b35 100644
--- a/crawl-ref/source/view.h
+++ b/crawl-ref/source/view.h
@@ -169,6 +169,8 @@ bool find_ray( int sourcex, int sourcey, int targetx, int targety,
dungeon_char_type dchar_by_name(const std::string &name);
+void handle_terminal_resize(bool redraw = true);
+
#if defined(WIN32CONSOLE) || defined(DOS)
unsigned short dos_brand( unsigned short colour,
unsigned brand = CHATTR_REVERSE);