Add delayed key repeat
This commit is contained in:
parent
80b35d404d
commit
8aa23b7cfc
@ -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
|
}
|
||||||
|
|
||||||
|
// Parse ui input
|
||||||
|
// TODO(doyle): Multi press within frame overrides UI input parsing
|
||||||
if ((i >= keycode_A && i <= keycode_Z) ||
|
if ((i >= keycode_A && i <= keycode_Z) ||
|
||||||
(i >= keycode_a && i <= keycode_z))
|
(i >= keycode_a && i <= keycode_z))
|
||||||
{
|
{
|
||||||
if (getKeyStatus(*currKey, readkeytype_oneShot))
|
|
||||||
|
if (getKeyStatus(currKey, readkeytype_repeat, 0.15f, dt))
|
||||||
{
|
{
|
||||||
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;
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user