|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505 |
- //
- // Lol Engine
- //
- // Copyright © 2010—2015 Benjamin Litzelmann
- // © 2017—2018 Sam Hocevar <sam@hocevar.net>
- //
- // Lol Engine is free software. It comes without any warranty, to
- // the extent permitted by applicable law. You can redistribute it
- // and/or modify it under the terms of the Do What the Fuck You Want
- // to Public License, Version 2, as published by the WTFPL Task Force.
- // See http://www.wtfpl.net/ for more details.
- //
-
- #include <lol/engine-internal.h>
-
- #include <string>
-
- namespace lol
- {
-
- ///////////////////////////////////////////////////////////////////////////////
- // KeyBinding
-
- void KeyBinding::Bind(const std::string& device_name, const std::string& key_name)
- {
- const InputDevice* device = InputDevice::Get(device_name);
-
- if (!device)
- {
- msg::warn("trying to bind key to nonexistent input device %s\n",
- device_name.c_str());
- return;
- }
-
- int keyindex = device->GetKeyIndex(key_name);
- if (keyindex < 0)
- {
- msg::warn("trying to bind nonexistent key %s.%s\n",
- device_name.c_str(), key_name.c_str());
- return;
- }
-
- m_keybindings.push(device, keyindex);
- }
-
- bool KeyBinding::Unbind(const std::string& device_name, const std::string& key_name)
- {
- for (int i = 0; i < m_keybindings.count(); ++i)
- {
- if (m_keybindings[i].m1->GetName() == device_name)
- {
- if (m_keybindings[i].m2 == m_keybindings[i].m1->GetKeyIndex(key_name))
- {
- m_keybindings.remove(i);
- return true;
- }
- }
- }
- return false;
- }
-
- void KeyBinding::ClearBindings()
- {
- m_keybindings.clear();
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- // AxisBinding
-
- void AxisBinding::Bind(const std::string& device_name, const std::string& axis_name)
- {
- const InputDevice* device = InputDevice::Get(device_name);
- if (!device)
- {
- msg::warn("trying to bind axis to nonexistent input device %s\n",
- device_name.c_str());
- return;
- }
-
- int axisindex = device->GetAxisIndex(axis_name);
- if (axisindex < 0)
- {
- msg::warn("trying to bind nonexistent axis %s.%s\n",
- device_name.c_str(), axis_name.c_str());
- return;
- }
-
- m_axisbindings.push(device, axisindex);
- }
-
- void AxisBinding::BindKey(const std::string& device_name, const std::string& key_name)
- {
- const InputDevice* device = InputDevice::Get(device_name);
- if (!device)
- {
- msg::warn("trying to bind axis key to nonexistent input device %s\n",
- device_name.c_str());
- return;
- }
-
- int keyindex = device->GetKeyIndex(key_name);
- if (keyindex < 0)
- {
- msg::warn("trying to bind nonexistent axis key %s.%s\n",
- device_name.c_str(), key_name.c_str());
- return;
- }
-
- m_keybindings.push(device, -1, keyindex);
- }
-
- void AxisBinding::BindKeys(const std::string& device_name, const std::string& min_key_name, const std::string& max_key_name)
- {
- const InputDevice* device = InputDevice::Get(device_name);
- if (!device)
- {
- msg::warn("trying to bind axis keys to nonexistent input device %s\n",
- device_name.c_str());
- return;
- }
-
- int minkeyindex = device->GetKeyIndex(min_key_name);
- if (minkeyindex < 0)
- {
- msg::warn("trying to bind nonexistent axis key %s.%s\n",
- device_name.c_str(), min_key_name.c_str());
- return;
- }
-
- int maxkeyindex = device->GetKeyIndex(max_key_name);
- if (maxkeyindex < 0)
- {
- msg::warn("trying to bind nonexistent axis key %s.%s\n",
- device_name.c_str(), max_key_name.c_str());
- return;
- }
-
- m_keybindings.push(device, minkeyindex, maxkeyindex);
- }
-
- bool AxisBinding::Unbind(const std::string& device_name, const std::string& axis_name)
- {
- for (int i = 0; i < m_keybindings.count(); ++i)
- {
- if (m_axisbindings[i].m1->GetName() == device_name)
- {
- if (m_axisbindings[i].m2 == m_axisbindings[i].m1->GetAxisIndex(axis_name))
- {
- m_axisbindings.remove(i);
- return true;
- }
- }
- }
- return false;
- }
-
- bool AxisBinding::UnbindKey(const std::string& device_name, const std::string& key_name)
- {
- for (int i = 0; i < m_keybindings.count(); ++i)
- {
- if (m_keybindings[i].m1->GetName() == device_name)
- {
- if (m_keybindings[i].m2 == -1 && m_keybindings[i].m3 == m_keybindings[i].m1->GetKeyIndex(key_name))
- {
- m_keybindings.remove(i);
- return true;
- }
- }
- }
- return false;
- }
-
- bool AxisBinding::UnbindKeys(const std::string& device_name, const std::string& min_key_name, const std::string& max_key_name)
- {
- for (int i = 0; i < m_keybindings.count(); ++i)
- {
- if (m_keybindings[i].m1->GetName() == device_name)
- {
- if (m_keybindings[i].m2 == m_keybindings[i].m1->GetKeyIndex(min_key_name)
- && m_keybindings[i].m3 == m_keybindings[i].m1->GetKeyIndex(max_key_name))
- {
- m_keybindings.remove(i);
- return true;
- }
- }
- }
- return false;
-
- }
-
- void AxisBinding::ClearBindings()
- {
- m_axisbindings.clear();
- m_keybindings.clear();
- }
-
- float AxisBinding::RetrieveCurrentValue()
- {
- float max_positive = 0.0f;
- float max_negative = 0.0f;
-
- for (int i = 0; i < m_axisbindings.count(); ++i)
- {
- float value = m_axisbindings[i].m1->GetAxis(m_axisbindings[i].m2);
- if (value > max_positive)
- max_positive = value;
- if (value < max_negative)
- max_negative = value;
- }
-
- for (int i = 0; i < m_keybindings.count(); ++i)
- {
- float value = 0.0f;
- m_keybindings[i].m1->GetKey(m_keybindings[i].m2);
- value += m_keybindings[i].m1->GetKey(m_keybindings[i].m3) ? 1.0f : 0.0f;
- if (m_keybindings[i].m2 != -1)
- value += m_keybindings[i].m1->GetKey(m_keybindings[i].m2) ? -1.0f : 0.0f;
-
- if (value > max_positive)
- max_positive = value;
- if (value < max_negative)
- max_negative = value;
- }
-
- return max_negative + max_positive;
- }
-
- ///////////////////////////////////////////////////////////////////////////////
- // Controller
-
- array<Controller*> Controller::controllers;
- uint32_t Controller::m_active_layer = ~((uint32_t)0);
-
- //-----------------------------------------------------------------------------
- Controller::Controller(std::string const &name)
- {
- m_gamegroup = GAMEGROUP_INPUT;
- m_name = name;
- m_activate_nextframe = true;
- m_deactivate_nextframe = false;
- m_active = false;
- if (Get(name) != nullptr)
- {
- msg::warn("controller “%s” has already been registered\n", name.c_str());
- }
- controllers.push(this);
- }
-
- Controller::Controller(std::string const &name, InputProfile const& profile)
- : Controller(name)
- {
- Init(profile);
- }
-
- Controller::~Controller()
- {
- ClearProfile();
- for (int i = 0; i < controllers.count(); ++i)
- {
- if (controllers[i] == this)
- {
- controllers.remove(i);
- break;
- }
- }
- }
-
- //Init mode 1: Input profile system -------------------------------------------
- void Controller::Init(InputProfile const& profile)
- {
- UnbindProfile();
- BindProfile(profile);
- }
- void Controller::ClearProfile()
- {
- UnbindProfile();
- }
-
- //Init mode 2: By hand, key/axis by key/axis ----------------------------------
- void Controller::SetInputCount(int nb_keys, int nb_axis)
- {
- m_keys.resize(nb_keys);
- m_axis.resize(nb_axis);
- }
-
- //Layer mask stuff ------------------------------------------------------------
- void Controller::SetLayerMask(uint32_t layer_mask)
- {
- m_layer_mask = layer_mask;
- }
- uint32_t Controller::GetLayerMask()
- {
- return m_layer_mask;
- }
- bool Controller::IsLayerActive()
- {
- return !!(m_layer_mask & m_active_layer);
- }
-
- //GetKeys/Axis stuff ----------------------------------------------------------
- KeyBinding& Controller::GetKey(int index)
- {
- return m_keys[index];
- }
- KeyBinding const& Controller::GetKey(int index) const
- {
- return m_keys[index];
- }
- AxisBinding& Controller::GetAxis(int index)
- {
- return m_axis[index];
- }
- AxisBinding const& Controller::GetAxis(int index) const
- {
- return m_axis[index];
- }
-
- //Key methods: should not go directly to binding ------------------------------
- bool Controller::IsKeyPressed(int index) const
- {
- //#error do something better IsLayerActive()
- return GetKey(index).IsPressed();
- }
- bool Controller::IsKeyReleased(int index) const
- {
- return GetKey(index).IsReleased();
- }
- bool Controller::WasKeyPressedThisFrame(int index) const
- {
- return GetKey(index).WasPressedThisFrame();
- }
- bool Controller::WasKeyReleasedThisFrame(int index) const
- {
- return GetKey(index).WasReleasedThisFrame();
- }
-
- //Axis methods: should not go directly to binding -----------------------------
- float Controller::GetAxisValue(int index) const
- {
- return GetAxis(index).GetValue();
- }
- float Controller::GetAxisDelta(int index) const
- {
- return GetAxis(index).GetDelta();
- }
-
- //-----------------------------------------------------------------------------
- Controller* Controller::Get(std::string const &name)
- {
- for (auto controller : controllers)
- if (controller->m_name == name)
- return controller;
- return nullptr;
- }
-
- //Input profile system --------------------------------------------------------
- void Controller::UnbindProfile()
- {
- if (m_profile.IsEmpty())
- return;
-
- m_mutex.lock();
-
- //Keyboard
- if (m_keyboard)
- {
- for (InputProfile::Keyboard& key : m_profile.m_keys)
- GetKey(key.m_idx).UnbindKeyboard(key.m_name);
- m_keyboard = nullptr;
- }
-
- //Mouse
- if (m_mouse)
- {
- for (InputProfile::MouseKey& key : m_profile.m_mouse_keys)
- GetKey(key.m_idx).UnbindMouse(key.m_name);
- for (InputProfile::MouseAxis& axis : m_profile.m_mouse_axis)
- GetAxis(axis.m_idx).UnbindMouse(axis.m_name);
- m_mouse = nullptr;
- }
-
- //Joystick
- for (InputProfile::JoystickKey& key : m_profile.m_joystick_keys)
- {
- if (m_joystick_idx.find(key.m_joy) != INDEX_NONE)
- GetKey(key.m_idx).UnbindJoystick(key.m_joy, key.m_name);
- }
- for (InputProfile::JoystickAxis& axis : m_profile.m_joystick_axis)
- {
- if (m_joystick_idx.find(axis.m_joy) != INDEX_NONE)
- GetAxis(axis.m_idx).UnbindJoystick(axis.m_joy, axis.m_name);
- }
- m_joystick.clear();
- m_joystick_idx.clear();
-
- m_mutex.unlock();
- }
- //Input profile system --------------------------------------------------------
- void Controller::BindProfile(InputProfile const& setup)
- {
- ASSERT(!setup.IsEmpty());
-
- m_mutex.lock();
- m_profile = setup;
-
- m_keys.resize(m_profile.GetKeyCount());
- m_axis.resize(m_profile.GetAxisCount());
-
- //Keyboard
- m_keyboard = InputDevice::GetKeyboard();
- if (m_keyboard)
- {
- for (InputProfile::Keyboard& key : m_profile.m_keys)
- GetKey(key.m_idx).BindKeyboard(key.m_name);
- }
-
- //Mouse
- m_mouse = InputDevice::GetMouse();
- if (m_mouse)
- {
- for (InputProfile::MouseKey& key : m_profile.m_mouse_keys)
- GetKey(key.m_idx).BindMouse(key.m_name);
- for (InputProfile::MouseAxis& axis : m_profile.m_mouse_axis)
- GetAxis(axis.m_idx).BindMouse(axis.m_name);
- }
-
- //Joystick
- for (uint64_t joy_idx : m_profile.m_joystick)
- {
- class InputDevice* joystick = InputDevice::GetJoystick(joy_idx);
- if (joystick)
- {
- m_joystick << joystick;
- m_joystick_idx << joy_idx;
- }
- }
- for (InputProfile::JoystickKey& key : m_profile.m_joystick_keys)
- {
- if (m_joystick_idx.find(key.m_joy) != INDEX_NONE)
- GetKey(key.m_idx).BindJoystick(key.m_joy, key.m_name);
- }
- for (InputProfile::JoystickAxis& axis : m_profile.m_joystick_axis)
- {
- if (m_joystick_idx.find(axis.m_joy) != INDEX_NONE)
- GetAxis(axis.m_idx).BindJoystick(axis.m_joy, axis.m_name);
- }
-
- m_mutex.unlock();
- }
-
- //-----------------------------------------------------------------------------
- void Controller::tick_game(float seconds)
- {
- Entity::tick_game(seconds);
-
- if (m_active)
- {
- for (int i = 0; i < m_keys.count(); ++i)
- m_keys[i].Update();
-
- for (int i = 0; i < m_axis.count(); ++i)
- m_axis[i].Update();
- }
-
- if (m_activate_nextframe)
- m_active = true;
-
- if (m_deactivate_nextframe)
- m_active = false;
-
- m_activate_nextframe = false;
- m_deactivate_nextframe = false;
- }
-
- //-----------------------------------------------------------------------------
- void Controller::Activate()
- {
- m_activate_nextframe = true;
- m_deactivate_nextframe = false;
- }
-
- void Controller::Deactivate()
- {
- m_deactivate_nextframe = true;
- m_activate_nextframe = false;
- }
-
- //-----------------------------------------------------------------------------
- array<Controller*> Controller::DeactivateAll()
- {
- array<Controller*> result;
-
- for (int i = 0; i < controllers.count(); ++i)
- {
- if (controllers[i]->m_active || controllers[i]->m_activate_nextframe)
- {
- result.push(controllers[i]);
- controllers[i]->Deactivate();
- }
- }
-
- return result;
- }
-
- } /* namespace lol */
|