1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-08-01 17:38:41 +00:00

SDL: Use scancodes for keybindings (#14964)

Co-authored-by: Lars Müller <34514239+appgurueu@users.noreply.github.com>
Co-authored-by: sfan5 <sfan5@live.de>
Co-authored-by: SmallJoker <SmallJoker@users.noreply.github.com>
This commit is contained in:
y5nw 2025-03-16 20:35:34 +01:00 committed by GitHub
parent e0378737b7
commit cc65c8bd70
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 509 additions and 369 deletions

View file

@ -4,62 +4,77 @@
#pragma once
#include "exceptions.h"
#include "irrlichttypes.h"
#include <Keycodes.h>
#include <IEventReceiver.h>
#include <string>
#include <variant>
class UnknownKeycode : public BaseException
{
public:
UnknownKeycode(const char *s) :
BaseException(s) {};
};
/* A key press, consisting of either an Irrlicht keycode
or an actual char */
/* A key press, consisting of a scancode or a keycode */
class KeyPress
{
public:
KeyPress() = default;
KeyPress(const char *name);
KeyPress(const std::string &name);
KeyPress(const irr::SEvent::SKeyInput &in, bool prefer_character = false);
KeyPress(const irr::SEvent::SKeyInput &in);
bool operator==(const KeyPress &o) const
// Get a string representation that is suitable for use in minetest.conf
std::string sym() const;
// Get a human-readable string representation
std::string name() const;
// Get the corresponding keycode or KEY_UNKNOWN if one is not available
irr::EKEY_CODE getKeycode() const;
// Get the corresponding keychar or '\0' if one is not available
wchar_t getKeychar() const;
// Get the scancode or 0 is one is not available
u32 getScancode() const
{
return (Char > 0 && Char == o.Char) || (valid_kcode(Key) && Key == o.Key);
if (auto pv = std::get_if<u32>(&scancode))
return *pv;
return 0;
}
const char *sym() const;
const char *name() const;
protected:
static bool valid_kcode(irr::EKEY_CODE k)
{
return k > 0 && k < irr::KEY_KEY_CODES_COUNT;
bool operator==(const KeyPress &o) const {
return scancode == o.scancode;
}
bool operator!=(const KeyPress &o) const {
return !(*this == o);
}
irr::EKEY_CODE Key = irr::KEY_KEY_CODES_COUNT;
wchar_t Char = L'\0';
std::string m_name = "";
// Check whether the keypress is valid
operator bool() const
{
return std::holds_alternative<irr::EKEY_CODE>(scancode) ?
Keycode::isValid(std::get<irr::EKEY_CODE>(scancode)) :
std::get<u32>(scancode) != 0;
}
static const KeyPress &getSpecialKey(const std::string &name);
private:
bool loadFromScancode(const std::string &name);
void loadFromKey(irr::EKEY_CODE keycode, wchar_t keychar);
std::string formatScancode() const;
std::variant<u32, irr::EKEY_CODE> scancode = irr::KEY_UNKNOWN;
};
// Global defines for convenience
extern const KeyPress EscapeKey;
extern const KeyPress LMBKey;
extern const KeyPress MMBKey; // Middle Mouse Button
extern const KeyPress RMBKey;
// This implementation defers creation of the objects to make sure that the
// IrrlichtDevice is initialized.
#define EscapeKey KeyPress::getSpecialKey("KEY_ESCAPE")
#define LMBKey KeyPress::getSpecialKey("KEY_LBUTTON")
#define MMBKey KeyPress::getSpecialKey("KEY_MBUTTON") // Middle Mouse Button
#define RMBKey KeyPress::getSpecialKey("KEY_RBUTTON")
// Key configuration getter
const KeyPress &getKeySetting(const char *settingname);
const KeyPress &getKeySetting(const std::string &settingname);
// Clear fast lookup cache
void clearKeyCache();
irr::EKEY_CODE keyname_to_keycode(const char *name);