diff options
-rw-r--r-- | crawl-ref/source/acr.cc | 6 | ||||
-rw-r--r-- | crawl-ref/source/defines.h | 3 | ||||
-rw-r--r-- | crawl-ref/source/externs.h | 20 | ||||
-rw-r--r-- | crawl-ref/source/initfile.cc | 6 | ||||
-rw-r--r-- | crawl-ref/source/libunix.cc | 53 | ||||
-rw-r--r-- | crawl-ref/source/stuff.cc | 7 | ||||
-rw-r--r-- | crawl-ref/source/view.cc | 26 | ||||
-rw-r--r-- | crawl-ref/source/view.h | 2 |
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); |