summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crawl-ref/source/acr.cc62
-rw-r--r--crawl-ref/source/direct.cc573
-rw-r--r--crawl-ref/source/externs.h2
-rw-r--r--crawl-ref/source/libutil.cc63
-rw-r--r--crawl-ref/source/libutil.h5
-rw-r--r--crawl-ref/source/macro.h2
-rw-r--r--crawl-ref/source/spells1.cc6
-rw-r--r--crawl-ref/source/view.cc20
8 files changed, 356 insertions, 377 deletions
diff --git a/crawl-ref/source/acr.cc b/crawl-ref/source/acr.cc
index d3f491f4a8..8b88aaf21a 100644
--- a/crawl-ref/source/acr.cc
+++ b/crawl-ref/source/acr.cc
@@ -166,7 +166,6 @@ static void input();
static void middle_input();
static void world_reacts();
static command_type get_next_cmd();
-typedef int keycode_type;
static keycode_type get_next_keycode();
static command_type keycode_to_command( keycode_type key );
@@ -2451,72 +2450,15 @@ command_type keycode_to_command( keycode_type key ) {
}
}
-#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
-
keycode_type get_next_keycode()
{
-
keycode_type keyin;
flush_input_buffer( FLUSH_BEFORE_COMMAND );
- keyin = getch_with_command_macros();
-
-#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 (keyin == '*')
- {
- keyin = getch();
- // return control-key
- keyin = CONTROL(toupper(numpad2vi(keyin)));
- }
- else if (keyin == '/')
- {
- keyin = getch();
- // 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 = getch();
- 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
+ keyin = unmangle_direction_keys(getch_with_command_macros());
mesclr();
- return keyin;
+ return (keyin);
}
static void middle_input() {
diff --git a/crawl-ref/source/direct.cc b/crawl-ref/source/direct.cc
index d7a64cf136..706bee5edb 100644
--- a/crawl-ref/source/direct.cc
+++ b/crawl-ref/source/direct.cc
@@ -78,8 +78,6 @@ static const char ycomp[9] = { 1, 1, 1, 0, 0, 0, -1, -1, -1 };
// [dshaligram] Removed . and 5 from dirchars so it's easier to
// special case them.
static const char dirchars[19] = { "b1j2n3h4bbl6y7k8u9" };
-static const char DOSidiocy[10] = { "OPQKSMGHI" };
-static const char DOSunidiocy[10] = { "bjnh.lyku" };
static const char *aim_prompt = "Aim (move cursor or -/+/=, change mode with CTRL-F, select with . or >)";
static void describe_feature(int mx, int my, bool oos);
@@ -100,10 +98,9 @@ static bool is_mapped(int x, int y)
return (is_player_mapped(x, y));
}
-int dos_direction_unmunge(int doskey)
+static int read_direction_key()
{
- const char *pos = strchr(DOSidiocy, doskey);
- return (pos? DOSunidiocy[ pos - DOSidiocy ] : doskey);
+ return unmangle_direction_keys(getchm(KC_TARGETING), KC_TARGETING);
}
//---------------------------------------------------------------
@@ -139,8 +136,8 @@ int dos_direction_unmunge(int doskey)
void direction2( struct dist &moves, int restrict, int mode )
{
- bool dirChosen = false;
- bool targChosen = false;
+ bool dir_chosen = false;
+ bool targ_chosen = false;
int dir = 0;
// init
@@ -155,114 +152,100 @@ void direction2( struct dist &moves, int restrict, int mode )
// nonetheless! --GDL
gotoxy( VIEW_CX + 1, VIEW_CY );
- int keyin = getchm(KC_TARGETING);
+ int keyin = read_direction_key();
- if (keyin == 0) // DOS idiocy (emulated by win32 console)
+ if (keyin == 0)
+ return;
+
+ if (strchr( dirchars, keyin ) != NULL)
{
- keyin = getchm(KC_TARGETING); // grrr.
- if (keyin == '*')
- {
- targChosen = true;
- dir = 0;
- }
- else
- {
- if (strchr(DOSidiocy, keyin) == NULL)
- return;
- dirChosen = true;
- dir = (int)(strchr(DOSidiocy, keyin) - DOSidiocy);
- }
+ dir_chosen = true;
+ dir = (int)(strchr(dirchars, keyin) - dirchars) / 2;
+ }
+ else if (strchr( dirchars, tolower(keyin) ) != NULL)
+ {
+ dir_chosen = true;
+ dir = (int)(strchr(dirchars, keyin) - dirchars) / 2;
}
else
{
- if (strchr( dirchars, keyin ) != NULL)
- {
- dirChosen = true;
- dir = (int)(strchr(dirchars, keyin) - dirchars) / 2;
- }
- else
+ switch (keyin)
{
- switch (keyin)
- {
- case CONTROL('F'):
- mode = (mode + 1) % TARG_NUM_MODES;
-
- snprintf( info, INFO_SIZE, "Targeting mode is now: %s",
- (mode == TARG_ANY) ? "any" :
- (mode == TARG_ENEMY) ? "enemies"
- : "friends" );
-
- mpr( info );
-
- targChosen = true;
- dir = 0;
- break;
-
- case '-':
- targChosen = true;
- dir = -1;
- break;
-
- case '*':
- targChosen = true;
- dir = 0;
- break;
-
- case ';':
- targChosen = true;
- dir = -3;
- break;
+ case CONTROL('F'):
+ mode = (mode + 1) % TARG_NUM_MODES;
+ snprintf( info, INFO_SIZE, "Targeting mode is now: %s",
+ (mode == TARG_ANY) ? "any" :
+ (mode == TARG_ENEMY) ? "enemies"
+ : "friends" );
+ mpr( info );
+ targ_chosen = true;
+ dir = 0;
+ break;
+
+ case '-':
+ targ_chosen = true;
+ dir = -1;
+ break;
+
+ case '*':
+ targ_chosen = true;
+ dir = 0;
+ break;
+
+ case ';':
+ targ_chosen = true;
+ dir = -3;
+ break;
- case '\'':
- targChosen = true;
- dir = -2;
- break;
+ case '\'':
+ targ_chosen = true;
+ dir = -2;
+ break;
- case '+':
- case '=':
- targChosen = true;
- dir = 1;
- break;
+ case '+':
+ case '=':
+ targ_chosen = true;
+ dir = 1;
+ break;
- case 't':
- case 'p':
- case 'f':
- targChosen = true;
- dir = 2;
- break;
+ case 't':
+ case 'p':
+ case 'f':
+ targ_chosen = true;
+ dir = 2;
+ break;
- case '.':
- case '5':
- dirChosen = true;
- dir = 4;
- break;
+ case '.':
+ case '5':
+ dir_chosen = true;
+ dir = 4;
+ break;
- case ESCAPE:
- moves.isCancel = true;
- return;
+ case ESCAPE:
+ moves.isCancel = true;
+ return;
- default:
- break;
- }
+ default:
+ break;
}
}
// at this point, we know exactly the input - validate
- if (!(targChosen || dirChosen) || (targChosen && restrict == DIR_DIR))
+ if (!(targ_chosen || dir_chosen) || (targ_chosen && restrict == DIR_DIR))
{
mpr("What an unusual direction.");
return;
}
// special case: they typed a dir key, but they're in target-only mode
- if (dirChosen && restrict == DIR_TARGET)
+ if (dir_chosen && restrict == DIR_TARGET)
{
mpr(aim_prompt);
- look_around( moves, false, dir, mode );
+ look_around( moves, false, keyin, mode );
return;
}
- if (targChosen)
+ if (targ_chosen)
{
if (dir < 2)
{
@@ -401,8 +384,9 @@ static void describe_oos_square(int x, int y)
void look_around(struct dist &moves, bool justLooking, int first_move, int mode)
{
int keyin = 0;
- bool dirChosen = false;
- bool targChosen = false;
+ bool dir_chosen = false;
+ bool targ_chosen = false;
+ bool shifted_direction = true;
int dir = 0;
int cx = VIEW_CX;
int cy = VIEW_CY;
@@ -419,7 +403,7 @@ void look_around(struct dist &moves, bool justLooking, int first_move, int mode)
// setup initial keystroke
if (first_move >= 0)
- keyin = (int)'1' + first_move;
+ keyin = first_move;
if (moves.prev_target == -1)
keyin = '-';
if (moves.prev_target == 1)
@@ -434,8 +418,9 @@ void look_around(struct dist &moves, bool justLooking, int first_move, int mode)
// loop until some exit criteria reached
while(true)
{
- dirChosen = false;
- targChosen = false;
+ dir_chosen = false;
+ targ_chosen = false;
+ shifted_direction = false;
newcx = cx;
newcy = cy;
@@ -443,7 +428,7 @@ void look_around(struct dist &moves, bool justLooking, int first_move, int mode)
gotoxy(cx+1, cy);
if (keyin == 0)
- keyin = getchm(KC_TARGETING);
+ keyin = unmangle_direction_keys(getchm(KC_TARGETING), KC_TARGETING);
// [dshaligram] Classic Crawl behaviour was to use space to select
// targets when targeting. The patch changed the meaning of space
@@ -458,237 +443,225 @@ void look_around(struct dist &moves, bool justLooking, int first_move, int mode)
if (!justLooking && keyin == '>')
keyin = 'X';
- // DOS idiocy
- if (keyin == 0)
+ if (strchr(dirchars, keyin) != NULL)
{
- // get the extended key
- keyin = getchm(KC_TARGETING);
-
- // look for CR - change to '5' to indicate selection
- if (keyin == 13)
- keyin = 'S';
-
- if (strchr(DOSidiocy, keyin) == NULL)
- break;
- dirChosen = true;
- dir = (int)(strchr(DOSidiocy, keyin) - DOSidiocy);
+ dir_chosen = true;
+ dir = (int)(strchr(dirchars, keyin) - dirchars) / 2;
+ }
+ else if (strchr(dirchars, tolower(keyin)) != NULL)
+ {
+ dir_chosen = true;
+ dir = (int)(strchr(dirchars, tolower(keyin)) - dirchars) / 2;
+ shifted_direction = true;
}
else
{
- if (strchr(dirchars, keyin) != NULL)
- {
- dirChosen = true;
- dir = (int)(strchr(dirchars, keyin) - dirchars) / 2;
- }
- else
+ // handle non-directional keys
+ switch (keyin)
{
- // handle non-directional keys
- switch (keyin)
- {
#ifdef WIZARD
- case 'C':
- targChosen = true;
- mx = you.x_pos + cx - VIEW_CX;
- my = you.y_pos + cy - VIEW_CY;
- if (!in_bounds(mx, my))
- break;
- if (mgrd[mx][my] != NON_MONSTER)
- {
- mprf("%s won't like that.",
- ptr_monam(&menv[mgrd[mx][my]], DESC_CAP_THE));
- break;
- }
- create_spec_monster_name(mx, my);
- viewwindow(true, false);
- break;
+ case 'C':
+ targ_chosen = true;
+ mx = you.x_pos + cx - VIEW_CX;
+ my = you.y_pos + cy - VIEW_CY;
+ if (!in_bounds(mx, my))
+ break;
+ if (mgrd[mx][my] != NON_MONSTER)
+ {
+ mprf("%s won't like that.",
+ ptr_monam(&menv[mgrd[mx][my]], DESC_CAP_THE));
+ break;
+ }
+ create_spec_monster_name(mx, my);
+ viewwindow(true, false);
+ break;
- case 'D':
- targChosen = true;
- mx = you.x_pos + cx - VIEW_CX;
- my = you.y_pos + cy - VIEW_CY;
- if (!in_bounds(mx, my))
- break;
- mid = mgrd[mx][my];
-
- if (mid == NON_MONSTER)
- break;
- monster_die(&menv[mid], KILL_RESET, 0);
- viewwindow(true, false);
- break;
+ case 'D':
+ targ_chosen = true;
+ mx = you.x_pos + cx - VIEW_CX;
+ my = you.y_pos + cy - VIEW_CY;
+ if (!in_bounds(mx, my))
+ break;
+ mid = mgrd[mx][my];
+
+ if (mid == NON_MONSTER)
+ break;
+ monster_die(&menv[mid], KILL_RESET, 0);
+ viewwindow(true, false);
+ break;
- case 'F':
- targChosen = true;
- mx = you.x_pos + cx - VIEW_CX;
- my = you.y_pos + cy - VIEW_CY;
- if (!in_bounds(mx, my))
- break;
- mid = mgrd[mx][my];
-
- if (mid == NON_MONSTER)
- break;
-
- mprf("Changing attitude of %s\n",
- ptr_monam(&menv[mid], DESC_PLAIN));
- menv[mid].attitude =
- menv[mid].attitude == ATT_HOSTILE?
- ATT_FRIENDLY
- : ATT_HOSTILE;
-
- describe_monsters( menv[ mid ].type, mid );
- redraw_screen();
- mesclr( true );
- // describe the cell again.
- describe_cell(view2gridX(cx), view2gridY(cy));
- break;
+ case 'F':
+ targ_chosen = true;
+ mx = you.x_pos + cx - VIEW_CX;
+ my = you.y_pos + cy - VIEW_CY;
+ if (!in_bounds(mx, my))
+ break;
+ mid = mgrd[mx][my];
+
+ if (mid == NON_MONSTER)
+ break;
+
+ mprf("Changing attitude of %s\n",
+ ptr_monam(&menv[mid], DESC_PLAIN));
+ menv[mid].attitude =
+ menv[mid].attitude == ATT_HOSTILE?
+ ATT_FRIENDLY
+ : ATT_HOSTILE;
+
+ describe_monsters( menv[ mid ].type, mid );
+ redraw_screen();
+ mesclr( true );
+ // describe the cell again.
+ describe_cell(view2gridX(cx), view2gridY(cy));
+ break;
#endif
- case CONTROL('F'):
- mode = (mode + 1) % TARG_NUM_MODES;
+ case CONTROL('F'):
+ mode = (mode + 1) % TARG_NUM_MODES;
- snprintf( info, INFO_SIZE, "Targeting mode is now: %s",
- (mode == TARG_ANY) ? "any" :
- (mode == TARG_ENEMY) ? "enemies"
- : "friends" );
-
- mpr( info );
- targChosen = true;
- break;
-
- case '^':
- case '\t':
- case '\\':
- case '_':
- case '<':
- case '>':
- {
- if (find_square( cx, cy, objfind_pos, 1,
- find_feature, keyin, true,
- Options.target_los_first
- ? LOS_FLIPVH : LOS_ANY))
- {
- newcx = objfind_pos[0];
- newcy = objfind_pos[1];
- }
- else
- flush_input_buffer( FLUSH_ON_FAILURE );
- targChosen = true;
- break;
- }
- case ';':
- case '/':
- case '\'':
- case '*':
- {
- dir = keyin == ';' || keyin == '/'? -1 : 1;
- if (find_square( cx, cy, objfind_pos, dir,
- find_object, 0, true,
- Options.target_los_first
- ? (dir == 1? LOS_FLIPVH : LOS_FLIPHV)
- : LOS_ANY))
+ snprintf( info, INFO_SIZE, "Targeting mode is now: %s",
+ (mode == TARG_ANY) ? "any" :
+ (mode == TARG_ENEMY) ? "enemies"
+ : "friends" );
- {
- newcx = objfind_pos[0];
- newcy = objfind_pos[1];
- }
- else
- flush_input_buffer( FLUSH_ON_FAILURE );
- targChosen = true;
- break;
- }
+ mpr( info );
+ targ_chosen = true;
+ break;
- case '-':
- case '+':
- case '=':
- {
- dir = keyin == '-'? -1 : 1;
- if (find_square( cx, cy, monsfind_pos, dir,
- find_monster, mode, Options.target_wrap ))
- {
- newcx = monsfind_pos[0];
- newcy = monsfind_pos[1];
- }
- else
- flush_input_buffer( FLUSH_ON_FAILURE );
- targChosen = true;
- break;
- }
+ case '^':
+ case '\t':
+ case '\\':
+ case '_':
+ case '<':
+ case '>':
+ {
+ if (find_square( cx, cy, objfind_pos, 1,
+ find_feature, keyin, true,
+ Options.target_los_first
+ ? LOS_FLIPVH : LOS_ANY))
+ {
+ newcx = objfind_pos[0];
+ newcy = objfind_pos[1];
+ }
+ else
+ flush_input_buffer( FLUSH_ON_FAILURE );
+ targ_chosen = true;
+ break;
+ }
+ case ';':
+ case '/':
+ case '\'':
+ case '*':
+ {
+ dir = keyin == ';' || keyin == '/'? -1 : 1;
+ if (find_square( cx, cy, objfind_pos, dir,
+ find_object, 0, true,
+ Options.target_los_first
+ ? (dir == 1? LOS_FLIPVH : LOS_FLIPHV)
+ : LOS_ANY))
- case 't':
- case 'p':
- moves.prev_target = -1;
- break;
+ {
+ newcx = objfind_pos[0];
+ newcy = objfind_pos[1];
+ }
+ else
+ flush_input_buffer( FLUSH_ON_FAILURE );
+ targ_chosen = true;
+ break;
+ }
+
+ case '-':
+ case '+':
+ case '=':
+ {
+ dir = keyin == '-'? -1 : 1;
+ if (find_square( cx, cy, monsfind_pos, dir,
+ find_monster, mode, Options.target_wrap ))
+ {
+ newcx = monsfind_pos[0];
+ newcy = monsfind_pos[1];
+ }
+ else
+ flush_input_buffer( FLUSH_ON_FAILURE );
+ targ_chosen = true;
+ break;
+ }
+
+ case 't':
+ case 'p':
+ moves.prev_target = -1;
+ break;
- case '?':
- targChosen = true;
- mx = you.x_pos + cx - VIEW_CX;
- my = you.y_pos + cy - VIEW_CY;
- if (!in_bounds(mx, my))
- break;
- mid = mgrd[mx][my];
+ case '?':
+ targ_chosen = true;
+ mx = you.x_pos + cx - VIEW_CX;
+ my = you.y_pos + cy - VIEW_CY;
+ if (!in_bounds(mx, my))
+ break;
+ mid = mgrd[mx][my];
- if (mid == NON_MONSTER)
- break;
+ if (mid == NON_MONSTER)
+ break;
#if (!DEBUG_DIAGNOSTICS)
- if (!player_monster_visible( &menv[mid] ))
- break;
+ if (!player_monster_visible( &menv[mid] ))
+ break;
#endif
- describe_monsters( menv[ mid ].type, mid );
- redraw_screen();
- mesclr( true );
- // describe the cell again.
- describe_cell(view2gridX(cx), view2gridY(cy));
- break;
-
- case '\r':
- case '\n':
- case '.':
- case '5':
- case 'X':
- // If we're in look-around mode, and the cursor is on
- // the character and there's a valid travel target
- // within the viewport, jump to that target.
- if (justLooking && cx == VIEW_CX && cy == VIEW_CY)
- {
- if (you.travel_x > 0 && you.travel_y > 0)
- {
- int nx = grid2viewX(you.travel_x);
- int ny = grid2viewY(you.travel_y);
- if (in_viewport_bounds(nx, ny))
- {
- newcx = nx;
- newcy = ny;
- targChosen = true;
- }
- }
- }
- else
+ describe_monsters( menv[ mid ].type, mid );
+ redraw_screen();
+ mesclr( true );
+ // describe the cell again.
+ describe_cell(view2gridX(cx), view2gridY(cy));
+ break;
+
+ case '\r':
+ case '\n':
+ case '.':
+ case '5':
+ case 'X':
+ // If we're in look-around mode, and the cursor is on
+ // the character and there's a valid travel target
+ // within the viewport, jump to that target.
+ if (justLooking && cx == VIEW_CX && cy == VIEW_CY)
+ {
+ if (you.travel_x > 0 && you.travel_y > 0)
+ {
+ int nx = grid2viewX(you.travel_x);
+ int ny = grid2viewY(you.travel_y);
+ if (in_viewport_bounds(nx, ny))
{
- dirChosen = true;
- dir = keyin == 'X'? -1 : 4;
+ newcx = nx;
+ newcy = ny;
+ targ_chosen = true;
}
- break;
+ }
+ }
+ else
+ {
+ dir_chosen = true;
+ dir = keyin == 'X'? -1 : 4;
+ }
+ break;
- case ' ':
- case ESCAPE:
- moves.isCancel = true;
- mesclr( true );
- return;
+ case ' ':
+ case ESCAPE:
+ moves.isCancel = true;
+ mesclr( true );
+ return;
- default:
- break;
- }
+ default:
+ break;
}
}
// now we have parsed the input character completely. Reset & Evaluate:
keyin = 0;
- if (!targChosen && !dirChosen)
+ if (!targ_chosen && !dir_chosen)
break;
// check for SELECTION
- if (dirChosen && (dir == 4 || dir == -1))
+ if (dir_chosen && (dir == 4 || dir == -1))
{
// [dshaligram] We no longer vet the square coordinates if
// we're justLooking. By not vetting the coordinates, we make 'x'
@@ -698,7 +671,6 @@ void look_around(struct dist &moves, bool justLooking, int first_move, int mode)
// RULE: cannot target what you cannot see
if (!in_vlos(cx, cy))
{
- // if (!justLooking)
mpr("Sorry, you can't target what you can't see.");
return;
}
@@ -731,10 +703,17 @@ void look_around(struct dist &moves, bool justLooking, int first_move, int mode)
}
// check for MOVE
- if (dirChosen)
+ if (dir_chosen)
{
- newcx = cx + xcomp[dir];
- newcy = cy + ycomp[dir];
+ int xi = xcomp[dir], yi = ycomp[dir];
+ if (shifted_direction)
+ {
+ // TODO: Add .crawlrc option for cursor step
+ xi *= 3;
+ yi *= 3;
+ }
+ newcx = cx + xi;
+ newcy = cy + yi;
}
// bounds check for newcx, newcy
diff --git a/crawl-ref/source/externs.h b/crawl-ref/source/externs.h
index c8246cc3c0..bd467f20e2 100644
--- a/crawl-ref/source/externs.h
+++ b/crawl-ref/source/externs.h
@@ -1102,4 +1102,6 @@ private:
extern const struct coord_def Compass[8];
extern const char* god_gain_power_messages[MAX_NUM_GODS][MAX_GOD_ABILITIES];
+typedef int keycode_type;
+
#endif // EXTERNS_H
diff --git a/crawl-ref/source/libutil.cc b/crawl-ref/source/libutil.cc
index 181dd180bf..061113adc7 100644
--- a/crawl-ref/source/libutil.cc
+++ b/crawl-ref/source/libutil.cc
@@ -16,6 +16,7 @@
#include "initfile.h"
#include "libutil.h"
#include "externs.h"
+#include "macro.h"
#include <stdio.h>
#include <ctype.h>
#include <stdarg.h>
@@ -44,6 +45,68 @@
#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)
+{
+ 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 (keyin == '*')
+ {
+ keyin = getchm(keymap);
+ // return control-key
+ keyin = CONTROL(toupper(numpad2vi(keyin)));
+ }
+ else if (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
+
+ return (keyin);
+}
+
// Should return true if the filename contains nothing that
// the shell can do damage with.
bool shell_safe(const char *file)
diff --git a/crawl-ref/source/libutil.h b/crawl-ref/source/libutil.h
index 4323b9c1c1..084a7318d9 100644
--- a/crawl-ref/source/libutil.h
+++ b/crawl-ref/source/libutil.h
@@ -19,6 +19,11 @@
#include <string>
#include <vector>
+// 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);
+
void lowercase(std::string &s);
void uppercase(std::string &s);
diff --git a/crawl-ref/source/macro.h b/crawl-ref/source/macro.h
index f56edcf219..c3ea7516a8 100644
--- a/crawl-ref/source/macro.h
+++ b/crawl-ref/source/macro.h
@@ -24,7 +24,7 @@
#endif
enum KeymapContext {
- KC_DEFAULT, // For no-arg getchm().
+ KC_DEFAULT, // For no-arg getchm(), must be zero.
KC_LEVELMAP, // When in the 'X' level map
KC_TARGETING, // Only during 'x' and other targeting modes
diff --git a/crawl-ref/source/spells1.cc b/crawl-ref/source/spells1.cc
index 38373820a5..5885526f29 100644
--- a/crawl-ref/source/spells1.cc
+++ b/crawl-ref/source/spells1.cc
@@ -72,6 +72,12 @@ int blink(void)
if (!beam.isValid)
{
+ if (!yesno("Are you sure you want to cancel this blink?",
+ false, 'n'))
+ {
+ mesclr();
+ continue;
+ }
canned_msg(MSG_OK);
return (-1); // early return {dlb}
}
diff --git a/crawl-ref/source/view.cc b/crawl-ref/source/view.cc
index 83c88f5e8c..52d83285aa 100644
--- a/crawl-ref/source/view.cc
+++ b/crawl-ref/source/view.cc
@@ -2117,25 +2117,7 @@ void show_map( FixedVector<int, 2> &spec_place, bool travel_mode )
redraw_map = true;
gotoxy(curs_x, curs_y);
- getty = getchm(KC_LEVELMAP);
- if (getty == 0)
- {
- getty = getchm(KC_LEVELMAP);
- // [dshaligram] DOS madness.
- getty = dos_direction_unmunge(getty);
- }
-
-#if defined(WIN32CONSOLE) || defined(DOS)
- // Translate shifted numpad to shifted vi keys. Yes,
- // this is horribly hacky.
- {
- static int win_keypad[] = { 'B', 'J', 'N',
- 'H', '5', 'L',
- 'Y', 'K', 'U' };
- if (getty >= '1' && getty <= '9')
- getty = win_keypad[ getty - '1' ];
- }
-#endif
+ getty = unmangle_direction_keys(getchm(KC_LEVELMAP), KC_LEVELMAP);
switch (getty)
{