summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/initfile.cc
diff options
context:
space:
mode:
Diffstat (limited to 'crawl-ref/source/initfile.cc')
-rw-r--r--crawl-ref/source/initfile.cc76
1 files changed, 75 insertions, 1 deletions
diff --git a/crawl-ref/source/initfile.cc b/crawl-ref/source/initfile.cc
index 5d8ae48751..98db34eaeb 100644
--- a/crawl-ref/source/initfile.cc
+++ b/crawl-ref/source/initfile.cc
@@ -36,6 +36,7 @@
#include "item_use.h"
#include "itemprop.h"
#include "libutil.h"
+#include "macro.h"
#include "message.h"
#include "mon-util.h"
#include "newgame.h"
@@ -1704,6 +1705,74 @@ void game_options::set_option_fragment(const std::string &s)
}
}
+// Not a method of the game_options class since keybindings aren't
+// stored in that class.
+static void _bindkey(std::string field)
+{
+ const size_t start_bracket = field.find_first_of('[');
+ const size_t end_bracket = field.find_last_of(']');
+
+ if (start_bracket == std::string::npos
+ || end_bracket == std::string::npos
+ || start_bracket > end_bracket)
+ {
+ mprf(MSGCH_ERROR, "Bad bindkey bracketing in '%s'",
+ field.c_str());
+ return;
+ }
+
+ const std::string key_str = field.substr(start_bracket + 1,
+ end_bracket - start_bracket - 1);
+
+ int key;
+
+ // TODO: Function keys.
+ if (key_str.length() == 0)
+ {
+ mprf(MSGCH_ERROR, "No key in bindkey directive '%s'",
+ field.c_str());
+ return;
+ }
+ else if (key_str.length() == 1)
+ {
+ key = key_str[0];
+ }
+ else if (key_str.length() == 2)
+ {
+ if(key_str[0] != '^')
+ {
+ mprf(MSGCH_ERROR, "Invalid key '%s' in bindkey directive '%s'",
+ key_str.c_str(), field.c_str());
+ return;
+ }
+ key = CONTROL(key_str[1]);
+ }
+ else
+ {
+ mprf(MSGCH_ERROR, "Invalid key '%s' in bindkey directive '%s'",
+ key_str.c_str(), field.c_str());
+ return;
+ }
+
+ const size_t start_name = field.find_first_not_of(' ', end_bracket + 1);
+ if (start_name == std::string::npos)
+ {
+ mprf(MSGCH_ERROR, "No command name for bindkey directive '%s'",
+ field.c_str());
+ return;
+ }
+
+ const std::string name = field.substr(start_name);
+ const command_type cmd = name_to_command(name);
+ if (cmd == CMD_NO_CMD)
+ {
+ mprf(MSGCH_ERROR, "No command named '%s'", name.c_str());
+ return;
+ }
+
+ bind_command_to_key(cmd, key);
+}
+
void game_options::read_option_line(const std::string &str, bool runscript)
{
#define BOOL_OPTION_NAMED(_opt_str, _opt_var) \
@@ -1830,7 +1899,7 @@ void game_options::read_option_line(const std::string &str, bool runscript)
&& key != "menu_colour" && key != "menu_color"
&& key != "message_colour" && key != "message_color"
&& key != "levels" && key != "level" && key != "entries"
- && key != "include")
+ && key != "include" && key != "bindkey")
{
lowercase( field );
}
@@ -2881,6 +2950,11 @@ void game_options::read_option_line(const std::string &str, bool runscript)
else BOOL_OPTION(use_dos_char);
#endif
+ else if(key == "bindkey")
+ {
+ _bindkey(field);
+ }
+
// Catch-all else, copies option into map
else if (runscript)
{