-
Notifications
You must be signed in to change notification settings - Fork 30
/
keybind.cpp
268 lines (247 loc) · 8.82 KB
/
keybind.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
#include "keybind.h"
#include "stringfunc.h"
#include "window.h" // For debugmsg() and key_name()
#include "globals.h"
#include <fstream>
#include <vector>
#include <sstream>
bool Keybinding_pool::bind_key(long key, Interface_action action)
{
bindings[key] = action;
if (reverse_bindings.count(action) == 0) {
reverse_bindings[action] = std::vector<long>();
}
reverse_bindings[action].push_back(key);
return true;
}
Interface_action Keybinding_pool::bound_to_key(long key)
{
if (bindings.count(key) == 0) {
return IACTION_NULL;
}
return bindings[key];
}
std::vector<long> Keybinding_pool::keys_bound_to(Interface_action action)
{
if (reverse_bindings.count(action) == 0) {
return std::vector<long>();
}
return reverse_bindings[action];
}
std::string Keybinding_pool::describe_bindings_for(Interface_action action)
{
std::vector<long> bindings = keys_bound_to(action);
if (bindings.empty()) {
return "nothing assigned";
}
std::stringstream ret;
for (int i = 0; i < bindings.size(); i++) {
ret << key_name(bindings[i]);
if (i + 2 < bindings.size()) {
ret << ", ";
} else if (i + 1 < bindings.size()) {
ret << " or ";
}
}
return ret.str();
}
bool Keybinding_pool::bind_debug_key(long key, Debug_action action)
{
debug_bindings[key] = action;
return true;
}
Debug_action Keybinding_pool::bound_to_debug_key(long key)
{
if (debug_bindings.count(key) == 0) {
return DEBUG_ACTION_NULL;
}
return debug_bindings[key];
}
bool Keybinding_pool::load_from(std::string filename)
{
std::ifstream fin;
fin.open(filename.c_str());
if (!fin.is_open()) {
debugmsg("Failed to open '%s'", filename.c_str());
return false;
}
std::string keystr;
std::vector<long> keys;
while (!fin.eof() && fin >> keystr) {
if (lookup_key(keystr) != 0) {
keys.push_back( lookup_key(keystr) );
} else if (keystr == "=") {
std::string action_name;
std::getline(fin, action_name);
action_name = trim(action_name);
Interface_action act = lookup_interface_action(action_name);
if (act == IACTION_NULL) {
Debug_action debug_act = lookup_debug_action(action_name);
if (debug_act == DEBUG_ACTION_NULL) {
debugmsg("Unknown action in '%s': '%s'", filename.c_str(),
action_name.c_str());
} else {
for (int i = 0; i < keys.size(); i++) {
Debug_action already_bound = bound_to_debug_key( keys[i] );
if (already_bound != DEBUG_ACTION_NULL) {
debugmsg("Key %c bound to %s; reassigned to %s. (%s)", keys[i],
debug_action_name(already_bound).c_str(),
debug_action_name(debug_act).c_str(),
filename.c_str());
}
bind_debug_key( keys[i], debug_act );
}
}
} else { // if (act == IACTION_NULL)
for (int i = 0; i < keys.size(); i++) {
Interface_action already_bound = bound_to_key( keys[i] );
if (already_bound != IACTION_NULL) {
debugmsg("Key %c bound to %s; reassigned to %s. (%s)", keys[i],
interface_action_name(already_bound).c_str(),
interface_action_name(act).c_str(),
filename.c_str());
}
bind_key( keys[i], act );
}
}
keys.clear();
} else {
for (int i = 0; i < keystr.size(); i++) {
keys.push_back( keystr[i] );
}
}
}
return true;
}
Interface_action lookup_interface_action(std::string name)
{
name = no_caps(name);
name = trim(name);
for (int i = 0; i < IACTION_MAX; i++) {
Interface_action ret = Interface_action(i);
if ( no_caps( interface_action_name(ret) ) == name ) {
return ret;
}
}
return IACTION_NULL;
}
std::string interface_action_name(Interface_action action)
{
switch (action) {
case IACTION_NULL: return "NULL";
case IACTION_SELECT: return "select";
case IACTION_MOVE_N: return "move_north";
case IACTION_MOVE_NE: return "move_northeast";
case IACTION_MOVE_E: return "move_east";
case IACTION_MOVE_SE: return "move_southeast";
case IACTION_MOVE_S: return "move_south";
case IACTION_MOVE_SW: return "move_southwest";
case IACTION_MOVE_W: return "move_west";
case IACTION_MOVE_NW: return "move_northwest";
case IACTION_PAUSE: return "pause";
case IACTION_MOVE_UP: return "move_up";
case IACTION_MOVE_DOWN: return "move_down";
case IACTION_PICK_UP: return "pick_up";
case IACTION_OPEN: return "open";
case IACTION_CLOSE: return "close";
case IACTION_SMASH: return "smash";
case IACTION_EXAMINE: return "examine";
case IACTION_LOOK: return "look";
case IACTION_GRAB: return "grab";
case IACTION_INVENTORY: return "inventory";
case IACTION_DROP: return "drop";
case IACTION_WIELD: return "wield";
case IACTION_WEAR: return "wear";
case IACTION_TAKE_OFF: return "take_off";
case IACTION_APPLY: return "apply";
case IACTION_READ: return "read";
case IACTION_RELOAD_EQUIPPED: return "reload_equipped";
case IACTION_RELOAD: return "reload";
case IACTION_THROW: return "throw";
case IACTION_FIRE: return "fire";
case IACTION_ADVANCE_FIRE_MODE: return "advance_fire_mode";
case IACTION_EAT: return "eat";
case IACTION_MESSAGES_SCROLL_BACK: return "messages_scroll_back";
case IACTION_MESSAGES_SCROLL_FORWARD: return "messages_scroll_forward";
case IACTION_VIEW_WORLDMAP: return "view_worldmap";
case IACTION_CHAR_STATUS: return "status";
case IACTION_CHAR_SKILLS: return "skills";
case IACTION_QUIT: return "quit";
case IACTION_SAVE: return "save";
case IACTION_DEBUG: return "debug";
case IACTION_MAX: return "BUG - IACTION_MAX";
default: return "BUG - Unnamed action";
}
return "BUG - Escaped interface_action_name() switch";
}
Debug_action lookup_debug_action(std::string name)
{
name = no_caps(name);
name = trim(name);
for (int i = 0; i < IACTION_MAX; i++) {
Debug_action ret = Debug_action(i);
if ( no_caps( debug_action_name(ret) ) == name ) {
return ret;
}
}
return DEBUG_ACTION_NULL;
}
std::string debug_action_name(Debug_action action)
{
switch (action) {
case DEBUG_ACTION_NULL: return "NULL";
case DEBUG_ACTION_CREATE_ITEM: return "create_item";
case DEBUG_ACTION_BUILD_MAP: return "build_map";
case DEBUG_ACTION_MAP_INFO: return "map_info";
case DEBUG_ACTION_PLACE_FIELD: return "place_field";
case DEBUG_ACTION_CLEAR_ITEMS: return "clear_items";
case DEBUG_ACTION_SPAWN_MONSTER: return "spawn_monster";
case DEBUG_ACTION_MONSTER_PATH: return "monster_path";
case DEBUG_ACTION_MEMORY_INFO: return "memory_info";
case DEBUG_ACTION_PLACE_BONUS: return "place_bonus";
case DEBUG_ACTION_GAIN_XP: return "gain_xp";
case DEBUG_ACTION_MAX: return "BUG - DEBUG_ACTION_MAX";
default: return "BUG - Unnamed Debug_action";
}
return "BUG - Escaped debug_action_name() switch";
}
long lookup_key(std::string name)
{
if (name == "UP") {
return KEY_UP;
} else if (name == "DOWN") {
return KEY_DOWN;
} else if (name == "LEFT") {
return KEY_LEFT;
} else if (name == "RIGHT") {
return KEY_RIGHT;
} else if (name == "ESC") {
return KEY_ESC;
} else if (name == "ENTER") {
return '\n';
} else if (name == "HOME") {
return KEY_HOME;
} else if (name == "END") {
return KEY_END;
} else if (name == "BACKSPACE" || name == "BKSP") {
return KEY_BACKSPACE;
} else {
return 0;
}
}
Point input_direction(long ch)
{
switch (KEYBINDINGS.bound_to_key(ch)) {
case IACTION_MOVE_N: return Point( 0, -1);
case IACTION_MOVE_NE: return Point( 1, -1);
case IACTION_MOVE_E: return Point( 1, 0);
case IACTION_MOVE_SE: return Point( 1, 1);
case IACTION_MOVE_S: return Point( 0, 1);
case IACTION_MOVE_SW: return Point(-1, 1);
case IACTION_MOVE_W: return Point(-1, 0);
case IACTION_MOVE_NW: return Point(-1, -1);
case IACTION_PAUSE: return Point( 0, 0);
default: return Point(-2, -2); // Be sure to check for this!
}
return Point(-2, -2);
}