Use scancodes only for SDL

This commit is contained in:
y5nw 2024-12-13 18:53:42 +01:00
parent c91d4edbef
commit 7624f77a1b
2 changed files with 80 additions and 19 deletions

View File

@ -243,6 +243,19 @@ static const table_key &lookup_keychar(wchar_t Char)
return table.emplace_back(std::move(new_key));
}
static const table_key &lookup_keykey(irr::EKEY_CODE key)
{
if (!Keycode::isValid(key))
return invalid_key;
for (const auto &table_key : table) {
if (table_key.Key == key)
return table_key;
}
return invalid_key;
}
static const table_key &lookup_keyname(std::string_view name)
{
if (name.empty())
@ -259,19 +272,7 @@ static const table_key &lookup_keyname(std::string_view name)
return lookup_keychar(wname[0]);
}
static const table_key &lookup_keykey(irr::EKEY_CODE key)
{
if (!Keycode::isValid(key))
return invalid_key;
for (const auto &table_key : table) {
if (table_key.Key == key)
return table_key;
}
return invalid_key;
}
#if USE_SDL2
static const table_key &lookup_scancode(const u32 scancode)
{
auto key = RenderingEngine::get_raw_device()->getKeyFromScancode(scancode);
@ -279,18 +280,33 @@ static const table_key &lookup_scancode(const u32 scancode)
lookup_keykey(std::get<irr::EKEY_CODE>(key)) :
lookup_keychar(std::get<wchar_t>(key));
}
#endif
KeyPress::KeyPress(std::string_view name)
{
#if USE_SDL2
if (loadFromScancode(name))
return;
const auto &key = lookup_keyname(name);
Keycode keycode(key.Key, key.Char);
scancode = RenderingEngine::get_raw_device()->getScancodeFromKey(keycode);
#else
const auto &key = lookup_keyname(name);
Key = key.Key;
Char = key.Char;
#endif
}
KeyPress::KeyPress(const irr::SEvent::SKeyInput &in) :
#if USE_SDL2
scancode(in.SystemKeyCode) {}
#else
Key(in.Key), Char(in.Char ? in.Char : lookup_keykey(in.Key).Char) {}
#endif
std::string KeyPress::sym(const bool force_scancode) const
{
#if USE_SDL2
if (scancode == 0)
return "";
if (force_scancode)
@ -299,27 +315,46 @@ std::string KeyPress::sym(const bool force_scancode) const
if (!name.empty())
return name;
return formatScancode();
#else
if (Keycode::isValid(Key))
if (const auto &sym = lookup_keykey(Key).Name; !sym.empty())
return sym;
return lookup_keychar(Char).Name;
#endif
}
std::string KeyPress::name() const
{
#if USE_SDL2
const auto &name = lookup_scancode(scancode).LangName;
auto table_key = lookup_scancode(scancode);
if (!name.empty() || scancode == 0)
return name;
return formatScancode();
#else
return (Keycode::isValid(Key) ? lookup_keykey(Key) : lookup_keychar(Char)).LangName;
#endif
}
irr::EKEY_CODE KeyPress::getKeycode() const
{
#if USE_SDL2
return lookup_scancode(scancode).Key;
#else
return Key;
#endif
}
wchar_t KeyPress::getKeychar() const
{
#if USE_SDL2
return lookup_scancode(scancode).Char;
#else
return Char;
#endif
}
#if USE_SDL2
bool KeyPress::loadFromScancode(std::string_view name)
{
if (name.size() < 2 || name[0] != '<' || name.back() != '>')
@ -331,6 +366,7 @@ bool KeyPress::loadFromScancode(std::string_view name)
scancode = code;
return true;
}
#endif
std::unordered_map<std::string, KeyPress> KeyPress::specialKeyCache;
const KeyPress &KeyPress::getSpecialKey(const std::string &name)

View File

@ -5,6 +5,7 @@
#pragma once
#include "irrlichttypes.h"
#include "cmake_config.h" // USE_SDL2
#include <Keycodes.h>
#include <IEventReceiver.h>
#include <string>
@ -14,12 +15,11 @@
class KeyPress
{
public:
KeyPress() {};
KeyPress() = default;
KeyPress(std::string_view name);
KeyPress(const irr::SEvent::SKeyInput &in) :
scancode(in.SystemKeyCode) {};
KeyPress(const irr::SEvent::SKeyInput &in);
std::string sym(const bool force_scancode = false) const;
std::string name() const;
@ -27,25 +27,46 @@ public:
irr::EKEY_CODE getKeycode() const;
wchar_t getKeychar() const;
//TODO: drop this once we fully switch to SDL
u32 getScancode() const
{
#if USE_SDL2
return scancode;
#else
return 0;
#endif
}
irr::SEvent toKeyEvent(bool pressedDown = false) const
{
irr::SEvent event;
event.EventType = EET_KEY_INPUT_EVENT;
event.KeyInput = {getKeychar(), getKeycode(), scancode, pressedDown, false, false};
event.KeyInput = {getKeychar(), getKeycode(), getScancode(), pressedDown, false, false};
return event;
}
bool operator==(const KeyPress &o) const {
bool operator==(const KeyPress &o) const
{
#if USE_SDL2
return scancode == o.scancode;
#else
return (Char > 0 && Char == o.Char) || (Keycode::isValid(Key) && Key == o.Key);
#endif
}
operator bool() const {
operator bool() const
{
#if USE_SDL2
return scancode != 0;
#else
return Char > 0 || Keycode::isValid(Key);
#endif
}
static const KeyPress &getSpecialKey(const std::string &name);
private:
#if USE_SDL2
bool loadFromScancode(std::string_view name);
inline std::string formatScancode() const
@ -54,6 +75,10 @@ private:
}
u32 scancode = 0;
#else
irr::EKEY_CODE Key = irr::KEY_KEY_CODES_COUNT;
wchar_t Char = L'\0';
#endif
static std::unordered_map<std::string, KeyPress> specialKeyCache;
};