Skip to content

Commit

Permalink
Implement secondary keybindings
Browse files Browse the repository at this point in the history
  • Loading branch information
y5nw committed Dec 19, 2024
1 parent f99a1a7 commit b344415
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 32 deletions.
25 changes: 13 additions & 12 deletions src/client/inputhandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

void KeyCache::populate_nonchanging()
{
key[KeyType::ESC] = EscapeKey;
key[KeyType::ESC] = std::vector<KeyPress>{EscapeKey};
}

void KeyCache::populate()
Expand Down Expand Up @@ -77,8 +77,9 @@ void KeyCache::populate()
if (handler) {
// First clear all keys, then re-add the ones we listen for
handler->dontListenForKeys();
for (const KeyPress &k : key) {
handler->listenForKey(k);
for (const auto &keylist : key) {
for (const auto &kp: keylist)
handler->listenForKey(kp);
}
handler->listenForKey(EscapeKey);
}
Expand Down Expand Up @@ -112,7 +113,7 @@ bool MyEventReceiver::OnEvent(const SEvent &event)
// This is separate from other keyboard handling so that it also works in menus.
if (event.EventType == EET_KEY_INPUT_EVENT) {
const KeyPress keyCode(event.KeyInput);
if (keyCode == getKeySetting("keymap_fullscreen")) {
if (inKeySetting("keymap_fullscreen", keyCode)) {
if (event.KeyInput.PressedDown && !fullscreen_is_down) {
IrrlichtDevice *device = RenderingEngine::get_raw_device();

Expand Down Expand Up @@ -257,27 +258,27 @@ s32 RandomInputHandler::Rand(s32 min, s32 max)
}

struct RandomInputHandlerSimData {
std::string key;
GameKeyType key;
float counter;
int time_max;
};

void RandomInputHandler::step(float dtime)
{
static RandomInputHandlerSimData rnd_data[] = {
{ "keymap_jump", 0.0f, 40 },
{ "keymap_aux1", 0.0f, 40 },
{ "keymap_forward", 0.0f, 40 },
{ "keymap_left", 0.0f, 40 },
{ "keymap_dig", 0.0f, 30 },
{ "keymap_place", 0.0f, 15 }
{ KeyType::JUMP, 0.0f, 40 },
{ KeyType::AUX1, 0.0f, 40 },
{ KeyType::FORWARD, 0.0f, 40 },
{ KeyType::LEFT, 0.0f, 40 },
{ KeyType::DIG, 0.0f, 30 },
{ KeyType::PLACE, 0.0f, 15 }
};

for (auto &i : rnd_data) {
i.counter -= dtime;
if (i.counter < 0.0) {
i.counter = 0.1 * Rand(1, i.time_max);
keydown.toggle(getKeySetting(i.key.c_str()));
keydown[i.key] = !keydown[i.key];
}
}
{
Expand Down
33 changes: 23 additions & 10 deletions src/client/inputhandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ struct KeyCache
// Keys that are not settings dependent
void populate_nonchanging();

KeyPress key[KeyType::INTERNAL_ENUM_COUNT];
std::vector<KeyPress> key[KeyType::INTERNAL_ENUM_COUNT];
InputHandler *handler;
};

Expand Down Expand Up @@ -117,6 +117,14 @@ class KeyList : private std::list<KeyPress>
}

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
Expand All @@ -126,23 +134,28 @@ class MyEventReceiver : public IEventReceiver
virtual bool OnEvent(const SEvent &event);

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
bool WasKeyDown(const KeyPress &keyCode)
{
bool b = keyWasDown[keyCode];
if (b)
keyWasDown.unset(keyCode);
bool WasKeyDown(const std::vector<KeyPress> &keylist)
{
bool b = false;
for (const auto &key: keylist) {
if (keyWasDown[key]) {
b = true;
keyWasDown.unset(key);
}
}
return b;
}

// Checks whether a key was just pressed. State will be cleared
// 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
// 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)
{
Expand Down Expand Up @@ -359,7 +372,7 @@ class RandomInputHandler final : public InputHandler
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 wasKeyPressed(GameKeyType k) { return false; }
virtual bool wasKeyReleased(GameKeyType k) { return false; }
Expand All @@ -376,7 +389,7 @@ class RandomInputHandler final : public InputHandler
s32 Rand(s32 min, s32 max);

private:
KeyList keydown;
std::bitset<KeyType::INTERNAL_ENUM_COUNT> keydown;
v2s32 mousepos;
v2s32 mousespeed;
float joystickSpeed;
Expand Down
24 changes: 21 additions & 3 deletions src/client/keycode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -343,19 +343,37 @@ const KeyPress RMBKey("KEY_RBUTTON");
*/

// 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);
if (n != g_key_setting_cache.end())
return n->second;

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;
}

bool inKeySetting(const std::string &settingname, const KeyPress &kp)
{
for (const auto &key: getKeySetting(settingname))
if (key == kp)
return true;
return false;
}

void clearKeyCache()
{
g_key_setting_cache.clear();
Expand Down
4 changes: 3 additions & 1 deletion src/client/keycode.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#include <Keycodes.h>
#include <IEventReceiver.h>
#include <string>
#include <vector>

class UnknownKeycode : public BaseException
{
Expand Down Expand Up @@ -57,7 +58,8 @@ extern const KeyPress MMBKey; // Middle Mouse Button
extern const KeyPress RMBKey;

// 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
void clearKeyCache();
Expand Down
2 changes: 1 addition & 1 deletion src/gui/guiChatConsole.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ bool GUIChatConsole::OnEvent(const SEvent& event)
}

// Key input
if (KeyPress(event.KeyInput) == getKeySetting("keymap_console")) {
if (inKeySetting("keymap_console", event.KeyInput)) {
closeConsole();

// inhibit open so the_game doesn't reopen immediately
Expand Down
8 changes: 4 additions & 4 deletions src/gui/guiFormSpecMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3953,7 +3953,7 @@ bool GUIFormSpecMenu::preprocessEvent(const SEvent& event)
if (event.EventType == EET_KEY_INPUT_EVENT) {
KeyPress kp(event.KeyInput);
if (kp == EscapeKey
|| kp == getKeySetting("keymap_inventory")
|| inKeySetting("keymap_inventory", kp)
|| event.KeyInput.Key==KEY_RETURN) {
gui::IGUIElement *focused = Environment->getFocus();
if (focused && isMyChild(focused) &&
Expand Down Expand Up @@ -4020,17 +4020,17 @@ bool GUIFormSpecMenu::OnEvent(const SEvent& event)
KeyPress kp(event.KeyInput);
if (event.KeyInput.PressedDown && (
(kp == EscapeKey) ||
((m_client != NULL) && (kp == getKeySetting("keymap_inventory"))))) {
((m_client != NULL) && (inKeySetting("keymap_inventory", kp))))) {
tryClose();
return true;
}

if (m_client != NULL && event.KeyInput.PressedDown &&
(kp == getKeySetting("keymap_screenshot"))) {
(inKeySetting("keymap_screenshot", kp))) {
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"))
m_show_debug = !m_show_debug;
}
Expand Down
3 changes: 2 additions & 1 deletion src/gui/guiKeyChangeMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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->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);
}

Expand Down

0 comments on commit b344415

Please sign in to comment.