--- a/src/Input.cc Mon Dec 08 22:23:14 2008 +0000
+++ b/src/Input.cc Mon Dec 08 22:28:51 2008 +0000
@@ -1,21 +1,22 @@
#include "Input.hh"
+#include "Engine.hh"
#include "Config.hh"
InputKeymapEntry<PlayerInputBit> INPUT_PLAYER_KEYMAP[] = {
- { INPUT_AIM_UP, INPUT_FLAG_REPEAT, { -CL_KEY_ENTER, CL_KEY_UP } },
- { INPUT_AIM_DOWN, INPUT_FLAG_REPEAT, { -CL_KEY_ENTER, CL_KEY_DOWN } },
- { INPUT_MOVE_LEFT, INPUT_FLAG_REPEAT, { -CL_KEY_ENTER, CL_KEY_LEFT } },
- { INPUT_MOVE_RIGHT, INPUT_FLAG_REPEAT, { -CL_KEY_ENTER, CL_KEY_RIGHT } },
- { INPUT_JUMP, INPUT_FLAG_NOREPEAT, { -CL_KEY_ENTER, CL_KEY_RSHIFT } },
+ { INPUT_AIM_UP, INPUT_FLAG_UNLIMITED, { -CL_KEY_ENTER, CL_KEY_UP } },
+ { INPUT_AIM_DOWN, INPUT_FLAG_UNLIMITED, { -CL_KEY_ENTER, CL_KEY_DOWN } },
+ { INPUT_MOVE_LEFT, INPUT_FLAG_UNLIMITED, { -CL_KEY_ENTER, CL_KEY_LEFT } },
+ { INPUT_MOVE_RIGHT, INPUT_FLAG_UNLIMITED, { -CL_KEY_ENTER, CL_KEY_RIGHT } },
+ { INPUT_JUMP, INPUT_FLAG_SLOWREPEAT, { -CL_KEY_ENTER, CL_KEY_RSHIFT } },
{ INPUT_DIG, INPUT_FLAG_NOREPEAT, { CL_KEY_LEFT, CL_KEY_RIGHT } },
- { INPUT_SHOOT, INPUT_FLAG_REPEAT, { CL_KEY_RCONTROL, 0 } },
- { INPUT_CHANGE_PREV, INPUT_FLAG_NOREPEAT, { CL_KEY_ENTER, CL_KEY_LEFT } },
- { INPUT_CHANGE_NEXT, INPUT_FLAG_NOREPEAT, { CL_KEY_ENTER, CL_KEY_RIGHT } },
+ { INPUT_SHOOT, INPUT_FLAG_UNLIMITED, { CL_KEY_RCONTROL, 0 } },
+ { INPUT_CHANGE_PREV, INPUT_FLAG_SLOWREPEAT, { CL_KEY_ENTER, CL_KEY_LEFT } },
+ { INPUT_CHANGE_NEXT, INPUT_FLAG_SLOWREPEAT, { CL_KEY_ENTER, CL_KEY_RIGHT } },
{ INPUT_ROPE, INPUT_FLAG_NOREPEAT, { CL_KEY_ENTER, CL_KEY_RSHIFT } },
- { INPUT_UNROPE, INPUT_FLAG_NOREPEAT, { -CL_KEY_ENTER, CL_KEY_RSHIFT } },
- { INPUT_ROPE_UP, INPUT_FLAG_REPEAT, { CL_KEY_ENTER, CL_KEY_UP } },
- { INPUT_ROPE_DOWN, INPUT_FLAG_REPEAT, { CL_KEY_ENTER, CL_KEY_DOWN } },
+ { INPUT_UNROPE, INPUT_FLAG_SLOWREPEAT, { -CL_KEY_ENTER, CL_KEY_RSHIFT } },
+ { INPUT_ROPE_UP, INPUT_FLAG_UNLIMITED, { CL_KEY_ENTER, CL_KEY_UP } },
+ { INPUT_ROPE_DOWN, INPUT_FLAG_UNLIMITED, { CL_KEY_ENTER, CL_KEY_DOWN } },
{ INPUT_SUICIDE, INPUT_FLAG_NOREPEAT, { CL_KEY_LCONTROL, CL_KEY_K } },
{ INPUT_NONE, 0, { 0, 0 } }
};
@@ -44,6 +45,9 @@
template <typename BitEnumType>
bool InputKeyRepeatEntry<BitEnumType>::updateExpired (TimeMS dt) {
+ if (expire == 0)
+ return false;
+
expire -= dt;
return (expire <= 0);
@@ -60,8 +64,21 @@
}
template <typename BitEnumType>
-void InputKeyRepeatQueue<BitEnumType>::push (BitEnumType bit) {
- list.push_back(InputKeyRepeatEntry<BitEnumType>(bit, expire));
+void InputKeyRepeatQueue<BitEnumType>::push (BitEnumType bit, bool expire) {
+ list.push_back(InputKeyRepeatEntry<BitEnumType>(bit, expire ? this->expire : 0));
+}
+
+template <typename BitEnumType>
+void InputKeyRepeatQueue<BitEnumType>::forget (BitEnumType bit) {
+ // go through the list, looking for it
+ for (list_iterator it = list.begin(); it != list.end(); it++) {
+ if (it->value == bit) {
+ // found, erase it and return
+ list.erase(it);
+
+ return;
+ }
+ }
}
template <typename BitEnumType>
@@ -95,6 +112,7 @@
keyboard(keyboard),
keymap(keymap),
value(0),
+ prev_value(0),
dt(0),
queue(keyrepeat_expire)
{
@@ -125,6 +143,9 @@
template <typename BitEnumType, typename BitMaskType>
void InputHandler<BitEnumType, BitMaskType>::update (TimeMS dt) {
+ // all bits that are held down, even those ignored
+ BitMaskType raw_value = 0;
+
// update the key-repeat queue
queue.update(dt);
@@ -132,20 +153,41 @@
for (InputKeymapEntry<BitEnumType> *e = keymap; e->input != 0; e++) {
// check if we've got the correct keycodes
if (checkKeycode(e->keycodes[0]) && checkKeycode(e->keycodes[1])) {
- // should we do keyrepeats?
- if (e->flags & INPUT_FLAG_NOREPEAT) {
- // if it's in the queue, ignore, else add it
- if (queue.find(e->input))
+ // set raw_value
+ raw_value |= e->input;
+
+ if (e->flags & INPUT_FLAG_SLOWREPEAT) {
+ // repeat, but slowly
+ if (!(prev_value & e->input)) {
+ // we've released the key earlier, move it to the back of the queue
+ queue.forget(e->input);
+ queue.push(e->input);
+
+ } else if (queue.find(e->input)) {
+ // it's still in the queue, so ignore, but set it in ignore_value
continue;
- else
+
+ } else {
+ // ok, but add it to the queue
queue.push(e->input);
+ }
+
+ } else if (e->flags & INPUT_FLAG_NOREPEAT) {
+ // do not repeat at all
+ if (prev_value & e->input) {
+ // ignore repeats
+ continue;
+ }
}
- // set bit in mask
+ // set bit in masks
this->value |= e->input;
}
}
+ // update prev_value, also adding ignored values
+ prev_value = raw_value;
+
// then increment our dt
this->dt += dt;
}
--- a/src/Input.hh Mon Dec 08 22:23:14 2008 +0000
+++ b/src/Input.hh Mon Dec 08 22:28:51 2008 +0000
@@ -15,8 +15,21 @@
*/
enum InputFlagBits {
/** Default */
- INPUT_FLAG_REPEAT = 0x0000,
- INPUT_FLAG_NOREPEAT = 0x0001,
+
+ /**
+ * The bit is not limited, i.e. it is set every time if it's present
+ */
+ INPUT_FLAG_UNLIMITED = 0x0000,
+
+ /**
+ * The bit is repeat-limited using INPUT_REPEAT_DELAY
+ */
+ INPUT_FLAG_SLOWREPEAT = 0x0001,
+
+ /**
+ * The bit is repeat-limited using an infinite delay, i.e. you must release the key to trigger it again
+ */
+ INPUT_FLAG_NOREPEAT = 0x0002,
};
/**
@@ -104,6 +117,10 @@
*/
template <typename BitEnumType> struct InputKeyRepeatEntry {
BitEnumType value;
+
+ /**
+ * The remaining expire time. If this is zero, it never expires
+ */
TimeMS expire;
public:
@@ -115,7 +132,8 @@
bool operator< (const struct InputKeyRepeatEntry &other);
/**
- * Decrements expire, returning true if it has now expired, false otherwise
+ * Decrements expire, returning true if it has now expired, false otherwise. Always returns false if expire is
+ * zero.
*/
bool updateExpired (TimeMS dt);
};
@@ -141,9 +159,17 @@
InputKeyRepeatQueue (TimeMS expire);
/**
- * Push a new input bit onto the queue
+ * Push a new input bit onto the queue.
+ *
+ * If expire is true, the bit will automatically expire after our expire time, otherwise, it iwll never expire
+ * until forget()'d
*/
- void push (BitEnumType bit);
+ void push (BitEnumType bit, bool expire = true);
+
+ /**
+ * Remove any entry for the given bit
+ */
+ void forget (BitEnumType bit);
/**
* Checks if the given input is in the queue
@@ -177,6 +203,11 @@
BitMaskType value;
/**
+ * The previous value, used to detect key-up. This also includes keys that were filtered out
+ */
+ BitMaskType prev_value;
+
+ /**
* How long the bitmask was held...
*/
TimeMS dt;