aboutsummaryrefslogtreecommitdiff
path: root/src
Commit message (Expand)AuthorAge
...
* Add cloud menu background by Krisi, configurable with the menu_clouds option.ShadowNinja2013-03-13
* fix typo invalid for loop endsapier2013-03-13
* Clean up Mapgenkwolekr2013-03-11
* Move l_get_all_craft_recipes to scriptapi_craftsapier2013-03-11
* Migrate to STL containers/algorithms.Ilya Zhuravlev2013-03-11
* Re-add dungeons in new dungeongen.cppkwolekr2013-03-10
* Fix Irrlicht includes in scriptapi_*kwolekr2013-03-06
* fix link if system json lib existsproller2013-03-05
* Added method to get all registered recipes for item(node)RealBadAngel2013-03-05
* Allow any character in formspec strings with escape charkwolekr2013-03-05
* split scriptapi.cppsapier2013-03-05
* Add one more curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);Ilya Zhuravlev2013-03-03
* Fix "longjmp causes uninitialized stack frame" (serverlist.cpp)Ilya Zhuravlev2013-03-01
* Change default settings for log level, texture atlas, document new settingskwolekr2013-02-27
* Fix nodeplacement predictionPilzAdam2013-02-27
* Fix most warnings, re-fix MSVC compile errorkwolekr2013-02-26
* Merge pull request #482 from proller/liquidkwolekr2013-02-25
|\
| * new adjustable finite liquidproller2013-02-24
* | Remove dead code, relocate some codekwolekr2013-02-25
* | Fix selection of # threads, set default to 1 threadkwolekr2013-02-25
* | Fix build on Windowskwolekr2013-02-25
* | Fix most walled-off caveskwolekr2013-02-25
* | Tune queue limits, some other adjustmentskwolekr2013-02-25
* | Misc. cleanup and minor fixeskwolekr2013-02-25
* | Add multi-Emerge thread supportkwolekr2013-02-25
* | Add emerge queue limit configurationkwolekr2013-02-25
* | Fix EmergeThread hang on exitkwolekr2013-02-25
* | Add global and per-peer queue limitskwolekr2013-02-25
* | Add emerge.cpp, initial EmergeThread changeskwolekr2013-02-25
* | Update Copyright YearsSfan52013-02-24
* | Change Minetest-c55 to MinetestPilzAdam2013-02-24
|/
* Add seed parameter for default and L-system treesRealBadAngel2013-02-24
* Merge pull request #503 from RealBadAngel/masterkwolekr2013-02-23
|\
| * Add sound volume controls to ingame menuRealBadAngel2013-02-23
* | Read server_announce from minetest.conf for GUIPilzAdam2013-02-23
|/
* Merge pull request #431 from sapier/dtime_clampingkwolekr2013-02-22
|\
| * add limit for steps to avoid runaway memory consumption by collision handlingsapier2013-01-16
* | Added debug log level settingkwolekr2013-02-21
* | Fix json includeIlya Zhuravlev2013-02-22
* | new auto masterserverproller2013-02-22
* | Print missing mod dependencies on server startJürgen Doser2013-02-20
* | Disable placement prediction for nodes that use on_rightclickJeija2013-02-19
* | Merge pull request #465 from doserj/mod_selection_empty_modname_fixkwolekr2013-02-15
|\ \
| * | Remove use of operator[] on a std::map, so no spurious elements get inserted....Jürgen Doser2013-02-01
* | | Some kind of middleway values for player acceleration for nowPerttu Ahola2013-02-15
* | | Restore old acceleration behavior until something is actually agreed on (part 2)Perttu Ahola2013-02-15
* | | Restore old acceleration behavior until something is actually agreed onPerttu Ahola2013-02-15
* | | Add Freetype supportIlya Zhuravlev2013-02-14
* | | Improved Player PhysicsMirceaKitsune2013-02-14
* | | Server requires gettext library as wellDmitry Marakasov2013-02-12
#include "keycode.h" #include "renderingengine.h" #ifdef HAVE_TOUCHSCREENGUI #include "gui/touchscreengui.h" #endif class InputHandler; /**************************************************************************** Fast key cache for main game loop ****************************************************************************/ /* This is faster than using getKeySetting with the tradeoff that functions * using it must make sure that it's initialised before using it and there is * no error handling (for example bounds checking). This is really intended for * use only in the main running loop of the client (the_game()) where the faster * (up to 10x faster) key lookup is an asset. Other parts of the codebase * (e.g. formspecs) should continue using getKeySetting(). */ struct KeyCache { KeyCache() { handler = NULL; populate(); populate_nonchanging(); } void populate(); // Keys that are not settings dependent void populate_nonchanging(); KeyPress key[KeyType::INTERNAL_ENUM_COUNT]; InputHandler *handler; }; class KeyList : private std::list<KeyPress> { typedef std::list<KeyPress> super; typedef super::iterator iterator; typedef super::const_iterator const_iterator; virtual const_iterator find(const KeyPress &key) const { const_iterator f(begin()); const_iterator e(end()); while (f != e) { if (*f == key) return f; ++f; } return e; } virtual iterator find(const KeyPress &key) { iterator f(begin()); iterator e(end()); while (f != e) { if (*f == key) return f; ++f; } return e; } public: void clear() { super::clear(); } void set(const KeyPress &key) { if (find(key) == end()) push_back(key); } void unset(const KeyPress &key) { iterator p(find(key)); if (p != end()) erase(p); } void toggle(const KeyPress &key) { iterator p(this->find(key)); if (p != end()) erase(p); else push_back(key); } bool operator[](const KeyPress &key) const { return find(key) != end(); } }; class MyEventReceiver : public IEventReceiver { public: // This is the one method that we have to implement virtual bool OnEvent(const SEvent &event); bool IsKeyDown(const 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); 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]; } // 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]; } void listenForKey(const KeyPress &keyCode) { keysListenedFor.set(keyCode); } void dontListenForKeys() { keysListenedFor.clear(); } s32 getMouseWheel() { s32 a = mouse_wheel; mouse_wheel = 0; return a; } void clearInput() { keyIsDown.clear(); keyWasDown.clear(); keyWasPressed.clear(); keyWasReleased.clear(); mouse_wheel = 0; } void clearWasKeyPressed() { keyWasPressed.clear(); } void clearWasKeyReleased() { keyWasReleased.clear(); } MyEventReceiver() { #ifdef HAVE_TOUCHSCREENGUI m_touchscreengui = NULL; #endif } JoystickController *joystick = nullptr; #ifdef HAVE_TOUCHSCREENGUI TouchScreenGUI *m_touchscreengui; #endif private: s32 mouse_wheel = 0; // The current state of keys KeyList keyIsDown; // Like keyIsDown but only reset when that key is read KeyList keyWasDown; // Whether a key has just been pressed KeyList keyWasPressed; // Whether a key has just been released KeyList keyWasReleased; // List of keys we listen for // TODO perhaps the type of this is not really // performant as KeyList is designed for few but // often changing keys, and keysListenedFor is expected // to change seldomly but contain lots of keys. KeyList keysListenedFor; }; class InputHandler { public: InputHandler() { keycache.handler = this; keycache.populate(); } virtual ~InputHandler() = default; virtual bool isRandom() const { return false; } virtual bool isKeyDown(GameKeyType k) = 0; virtual bool wasKeyDown(GameKeyType k) = 0; virtual bool wasKeyPressed(GameKeyType k) = 0; virtual bool wasKeyReleased(GameKeyType k) = 0; virtual bool cancelPressed() = 0; virtual float getMovementSpeed() = 0; virtual float getMovementDirection() = 0; virtual void clearWasKeyPressed() {} virtual void clearWasKeyReleased() {} virtual void listenForKey(const KeyPress &keyCode) {} virtual void dontListenForKeys() {} virtual v2s32 getMousePos() = 0; virtual void setMousePos(s32 x, s32 y) = 0; virtual s32 getMouseWheel() = 0; virtual void step(float dtime) {} virtual void clear() {} JoystickController joystick; KeyCache keycache; }; /* Separated input handler */ class RealInputHandler : public InputHandler { public: RealInputHandler(MyEventReceiver *receiver) : m_receiver(receiver) { m_receiver->joystick = &joystick; } virtual ~RealInputHandler() { m_receiver->joystick = nullptr; } virtual bool isKeyDown(GameKeyType k) { return m_receiver->IsKeyDown(keycache.key[k]) || joystick.isKeyDown(k); } virtual bool wasKeyDown(GameKeyType k) { return m_receiver->WasKeyDown(keycache.key[k]) || joystick.wasKeyDown(k); } virtual bool wasKeyPressed(GameKeyType k) { return m_receiver->WasKeyPressed(keycache.key[k]) || joystick.wasKeyPressed(k); } virtual bool wasKeyReleased(GameKeyType k) { return m_receiver->WasKeyReleased(keycache.key[k]) || joystick.wasKeyReleased(k); } virtual float getMovementSpeed() { bool f = m_receiver->IsKeyDown(keycache.key[KeyType::FORWARD]), b = m_receiver->IsKeyDown(keycache.key[KeyType::BACKWARD]), l = m_receiver->IsKeyDown(keycache.key[KeyType::LEFT]), r = m_receiver->IsKeyDown(keycache.key[KeyType::RIGHT]); if (f || b || l || r) { // if contradictory keys pressed, stay still if (f && b && l && r) return 0.0f; else if (f && b && !l && !r) return 0.0f; else if (!f && !b && l && r) return 0.0f; return 1.0f; // If there is a keyboard event, assume maximum speed } return joystick.getMovementSpeed(); } virtual float getMovementDirection() { float x = 0, z = 0; /* Check keyboard for input */ if (m_receiver->IsKeyDown(keycache.key[KeyType::FORWARD])) z += 1; if (m_receiver->IsKeyDown(keycache.key[KeyType::BACKWARD])) z -= 1; if (m_receiver->IsKeyDown(keycache.key[KeyType::RIGHT])) x += 1; if (m_receiver->IsKeyDown(keycache.key[KeyType::LEFT])) x -= 1; if (x != 0 || z != 0) /* If there is a keyboard event, it takes priority */ return atan2(x, z); else return joystick.getMovementDirection(); } virtual bool cancelPressed() { return wasKeyDown(KeyType::ESC) || m_receiver->WasKeyDown(CancelKey); } virtual void clearWasKeyPressed() { m_receiver->clearWasKeyPressed(); } virtual void clearWasKeyReleased() { m_receiver->clearWasKeyReleased(); } virtual void listenForKey(const KeyPress &keyCode) { m_receiver->listenForKey(keyCode); } virtual void dontListenForKeys() { m_receiver->dontListenForKeys(); } virtual v2s32 getMousePos() { auto control = RenderingEngine::get_raw_device()->getCursorControl(); if (control) { return control->getPosition(); } return m_mousepos; } virtual void setMousePos(s32 x, s32 y) { auto control = RenderingEngine::get_raw_device()->getCursorControl(); if (control) { control->setPosition(x, y); } else { m_mousepos = v2s32(x, y); } } virtual s32 getMouseWheel() { return m_receiver->getMouseWheel(); } void clear() { joystick.clear(); m_receiver->clearInput(); } private: MyEventReceiver *m_receiver = nullptr; v2s32 m_mousepos; }; class RandomInputHandler : public InputHandler { public: RandomInputHandler() = default; bool isRandom() const { return true; } virtual bool isKeyDown(GameKeyType k) { return keydown[keycache.key[k]]; } virtual bool wasKeyDown(GameKeyType k) { return false; } virtual bool wasKeyPressed(GameKeyType k) { return false; } virtual bool wasKeyReleased(GameKeyType k) { return false; } virtual bool cancelPressed() { return false; } virtual float getMovementSpeed() { return movementSpeed; } virtual float getMovementDirection() { return movementDirection; } virtual v2s32 getMousePos() { return mousepos; } virtual void setMousePos(s32 x, s32 y) { mousepos = v2s32(x, y); } virtual s32 getMouseWheel() { return 0; } virtual void step(float dtime); s32 Rand(s32 min, s32 max); private: KeyList keydown; v2s32 mousepos; v2s32 mousespeed; float movementSpeed; float movementDirection; };