Implemented fix for arrow key handling on mac, which also introduces a frame buffer for arrow key combinations that would solve #225.
This commit is contained in:
@@ -1648,6 +1648,8 @@ bool handle_keystroke(const sf::Event& event, cFramerateLimiter& fps_limiter){
|
||||
Key::Numpad4,Key::Numpad5,Key::Numpad6,
|
||||
Key::Numpad7,Key::Numpad8,Key::Numpad9
|
||||
};
|
||||
// Terrain map coordinates to simulate a click for 8-directional movement/waiting
|
||||
// ordered to correspond with keypad keys
|
||||
location terrain_click[10] = {
|
||||
{150,185},{120,215},{150,215},{180,215},
|
||||
{120,185},{150,185},{180,185},
|
||||
@@ -1678,23 +1680,7 @@ bool handle_keystroke(const sf::Event& event, cFramerateLimiter& fps_limiter){
|
||||
if(chr2 == Key::LShift || chr2 == Key::LAlt || chr2 == Key::LControl || chr2 == Key::LSystem) return false;
|
||||
if(chr2 == Key::RShift || chr2 == Key::RAlt || chr2 == Key::RControl || chr2 == Key::RSystem) return false;
|
||||
|
||||
if(chr2 == Key::Up && !kb.isDownPressed()) {
|
||||
if(kb.isLeftPressed()) chr2 = Key::Numpad7;
|
||||
else if(kb.isRightPressed()) chr2 = Key::Numpad9;
|
||||
else chr2 = Key::Numpad8;
|
||||
} else if(chr2 == Key::Down && !kb.isUpPressed()) {
|
||||
if(kb.isLeftPressed()) chr2 = Key::Numpad1;
|
||||
else if(kb.isRightPressed()) chr2 = Key::Numpad3;
|
||||
else chr2 = Key::Numpad2;
|
||||
} else if(chr2 == Key::Left && !kb.isRightPressed()) {
|
||||
if(kb.isUpPressed()) chr2 = Key::Numpad7;
|
||||
else if(kb.isDownPressed()) chr2 = Key::Numpad1;
|
||||
else chr2 = Key::Numpad4;
|
||||
} else if(chr2 == Key::Right && !kb.isLeftPressed()) {
|
||||
if(kb.isUpPressed()) chr2 = Key::Numpad9;
|
||||
else if(kb.isDownPressed()) chr2 = Key::Numpad3;
|
||||
else chr2 = Key::Numpad6;
|
||||
} else if(chr2 == Key::Home) chr2 = Key::Numpad7;
|
||||
if(chr2 == Key::Home) chr2 = Key::Numpad7;
|
||||
else if(chr2 == Key::End) chr2 = Key::Numpad1;
|
||||
else if(chr2 == Key::PageUp) chr2 = Key::Numpad9;
|
||||
else if(chr2 == Key::PageDown) chr2 = Key::Numpad3;
|
||||
|
@@ -471,10 +471,103 @@ void showWelcome() {
|
||||
welcome.show();
|
||||
}
|
||||
|
||||
using Key = sf::Keyboard::Key;
|
||||
std::map<Key,int> delayed_keys;
|
||||
const int ARROW_SIMUL_FRAMES = 3;
|
||||
|
||||
// Terrain map coordinates to simulate a click for 8-directional movement
|
||||
// ordered to correspond with eDirection
|
||||
// TODO terrain_click is duplicated (with different ordering) in boe.actions.cpp
|
||||
location terrain_click[8] = {
|
||||
{150,155}, // north
|
||||
{180,135}, // northeast
|
||||
{180,185}, // east
|
||||
{180,215}, // southeast
|
||||
{150,215}, // south
|
||||
{120,215}, // southwest
|
||||
{120,185}, // west
|
||||
{120,155}, // northwest
|
||||
};
|
||||
|
||||
void fire_delayed_key(Key code) {
|
||||
bool isUpPressed = delayed_keys[Key::Up] > 0;
|
||||
bool isDownPressed = delayed_keys[Key::Down] > 0;
|
||||
bool isLeftPressed = delayed_keys[Key::Left] > 0;
|
||||
bool isRightPressed = delayed_keys[Key::Right] > 0;
|
||||
delayed_keys[Key::Up] = 0;
|
||||
delayed_keys[Key::Down] = 0;
|
||||
delayed_keys[Key::Left] = 0;
|
||||
delayed_keys[Key::Right] = 0;
|
||||
|
||||
bool diagonal = false;
|
||||
int dir = -1;
|
||||
|
||||
if(code == Key::Up && !isDownPressed) {
|
||||
if(isLeftPressed){ dir = DIR_NW; diagonal = true; }
|
||||
else if(isRightPressed){ dir = DIR_NE; diagonal = true; }
|
||||
else dir = DIR_N;
|
||||
} else if(code == Key::Down && !isUpPressed) {
|
||||
if(isLeftPressed){ dir = DIR_SW; diagonal = true; }
|
||||
else if(isRightPressed){ dir = DIR_SE; diagonal = true; }
|
||||
else dir = DIR_S;
|
||||
} else if(code == Key::Left && !isRightPressed) {
|
||||
if(isUpPressed){ dir = DIR_NW; diagonal = true; }
|
||||
else if(isDownPressed){ dir = DIR_SW; diagonal = true; }
|
||||
else dir = DIR_W;
|
||||
} else if(code == Key::Right && !isLeftPressed) {
|
||||
if(isUpPressed){ dir = DIR_NE; diagonal = true; }
|
||||
else if(isDownPressed){ dir = DIR_SE; diagonal = true; }
|
||||
else dir = DIR_E;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
if(diagonal){
|
||||
mainPtr.setKeyRepeatEnabled(false);
|
||||
}else{
|
||||
mainPtr.setKeyRepeatEnabled(true);
|
||||
}
|
||||
|
||||
if(dir != -1){
|
||||
sf::Event pass_event = {sf::Event::MouseButtonPressed};
|
||||
location pass_point = mainPtr.mapCoordsToPixel(terrain_click[dir], mainView);
|
||||
pass_event.mouseButton.x = pass_point.x;
|
||||
pass_event.mouseButton.y = pass_point.y;
|
||||
queue_fake_event(pass_event);
|
||||
}
|
||||
}
|
||||
|
||||
void handle_delayed_key(Key code) {
|
||||
// a keypress of this code is already delayed, so push it through:
|
||||
if(delayed_keys[code] > 0)
|
||||
fire_delayed_key(code);
|
||||
|
||||
delayed_keys[code] = ARROW_SIMUL_FRAMES;
|
||||
}
|
||||
|
||||
void update_delayed_keys() {
|
||||
for(auto elem : delayed_keys){
|
||||
Key code = elem.first;
|
||||
int countdown = elem.second;
|
||||
|
||||
if(countdown > 0){
|
||||
--countdown;
|
||||
delayed_keys[code] = countdown;
|
||||
if(countdown == 0){
|
||||
fire_delayed_key(code);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void handle_events() {
|
||||
sf::Event currentEvent;
|
||||
cFramerateLimiter fps_limiter;
|
||||
|
||||
delayed_keys[Key::Left] = 0;
|
||||
delayed_keys[Key::Right] = 0;
|
||||
delayed_keys[Key::Up] = 0;
|
||||
delayed_keys[Key::Down] = 0;
|
||||
|
||||
while(!All_Done) {
|
||||
if(replaying && has_next_action()){
|
||||
replay_next_action();
|
||||
@@ -499,6 +592,7 @@ void handle_events() {
|
||||
menuChoiceId=-1;
|
||||
}
|
||||
#endif
|
||||
update_delayed_keys();
|
||||
while(!fake_event_queue.empty()){
|
||||
const sf::Event& next_event = fake_event_queue.front();
|
||||
fake_event_queue.pop_front();
|
||||
@@ -581,7 +675,12 @@ void handle_one_event(const sf::Event& event, cFramerateLimiter& fps_limiter) {
|
||||
switch(event.type) {
|
||||
case sf::Event::KeyPressed:
|
||||
if(flushingInput) return;
|
||||
if(!(event.key.*systemKey)) handle_keystroke(event, fps_limiter);
|
||||
if (delayed_keys.find(event.key.code) != delayed_keys.end()){
|
||||
handle_delayed_key(event.key.code);
|
||||
} else if(!(event.key.*systemKey)) {
|
||||
mainPtr.setKeyRepeatEnabled(true);
|
||||
handle_keystroke(event, fps_limiter);
|
||||
}
|
||||
break;
|
||||
|
||||
case sf::Event::MouseButtonPressed:
|
||||
|
Reference in New Issue
Block a user