This commit is contained in:
y5nw 2025-01-01 15:17:54 +01:00 committed by GitHub
commit dad8ac2057
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 66 additions and 31 deletions

View File

@ -14,7 +14,7 @@
void KeyCache::populate_nonchanging() void KeyCache::populate_nonchanging()
{ {
key[KeyType::ESC] = EscapeKey; key[KeyType::ESC] = std::vector<KeyPress>{EscapeKey};
} }
void KeyCache::populate() void KeyCache::populate()
@ -77,8 +77,9 @@ void KeyCache::populate()
if (handler) { if (handler) {
// First clear all keys, then re-add the ones we listen for // First clear all keys, then re-add the ones we listen for
handler->dontListenForKeys(); handler->dontListenForKeys();
for (const KeyPress &k : key) { for (const auto &keylist : key) {
handler->listenForKey(k); for (const auto &kp: keylist)
handler->listenForKey(kp);
} }
handler->listenForKey(EscapeKey); handler->listenForKey(EscapeKey);
} }
@ -112,7 +113,7 @@ bool MyEventReceiver::OnEvent(const SEvent &event)
// This is separate from other keyboard handling so that it also works in menus. // This is separate from other keyboard handling so that it also works in menus.
if (event.EventType == EET_KEY_INPUT_EVENT) { if (event.EventType == EET_KEY_INPUT_EVENT) {
const KeyPress keyCode(event.KeyInput); const KeyPress keyCode(event.KeyInput);
if (keyCode == getKeySetting("keymap_fullscreen")) { if (inKeySetting("keymap_fullscreen", keyCode)) {
if (event.KeyInput.PressedDown && !fullscreen_is_down) { if (event.KeyInput.PressedDown && !fullscreen_is_down) {
IrrlichtDevice *device = RenderingEngine::get_raw_device(); IrrlichtDevice *device = RenderingEngine::get_raw_device();
@ -257,7 +258,7 @@ s32 RandomInputHandler::Rand(s32 min, s32 max)
} }
struct RandomInputHandlerSimData { struct RandomInputHandlerSimData {
std::string key; GameKeyType key;
float counter; float counter;
int time_max; int time_max;
}; };
@ -265,19 +266,19 @@ struct RandomInputHandlerSimData {
void RandomInputHandler::step(float dtime) void RandomInputHandler::step(float dtime)
{ {
static RandomInputHandlerSimData rnd_data[] = { static RandomInputHandlerSimData rnd_data[] = {
{ "keymap_jump", 0.0f, 40 }, { KeyType::JUMP, 0.0f, 40 },
{ "keymap_aux1", 0.0f, 40 }, { KeyType::AUX1, 0.0f, 40 },
{ "keymap_forward", 0.0f, 40 }, { KeyType::FORWARD, 0.0f, 40 },
{ "keymap_left", 0.0f, 40 }, { KeyType::LEFT, 0.0f, 40 },
{ "keymap_dig", 0.0f, 30 }, { KeyType::DIG, 0.0f, 30 },
{ "keymap_place", 0.0f, 15 } { KeyType::PLACE, 0.0f, 15 }
}; };
for (auto &i : rnd_data) { for (auto &i : rnd_data) {
i.counter -= dtime; i.counter -= dtime;
if (i.counter < 0.0) { if (i.counter < 0.0) {
i.counter = 0.1 * Rand(1, i.time_max); i.counter = 0.1 * Rand(1, i.time_max);
keydown.toggle(getKeySetting(i.key.c_str())); keydown[i.key] = !keydown[i.key];
} }
} }
{ {

View File

@ -42,7 +42,7 @@ struct KeyCache
// Keys that are not settings dependent // Keys that are not settings dependent
void populate_nonchanging(); void populate_nonchanging();
KeyPress key[KeyType::INTERNAL_ENUM_COUNT]; std::vector<KeyPress> key[KeyType::INTERNAL_ENUM_COUNT];
InputHandler *handler; InputHandler *handler;
}; };
@ -117,6 +117,14 @@ public:
} }
bool operator[](const KeyPress &key) const { return find(key) != end(); } bool operator[](const KeyPress &key) const { return find(key) != end(); }
bool operator[](const std::vector<KeyPress> &keylist) const
{
for (const auto &key: keylist)
if (find(key) != end())
return true;
return false;
}
}; };
class MyEventReceiver : public IEventReceiver class MyEventReceiver : public IEventReceiver
@ -126,23 +134,28 @@ public:
virtual bool OnEvent(const SEvent &event); virtual bool OnEvent(const SEvent &event);
bool IsKeyDown(const KeyPress &keyCode) const { return keyIsDown[keyCode]; } bool IsKeyDown(const KeyPress &keyCode) const { return keyIsDown[keyCode]; }
bool IsKeyDown(const std::vector<KeyPress> &keyCode) const { return keyIsDown[keyCode]; }
// Checks whether a key was down and resets the state // Checks whether a key was down and resets the state
bool WasKeyDown(const KeyPress &keyCode) bool WasKeyDown(const std::vector<KeyPress> &keylist)
{ {
bool b = keyWasDown[keyCode]; bool b = false;
if (b) for (const auto &key: keylist) {
keyWasDown.unset(keyCode); if (keyWasDown[key]) {
b = true;
keyWasDown.unset(key);
}
}
return b; return b;
} }
// Checks whether a key was just pressed. State will be cleared // Checks whether a key was just pressed. State will be cleared
// in the subsequent iteration of Game::processPlayerInteraction // in the subsequent iteration of Game::processPlayerInteraction
bool WasKeyPressed(const KeyPress &keycode) const { return keyWasPressed[keycode]; } bool WasKeyPressed(const std::vector<KeyPress> &keycode) const { return keyWasPressed[keycode]; }
// Checks whether a key was just released. State will be cleared // Checks whether a key was just released. State will be cleared
// in the subsequent iteration of Game::processPlayerInteraction // in the subsequent iteration of Game::processPlayerInteraction
bool WasKeyReleased(const KeyPress &keycode) const { return keyWasReleased[keycode]; } bool WasKeyReleased(const std::vector<KeyPress> &keycode) const { return keyWasReleased[keycode]; }
void listenForKey(const KeyPress &keyCode) void listenForKey(const KeyPress &keyCode)
{ {
@ -359,7 +372,7 @@ public:
return true; return true;
} }
virtual bool isKeyDown(GameKeyType k) { return keydown[keycache.key[k]]; } virtual bool isKeyDown(GameKeyType k) { return keydown[k]; }
virtual bool wasKeyDown(GameKeyType k) { return false; } virtual bool wasKeyDown(GameKeyType k) { return false; }
virtual bool wasKeyPressed(GameKeyType k) { return false; } virtual bool wasKeyPressed(GameKeyType k) { return false; }
virtual bool wasKeyReleased(GameKeyType k) { return false; } virtual bool wasKeyReleased(GameKeyType k) { return false; }
@ -376,7 +389,7 @@ public:
s32 Rand(s32 min, s32 max); s32 Rand(s32 min, s32 max);
private: private:
KeyList keydown; std::bitset<KeyType::INTERNAL_ENUM_COUNT> keydown;
v2s32 mousepos; v2s32 mousepos;
v2s32 mousespeed; v2s32 mousespeed;
float joystickSpeed; float joystickSpeed;

View File

@ -343,19 +343,37 @@ const KeyPress RMBKey("KEY_RBUTTON");
*/ */
// A simple cache for quicker lookup // A simple cache for quicker lookup
static std::unordered_map<std::string, KeyPress> g_key_setting_cache; static std::unordered_map<std::string, std::vector<KeyPress>> g_key_setting_cache;
const KeyPress &getKeySetting(const char *settingname) const std::vector<KeyPress> &getKeySetting(const std::string &settingname)
{ {
auto n = g_key_setting_cache.find(settingname); auto n = g_key_setting_cache.find(settingname);
if (n != g_key_setting_cache.end()) if (n != g_key_setting_cache.end())
return n->second; return n->second;
auto &ref = g_key_setting_cache[settingname]; auto &ref = g_key_setting_cache[settingname];
ref = g_settings->get(settingname).c_str(); auto &settingvalue = g_settings->get(settingname);
if (settingvalue == "|") {
// TODO: with SDL scancodes we should check that there is a key with "|"
ref.push_back("|");
} else {
for (const auto &str: str_split(settingvalue, '|'))
if (KeyPress kp(str.c_str()); strlen(kp.sym()) > 0)
ref.push_back(kp);
}
return ref; return ref;
} }
bool inKeySetting(const std::string &settingname, const KeyPress &kp)
{
for (const auto &key: getKeySetting(settingname))
if (key == kp)
return true;
return false;
}
void clearKeyCache() void clearKeyCache()
{ {
g_key_setting_cache.clear(); g_key_setting_cache.clear();

View File

@ -9,6 +9,7 @@
#include <Keycodes.h> #include <Keycodes.h>
#include <IEventReceiver.h> #include <IEventReceiver.h>
#include <string> #include <string>
#include <vector>
class UnknownKeycode : public BaseException class UnknownKeycode : public BaseException
{ {
@ -57,7 +58,8 @@ extern const KeyPress MMBKey; // Middle Mouse Button
extern const KeyPress RMBKey; extern const KeyPress RMBKey;
// Key configuration getter // Key configuration getter
const KeyPress &getKeySetting(const char *settingname); const std::vector<KeyPress> &getKeySetting(const std::string &settingname);
bool inKeySetting(const std::string &settingname, const KeyPress &kp);
// Clear fast lookup cache // Clear fast lookup cache
void clearKeyCache(); void clearKeyCache();

View File

@ -415,7 +415,7 @@ bool GUIChatConsole::OnEvent(const SEvent& event)
} }
// Key input // Key input
if (KeyPress(event.KeyInput) == getKeySetting("keymap_console")) { if (inKeySetting("keymap_console", event.KeyInput)) {
closeConsole(); closeConsole();
// inhibit open so the_game doesn't reopen immediately // inhibit open so the_game doesn't reopen immediately

View File

@ -3953,7 +3953,7 @@ bool GUIFormSpecMenu::preprocessEvent(const SEvent& event)
if (event.EventType == EET_KEY_INPUT_EVENT) { if (event.EventType == EET_KEY_INPUT_EVENT) {
KeyPress kp(event.KeyInput); KeyPress kp(event.KeyInput);
if (kp == EscapeKey if (kp == EscapeKey
|| kp == getKeySetting("keymap_inventory") || inKeySetting("keymap_inventory", kp)
|| event.KeyInput.Key==KEY_RETURN) { || event.KeyInput.Key==KEY_RETURN) {
gui::IGUIElement *focused = Environment->getFocus(); gui::IGUIElement *focused = Environment->getFocus();
if (focused && isMyChild(focused) && if (focused && isMyChild(focused) &&
@ -4020,17 +4020,17 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
KeyPress kp(event.KeyInput); KeyPress kp(event.KeyInput);
if (event.KeyInput.PressedDown && ( if (event.KeyInput.PressedDown && (
(kp == EscapeKey) || (kp == EscapeKey) ||
((m_client != NULL) && (kp == getKeySetting("keymap_inventory"))))) { ((m_client != NULL) && (inKeySetting("keymap_inventory", kp))))) {
tryClose(); tryClose();
return true; return true;
} }
if (m_client != NULL && event.KeyInput.PressedDown && if (m_client != NULL && event.KeyInput.PressedDown &&
(kp == getKeySetting("keymap_screenshot"))) { (inKeySetting("keymap_screenshot", kp))) {
m_client->makeScreenshot(); m_client->makeScreenshot();
} }
if (event.KeyInput.PressedDown && kp == getKeySetting("keymap_toggle_debug")) { if (event.KeyInput.PressedDown && inKeySetting("keymap_toggle_debug", kp)) {
if (!m_client || m_client->checkPrivilege("debug")) if (!m_client || m_client->checkPrivilege("debug"))
m_show_debug = !m_show_debug; m_show_debug = !m_show_debug;
} }

View File

@ -359,7 +359,8 @@ void GUIKeyChangeMenu::add_key(int id, std::wstring button_name, const std::stri
k->button_name = std::move(button_name); k->button_name = std::move(button_name);
k->setting_name = setting_name; k->setting_name = setting_name;
k->key = getKeySetting(k->setting_name.c_str()); if (const auto &keylist = getKeySetting(k->setting_name.c_str()); keylist.size() > 0)
k->key = keylist.front();
key_settings.push_back(k); key_settings.push_back(k);
} }