aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCraig Robbins <kde.psych@gmail.com>2014-11-10 12:26:19 +1000
committerCraig Robbins <kde.psych@gmail.com>2014-11-10 12:26:19 +1000
commit987e565eeb80f0fe2825267de728f8a1989a051d (patch)
tree27e39b75fe16e5aa58e1847f2b769a7f437c2429
parent18c583ee0b7548d5ea5d5ccd3085008d94620e5c (diff)
downloadminetest-987e565eeb80f0fe2825267de728f8a1989a051d.tar.gz
minetest-987e565eeb80f0fe2825267de728f8a1989a051d.tar.bz2
minetest-987e565eeb80f0fe2825267de728f8a1989a051d.zip
Create faster key cache for main game loop (client)
-rw-r--r--src/game.cpp231
-rw-r--r--src/guiKeyChangeMenu.cpp8
-rw-r--r--src/mainmenumanager.h11
-rw-r--r--src/quicktune_shortcutter.h5
4 files changed, 202 insertions, 53 deletions
diff --git a/src/game.cpp b/src/game.cpp
index fee45e31d..1396e9439 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -1181,9 +1181,119 @@ static void updateChat(Client &client, f32 dtime, bool show_debug,
}
+/****************************************************************************
+ 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() { populate(); }
+
+ enum {
+ // Player movement
+ KEYMAP_ID_FORWARD,
+ KEYMAP_ID_BACKWARD,
+ KEYMAP_ID_LEFT,
+ KEYMAP_ID_RIGHT,
+ KEYMAP_ID_JUMP,
+ KEYMAP_ID_SPECIAL1,
+ KEYMAP_ID_SNEAK,
+
+ // Other
+ KEYMAP_ID_DROP,
+ KEYMAP_ID_INVENTORY,
+ KEYMAP_ID_CHAT,
+ KEYMAP_ID_CMD,
+ KEYMAP_ID_CONSOLE,
+ KEYMAP_ID_FREEMOVE,
+ KEYMAP_ID_FASTMOVE,
+ KEYMAP_ID_NOCLIP,
+ KEYMAP_ID_SCREENSHOT,
+ KEYMAP_ID_TOGGLE_HUD,
+ KEYMAP_ID_TOGGLE_CHAT,
+ KEYMAP_ID_TOGGLE_FORCE_FOG_OFF,
+ KEYMAP_ID_TOGGLE_UPDATE_CAMERA,
+ KEYMAP_ID_TOGGLE_DEBUG,
+ KEYMAP_ID_TOGGLE_PROFILER,
+ KEYMAP_ID_CAMERA_MODE,
+ KEYMAP_ID_INCREASE_VIEWING_RANGE,
+ KEYMAP_ID_DECREASE_VIEWING_RANGE,
+ KEYMAP_ID_RANGESELECT,
+
+ KEYMAP_ID_QUICKTUNE_NEXT,
+ KEYMAP_ID_QUICKTUNE_PREV,
+ KEYMAP_ID_QUICKTUNE_INC,
+ KEYMAP_ID_QUICKTUNE_DEC,
+
+ KEYMAP_ID_DEBUG_STACKS,
+
+ // Fake keycode for array size and internal checks
+ KEYMAP_INTERNAL_ENUM_COUNT
+
+
+ };
+
+ void populate();
+
+ KeyPress key[KEYMAP_INTERNAL_ENUM_COUNT];
+};
+
+void KeyCache::populate()
+{
+ key[KEYMAP_ID_FORWARD] = getKeySetting("keymap_forward");
+ key[KEYMAP_ID_BACKWARD] = getKeySetting("keymap_backward");
+ key[KEYMAP_ID_LEFT] = getKeySetting("keymap_left");
+ key[KEYMAP_ID_RIGHT] = getKeySetting("keymap_right");
+ key[KEYMAP_ID_JUMP] = getKeySetting("keymap_jump");
+ key[KEYMAP_ID_SPECIAL1] = getKeySetting("keymap_special1");
+ key[KEYMAP_ID_SNEAK] = getKeySetting("keymap_sneak");
+
+ key[KEYMAP_ID_DROP] = getKeySetting("keymap_drop");
+ key[KEYMAP_ID_INVENTORY] = getKeySetting("keymap_inventory");
+ key[KEYMAP_ID_CHAT] = getKeySetting("keymap_chat");
+ key[KEYMAP_ID_CMD] = getKeySetting("keymap_cmd");
+ key[KEYMAP_ID_CONSOLE] = getKeySetting("keymap_console");
+ key[KEYMAP_ID_FREEMOVE] = getKeySetting("keymap_freemove");
+ key[KEYMAP_ID_FASTMOVE] = getKeySetting("keymap_fastmove");
+ key[KEYMAP_ID_NOCLIP] = getKeySetting("keymap_noclip");
+ key[KEYMAP_ID_SCREENSHOT] = getKeySetting("keymap_screenshot");
+ key[KEYMAP_ID_TOGGLE_HUD] = getKeySetting("keymap_toggle_hud");
+ key[KEYMAP_ID_TOGGLE_CHAT] = getKeySetting("keymap_toggle_chat");
+ key[KEYMAP_ID_TOGGLE_FORCE_FOG_OFF]
+ = getKeySetting("keymap_toggle_force_fog_off");
+ key[KEYMAP_ID_TOGGLE_UPDATE_CAMERA]
+ = getKeySetting("keymap_toggle_update_camera");
+ key[KEYMAP_ID_TOGGLE_DEBUG]
+ = getKeySetting("keymap_toggle_debug");
+ key[KEYMAP_ID_TOGGLE_PROFILER]
+ = getKeySetting("keymap_toggle_profiler");
+ key[KEYMAP_ID_CAMERA_MODE]
+ = getKeySetting("keymap_camera_mode");
+ key[KEYMAP_ID_INCREASE_VIEWING_RANGE]
+ = getKeySetting("keymap_increase_viewing_range_min");
+ key[KEYMAP_ID_DECREASE_VIEWING_RANGE]
+ = getKeySetting("keymap_decrease_viewing_range_min");
+ key[KEYMAP_ID_RANGESELECT]
+ = getKeySetting("keymap_rangeselect");
+
+ key[KEYMAP_ID_QUICKTUNE_NEXT] = getKeySetting("keymap_quicktune_next");
+ key[KEYMAP_ID_QUICKTUNE_PREV] = getKeySetting("keymap_quicktune_prev");
+ key[KEYMAP_ID_QUICKTUNE_INC] = getKeySetting("keymap_quicktune_inc");
+ key[KEYMAP_ID_QUICKTUNE_DEC] = getKeySetting("keymap_quicktune_dec");
+
+ key[KEYMAP_ID_DEBUG_STACKS] = getKeySetting("keymap_print_debug_stacks");
+}
+
/****************************************************************************
- THE GAME
+
****************************************************************************/
const float object_hit_delay = 0.2;
@@ -1264,6 +1374,10 @@ struct VolatileRunFlags {
};
+/****************************************************************************
+ THE GAME
+ ****************************************************************************/
+
/* This is not intended to be a public class. If a public class becomes
* desirable then it may be better to create another 'wrapper' class that
* hides most of the stuff in this class (nothing in this class is required
@@ -1458,6 +1572,8 @@ private:
std::wstring infotext;
std::wstring statustext;
+
+ KeyCache keycache;
};
Game::Game() :
@@ -2186,6 +2302,11 @@ inline bool Game::handleCallbacks()
g_gamecallback->keyconfig_requested = false;
}
+ if (g_gamecallback->keyconfig_changed) {
+ keycache.populate(); // update the cache with new settings
+ g_gamecallback->keyconfig_changed = false;
+ }
+
return true;
}
@@ -2322,70 +2443,63 @@ void Game::processKeyboardInput(VolatileRunFlags *flags,
u32 *profiler_current_page,
u32 profiler_max_page)
{
- if (input->wasKeyDown(getKeySetting("keymap_drop"))) {
+
+ //TimeTaker tt("process kybd input", NULL, PRECISION_NANO);
+
+ if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_DROP])) {
dropSelectedItem();
- } else if (input->wasKeyDown(getKeySetting("keymap_inventory"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_INVENTORY])) {
openInventory();
} else if (input->wasKeyDown(EscapeKey) || input->wasKeyDown(CancelKey)) {
show_pause_menu(&current_formspec, client, gamedef, texture_src, device,
simple_singleplayer_mode);
- } else if (input->wasKeyDown(getKeySetting("keymap_chat"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_CHAT])) {
show_chat_menu(&current_formspec, client, gamedef, texture_src, device,
client, "");
- } else if (input->wasKeyDown(getKeySetting("keymap_cmd"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_CMD])) {
show_chat_menu(&current_formspec, client, gamedef, texture_src, device,
client, "/");
- } else if (input->wasKeyDown(getKeySetting("keymap_console"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_CONSOLE])) {
openConsole();
- } else if (input->wasKeyDown(getKeySetting("keymap_freemove"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_FREEMOVE])) {
toggleFreeMove(statustext_time);
- } else if (input->wasKeyDown(getKeySetting("keymap_jump"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_JUMP])) {
toggleFreeMoveAlt(statustext_time, jump_timer);
*reset_jump_timer = true;
- } else if (input->wasKeyDown(getKeySetting("keymap_fastmove"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_FASTMOVE])) {
toggleFast(statustext_time);
- } else if (input->wasKeyDown(getKeySetting("keymap_noclip"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_NOCLIP])) {
toggleNoClip(statustext_time);
- } else if (input->wasKeyDown(getKeySetting("keymap_screenshot"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_SCREENSHOT])) {
client->makeScreenshot(device);
- } else if (input->wasKeyDown(getKeySetting("keymap_toggle_hud"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_TOGGLE_HUD])) {
toggleHud(statustext_time, &flags->show_hud);
- } else if (input->wasKeyDown(getKeySetting("keymap_toggle_chat"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_TOGGLE_CHAT])) {
toggleChat(statustext_time, &flags->show_chat);
- } else if (input->wasKeyDown(getKeySetting("keymap_toggle_force_fog_off"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_TOGGLE_FORCE_FOG_OFF])) {
toggleFog(statustext_time, &flags->force_fog_off);
- } else if (input->wasKeyDown(getKeySetting("keymap_toggle_update_camera"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_TOGGLE_UPDATE_CAMERA])) {
toggleUpdateCamera(statustext_time, &flags->disable_camera_update);
- } else if (input->wasKeyDown(getKeySetting("keymap_toggle_debug"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_TOGGLE_DEBUG])) {
toggleDebug(statustext_time, &flags->show_debug, &flags->show_profiler_graph);
- } else if (input->wasKeyDown(getKeySetting("keymap_toggle_profiler"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_TOGGLE_PROFILER])) {
toggleProfiler(statustext_time, profiler_current_page, profiler_max_page);
- } else if (input->wasKeyDown(getKeySetting("keymap_increase_viewing_range_min"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_INCREASE_VIEWING_RANGE])) {
increaseViewRange(statustext_time);
- } else if (input->wasKeyDown(getKeySetting("keymap_decrease_viewing_range_min"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_DECREASE_VIEWING_RANGE])) {
decreaseViewRange(statustext_time);
- } else if (input->wasKeyDown(getKeySetting("keymap_rangeselect"))) {
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_RANGESELECT])) {
toggleFullViewRange(statustext_time);
- }
-
- // Handle QuicktuneShortcutter
- if (input->wasKeyDown(getKeySetting("keymap_quicktune_next")))
+ } else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_QUICKTUNE_NEXT]))
quicktune->next();
- else if (input->wasKeyDown(getKeySetting("keymap_quicktune_prev")))
+ else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_QUICKTUNE_PREV]))
quicktune->prev();
- else if (input->wasKeyDown(getKeySetting("keymap_quicktune_inc")))
+ else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_QUICKTUNE_INC]))
quicktune->inc();
- else if (input->wasKeyDown(getKeySetting("keymap_quicktune_dec")))
+ else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_QUICKTUNE_DEC]))
quicktune->dec();
-
- std::string msg = quicktune->getMessage();
- if (msg != "") {
- statustext = narrow_to_wide(msg);
- *statustext_time = 0;
- }
-
- // Print debug stacks
- if (input->wasKeyDown(getKeySetting("keymap_print_debug_stacks"))) {
+ else if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_DEBUG_STACKS])) {
+ // Print debug stacks
dstream << "-----------------------------------------"
<< std::endl;
dstream << DTIME << "Printing debug stacks:" << std::endl;
@@ -2398,6 +2512,14 @@ void Game::processKeyboardInput(VolatileRunFlags *flags,
*reset_jump_timer = false;
*jump_timer = 0.0;
}
+
+ //tt.stop();
+
+ if (quicktune->hasMessage()) {
+ std::string msg = quicktune->getMessage();
+ statustext = narrow_to_wide(msg);
+ *statustext_time = 0;
+ }
}
@@ -2730,14 +2852,16 @@ void Game::updateCameraDirection(CameraOrientation *cam,
void Game::updatePlayerControl(const CameraOrientation &cam)
{
+ //TimeTaker tt("update player control", NULL, PRECISION_NANO);
+
PlayerControl control(
- input->isKeyDown(getKeySetting("keymap_forward")),
- input->isKeyDown(getKeySetting("keymap_backward")),
- input->isKeyDown(getKeySetting("keymap_left")),
- input->isKeyDown(getKeySetting("keymap_right")),
- input->isKeyDown(getKeySetting("keymap_jump")),
- input->isKeyDown(getKeySetting("keymap_special1")),
- input->isKeyDown(getKeySetting("keymap_sneak")),
+ input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_FORWARD]),
+ input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_BACKWARD]),
+ input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_LEFT]),
+ input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_RIGHT]),
+ input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_JUMP]),
+ input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_SPECIAL1]),
+ input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_SNEAK]),
input->getLeftState(),
input->getRightState(),
cam.camera_pitch,
@@ -2746,17 +2870,18 @@ void Game::updatePlayerControl(const CameraOrientation &cam)
client->setPlayerControl(control);
LocalPlayer *player = client->getEnv().getLocalPlayer();
player->keyPressed =
- ( (u32)(input->isKeyDown(getKeySetting("keymap_forward")) & 0x1) << 0) |
- ( (u32)(input->isKeyDown(getKeySetting("keymap_backward")) & 0x1) << 1) |
- ( (u32)(input->isKeyDown(getKeySetting("keymap_left")) & 0x1) << 2) |
- ( (u32)(input->isKeyDown(getKeySetting("keymap_right")) & 0x1) << 3) |
- ( (u32)(input->isKeyDown(getKeySetting("keymap_jump")) & 0x1) << 4) |
- ( (u32)(input->isKeyDown(getKeySetting("keymap_special1")) & 0x1) << 5) |
- ( (u32)(input->isKeyDown(getKeySetting("keymap_sneak")) & 0x1) << 6) |
- ( (u32)(input->getLeftState() & 0x1) << 7) |
- ( (u32)(input->getRightState() & 0x1) << 8
+ ( (u32)(input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_FORWARD]) & 0x1) << 0) |
+ ( (u32)(input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_BACKWARD]) & 0x1) << 1) |
+ ( (u32)(input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_LEFT]) & 0x1) << 2) |
+ ( (u32)(input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_RIGHT]) & 0x1) << 3) |
+ ( (u32)(input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_JUMP]) & 0x1) << 4) |
+ ( (u32)(input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_SPECIAL1]) & 0x1) << 5) |
+ ( (u32)(input->isKeyDown(keycache.key[KeyCache::KEYMAP_ID_SNEAK]) & 0x1) << 6) |
+ ( (u32)(input->getLeftState() & 0x1) << 7) |
+ ( (u32)(input->getRightState() & 0x1) << 8
);
+ //tt.stop();
}
@@ -3042,7 +3167,7 @@ void Game::updateCamera(VolatileRunFlags *flags, u32 busy_time,
v3s16 old_camera_offset = camera->getOffset();
- if (input->wasKeyDown(getKeySetting("keymap_camera_mode"))) {
+ if (input->wasKeyDown(keycache.key[KeyCache::KEYMAP_ID_CAMERA_MODE])) {
camera->toggleCameraMode();
GenericCAO *playercao = player->getCAO();
diff --git a/src/guiKeyChangeMenu.cpp b/src/guiKeyChangeMenu.cpp
index 85222431e..8b0bb8278 100644
--- a/src/guiKeyChangeMenu.cpp
+++ b/src/guiKeyChangeMenu.cpp
@@ -32,8 +32,12 @@
#include "settings.h"
#include <algorithm>
+#include "mainmenumanager.h" // for g_gamecallback
+
#define KMaxButtonPerColumns 12
+extern MainGameCallback *g_gamecallback;
+
enum
{
GUI_ID_BACK_BUTTON = 101, GUI_ID_ABORT_BUTTON, GUI_ID_SCROLL_BAR,
@@ -234,7 +238,11 @@ bool GUIKeyChangeMenu::acceptInput()
if(e != NULL && e->getType() == gui::EGUIET_CHECK_BOX)
g_settings->setBool("doubletap_jump", ((gui::IGUICheckBox*)e)->isChecked());
}
+
clearKeyCache();
+
+ g_gamecallback->signalKeyConfigChange();
+
return true;
}
diff --git a/src/mainmenumanager.h b/src/mainmenumanager.h
index 56ba40129..db8aa9e19 100644
--- a/src/mainmenumanager.h
+++ b/src/mainmenumanager.h
@@ -35,6 +35,8 @@ public:
virtual void disconnect() = 0;
virtual void changePassword() = 0;
virtual void changeVolume() = 0;
+
+ virtual void signalKeyConfigChange() = 0;
};
extern gui::IGUIEnvironment* guienv;
@@ -127,6 +129,7 @@ public:
changevolume_requested(false),
keyconfig_requested(false),
shutdown_requested(false),
+ keyconfig_changed(false),
device(a_device)
{
}
@@ -159,12 +162,20 @@ public:
keyconfig_requested = true;
}
+ virtual void signalKeyConfigChange()
+ {
+ keyconfig_changed = true;
+ }
+
bool disconnect_requested;
bool changepassword_requested;
bool changevolume_requested;
bool keyconfig_requested;
bool shutdown_requested;
+
+ bool keyconfig_changed;
+
IrrlichtDevice *device;
};
diff --git a/src/quicktune_shortcutter.h b/src/quicktune_shortcutter.h
index 16bcc07e8..fe1463c93 100644
--- a/src/quicktune_shortcutter.h
+++ b/src/quicktune_shortcutter.h
@@ -29,6 +29,11 @@ private:
u32 m_selected_i;
std::string m_message;
public:
+ bool hasMessage()
+ {
+ return m_message != "";
+ }
+
std::string getMessage()
{
std::string s = m_message;