summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/acr.cc53
-rw-r--r--crawl-ref/source/beam.cc1
-rw-r--r--crawl-ref/source/cio.cc582
-rw-r--r--crawl-ref/source/cio.h226
-rw-r--r--crawl-ref/source/clua.cc1
-rw-r--r--crawl-ref/source/debug.cc1
-rw-r--r--crawl-ref/source/direct.cc71
-rw-r--r--crawl-ref/source/direct.h2
-rw-r--r--crawl-ref/source/enum.h3
-rw-r--r--crawl-ref/source/externs.h17
-rw-r--r--crawl-ref/source/initfile.cc6
-rw-r--r--crawl-ref/source/item_use.cc1
-rw-r--r--crawl-ref/source/libdos.cc34
-rw-r--r--crawl-ref/source/libdos.h2
-rw-r--r--crawl-ref/source/libunix.cc78
-rw-r--r--crawl-ref/source/libunix.h2
-rw-r--r--crawl-ref/source/libutil.cc558
-rw-r--r--crawl-ref/source/libutil.h142
-rw-r--r--crawl-ref/source/libw32c.cc42
-rw-r--r--crawl-ref/source/libw32c.h7
-rw-r--r--crawl-ref/source/macro.cc17
-rw-r--r--crawl-ref/source/makefile.obj1
-rw-r--r--crawl-ref/source/menu.cc1
-rw-r--r--crawl-ref/source/message.cc2
-rw-r--r--crawl-ref/source/newgame.cc1
-rw-r--r--crawl-ref/source/notes.cc1
-rw-r--r--crawl-ref/source/player.cc46
-rw-r--r--crawl-ref/source/shopping.cc2
-rw-r--r--crawl-ref/source/skills2.cc99
-rw-r--r--crawl-ref/source/spl-book.cc12
-rw-r--r--crawl-ref/source/spl-book.h4
-rw-r--r--crawl-ref/source/stash.cc1
-rw-r--r--crawl-ref/source/travel.cc10
-rw-r--r--crawl-ref/source/tutorial.cc2
-rw-r--r--crawl-ref/source/view.cc47
35 files changed, 1212 insertions, 863 deletions
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index 022c264ec7..df5ff8929d 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -74,6 +74,7 @@
#include "abyss.h"
#include "branch.h"
#include "chardump.h"
+#include "cio.h"
#include "cloud.h"
#include "clua.h"
#include "command.h"
@@ -923,14 +924,23 @@ static void input()
cursor_control con(true);
crawl_state.waiting_for_command = true;
- command_type cmd = get_next_cmd();
+ c_input_reset(true);
+
+ const command_type cmd = get_next_cmd();
+
crawl_state.waiting_for_command = false;
+ if (cmd != CMD_MOUSE_MOVE)
+ c_input_reset(false);
+
// [dshaligram] If get_next_cmd encountered a Lua macro
// binding, your turn may be ended by the first invoke of the
// macro.
if (!you.turn_is_over && cmd != CMD_NEXT_CMD)
process_command( cmd );
+
+ if (cmd != CMD_MOUSE_MOVE)
+ c_input_reset(false, true);
}
if (you.turn_is_over)
@@ -1127,7 +1137,6 @@ void process_command( command_type cmd )
break;
case CMD_MAKE_NOTE:
-// Options.tut_made_note = 0;
make_user_note();
break;
@@ -1342,13 +1351,6 @@ void process_command( command_type cmd )
break;
case CMD_EXPLORE:
- if (Options.tut_explored)
- Options.tut_explored = 0;
- if (you.level_type == LEVEL_LABYRINTH || you.level_type == LEVEL_ABYSS)
- {
- mpr("It would help if you knew where you were, first.");
- break;
- }
// Start exploring
start_explore(Options.explore_greedy);
break;
@@ -1414,9 +1416,37 @@ void process_command( command_type cmd )
break;
case CMD_SHOUT:
- yell(); /* in effects.cc */
+ yell();
break;
+ case CMD_MOUSE_MOVE:
+ break;
+
+ case CMD_MOUSE_CLICK:
+ {
+ // XXX: We should probably use specific commands such as
+ // CMD_MOUSE_TRAVEL and get rid of CMD_MOUSE_CLICK and
+ // CMD_MOUSE_MOVE.
+ c_mouse_event cme = get_mouse_event();
+ if (cme && crawl_view.in_view_viewport(cme.pos))
+ {
+ const coord_def dest = view2grid(cme.pos);
+ if (cme.left_clicked())
+ {
+ if (in_bounds(dest))
+ start_travel(dest.x, dest.y);
+ }
+ else if (cme.right_clicked())
+ {
+ if (see_grid(dest.x, dest.y))
+ full_describe_square(dest);
+ else
+ mpr("You can't see that place.");
+ }
+ }
+ break;
+ }
+
case CMD_DISPLAY_CHARACTER_STATUS:
display_char_status();
break;
@@ -2668,6 +2698,9 @@ command_type keycode_to_command( keycode_type key )
case CONTROL('W'): return CMD_FIX_WAYPOINT;
case CONTROL('X'): return CMD_SAVE_GAME_NOW;
case CONTROL('Z'): return CMD_SUSPEND_GAME;
+
+ case CK_MOUSE_MOVE: return CMD_MOUSE_MOVE;
+ case CK_MOUSE_CLICK: return CMD_MOUSE_CLICK;
default: return CMD_NO_CMD;
}
}
diff --git a/crawl-ref/source/beam.cc b/crawl-ref/source/beam.cc
index e5a11f1f2f..5027becf19 100644
--- a/crawl-ref/source/beam.cc
+++ b/crawl-ref/source/beam.cc
@@ -34,6 +34,7 @@
#include "externs.h"
+#include "cio.h"
#include "cloud.h"
#include "effects.h"
#include "enum.h"
diff --git a/crawl-ref/source/cio.cc b/crawl-ref/source/cio.cc
new file mode 100644
index 0000000000..d22729a7fa
--- /dev/null
+++ b/crawl-ref/source/cio.cc
@@ -0,0 +1,582 @@
+/*
+ * File: cio.cc
+ * Summary: Platform-independent console IO functions.
+ *
+ * Modified for Crawl Reference by $Author: dshaligram $ on $Date: 2007-06-14T18:14:26.828542Z $
+ */
+
+#include "AppHdr.h"
+
+#include "cio.h"
+#include "externs.h"
+#include "macro.h"
+
+#include <queue>
+
+#ifdef UNIX
+static keycode_type numpad2vi(keycode_type key)
+{
+ if (key >= '1' && key <= '9')
+ {
+ const char *vikeys = "bjnh.lyku";
+ return keycode_type(vikeys[key - '1']);
+ }
+ return (key);
+}
+#endif
+
+int unmangle_direction_keys(int keyin, int km, bool fake_ctrl, bool fake_shift)
+{
+ const KeymapContext keymap = static_cast<KeymapContext>(km);
+#ifdef UNIX
+ // Kludging running and opening as two character sequences
+ // for Unix systems. This is an easy way out... all the
+ // player has to do is find a termcap and numlock setting
+ // that will get curses the numbers from the keypad. This
+ // will hopefully be easy.
+
+ /* can we say yuck? -- haranp */
+ if (fake_ctrl && keyin == '*')
+ {
+ keyin = getchm(keymap);
+ // return control-key
+ keyin = CONTROL(toupper(numpad2vi(keyin)));
+ }
+ else if (fake_shift && keyin == '/')
+ {
+ keyin = getchm(keymap);
+ // return shift-key
+ keyin = toupper(numpad2vi(keyin));
+ }
+#else
+ // Old DOS keypad support
+ if (keyin == 0)
+ {
+ /* FIXME haranp - hackiness */
+ const char DOSidiocy[10] = { "OPQKSMGHI" };
+ const char DOSunidiocy[10] = { "bjnh.lyku" };
+ const int DOScontrolidiocy[9] =
+ {
+ 117, 145, 118, 115, 76, 116, 119, 141, 132
+ };
+ keyin = getchm(keymap);
+ for (int j = 0; j < 9; ++j )
+ {
+ if (keyin == DOSidiocy[j])
+ {
+ keyin = DOSunidiocy[j];
+ break;
+ }
+ if (keyin == DOScontrolidiocy[j])
+ {
+ keyin = CONTROL(toupper(DOSunidiocy[j]));
+ break;
+ }
+ }
+ }
+#endif
+
+ // [dshaligram] More lovely keypad mangling.
+ switch (keyin)
+ {
+#ifdef UNIX
+ case '1': return 'b';
+ case '2': return 'j';
+ case '3': return 'n';
+ case '4': return 'h';
+ case '6': return 'l';
+ case '7': return 'y';
+ case '8': return 'k';
+ case '9': return 'u';
+#else
+ case '1': return 'B';
+ case '2': return 'J';
+ case '3': return 'N';
+ case '4': return 'H';
+ case '6': return 'L';
+ case '7': return 'Y';
+ case '8': return 'K';
+ case '9': return 'U';
+#endif
+ }
+
+ return (keyin);
+}
+
+void get_input_line( char *const buff, int len )
+{
+ buff[0] = 0; // just in case
+
+#if defined(UNIX)
+ get_input_line_from_curses( buff, len ); // implemented in libunix.cc
+#elif defined(WIN32CONSOLE)
+ getstr( buff, len );
+#else
+
+ // [dshaligram] Turn on the cursor for DOS.
+#ifdef DOS
+ _setcursortype(_NORMALCURSOR);
+#endif
+
+ fgets( buff, len, stdin ); // much safer than gets()
+#endif
+
+ buff[ len - 1 ] = 0; // just in case
+
+ // Removing white space from the end in order to get rid of any
+ // newlines or carriage returns that any of the above might have
+ // left there (ie fgets especially). -- bwr
+ const int end = strlen( buff );
+ int i;
+
+ for (i = end - 1; i >= 0; i++)
+ {
+ if (isspace( buff[i] ))
+ buff[i] = 0;
+ else
+ break;
+ }
+}
+
+// Hacky wrapper around getch() that returns CK_ codes for keys
+// we want to use in cancelable_get_line() and menus.
+int c_getch()
+{
+#if defined(DOS) || defined(UNIX) || defined(WIN32CONSOLE)
+ return getch_ck();
+#else
+ return m_getch();
+#endif
+}
+
+// Wrapper around gotoxy that can draw a fake cursor for Unix terms where
+// cursoring over darkgray or black causes problems.
+void cursorxy(int x, int y)
+{
+#ifdef UNIX
+ if (Options.use_fake_cursor)
+ fakecursorxy(x, y);
+ else
+ gotoxy(x, y);
+#else
+ gotoxy(x, y);
+#endif
+}
+
+// cprintf that knows how to wrap down lines (primitive, but what the heck)
+int wrapcprintf( int wrapcol, const char *s, ... )
+{
+ char buf[1000]; // Hard max
+ va_list args;
+ va_start(args, s);
+
+ // XXX: If snprintf isn't available, vsnprintf probably isn't, either.
+ int len = vsnprintf(buf, sizeof buf, s, args);
+ int olen = len;
+ va_end(args);
+
+ char *run = buf;
+ while (len > 0)
+ {
+ int x = wherex(), y = wherey();
+
+ if (x > wrapcol) // Somebody messed up!
+ return 0;
+
+ int avail = wrapcol - x + 1;
+ int c = 0;
+ if (len > avail)
+ {
+ c = run[avail];
+ run[avail] = 0;
+ }
+ cprintf("%s", run);
+
+ if (len > avail)
+ run[avail] = c;
+
+ if ((len -= avail) > 0)
+ gotoxy(1, y + 1);
+ run += avail;
+ }
+ return (olen);
+}
+
+int cancelable_get_line( char *buf, int len, int maxcol,
+ input_history *mh, int (*keyproc)(int &ch) )
+{
+ line_reader reader(buf, len, maxcol);
+ reader.set_input_history(mh);
+ reader.set_keyproc(keyproc);
+
+ return reader.read_line();
+}
+
+
+/////////////////////////////////////////////////////////////
+// input_history
+//
+
+input_history::input_history(size_t size)
+ : history(), pos(), maxsize(size)
+{
+ if (maxsize < 2)
+ maxsize = 2;
+
+ pos = history.end();
+}
+
+void input_history::new_input(const std::string &s)
+{
+ history.remove(s);
+
+ if (history.size() == maxsize)
+ history.pop_front();
+
+ history.push_back(s);
+
+ // Force the iterator to the end (also revalidates it)
+ go_end();
+}
+
+const std::string *input_history::prev()
+{
+ if (history.empty())
+ return NULL;
+
+ if (pos == history.begin())
+ pos = history.end();
+
+ return &*--pos;
+}
+
+const std::string *input_history::next()
+{
+ if (history.empty())
+ return NULL;
+
+ if (pos == history.end() || ++pos == history.end())
+ pos = history.begin();
+
+ return &*pos;
+}
+
+void input_history::go_end()
+{
+ pos = history.end();
+}
+
+void input_history::clear()
+{
+ history.clear();
+ go_end();
+}
+
+/////////////////////////////////////////////////////////////////////////
+// line_reader
+
+line_reader::line_reader(char *buf, size_t sz, int wrap)
+ : buffer(buf), bufsz(sz), history(NULL), start_x(0),
+ start_y(0), keyfn(NULL), wrapcol(wrap), cur(NULL),
+ length(0), pos(-1)
+{
+}
+
+std::string line_reader::get_text() const
+{
+ return (buffer);
+}
+
+void line_reader::set_input_history(input_history *i)
+{
+ history = i;
+}
+
+void line_reader::set_keyproc(keyproc fn)
+{
+ keyfn = fn;
+}
+
+void line_reader::cursorto(int ncx)
+{
+ int x = (start_x + ncx - 1) % wrapcol + 1;
+ int y = start_y + (start_x + ncx - 1) / wrapcol;
+ ::gotoxy(x, y);
+}
+
+int line_reader::read_line(bool clear_previous)
+{
+ if (bufsz <= 0) return false;
+
+ cursor_control coff(true);
+
+ if (clear_previous)
+ *buffer = 0;
+
+ start_x = wherex();
+ start_y = wherey();
+
+ length = strlen(buffer);
+
+ // Remember the previous cursor position, if valid.
+ if (pos < 0 || pos > length)
+ pos = length;
+
+ cur = buffer + pos;
+
+ if (length)
+ wrapcprintf(wrapcol, "%s", buffer);
+
+ if (pos != length)
+ cursorto(pos);
+
+ if (history)
+ history->go_end();
+
+ for ( ; ; )
+ {
+ int ch = c_getch();
+
+ if (keyfn)
+ {
+ int whattodo = (*keyfn)(ch);
+ if (whattodo == 0)
+ {
+ buffer[length] = 0;
+ if (history && length)
+ history->new_input(buffer);
+ return (0);
+ }
+ else if (whattodo == -1)
+ {
+ buffer[length] = 0;
+ return (ch);
+ }
+ }
+
+ int ret = process_key(ch);
+ if (ret != -1)
+ return (ret);
+ }
+}
+
+void line_reader::backspace()
+{
+ if (pos)
+ {
+ --cur;
+ char *c = cur;
+ while (*c)
+ {
+ *c = c[1];
+ c++;
+ }
+ --pos;
+ --length;
+
+ cursorto(pos);
+ buffer[length] = 0;
+ wrapcprintf( wrapcol, "%s ", cur );
+ cursorto(pos);
+ }
+}
+
+bool line_reader::is_wordchar(int c)
+{
+ return isalnum(c) || c == '_' || c == '-';
+}
+
+void line_reader::killword()
+{
+ if (!pos || cur == buffer)
+ return;
+
+ bool foundwc = false;
+ while (pos)
+ {
+ if (is_wordchar(cur[-1]))
+ foundwc = true;
+ else if (foundwc)
+ break;
+
+ backspace();
+ }
+}
+
+int line_reader::process_key(int ch)
+{
+ switch (ch)
+ {
+ case CONTROL('G'):
+ case CK_ESCAPE:
+ return (CK_ESCAPE);
+ case CK_UP:
+ case CK_DOWN:
+ {
+ if (!history)
+ break;
+
+ const std::string *text =
+ ch == CK_UP? history->prev() : history->next();
+
+ if (text)
+ {
+ int olen = length;
+ length = text->length();
+ if (length >= (int) bufsz)
+ length = bufsz - 1;
+ memcpy(buffer, text->c_str(), length);
+ buffer[length] = 0;
+ cursorto(0);
+
+ int clear = length < olen? olen - length : 0;
+ wrapcprintf(wrapcol, "%s%*s", buffer, clear, "");
+
+ pos = length;
+ cur = buffer + pos;
+ cursorto(pos);
+ }
+ break;
+ }
+ case CK_ENTER:
+ buffer[length] = 0;
+ if (history && length)
+ history->new_input(buffer);
+ return (0);
+
+ case CONTROL('K'):
+ {
+ // Kill to end of line
+ int erase = length - pos;
+ if (erase)
+ {
+ length = pos;
+ buffer[length] = 0;
+ wrapcprintf( wrapcol, "%*s", erase, "" );
+ cursorto(pos);
+ }
+ break;
+ }
+ case CK_DELETE:
+ if (pos < length)
+ {
+ char *c = cur;
+ while (c - buffer < length)
+ {
+ *c = c[1];
+ c++;
+ }
+ --length;
+
+ cursorto(pos);
+ buffer[length] = 0;
+ wrapcprintf( wrapcol, "%s ", cur );
+ cursorto(pos);
+ }
+ break;
+
+ case CK_BKSP:
+ backspace();
+ break;
+
+ case CONTROL('W'):
+ killword();
+ break;
+
+ case CK_LEFT:
+ if (pos)
+ {
+ --pos;
+ cur = buffer + pos;
+ cursorto(pos);
+ }
+ break;
+ case CK_RIGHT:
+ if (pos < length)
+ {
+ ++pos;
+ cur = buffer + pos;
+ cursorto(pos);
+ }
+ break;
+ case CK_HOME:
+ case CONTROL('A'):
+ pos = 0;
+ cur = buffer + pos;
+ cursorto(pos);
+ break;
+ case CK_END:
+ case CONTROL('E'):
+ pos = length;
+ cur = buffer + pos;
+ cursorto(pos);
+ break;
+ default:
+ if (isprint(ch) && length < (int) bufsz - 1)
+ {
+ if (pos < length)
+ {
+ char *c = buffer + length - 1;
+ while (c >= cur)
+ {
+ c[1] = *c;
+ c--;
+ }
+ }
+ *cur++ = (char) ch;
+ ++length;
+ ++pos;
+ putch(ch);
+ if (pos < length)
+ {
+ buffer[length] = 0;
+ wrapcprintf( wrapcol, "%s", cur );
+ }
+ cursorto(pos);
+ }
+ break;
+ }
+
+ return (-1);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// Of mice and other mice.
+
+static std::queue<c_mouse_event> mouse_events;
+
+coord_def get_mouse_pos()
+{
+ // lib$(OS) has to maintain mousep. This function is just the messenger.
+ return (crawl_view.mousep);
+}
+
+c_mouse_event get_mouse_event()
+{
+ if (mouse_events.empty())
+ return c_mouse_event();
+
+ c_mouse_event ce = mouse_events.front();
+ mouse_events.pop();
+ return (ce);
+}
+
+void new_mouse_event(const c_mouse_event &ce)
+{
+ mouse_events.push(ce);
+}
+
+void flush_mouse_events()
+{
+ while (!mouse_events.empty())
+ mouse_events.pop();
+}
+
+void c_input_reset(bool enable_mouse, bool flush)
+{
+ crawl_state.mouse_enabled = (enable_mouse && Options.mouse_input);
+ set_mouse_enabled(crawl_state.mouse_enabled);
+
+ if (flush)
+ flush_mouse_events();
+}
diff --git a/crawl-ref/source/cio.h b/crawl-ref/source/cio.h
new file mode 100644
index 0000000000..552ea1b699
--- /dev/null
+++ b/crawl-ref/source/cio.h
@@ -0,0 +1,226 @@
+/*
+ * File: cio.h
+ * Summary: System independent console IO functions
+ *
+ * Modified for Crawl Reference by $Author: dshaligram $ on $Date: 2007-06-14T18:14:26.828542Z $
+ */
+
+#ifndef CIO_H
+#define CIO_H
+
+#include "AppHdr.h"
+#include "externs.h"
+#include "defines.h"
+#include <cctype>
+#include <string>
+#include <vector>
+
+void cursorxy(int x, int y);
+
+// Read one key, flag it as a mouse event if appropriate, but apply no
+// other conversions. Defined in lib$OS.cc, not in cio.cc.
+int m_getch();
+
+// A getch() that flags mouse events and returns a consistent set of key codes
+// for all platforms for a small subset of the keys Crawl is interested in.
+int c_getch();
+
+// Converts a key to a direction key, converting keypad and other sequences
+// to vi key sequences (shifted/control key directions are also handled). Non
+// direction keys (hopefully) pass through unmangled.
+int unmangle_direction_keys(int keyin, int keymap = 0,
+ bool fake_ctrl = true, bool fake_shift = true);
+
+void get_input_line( char *const buff, int len );
+
+// In view.cc, declared here for default argument to cancelable_get_line()
+int get_number_of_cols(void);
+
+class input_history;
+// Returns zero if user entered text and pressed Enter, otherwise returns the
+// key pressed that caused the exit, usually Escape.
+//
+// If keyproc is provided, it must return 1 for normal processing, 0 to exit
+// normally (pretend the user pressed Enter), or -1 to exit as if the user
+// pressed Escape
+int cancelable_get_line( char *buf,
+ int len,
+ int wrapcol = get_number_of_cols(),
+ input_history *mh = NULL,
+ int (*keyproc)(int &c) = NULL );
+
+struct c_mouse_event
+{
+ coord_def pos;
+ int bstate;
+
+ enum button_state_type
+ {
+ BUTTON1 = 0x1,
+ BUTTON1_DBL = 0x2,
+ BUTTON2 = 0x4,
+ BUTTON2_DBL = 0x8,
+ BUTTON3 = 0x10,
+ BUTTON3_DBL = 0x20,
+ BUTTON4 = 0x40,
+ BUTTON4_DBL = 0x80,
+ BUTTON_SCRL_UP = 0x100,
+ BUTTON_SCRL_DN = 0x200
+ };
+
+ c_mouse_event() : pos(-1, -1), bstate(0)
+ {
+ }
+
+ c_mouse_event(const coord_def &c, int state = 0) : pos(c), bstate(state)
+ {
+ }
+
+ // Returns true for valid events.
+ operator bool () const
+ {
+ return (bstate);
+ }
+
+ bool left_clicked() const
+ {
+ return (bstate & BUTTON1);
+ }
+
+ bool right_clicked() const
+ {
+ return (bstate & BUTTON3);
+ }
+
+ bool scroll_up() const
+ {
+ return (bstate & (BUTTON4 | BUTTON4_DBL | BUTTON_SCRL_UP));
+ }
+
+ bool scroll_down() const
+ {
+ return (bstate & (BUTTON2 | BUTTON2_DBL | BUTTON_SCRL_DN));
+ }
+};
+
+coord_def get_mouse_pos();
+c_mouse_event get_mouse_event();
+void new_mouse_event(const c_mouse_event &ce);
+void flush_mouse_events();
+void c_input_reset(bool enable_mouse, bool flush = false);
+
+// Keys that getch() must return for keys Crawl is interested in.
+enum KEYS
+{
+ CK_ENTER = '\r',
+ CK_BKSP = 8,
+ CK_ESCAPE = ESCAPE,
+
+ // 128 is off-limits because it's the code that's used when running
+ CK_DELETE = 129,
+
+ // This sequence of enums should not be rearranged.
+ CK_UP,
+ CK_DOWN,
+ CK_LEFT,
+ CK_RIGHT,
+
+ CK_INSERT,
+
+ CK_HOME,
+ CK_END,
+ CK_CLEAR,
+
+ CK_PGUP,
+ CK_PGDN,
+
+ CK_SHIFT_UP,
+ CK_SHIFT_DOWN,
+ CK_SHIFT_LEFT,
+ CK_SHIFT_RIGHT,
+
+ CK_SHIFT_INSERT,
+
+ CK_SHIFT_HOME,
+ CK_SHIFT_END,
+ CK_SHIFT_CLEAR,
+
+ CK_SHIFT_PGUP,
+ CK_SHIFT_PGDN,
+
+ CK_CTRL_UP,
+ CK_CTRL_DOWN,
+ CK_CTRL_LEFT,
+ CK_CTRL_RIGHT,
+
+ CK_CTRL_INSERT,
+
+ CK_CTRL_HOME,
+ CK_CTRL_END,
+ CK_CTRL_CLEAR,
+
+ CK_CTRL_PGUP,
+ CK_CTRL_PGDN,
+
+ // Mouse codes.
+ CK_MOUSE_MOVE = 10001,
+ CK_MOUSE_CLICK
+};
+
+class cursor_control
+{
+public:
+ cursor_control(bool cursor_enabled)
+ : cstate(is_cursor_enabled()), smartcstate(is_smart_cursor_enabled())
+ {
+ enable_smart_cursor(false);
+ set_cursor_enabled(cursor_enabled);
+ }
+ ~cursor_control() {
+ set_cursor_enabled(cstate);
+ enable_smart_cursor(smartcstate);
+ }
+private:
+ bool cstate;
+ bool smartcstate;
+};
+
+// Reads lines of text; used internally by cancelable_get_line.
+class line_reader
+{
+public:
+ line_reader(char *buffer, size_t bufsz,
+ int wrap_col = get_number_of_cols());
+
+ typedef int (*keyproc)(int &key);
+
+ int read_line(bool clear_previous = true);
+
+ std::string get_text() const;
+
+ void set_input_history(input_history *ih);
+ void set_keyproc(keyproc fn);
+
+protected:
+ void cursorto(int newcpos);
+ int process_key(int ch);
+ void backspace();
+ void killword();
+
+ bool is_wordchar(int c);
+
+private:
+ char *buffer;
+ size_t bufsz;
+ input_history *history;
+ int start_x, start_y;
+ keyproc keyfn;
+ int wrapcol;
+
+ // These are subject to change during editing.
+ char *cur;
+ int length;
+ int pos;
+};
+
+#endif
diff --git a/crawl-ref/source/clua.cc b/crawl-ref/source/clua.cc
index 9140cf5d2b..fb36672fe9 100644
--- a/crawl-ref/source/clua.cc
+++ b/crawl-ref/source/clua.cc
@@ -9,6 +9,7 @@
#include "abl-show.h"
#include "command.h"
#include "chardump.h"
+#include "cio.h"
#include "delay.h"
#include "food.h"
#include "invent.h"
diff --git a/crawl-ref/source/debug.cc b/crawl-ref/source/debug.cc
index a40a3c4492..4f7badcd30 100644
--- a/crawl-ref/source/debug.cc
+++ b/crawl-ref/source/debug.cc
@@ -37,6 +37,7 @@
#include "externs.h"
#include "branch.h"
+#include "cio.h"
#include "decks.h"
#include "describe.h"
#include "direct.h"
diff --git a/crawl-ref/source/direct.cc b/crawl-ref/source/direct.cc
index 5b2ebf3f55..e6da1565ff 100644
--- a/crawl-ref/source/direct.cc
+++ b/crawl-ref/source/direct.cc
@@ -32,6 +32,7 @@
#include "externs.h"
+#include "cio.h"
#include "command.h"
#include "debug.h"
#include "describe.h"
@@ -416,7 +417,7 @@ void direction(dist& moves, targeting_type restricts,
const int old_tx = moves.tx + (skip_iter ? 500 : 0); // hmmm...hack
const int old_ty = moves.ty;
- int i, mid, oid;
+ int i, mid;
switch ( key_command )
{
@@ -628,32 +629,8 @@ void direction(dist& moves, targeting_type restricts,
#endif
case CMD_TARGET_DESCRIBE:
- // Don't give out information for things outside LOS
- if (!see_grid(moves.tx, moves.ty))
- break;
-
- mid = mgrd[moves.tx][moves.ty];
- oid = igrd[moves.tx][moves.ty];
-
- if (mid != NON_MONSTER && player_monster_visible(&menv[mid]))
- {
- // First priority: monsters
- describe_monsters(menv[mid]);
- }
- else if (oid != NON_ITEM)
- {
- // Second priority: objects
- describe_item( mitm[oid] );
- }
- else
- {
- // Third priority: features
- describe_feature_wide(moves.tx, moves.ty);
- }
-
+ full_describe_square(moves.target());
force_redraw = true;
- redraw_screen();
- mesclr(true);
break;
case CMD_TARGET_HELP:
@@ -735,10 +712,7 @@ void direction(dist& moves, targeting_type restricts,
if ( !skip_iter ) // don't clear before we get a chance to see
mesclr(true); // maybe not completely necessary
- if ( !in_vlos(grid2viewX(moves.tx), grid2viewY(moves.ty)) )
- describe_oos_square(moves.tx, moves.ty);
- else if ( in_bounds(moves.tx, moves.ty) )
- describe_cell(moves.tx, moves.ty);
+ terse_describe_square(moves.target());
}
if ( need_beam_redraw )
@@ -776,6 +750,43 @@ void direction(dist& moves, targeting_type restricts,
extend_move_to_edge(moves);
}
+void terse_describe_square(const coord_def &c)
+{
+ if (!see_grid(c.x, c.y))
+ describe_oos_square(c.x, c.y);
+ else if (in_bounds(c) )
+ describe_cell(c.x, c.y);
+}
+
+void full_describe_square(const coord_def &c)
+{
+ // Don't give out information for things outside LOS
+ if (!see_grid(c.x, c.y))
+ return;
+
+ const int mid = mgrd(c);
+ const int oid = igrd(c);
+
+ if (mid != NON_MONSTER && player_monster_visible(&menv[mid]))
+ {
+ // First priority: monsters
+ describe_monsters(menv[mid]);
+ }
+ else if (oid != NON_ITEM)
+ {
+ // Second priority: objects
+ describe_item( mitm[oid] );
+ }
+ else
+ {
+ // Third priority: features
+ describe_feature_wide(c.x, c.y);
+ }
+
+ redraw_screen();
+ mesclr(true);
+}
+
static void extend_move_to_edge(dist &moves)
{
if (!moves.dx && !moves.dy)
diff --git a/crawl-ref/source/direct.h b/crawl-ref/source/direct.h
index 8f2c243955..54b7a4821d 100644
--- a/crawl-ref/source/direct.h
+++ b/crawl-ref/source/direct.h
@@ -33,6 +33,8 @@ bool in_los(int x, int y);
bool in_vlos(int x, int y);
bool in_vlos(const coord_def &pos);
+void terse_describe_square(const coord_def &c);
+void full_describe_square(const coord_def &c);
void describe_floor();
int dos_direction_unmunge(int doskey);
diff --git a/crawl-ref/source/enum.h b/crawl-ref/source/enum.h
index a86a978218..e86dcc2a0e 100644
--- a/crawl-ref/source/enum.h
+++ b/crawl-ref/source/enum.h
@@ -661,6 +661,9 @@ enum command_type
CMD_RESISTS_SCREEN,
CMD_READ_MESSAGES,
+
+ CMD_MOUSE_MOVE,
+ CMD_MOUSE_CLICK,
/* overmap commands */
CMD_MAP_CLEAR_MAP,
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index 9271c72dea..53165a8240 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -1185,6 +1185,8 @@ extern struct crawl_environment env;
// Track various aspects of Crawl game state.
struct game_state
{
+ bool mouse_enabled; // True if mouse input is currently relevant.
+
bool waiting_for_command; // 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.
@@ -1204,11 +1206,12 @@ struct game_state
void (*terminal_resize_handler)();
void (*terminal_resize_check)();
- game_state() : waiting_for_command(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), terminal_resize_check(NULL)
+ game_state() : mouse_enabled(false), waiting_for_command(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),
+ terminal_resize_check(NULL)
{
}
@@ -1289,6 +1292,8 @@ public:
coord_def glos1, glos2; // LOS limit grid coords (inclusive)
coord_def vlos1, vlos2; // LOS limit viewport coords (inclusive)
+ coord_def mousep; // Where the mouse is.
+
static const int message_min_lines = 7;
static const int hud_min_width = 41;
static const int hud_min_gutter = 3;
@@ -1458,6 +1463,8 @@ public:
bool messaging; // Check for messages.
#endif
+ bool mouse_input;
+
int view_max_width;
int view_max_height;
diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc
index 6fb3700514..3662b31a1a 100644
--- a/crawl-ref/source/initfile.cc
+++ b/crawl-ref/source/initfile.cc
@@ -559,6 +559,8 @@ void game_options::reset_options()
messaging = true;
#endif
+ mouse_input = false;
+
view_max_width = VIEW_BASE_WIDTH;
view_max_height = VIEW_MIN_HEIGHT;
@@ -1873,6 +1875,10 @@ void game_options::read_option_line(const std::string &str, bool runscript)
messaging = read_bool(field, messaging);
}
#endif
+ else if (key == "mouse_input")
+ {
+ mouse_input = read_bool(field, mouse_input);
+ }
else if (key == "view_max_width")
{
view_max_width = atoi(field.c_str());
diff --git a/crawl-ref/source/item_use.cc b/crawl-ref/source/item_use.cc
index 271852cd2d..0db383d21e 100644
--- a/crawl-ref/source/item_use.cc
+++ b/crawl-ref/source/item_use.cc
@@ -35,6 +35,7 @@
#include "externs.h"
#include "beam.h"
+#include "cio.h"
#include "debug.h"
#include "delay.h"
#include "describe.h"
diff --git a/crawl-ref/source/libdos.cc b/crawl-ref/source/libdos.cc
index 8c197e1c8e..02e1b7f85c 100644
--- a/crawl-ref/source/libdos.cc
+++ b/crawl-ref/source/libdos.cc
@@ -93,4 +93,38 @@ int get_number_of_cols()
return (80);
}
+int getch_ck()
+{
+ int c = getch();
+ if (!c)
+ {
+ switch (c = getch())
+ {
+ case 'O': return CK_END;
+ case 'P': return CK_DOWN;
+ case 'I': return CK_PGUP;
+ case 'H': return CK_UP;
+ case 'G': return CK_HOME;
+ case 'K': return CK_LEFT;
+ case 'Q': return CK_PGDN;
+ case 'M': return CK_RIGHT;
+ case 119: return CK_CTRL_HOME;
+ case 141: return CK_CTRL_UP;
+ case 132: return CK_CTRL_PGUP;
+ case 116: return CK_CTRL_RIGHT;
+ case 118: return CK_CTRL_PGDN;
+ case 145: return CK_CTRL_DOWN;
+ case 117: return CK_CTRL_END;
+ case 115: return CK_CTRL_LEFT;
+ case 'S': return CK_DELETE;
+ }
+ }
+ return c;
+}
+
+int m_getch()
+{
+ return getch();
+}
+
#endif /* #if defined(DOS) */
diff --git a/crawl-ref/source/libdos.h b/crawl-ref/source/libdos.h
index 6e2d3f16a6..fd6a0a0d92 100644
--- a/crawl-ref/source/libdos.h
+++ b/crawl-ref/source/libdos.h
@@ -11,6 +11,8 @@ inline bool is_smart_cursor_enabled() { return (false); }
void set_cursor_enabled(bool enabled);
bool is_cursor_enabled();
void clear_to_end_of_line();
+int getch_ck();
+void set_mouse_enabled(bool enabled) { }
void message_out(int mline, int colour, const char *str, int firstcol = 0,
bool newline = true);
diff --git a/crawl-ref/source/libunix.cc b/crawl-ref/source/libunix.cc
index 7af2b38f3e..84d0beaa80 100644
--- a/crawl-ref/source/libunix.cc
+++ b/crawl-ref/source/libunix.cc
@@ -43,6 +43,7 @@
#include "libunix.h"
#include "defines.h"
+#include "cio.h"
#include "enum.h"
#include "externs.h"
#include "files.h"
@@ -225,10 +226,83 @@ static void termio_init()
crawl_state.terminal_resize_handler = unix_handle_terminal_resize;
}
+void set_mouse_enabled(bool enabled)
+{
+#ifdef NCURSES_MOUSE_VERSION
+ const int mask = enabled? ALL_MOUSE_EVENTS | REPORT_MOUSE_POSITION : 0;
+ mousemask(mask, NULL);
+#endif
+}
+
+#ifdef NCURSES_MOUSE_VERSION
+static int proc_mouse_event(int c, const MEVENT *me)
+{
+ crawl_view.mousep.x = me->x + 1;
+ crawl_view.mousep.y = me->y + 1;
+
+ if (!crawl_state.mouse_enabled)
+ return (CK_MOUSE_MOVE);
+
+ c_mouse_event cme(crawl_view.mousep);
+ if (me->bstate & BUTTON1_CLICKED)
+ cme.bstate |= c_mouse_event::BUTTON1;
+ else if (me->bstate & BUTTON1_DOUBLE_CLICKED)
+ cme.bstate |= c_mouse_event::BUTTON1_DBL;
+ else if (me->bstate & BUTTON2_CLICKED)
+ cme.bstate |= c_mouse_event::BUTTON2;
+ else if (me->bstate & BUTTON2_DOUBLE_CLICKED)
+ cme.bstate |= c_mouse_event::BUTTON2_DBL;
+ else if (me->bstate & BUTTON3_CLICKED)
+ cme.bstate |= c_mouse_event::BUTTON3;
+ else if (me->bstate & BUTTON3_DOUBLE_CLICKED)
+ cme.bstate |= c_mouse_event::BUTTON3_DBL;
+ else if (me->bstate & BUTTON4_CLICKED)
+ cme.bstate |= c_mouse_event::BUTTON4;
+ else if (me->bstate & BUTTON4_DOUBLE_CLICKED)
+ cme.bstate |= c_mouse_event::BUTTON4_DBL;
+
+ if (cme)
+ {
+ new_mouse_event(cme);
+ return (CK_MOUSE_CLICK);
+ }
+
+ return (CK_MOUSE_MOVE);
+}
+#endif
+
+static int raw_m_getch()
+{
+ const int c = getch();
+ switch (c)
+ {
+#ifdef NCURSES_MOUSE_VERSION
+ case KEY_MOUSE:
+ {
+ MEVENT me;
+ getmouse(&me);
+ return (proc_mouse_event(c, &me));
+ }
+#endif
+ default:
+ return (c);
+ }
+}
+
+int m_getch()
+{
+ int c;
+ do
+ c = raw_m_getch();
+ while ((c == CK_MOUSE_MOVE || c == CK_MOUSE_CLICK)
+ && !crawl_state.mouse_enabled);
+
+ return (c);
+}
int getch_ck()
{
- int c = getch();
+ int c = m_getch();
switch (c)
{
// [dshaligram] MacOS ncurses returns 127 for backspace.
@@ -389,6 +463,8 @@ void unixcurses_startup( void )
crawl_view.init_geometry();
setup_message_window();
+
+ set_mouse_enabled(false);
}
void unixcurses_shutdown()
diff --git a/crawl-ref/source/libunix.h b/crawl-ref/source/libunix.h
index 42d9ba9449..03d63a8be4 100644
--- a/crawl-ref/source/libunix.h
+++ b/crawl-ref/source/libunix.h
@@ -51,6 +51,8 @@ bool is_cursor_enabled();
inline void enable_smart_cursor(bool) { }
inline bool is_smart_cursor_enabled() { return (false); }
+void set_mouse_enabled(bool enabled);
+
#ifndef _LIBUNIX_IMPLEMENTATION
/* Some stuff from curses, to remove compiling warnings.. */
extern "C"
diff --git a/crawl-ref/source/libutil.cc b/crawl-ref/source/libutil.cc
index 27d28e6e7a..98dd7f598f 100644
--- a/crawl-ref/source/libutil.cc
+++ b/crawl-ref/source/libutil.cc
@@ -46,96 +46,6 @@
#include <regex.h>
#endif
-#ifdef UNIX
-static keycode_type numpad2vi(keycode_type key)
-{
- if (key >= '1' && key <= '9')
- {
- const char *vikeys = "bjnh.lyku";
- return keycode_type(vikeys[key - '1']);
- }
- return (key);
-}
-#endif
-
-int unmangle_direction_keys(int keyin, int km, bool fake_ctrl, bool fake_shift)
-{
- const KeymapContext keymap = static_cast<KeymapContext>(km);
-#ifdef UNIX
- // Kludging running and opening as two character sequences
- // for Unix systems. This is an easy way out... all the
- // player has to do is find a termcap and numlock setting
- // that will get curses the numbers from the keypad. This
- // will hopefully be easy.
-
- /* can we say yuck? -- haranp */
- if (fake_ctrl && keyin == '*')
- {
- keyin = getchm(keymap);
- // return control-key
- keyin = CONTROL(toupper(numpad2vi(keyin)));
- }
- else if (fake_shift && keyin == '/')
- {
- keyin = getchm(keymap);
- // return shift-key
- keyin = toupper(numpad2vi(keyin));
- }
-#else
- // Old DOS keypad support
- if (keyin == 0)
- {
- /* FIXME haranp - hackiness */
- const char DOSidiocy[10] = { "OPQKSMGHI" };
- const char DOSunidiocy[10] = { "bjnh.lyku" };
- const int DOScontrolidiocy[9] =
- {
- 117, 145, 118, 115, 76, 116, 119, 141, 132
- };
- keyin = getchm(keymap);
- for (int j = 0; j < 9; ++j )
- {
- if (keyin == DOSidiocy[j])
- {
- keyin = DOSunidiocy[j];
- break;
- }
- if (keyin == DOScontrolidiocy[j])
- {
- keyin = CONTROL(toupper(DOSunidiocy[j]));
- break;
- }
- }
- }
-#endif
-
- // [dshaligram] More lovely keypad mangling.
- switch (keyin)
- {
-#ifdef UNIX
- case '1': return 'b';
- case '2': return 'j';
- case '3': return 'n';
- case '4': return 'h';
- case '6': return 'l';
- case '7': return 'y';
- case '8': return 'k';
- case '9': return 'u';
-#else
- case '1': return 'B';
- case '2': return 'J';
- case '3': return 'N';
- case '4': return 'H';
- case '6': return 'L';
- case '7': return 'Y';
- case '8': return 'K';
- case '9': return 'U';
-#endif
- }
-
- return (keyin);
-}
-
// Should return true if the filename contains nothing that
// the shell can do damage with.
bool shell_safe(const char *file)
@@ -321,146 +231,6 @@ int count_occurrences(const std::string &text, const std::string &s)
return (nfound);
}
-void get_input_line( char *const buff, int len )
-{
- buff[0] = 0; // just in case
-
-#if defined(UNIX)
- get_input_line_from_curses( buff, len ); // implemented in libunix.cc
-#elif defined(WIN32CONSOLE)
- getstr( buff, len );
-#else
-
- // [dshaligram] Turn on the cursor for DOS.
-#ifdef DOS
- _setcursortype(_NORMALCURSOR);
-#endif
-
- fgets( buff, len, stdin ); // much safer than gets()
-#endif
-
- buff[ len - 1 ] = 0; // just in case
-
- // Removing white space from the end in order to get rid of any
- // newlines or carriage returns that any of the above might have
- // left there (ie fgets especially). -- bwr
- const int end = strlen( buff );
- int i;
-
- for (i = end - 1; i >= 0; i++)
- {
- if (isspace( buff[i] ))
- buff[i] = 0;
- else
- break;
- }
-}
-
-#ifdef DOS
-static int getch_ck()
-{
- int c = getch();
- if (!c)
- {
- switch (c = getch())
- {
- case 'O': return CK_END;
- case 'P': return CK_DOWN;
- case 'I': return CK_PGUP;
- case 'H': return CK_UP;
- case 'G': return CK_HOME;
- case 'K': return CK_LEFT;
- case 'Q': return CK_PGDN;
- case 'M': return CK_RIGHT;
- case 119: return CK_CTRL_HOME;
- case 141: return CK_CTRL_UP;
- case 132: return CK_CTRL_PGUP;
- case 116: return CK_CTRL_RIGHT;
- case 118: return CK_CTRL_PGDN;
- case 145: return CK_CTRL_DOWN;
- case 117: return CK_CTRL_END;
- case 115: return CK_CTRL_LEFT;
- case 'S': return CK_DELETE;
- }
- }
- return c;
-}
-#endif
-
-// Hacky wrapper around getch() that returns CK_ codes for keys
-// we want to use in cancelable_get_line() and menus.
-int c_getch()
-{
-#if defined(DOS) || defined(UNIX) || defined(WIN32CONSOLE)
- return getch_ck();
-#else
- return getch();
-#endif
-}
-
-// Wrapper around gotoxy that can draw a fake cursor for Unix terms where
-// cursoring over darkgray or black causes problems.
-void cursorxy(int x, int y)
-{
-#ifdef UNIX
- if (Options.use_fake_cursor)
- fakecursorxy(x, y);
- else
- gotoxy(x, y);
-#else
- gotoxy(x, y);
-#endif
-}
-
-// cprintf that knows how to wrap down lines (primitive, but what the heck)
-int wrapcprintf( int wrapcol, const char *s, ... )
-{
- char buf[1000]; // Hard max
- va_list args;
- va_start(args, s);
-
- // XXX: If snprintf isn't available, vsnprintf probably isn't, either.
- int len = vsnprintf(buf, sizeof buf, s, args);
- int olen = len;
- va_end(args);
-
- char *run = buf;
- while (len > 0)
- {
- int x = wherex(), y = wherey();
-
- if (x > wrapcol) // Somebody messed up!
- return 0;
-
- int avail = wrapcol - x + 1;
- int c = 0;
- if (len > avail)
- {
- c = run[avail];
- run[avail] = 0;
- }
- cprintf("%s", run);
-
- if (len > avail)
- run[avail] = c;
-
- if ((len -= avail) > 0)
- gotoxy(1, y + 1);
- run += avail;
- }
- return (olen);
-}
-
-int cancelable_get_line( char *buf, int len, int maxcol,
- input_history *mh, int (*keyproc)(int &ch) )
-{
- line_reader reader(buf, len, maxcol);
- reader.set_input_history(mh);
- reader.set_keyproc(keyproc);
-
- return reader.read_line();
-}
-
std::string trimmed_string( std::string s )
{
trim_string(s);
@@ -724,331 +494,3 @@ bool pattern_match(void *compiled_pattern, const char *text, int length)
////////////////////////////////////////////////////////////////////
#endif
-
-
-/////////////////////////////////////////////////////////////
-// input_history
-//
-
-input_history::input_history(size_t size)
- : history(), pos(), maxsize(size)
-{
- if (maxsize < 2)
- maxsize = 2;
-
- pos = history.end();
-}
-
-void input_history::new_input(const std::string &s)
-{
- history.remove(s);
-
- if (history.size() == maxsize)
- history.pop_front();
-
- history.push_back(s);
-
- // Force the iterator to the end (also revalidates it)
- go_end();
-}
-
-const std::string *input_history::prev()
-{
- if (history.empty())
- return NULL;
-
- if (pos == history.begin())
- pos = history.end();
-
- return &*--pos;
-}
-
-const std::string *input_history::next()
-{
- if (history.empty())
- return NULL;
-
- if (pos == history.end() || ++pos == history.end())
- pos = history.begin();
-
- return &*pos;
-}
-
-void input_history::go_end()
-{
- pos = history.end();
-}
-
-void input_history::clear()
-{
- history.clear();
- go_end();
-}
-
-/////////////////////////////////////////////////////////////////////////
-// line_reader
-
-line_reader::line_reader(char *buf, size_t sz, int wrap)
- : buffer(buf), bufsz(sz), history(NULL), start_x(0),
- start_y(0), keyfn(NULL), wrapcol(wrap), cur(NULL),
- length(0), pos(-1)
-{
-}
-
-std::string line_reader::get_text() const
-{
- return (buffer);
-}
-
-void line_reader::set_input_history(input_history *i)
-{
- history = i;
-}
-
-void line_reader::set_keyproc(keyproc fn)
-{
- keyfn = fn;
-}
-
-void line_reader::cursorto(int ncx)
-{
- int x = (start_x + ncx - 1) % wrapcol + 1;
- int y = start_y + (start_x + ncx - 1) / wrapcol;
- ::gotoxy(x, y);
-}
-
-int line_reader::read_line(bool clear_previous)
-{
- if (bufsz <= 0) return false;
-
- cursor_control coff(true);
-
- if (clear_previous)
- *buffer = 0;
-
- start_x = wherex();
- start_y = wherey();
-
- length = strlen(buffer);
-
- // Remember the previous cursor position, if valid.
- if (pos < 0 || pos > length)
- pos = length;
-
- cur = buffer + pos;
-
- if (length)
- wrapcprintf(wrapcol, "%s", buffer);
-
- if (pos != length)
- cursorto(pos);
-
- if (history)
- history->go_end();
-
- for ( ; ; )
- {
- int ch = c_getch();
-
- if (keyfn)
- {
- int whattodo = (*keyfn)(ch);
- if (whattodo == 0)
- {
- buffer[length] = 0;
- if (history && length)
- history->new_input(buffer);
- return (0);
- }
- else if (whattodo == -1)
- {
- buffer[length] = 0;
- return (ch);
- }
- }
-
- int ret = process_key(ch);
- if (ret != -1)
- return (ret);
- }
-}
-
-void line_reader::backspace()
-{
- if (pos)
- {
- --cur;
- char *c = cur;
- while (*c)
- {
- *c = c[1];
- c++;
- }
- --pos;
- --length;
-
- cursorto(pos);
- buffer[length] = 0;
- wrapcprintf( wrapcol, "%s ", cur );
- cursorto(pos);
- }
-}
-
-bool line_reader::is_wordchar(int c)
-{
- return isalnum(c) || c == '_' || c == '-';
-}
-
-void line_reader::killword()
-{
- if (!pos || cur == buffer)
- return;
-
- bool foundwc = false;
- while (pos)
- {
- if (is_wordchar(cur[-1]))
- foundwc = true;
- else if (foundwc)
- break;
-
- backspace();
- }
-}
-
-int line_reader::process_key(int ch)
-{
- switch (ch)
- {
- case CONTROL('G'):
- case CK_ESCAPE:
- return (CK_ESCAPE);
- case CK_UP:
- case CK_DOWN:
- {
- if (!history)
- break;
-
- const std::string *text =
- ch == CK_UP? history->prev() : history->next();
-
- if (text)
- {
- int olen = length;
- length = text->length();
- if (length >= (int) bufsz)
- length = bufsz - 1;
- memcpy(buffer, text->c_str(), length);
- buffer[length] = 0;
- cursorto(0);
-
- int clear = length < olen? olen - length : 0;
- wrapcprintf(wrapcol, "%s%*s", buffer, clear, "");
-
- pos = length;
- cur = buffer + pos;
- cursorto(pos);
- }
- break;
- }
- case CK_ENTER:
- buffer[length] = 0;
- if (history && length)
- history->new_input(buffer);
- return (0);
-
- case CONTROL('K'):
- {
- // Kill to end of line
- int erase = length - pos;
- if (erase)
- {
- length = pos;
- buffer[length] = 0;
- wrapcprintf( wrapcol, "%*s", erase, "" );
- cursorto(pos);
- }
- break;
- }
- case CK_DELETE:
- if (pos < length)
- {
- char *c = cur;
- while (c - buffer < length)
- {
- *c = c[1];
- c++;
- }
- --length;
-
- cursorto(pos);
- buffer[length] = 0;
- wrapcprintf( wrapcol, "%s ", cur );
- cursorto(pos);
- }
- break;
-
- case CK_BKSP:
- backspace();
- break;
-
- case CONTROL('W'):
- killword();
- break;
-
- case CK_LEFT:
- if (pos)
- {
- --pos;
- cur = buffer + pos;
- cursorto(pos);
- }
- break;
- case CK_RIGHT:
- if (pos < length)
- {
- ++pos;
- cur = buffer + pos;
- cursorto(pos);
- }
- break;
- case CK_HOME:
- case CONTROL('A'):
- pos = 0;
- cur = buffer + pos;
- cursorto(pos);
- break;
- case CK_END:
- case CONTROL('E'):
- pos = length;
- cur = buffer + pos;
- cursorto(pos);
- break;
- default:
- if (isprint(ch) && length < (int) bufsz - 1)
- {
- if (pos < length)
- {
- char *c = buffer + length - 1;
- while (c >= cur)
- {
- c[1] = *c;
- c--;
- }
- }
- *cur++ = (char) ch;
- ++length;
- ++pos;
- putch(ch);
- if (pos < length)
- {
- buffer[length] = 0;
- wrapcprintf( wrapcol, "%s", cur );
- }
- cursorto(pos);
- }
- break;
- }
-
- return (-1);
-}
diff --git a/crawl-ref/source/libutil.h b/crawl-ref/source/libutil.h
index e9d6d987b8..4eed5ab7a7 100644
--- a/crawl-ref/source/libutil.h
+++ b/crawl-ref/source/libutil.h
@@ -1,6 +1,6 @@
/*
* File: libutil.h
- * Summary: System indepentant functions
+ * Summary: System independent functions
*
* Modified for Crawl Reference by $Author$ on $Date$
*
@@ -19,14 +19,6 @@
#include <string>
#include <vector>
-void cursorxy(int x, int y);
-
-// Converts a key to a direction key, converting keypad and other sequences
-// to vi key sequences (shifted/control key directions are also handled). Non
-// direction keys (hopefully) pass through unmangled.
-int unmangle_direction_keys(int keyin, int keymap = 0,
- bool fake_ctrl = true, bool fake_shift = true);
-
std::string lowercase_string(std::string s);
std::string &lowercase(std::string &s);
std::string &uppercase(std::string &s);
@@ -54,9 +46,6 @@ std::string replace_all_of(std::string s,
int count_occurrences(const std::string &text, const std::string &searchfor);
-// getch() that returns a consistent set of values for all platforms.
-int c_getch();
-
void play_sound(const char *file);
// Pattern matching
@@ -64,25 +53,6 @@ void *compile_pattern(const char *pattern, bool ignore_case = false);
void free_compiled_pattern(void *cp);
bool pattern_match(void *compiled_pattern, const char *text, int length);
-void get_input_line( char *const buff, int len );
-
-class input_history;
-
-// In view.cc, declared here for default argument to cancelable_get_line()
-int get_number_of_cols(void);
-
-// Returns zero if user entered text and pressed Enter, otherwise returns the
-// key pressed that caused the exit, usually Escape.
-//
-// If keyproc is provided, it must return 1 for normal processing, 0 to exit
-// normally (pretend the user pressed Enter), or -1 to exit as if the user
-// pressed Escape
-int cancelable_get_line( char *buf,
- int len,
- int wrapcol = get_number_of_cols(),
- input_history *mh = NULL,
- int (*keyproc)(int &c) = NULL );
-
std::string & trim_string( std::string &str );
std::string trimmed_string( std::string s );
@@ -135,60 +105,6 @@ void usleep( unsigned long time );
int snprintf( char *str, size_t size, const char *format, ... );
#endif
-// Keys that getch() must return for keys Crawl is interested in.
-enum KEYS
-{
- CK_ENTER = '\r',
- CK_BKSP = 8,
- CK_ESCAPE = ESCAPE,
-
- // 128 is off-limits because it's the code that's used when running
- CK_DELETE = 129,
-
- // This sequence of enums should not be rearranged.
- CK_UP,
- CK_DOWN,
- CK_LEFT,
- CK_RIGHT,
-
- CK_INSERT,
-
- CK_HOME,
- CK_END,
- CK_CLEAR,
-
- CK_PGUP,
- CK_PGDN,
-
- CK_SHIFT_UP,
- CK_SHIFT_DOWN,
- CK_SHIFT_LEFT,
- CK_SHIFT_RIGHT,
-
- CK_SHIFT_INSERT,
-
- CK_SHIFT_HOME,
- CK_SHIFT_END,
- CK_SHIFT_CLEAR,
-
- CK_SHIFT_PGUP,
- CK_SHIFT_PGDN,
-
- CK_CTRL_UP,
- CK_CTRL_DOWN,
- CK_CTRL_LEFT,
- CK_CTRL_RIGHT,
-
- CK_CTRL_INSERT,
-
- CK_CTRL_HOME,
- CK_CTRL_END,
- CK_CTRL_CLEAR,
-
- CK_CTRL_PGUP,
- CK_CTRL_PGDN
-};
-
// Sets a boolean to a new value in the scope of the object instance.
class unwind_bool
{
@@ -206,62 +122,6 @@ private:
bool oldval;
};
-class cursor_control
-{
-public:
- cursor_control(bool cursor_enabled)
- : cstate(is_cursor_enabled()), smartcstate(is_smart_cursor_enabled())
- {
- enable_smart_cursor(false);
- set_cursor_enabled(cursor_enabled);
- }
- ~cursor_control() {
- set_cursor_enabled(cstate);
- enable_smart_cursor(smartcstate);
- }
-private:
- bool cstate;
- bool smartcstate;
-};
-
-// Reads lines of text; used internally by cancelable_get_line.
-class line_reader
-{
-public:
- line_reader(char *buffer, size_t bufsz,
- int wrap_col = get_number_of_cols());
-
- typedef int (*keyproc)(int &key);
-
- int read_line(bool clear_previous = true);
-
- std::string get_text() const;
-
- void set_input_history(input_history *ih);
- void set_keyproc(keyproc fn);
-
-protected:
- void cursorto(int newcpos);
- int process_key(int ch);
- void backspace();
- void killword();
-
- bool is_wordchar(int c);
-
-private:
- char *buffer;
- size_t bufsz;
- input_history *history;
- int start_x, start_y;
- keyproc keyfn;
- int wrapcol;
-
- // These are subject to change during editing.
- char *cur;
- int length;
- int pos;
-};
-
class base_pattern
{
public:
diff --git a/crawl-ref/source/libw32c.cc b/crawl-ref/source/libw32c.cc
index 015b2b7e34..42f730a08e 100644
--- a/crawl-ref/source/libw32c.cc
+++ b/crawl-ref/source/libw32c.cc
@@ -221,8 +221,21 @@ void bFlush(void)
}
}
+void set_mouse_enabled(bool enabled)
+{
+ DWORD inmode;
+ if (::GetConsoleMode(inbuf, &inmode))
+ {
+ if (enabled)
+ inmode |= ENABLE_MOUSE_INPUT;
+ else
+ inmode &= ~ENABLE_MOUSE_INPUT;
+
+ ::SetConsoleMode(inbuf, inmode);
+ }
+}
-void setStringInput(bool value)
+void set_string_input(bool value)
{
DWORD inmodes, outmodes;
if (value == TRUE)
@@ -352,7 +365,7 @@ void init_libw32c(void)
init_colors(oldTitle);
// by default, set string input to false: use char-input only
- setStringInput( false );
+ set_string_input( false );
// set up screen size
set_w32_screen_size();
@@ -364,7 +377,7 @@ void init_libw32c(void)
_setcursortype_internal(false);
// buffering defaults to ON -- very important!
- setBuffering(true);
+ set_buffering(true);
crawl_state.terminal_resize_handler = w32_term_resizer;
crawl_state.terminal_resize_check = w32_check_screen_resize;
@@ -399,7 +412,7 @@ void deinit_libw32c(void)
SetConsoleOutputCP(OutputCP);
// restore console attributes for normal function
- setStringInput(true);
+ set_string_input(true);
// set cursor and normal textcolor
_setcursortype_internal(true);
@@ -613,7 +626,7 @@ static void cprintf_aux(const char *s)
// turn buffering ON (temporarily)
bool oldValue = buffering;
- setBuffering(true);
+ set_buffering(true);
// loop through string
char *p = (char *)s;
@@ -623,7 +636,7 @@ static void cprintf_aux(const char *s)
}
// reset buffering
- setBuffering(oldValue);
+ set_buffering(oldValue);
// flush string
bFlush();
@@ -773,6 +786,11 @@ int vk_translate( WORD VirtCode, CHAR c, DWORD cKeys)
return vk_tr[1][mkey];
}
+int m_getch()
+{
+ return getch();
+}
+
int getch_ck(void)
{
INPUT_RECORD ir;
@@ -845,7 +863,7 @@ int getche(void)
{
// turn buffering off temporarily
const bool oldValue = buffering;
- setBuffering(false);
+ set_buffering(false);
int val = getch();
@@ -853,7 +871,7 @@ int getche(void)
putch(val);
// restore buffering value
- setBuffering(oldValue);
+ set_buffering(oldValue);
return val;
}
@@ -889,11 +907,11 @@ void textbackground(int c)
UNUSED( c );
}
-int getConsoleString(char *buf, int maxlen)
+int get_console_string(char *buf, int maxlen)
{
DWORD nread;
// set console input to line mode
- setStringInput( true );
+ set_string_input( true );
// force cursor
const bool oldValue = cursor_is_enabled;
@@ -920,7 +938,7 @@ int getConsoleString(char *buf, int maxlen)
// reset console mode - also flushes if player has typed in
// too long of a name so we don't get silly garbage on return.
- setStringInput( false );
+ set_string_input( false );
// restore old cursor
if (w32_smart_cursor)
@@ -935,7 +953,7 @@ void update_screen()
bFlush();
}
-bool setBuffering( bool value )
+bool set_buffering( bool value )
{
bool oldValue = buffering;
diff --git a/crawl-ref/source/libw32c.h b/crawl-ref/source/libw32c.h
index 70c038c49e..6e424a43ca 100644
--- a/crawl-ref/source/libw32c.h
+++ b/crawl-ref/source/libw32c.h
@@ -28,9 +28,9 @@ void textcolor(int c);
void textattr(int c);
void cprintf( const char *format, ... );
// void cprintf(const char *s);
-void setStringInput(bool value);
-bool setBuffering(bool value);
-int getConsoleString(char *buf, int maxlen);
+void set_string_input(bool value);
+bool set_buffering(bool value);
+int get_console_string(char *buf, int maxlen);
void print_timings(void);
void window(int x, int y, int lx, int ly);
@@ -49,6 +49,7 @@ void update_screen();
void enable_smart_cursor(bool cursor);
bool is_smart_cursor_enabled();
+void set_mouse_enabled(bool enabled);
#endif
diff --git a/crawl-ref/source/macro.cc b/crawl-ref/source/macro.cc
index 4f9e8cbf45..0deb31ae04 100644
--- a/crawl-ref/source/macro.cc
+++ b/crawl-ref/source/macro.cc
@@ -44,6 +44,7 @@
#include <cctype> // for tolower
#include <cstdlib>
+#include "cio.h"
#include "externs.h"
#include "stuff.h"
@@ -577,7 +578,7 @@ static keyseq getch_mul( int (*rgetch)() = NULL )
int a;
if (!rgetch)
- rgetch = getch;
+ rgetch = m_getch;
keys.push_back( a = rgetch() );
@@ -655,16 +656,14 @@ void flush_input_buffer( int reason )
void macro_add_query( void )
{
- unsigned char input;
+ int input;
bool keymap = false;
KeymapContext keymc = KC_DEFAULT;
mesclr();
- mpr( "(m)acro, keymap [(k) default, (x) level-map or (t)argeting], (s)ave?", MSGCH_PROMPT );
- input = getch();
- if (input == 0)
- input = getch();
-
+ mpr("(m)acro, keymap [(k) default, (x) level-map or (t)argeting], (s)ave?",
+ MSGCH_PROMPT);
+ input = m_getch();
input = tolower( input );
if (input == 'k')
{
@@ -714,9 +713,7 @@ void macro_add_query( void )
mprf(MSGCH_WARN, "Current Action: %s", vtostr(mapref[key]).c_str());
mpr( "Do you wish to (r)edefine, (c)lear, or (a)bort?", MSGCH_PROMPT );
- input = getch();
- if (input == 0)
- input = getch();
+ input = m_getch();
input = tolower( input );
if (input == 'a' || input == ESCAPE)
diff --git a/crawl-ref/source/makefile.obj b/crawl-ref/source/makefile.obj
index 0316e1cb7f..20e016dc9b 100644
--- a/crawl-ref/source/makefile.obj
+++ b/crawl-ref/source/makefile.obj
@@ -7,6 +7,7 @@ acr.o \
beam.o \
branch.o \
chardump.o \
+cio.o \
cloud.o \
command.o \
database.o \
diff --git a/crawl-ref/source/menu.cc b/crawl-ref/source/menu.cc
index 4d88c2160b..7b78c92b1e 100644
--- a/crawl-ref/source/menu.cc
+++ b/crawl-ref/source/menu.cc
@@ -7,6 +7,7 @@
*/
#include <cctype>
#include "AppHdr.h"
+#include "cio.h"
#include "menu.h"
#include "macro.h"
#include "tutorial.h"
diff --git a/crawl-ref/source/message.cc b/crawl-ref/source/message.cc
index 8c947fb4d7..487fedb422 100644
--- a/crawl-ref/source/message.cc
+++ b/crawl-ref/source/message.cc
@@ -24,7 +24,7 @@
#endif
#include "externs.h"
-
+#include "cio.h"
#include "initfile.h"
#include "libutil.h"
#include "macro.h"
diff --git a/crawl-ref/source/newgame.cc b/crawl-ref/source/newgame.cc
index 1f81f6329d..f09b3e6049 100644
--- a/crawl-ref/source/newgame.cc
+++ b/crawl-ref/source/newgame.cc
@@ -71,6 +71,7 @@
#include "abl-show.h"
#include "branch.h"
+#include "cio.h"
#include "command.h"
#include "files.h"
#include "fight.h"
diff --git a/crawl-ref/source/notes.cc b/crawl-ref/source/notes.cc
index 3ea3d44edc..7b21af98e1 100644
--- a/crawl-ref/source/notes.cc
+++ b/crawl-ref/source/notes.cc
@@ -10,6 +10,7 @@
#include "notes.h"
#include "branch.h"
+#include "cio.h"
#include "files.h"
#include "Kills.h"
#include "hiscores.h"
diff --git a/crawl-ref/source/player.cc b/crawl-ref/source/player.cc
index 598aa55dc0..984dc715b8 100644
--- a/crawl-ref/source/player.cc
+++ b/crawl-ref/source/player.cc
@@ -2930,8 +2930,6 @@ int check_stealth(void)
void ability_increase(void)
{
- unsigned char keyin;
-
mpr("Your experience leads to an increase in your attributes!",
MSGCH_INTRINSIC_GAIN);
@@ -2940,34 +2938,28 @@ void ability_increase(void)
mpr("Increase (S)trength, (I)ntelligence, or (D)exterity? ", MSGCH_PROMPT);
- get_key:
- keyin = getch();
- if (keyin == 0)
- {
- getch();
- goto get_key;
- }
-
- switch (keyin)
+ while (true)
{
- case 's':
- case 'S':
- modify_stat(STAT_STRENGTH, 1, false);
- return;
+ const int keyin = getch();
- case 'i':
- case 'I':
- modify_stat(STAT_INTELLIGENCE, 1, false);
- return;
-
- case 'd':
- case 'D':
- modify_stat(STAT_DEXTERITY, 1, false);
- return;
+ switch (keyin)
+ {
+ case 's':
+ case 'S':
+ modify_stat(STAT_STRENGTH, 1, false);
+ return;
+
+ case 'i':
+ case 'I':
+ modify_stat(STAT_INTELLIGENCE, 1, false);
+ return;
+
+ case 'd':
+ case 'D':
+ modify_stat(STAT_DEXTERITY, 1, false);
+ return;
+ }
}
-
- goto get_key;
-/* this is an infinite loop because it is reasonable to assume that you're not going to want to leave it prematurely. */
} // end ability_increase()
void display_char_status()
diff --git a/crawl-ref/source/shopping.cc b/crawl-ref/source/shopping.cc
index d98117f1b5..9f722b94bd 100644
--- a/crawl-ref/source/shopping.cc
+++ b/crawl-ref/source/shopping.cc
@@ -25,7 +25,7 @@
#endif
#include "externs.h"
-
+#include "cio.h"
#include "describe.h"
#include "invent.h"
#include "items.h"
diff --git a/crawl-ref/source/skills2.cc b/crawl-ref/source/skills2.cc
index 1e2d3dd43f..2c29dcea27 100644
--- a/crawl-ref/source/skills2.cc
+++ b/crawl-ref/source/skills2.cc
@@ -1818,20 +1818,11 @@ static const skill_type skill_display_order[] =
static const int ndisplayed_skills =
sizeof(skill_display_order) / sizeof(*skill_display_order);
-void show_skills()
+static void display_skill_table(bool show_aptitudes)
{
- int i;
- int x;
- menu_letter lcount;
- bool show_aptitudes = false;
-
+ menu_letter lcount = 'a';
const int num_lines = get_number_of_lines();
- clrscr();
-
- reprint_stuff:
- lcount = 'a';
-
gotoxy(1, 1);
textcolor(LIGHTGREY);
@@ -1848,11 +1839,11 @@ void show_skills()
#endif
int scrln = 3, scrcol = 1;
-
+ int x;
// Don't want the help line to appear too far down a big window.
const int bottom_line = ((num_lines > 30) ? 30 : num_lines);
- for (i = 0; i < ndisplayed_skills; ++i)
+ for (int i = 0; i < ndisplayed_skills; ++i)
{
x = skill_display_order[i];
@@ -1939,76 +1930,80 @@ void show_skills()
if (Options.tutorial_left)
{
- textcolor(MAGENTA);
- gotoxy(1, bottom_line-5);
- formatted_string::parse_block(
- "This screen shows the skill set of your character. You can pick up new" EOL
- "skills by performing the corresponding actions. The number next to the" EOL
- "skill is your current level, the higher the better. The blue percent " EOL
- "value shows your progress towards the next skill level. You can toggle" EOL
- "which skills to train by pressing their slot letters. A <darkgrey>greyish<magenta> skill " EOL
- "will increase at a decidedly slower rate and ease training of others. ",
- false).display();
+ textcolor(MAGENTA);
+ gotoxy(1, bottom_line-5);
+ formatted_string::parse_block(
+ "This screen shows the skill set of your character. You can pick up new" EOL
+ "skills by performing the corresponding actions. The number next to the" EOL
+ "skill is your current level, the higher the better. The blue percent " EOL
+ "value shows your progress towards the next skill level. You can toggle" EOL
+ "which skills to train by pressing their slot letters. A <darkgrey>greyish<magenta> skill " EOL
+ "will increase at a decidedly slower rate and ease training of others. ",
+ false).display();
}
else
{
- // if any more skills added, must adapt letters to go into caps
- gotoxy(1, bottom_line-1);
- textcolor(LIGHTGREY);
- cprintf("Press the letter of a skill to choose whether you want to practise it.");
- if (!player_genus(GENPC_DRACONIAN) || you.max_level >= 7)
- {
- gotoxy(1, bottom_line);
- formatted_string::parse_string("Press '!' to toggle between "
- "<blue>progress</blue> and "
- "<red>aptitude</red> "
- "display.").display();
- }
+ // if any more skills added, must adapt letters to go into caps
+ gotoxy(1, bottom_line-1);
+ textcolor(LIGHTGREY);
+ cprintf("Press the letter of a skill to choose "
+ "whether you want to practise it.");
+ if (!player_genus(GENPC_DRACONIAN) || you.max_level >= 7)
+ {
+ gotoxy(1, bottom_line);
+ formatted_string::parse_string("Press '!' to toggle between "
+ "<blue>progress</blue> and "
+ "<red>aptitude</red> "
+ "display.").display();
+ }
}
+}
- int get_thing = getch();
-
- if (get_thing == 0)
- getch();
- else
+void show_skills()
+{
+ bool show_aptitudes = false;
+ clrscr();
+ while (true)
{
+ display_skill_table(show_aptitudes);
+
+ const int get_thing = getch();
if (get_thing == '!' && (!player_genus(GENPC_DRACONIAN) ||
- you.max_level >= 7))
+ you.max_level >= 7))
{
show_aptitudes = !show_aptitudes;
- goto reprint_stuff;
+ continue;
}
+
if ((get_thing >= 'a' && get_thing <= 'z')
|| (get_thing >= 'A' && get_thing <= 'Z'))
{
- lcount = 'a'; // toggle skill practise
+ menu_letter lcount = 'a'; // toggle skill practise
- for (i = 0; i < ndisplayed_skills; i++)
+ int x;
+ for (int i = 0; i < ndisplayed_skills; i++)
{
x = skill_display_order[i];
if (x == SK_BLANK_LINE || x == SK_COLUMN_BREAK)
continue;
-
+
if (you.skills[x] == 0)
continue;
-
+
if (get_thing == lcount)
{
you.practise_skill[x] = !you.practise_skill[x];
break;
}
-
+
++lcount;
}
-
- goto reprint_stuff;
+ continue;
}
+ break;
}
-
- return;
}
-
const char *skill_name(int which_skill)
{
return (skills[which_skill][0]);
diff --git a/crawl-ref/source/spl-book.cc b/crawl-ref/source/spl-book.cc
index 02bb77e9af..bc3eee8912 100644
--- a/crawl-ref/source/spl-book.cc
+++ b/crawl-ref/source/spl-book.cc
@@ -25,7 +25,7 @@
#endif
#include "externs.h"
-
+#include "cio.h"
#include "debug.h"
#include "delay.h"
#include "food.h"
@@ -685,8 +685,8 @@ spell_type which_spell_in_book(int sbook_type, int spl)
// If fs is not NULL, updates will be to the formatted_string instead of
// the display.
-unsigned char spellbook_contents( item_def &book, int action,
- formatted_string *fs )
+int spellbook_contents( item_def &book, int action,
+ formatted_string *fs )
{
int spelcount = 0;
int i, j;
@@ -827,7 +827,7 @@ unsigned char spellbook_contents( item_def &book, int action,
if (fs)
*fs = out;
- unsigned char keyn = 0;
+ int keyn = 0;
if (update_screen)
{
cursor_control coff(false);
@@ -835,9 +835,7 @@ unsigned char spellbook_contents( item_def &book, int action,
out.display();
- keyn = getch();
- if (keyn == 0)
- getch();
+ keyn = c_getch();
}
return (keyn); // try to figure out that for which this is used {dlb}
diff --git a/crawl-ref/source/spl-book.h b/crawl-ref/source/spl-book.h
index d06172cc8f..a118b0b370 100644
--- a/crawl-ref/source/spl-book.h
+++ b/crawl-ref/source/spl-book.h
@@ -48,8 +48,8 @@ int staff_spell( int zap_device_2 );
bool undead_cannot_memorise(spell_type spell, char being);
-unsigned char spellbook_contents( item_def &book, int action,
- formatted_string *fs = NULL );
+int spellbook_contents( item_def &book, int action,
+ formatted_string *fs = NULL );
int count_staff_spells(const item_def &item, bool need_id);
int rod_shield_leakage();
diff --git a/crawl-ref/source/stash.cc b/crawl-ref/source/stash.cc
index a1ed94ed47..7c58b55cde 100644
--- a/crawl-ref/source/stash.cc
+++ b/crawl-ref/source/stash.cc
@@ -8,6 +8,7 @@
#include "AppHdr.h"
#include "chardump.h"
+#include "cio.h"
#include "clua.h"
#include "describe.h"
#include "direct.h"
diff --git a/crawl-ref/source/travel.cc b/crawl-ref/source/travel.cc
index 20f6d49160..1db49cdff9 100644
--- a/crawl-ref/source/travel.cc
+++ b/crawl-ref/source/travel.cc
@@ -14,6 +14,7 @@
#include "FixAry.h"
#include "branch.h"
#include "command.h"
+#include "cio.h"
#include "clua.h"
#include "delay.h"
#include "describe.h"
@@ -2552,6 +2553,15 @@ void start_travel(int x, int y)
void start_explore(bool grab_items)
{
+ if (Options.tut_explored)
+ Options.tut_explored = 0;
+
+ if (you.level_type == LEVEL_LABYRINTH || you.level_type == LEVEL_ABYSS)
+ {
+ mpr("It would help if you knew where you were, first.");
+ return;
+ }
+
if (!i_feel_safe(true))
return;
diff --git a/crawl-ref/source/tutorial.cc b/crawl-ref/source/tutorial.cc
index 390c7e56c0..522511002a 100644
--- a/crawl-ref/source/tutorial.cc
+++ b/crawl-ref/source/tutorial.cc
@@ -6,7 +6,7 @@
#include <sstream>
#include "tutorial.h"
-
+#include "cio.h"
#include "command.h"
#include "files.h"
#include "initfile.h"
diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc
index fe384a5809..a3fb63f251 100644
--- a/crawl-ref/source/view.cc
+++ b/crawl-ref/source/view.cc
@@ -37,6 +37,7 @@
#include "externs.h"
#include "command.h"
+#include "cio.h"
#include "cloud.h"
#include "clua.h"
#include "debug.h"
@@ -2518,7 +2519,7 @@ void show_map( FixedVector<int, 2> &spec_place, bool travel_mode )
char move_x = 0;
char move_y = 0;
- char getty = 0;
+ int getty = 0;
// Vector to track all features we can travel to, in order of distance.
std::vector<coord_def> features;
@@ -2605,8 +2606,10 @@ void show_map( FixedVector<int, 2> &spec_place, bool travel_mode )
redraw_map = true;
cursorxy(curs_x, curs_y + top - 1);
+ c_input_reset(true);
getty = unmangle_direction_keys(getchm(KC_LEVELMAP), KC_LEVELMAP,
false, false);
+ c_input_reset(false);
switch (getty)
{
@@ -2641,7 +2644,7 @@ void show_map( FixedVector<int, 2> &spec_place, bool travel_mode )
move_x = move_y = 0;
break;
}
-
+
case CONTROL('E'):
case CONTROL('X'):
{
@@ -2805,6 +2808,46 @@ void show_map( FixedVector<int, 2> &spec_place, bool travel_mode )
search_found, &move_x, &move_y);
break;
}
+
+ case CK_MOUSE_MOVE:
+ move_x = move_y = 0;
+ break;
+
+ case CK_MOUSE_CLICK:
+ {
+ const c_mouse_event cme = get_mouse_event();
+ const coord_def curp(start_x + curs_x - 1, start_y + curs_y - 1);
+ const coord_def grdp =
+ cme.pos + coord_def(start_x - 1, start_y - top);
+
+ if (cme.left_clicked() && in_bounds(grdp))
+ {
+ spec_place[0] = grdp.x;
+ spec_place[1] = grdp.y;
+ map_alive = false;
+ }
+ else if (cme.scroll_up())
+ {
+ move_y = -block_step * ((curs_y - top + 1) / block_step + 1);
+ move_x = 0;
+ }
+ else if (cme.scroll_down())
+ {
+ move_y =
+ block_step *
+ ((get_number_of_lines() - curs_y + top - 1) / block_step
+ + 1);
+ move_x = 0;
+ }
+ else if (cme.right_clicked())
+ {
+ const coord_def delta = grdp - curp;
+ move_y = delta.y;
+ move_x = delta.x;
+ }
+ break;
+ }
+
case '.':
case '\r':
case 'S':