spacebox/src/Input.cpp

148 lines
4.5 KiB
C++
Raw Permalink Normal View History

/* +------------------------------------------------------+
____/ \____ /| - Open source game framework licensed to freely use, |
\ / / | copy, modify and sell without restriction |
+--\ ^__^ /--+ | |
| ~/ \~ | | - created for <https://foam.shampoo.ooo> |
| ~~~~~~~~~~~~ | +------------------------------------------------------+
| SPACE ~~~~~ | /
| ~~~~~~~ BOX |/
+-------------*/
2019-05-03 02:09:48 -04:00
#include "Input.hpp"
2020-07-21 01:09:34 -04:00
2019-05-03 02:09:48 -04:00
Input::Input(Node *parent) : Node(parent)
{
get_delegate().subscribe(&Input::respond, this, SDL_KEYDOWN);
get_delegate().subscribe(&Input::respond, this, SDL_KEYUP);
2019-05-04 03:25:35 -04:00
for (KeyCombination& combination : key_map)
{
print_key_combination(combination);
}
}
2020-07-21 01:09:34 -04:00
void Input::print_key_combination(const KeyCombination &combination) const
2019-05-04 03:25:35 -04:00
{
std::cout << "<KeyCombination " << combination.command << ", " <<
combination.key << ", ctrl " << combination.ctrl << ", shift " <<
combination.shift << ", alt " << combination.alt << ">" << std::endl;
}
void Input::load_key_map()
{
const nlohmann::json& config = configuration()();
for (const auto& [command, input] : config.at("keys").items())
2019-05-04 03:25:35 -04:00
{
if (input.is_array() && input.size())
2019-05-04 03:25:35 -04:00
{
if (input[0].is_array())
2019-05-04 03:25:35 -04:00
{
for (nlohmann::json version : input)
2019-05-16 04:04:02 -04:00
{
key_map.push_back(parse_key(command, version));
2019-05-04 03:25:35 -04:00
}
}
else
{
key_map.push_back(parse_key(command, input));
}
}
else if (!input.is_array())
{
key_map.push_back((KeyCombination){command, get_key_code(input.get<std::string>()), false, false, false});
}
}
}
KeyCombination Input::parse_key(const std::string& command, const nlohmann::json& json) const
{
SDL_Keycode key_code;
bool ctrl = false, alt = false, shift = false;
for (const std::string& component : json)
{
if (component == "CTRL")
{
ctrl = true;
}
else if (component == "SHIFT")
{
shift = true;
}
else if (component == "ALT")
{
alt = true;
2019-05-04 03:25:35 -04:00
}
else
{
key_code = get_key_code(component);
2019-05-04 03:25:35 -04:00
}
}
return (KeyCombination){command, key_code, ctrl, shift, alt};
2019-05-04 03:25:35 -04:00
}
int Input::get_key_code(const std::string& name) const
2019-05-04 03:25:35 -04:00
{
if (key_ids.count(name) > 0)
{
return key_ids.at(name);
2019-05-04 03:25:35 -04:00
}
else
{
return (SDL_Keycode) name[0];
}
}
void Input::add_to_key_map(std::string command, SDL_Keycode key_code, bool ctrl, bool shift, bool alt)
{
2019-05-04 03:25:35 -04:00
key_map.push_back((KeyCombination){command, key_code, ctrl, shift, alt});
2019-05-03 02:09:48 -04:00
}
2019-05-04 03:25:35 -04:00
void Input::respond(SDL_Event &event)
2019-05-03 02:09:48 -04:00
{
if (!is_suppressed())
2019-06-16 03:05:02 -04:00
{
2020-07-22 00:53:40 -04:00
SDL_Keymod mod = SDL_GetModState();
SDL_Keycode sym = event.key.keysym.sym;
bool found_command = false, cancel = event.type != SDL_KEYDOWN, ctrl = mod & KMOD_CTRL,
shift = mod & KMOD_SHIFT, alt = mod & KMOD_ALT,
suppress_any_key = configuration()["input"]["suppress any key on mods"] && (ctrl || alt);
const std::vector<std::string>& system_any_key_ignore = configuration()["input"]["system any key ignore commands"];
const std::vector<std::string>& any_key_ignore = configuration()["input"]["any key ignore commands"];
bool ignore_repeat = configuration()["input"]["ignore repeat keypress"];
if (event.key.repeat == 0 || !ignore_repeat)
2019-05-04 20:30:39 -04:00
{
for (KeyCombination& combination : key_map)
2020-07-21 01:09:34 -04:00
{
if (sym == combination.key && (!combination.ctrl || ctrl) && (!combination.shift || shift) && (!combination.alt || alt))
2020-07-22 00:53:40 -04:00
{
2023-07-19 12:47:18 -04:00
sb::Delegate::post(combination.command, cancel);
2021-09-02 18:23:48 -04:00
if (!sb::is_in_container(system_any_key_ignore, combination.command) && !found_command &&
!sb::is_in_container(any_key_ignore, combination.command) && !suppress_any_key)
{
2023-07-19 12:47:18 -04:00
sb::Delegate::post(any, cancel);
}
found_command = true;
2020-07-22 00:53:40 -04:00
}
2020-07-21 01:09:34 -04:00
}
if (!found_command && !suppress_any_key)
{
2023-07-19 12:47:18 -04:00
sb::Delegate::post(any, cancel);
}
2020-07-22 00:53:40 -04:00
}
2020-07-21 01:09:34 -04:00
}
}
2020-07-22 00:53:40 -04:00
void Input::suppress()
{
suppressed = true;
2020-07-22 00:53:40 -04:00
}
void Input::unsuppress()
{
suppressed = false;
}
bool Input::is_suppressed()
{
return suppressed;
2020-07-22 00:53:40 -04:00
}