Add delayed key repeat

This commit is contained in:
Doyle Thai 2016-08-17 15:29:14 +10:00
parent 80b35d404d
commit 8aa23b7cfc
3 changed files with 62 additions and 25 deletions

View File

@ -360,25 +360,51 @@ enum ReadKeyType
readkeytype_count, readkeytype_count,
}; };
INTERNAL b32 getKeyStatus(KeyState key, enum ReadKeyType readType) #define KEY_DELAY_NONE 0.0f
INTERNAL b32 getKeyStatus(KeyState *key, enum ReadKeyType readType,
f32 delayInterval, f32 dt)
{ {
if (!key->endedDown) return FALSE;
switch(readType) switch(readType)
{ {
case readkeytype_oneShot: case readkeytype_oneShot:
{ {
if (key.endedDown && if (key->newHalfTransitionCount > key->oldHalfTransitionCount)
(key.newHalfTransitionCount > key.oldHalfTransitionCount))
return TRUE; return TRUE;
break; break;
} }
case readkeytype_repeat: case readkeytype_repeat:
case readkeytype_delayedRepeat:
{ {
if (key.endedDown) return TRUE; if (key->newHalfTransitionCount > key->oldHalfTransitionCount)
{
if (readType == readkeytype_delayedRepeat)
{
// TODO(doyle): Let user set arbitrary delay after initial input
key->delayInterval = 2 * delayInterval;
}
else
{
key->delayInterval = delayInterval;
}
return TRUE;
}
else if (key->delayInterval <= 0.0f)
{
key->delayInterval = delayInterval;
return TRUE;
}
else
{
key->delayInterval -= dt;
}
break; break;
} }
case readkeytype_delayedRepeat:
default: default:
// TODO(doyle): Add delayed repeat of keys DEBUG_LOG("getKeyStatus() error: Invalid ReadKeyType enum");
#ifdef DENGINE_DEBUG #ifdef DENGINE_DEBUG
ASSERT(INVALID_CODE_PATH); ASSERT(INVALID_CODE_PATH);
#endif #endif
@ -407,7 +433,7 @@ INTERNAL void parseInput(GameState *state, const f32 dt)
v2 ddPos = V2(0, 0); v2 ddPos = V2(0, 0);
KeyState *keys = state->input.keys; KeyState *keys = state->input.keys;
for (i32 i = 0; i < keycode_count; i++) for (enum KeyCode i = 0; i < keycode_count; i++)
{ {
KeyState *currKey = &keys[i]; KeyState *currKey = &keys[i];
if (currKey->newHalfTransitionCount > currKey->oldHalfTransitionCount) if (currKey->newHalfTransitionCount > currKey->oldHalfTransitionCount)
@ -415,43 +441,50 @@ INTERNAL void parseInput(GameState *state, const f32 dt)
i32 numTransitions = currKey->newHalfTransitionCount - i32 numTransitions = currKey->newHalfTransitionCount -
currKey->oldHalfTransitionCount; currKey->oldHalfTransitionCount;
if ((numTransitions & 1) == 1) if (!IS_EVEN(numTransitions))
{ {
currKey->endedDown = ~currKey->endedDown; currKey->endedDown = ~currKey->endedDown;
} }
// TODO(doyle): Multi press within frame override UI input parsing }
if ((i >= keycode_A && i <= keycode_Z) ||
(i >= keycode_a && i <= keycode_z)) // Parse ui input
// TODO(doyle): Multi press within frame overrides UI input parsing
if ((i >= keycode_A && i <= keycode_Z) ||
(i >= keycode_a && i <= keycode_z))
{
if (getKeyStatus(currKey, readkeytype_repeat, 0.15f, dt))
{ {
if (getKeyStatus(*currKey, readkeytype_oneShot)) state->uiState.keyChar = i;
{
state->uiState.keyChar = i;
}
} }
} }
} }
if (hero->stats->busyDuration <= 0) if (hero->stats->busyDuration <= 0)
{ {
if (getKeyStatus(keys[keycode_right], readkeytype_repeat)) if (getKeyStatus(&keys[keycode_right], readkeytype_repeat,
KEY_DELAY_NONE, dt))
{ {
ddPos.x = 1.0f; ddPos.x = 1.0f;
hero->direction = direction_east; hero->direction = direction_east;
} }
if (getKeyStatus(keys[keycode_left], readkeytype_repeat)) if (getKeyStatus(&keys[keycode_left], readkeytype_repeat,
KEY_DELAY_NONE, dt))
{ {
ddPos.x = -1.0f; ddPos.x = -1.0f;
hero->direction = direction_west; hero->direction = direction_west;
} }
if (getKeyStatus(keys[keycode_up], readkeytype_repeat)) if (getKeyStatus(&keys[keycode_up], readkeytype_repeat, KEY_DELAY_NONE,
dt))
{ {
ddPos.y = 1.0f; ddPos.y = 1.0f;
} }
if (getKeyStatus(keys[keycode_down], readkeytype_repeat)) if (getKeyStatus(&keys[keycode_down], readkeytype_repeat,
KEY_DELAY_NONE, dt))
{ {
ddPos.y = -1.0f; ddPos.y = -1.0f;
} }
@ -465,12 +498,14 @@ INTERNAL void parseInput(GameState *state, const f32 dt)
ddPos = v2_scale(ddPos, 0.70710678118f); ddPos = v2_scale(ddPos, 0.70710678118f);
} }
if (getKeyStatus(keys[keycode_enter], readkeytype_oneShot)) if (getKeyStatus(&keys[keycode_enter], readkeytype_oneShot,
KEY_DELAY_NONE, dt))
{ {
state->uiState.keyEntered = keycode_enter; state->uiState.keyEntered = keycode_enter;
} }
if (getKeyStatus(keys[keycode_space], readkeytype_oneShot)) if (getKeyStatus(&keys[keycode_space], readkeytype_delayedRepeat, 0.25f,
dt))
{ {
state->uiState.keyEntered = keycode_space; state->uiState.keyEntered = keycode_space;
DEBUG_LOG("push space"); DEBUG_LOG("push space");
@ -504,7 +539,8 @@ INTERNAL void parseInput(GameState *state, const f32 dt)
} }
f32 heroSpeed = 6.2f * METERS_TO_PIXEL; f32 heroSpeed = 6.2f * METERS_TO_PIXEL;
if (state->input.keys[keycode_leftShift].endedDown) if (getKeyStatus(&state->input.keys[keycode_leftShift], readkeytype_repeat,
KEY_DELAY_NONE, dt))
{ {
// TODO: Context sensitive command separation // TODO: Context sensitive command separation
state->uiState.keyMod = keycode_leftShift; state->uiState.keyMod = keycode_leftShift;
@ -1132,8 +1168,7 @@ INTERNAL i32 scrollBar(UiState *uiState, AssetManager *assetManager,
INTERNAL i32 textField(UiState *const uiState, MemoryArena *arena, INTERNAL i32 textField(UiState *const uiState, MemoryArena *arena,
AssetManager *const assetManager, AssetManager *const assetManager,
Renderer *const renderer, Font *const font, Renderer *const renderer, Font *const font,
KeyInput input, const i32 id, v2 pos, KeyInput input, const i32 id, v2 pos, char *const string)
char *const string)
{ {
i32 strLen = common_strlen(string); i32 strLen = common_strlen(string);
b32 changed = FALSE; b32 changed = FALSE;

View File

@ -23,7 +23,8 @@ typedef double f64;
#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0])) #define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
#define CAST(type) (type) #define CAST(type) (type)
#define ASSERT(expr) if(!(expr)) { *(int *)0 = 0; } #define ASSERT(expr) if (!(expr)) { *(int *)0 = 0; }
#define IS_EVEN(value) (((value) & 1) == 0)
#define DENGINE_DEBUG #define DENGINE_DEBUG

View File

@ -120,6 +120,7 @@ enum KeyCode
typedef struct KeyState typedef struct KeyState
{ {
f32 delayInterval;
u32 oldHalfTransitionCount; u32 oldHalfTransitionCount;
u32 newHalfTransitionCount; u32 newHalfTransitionCount;
b32 endedDown; b32 endedDown;