Input: Hack around desync with mkxpRawKeyStates

Make sure that when mkxpRawKeyStates was called, the Input module
will work off of the same queried snapshot of pressed keys
during the next update call.
This commit is contained in:
Jonas Kulla 2017-03-21 10:47:32 +01:00
parent ea742be6b0
commit ef06c8eca4
2 changed files with 25 additions and 6 deletions

View File

@ -214,12 +214,25 @@ RB_METHOD(mkxpPuts)
return Qnil; return Qnil;
} }
static uint8_t keyStatesMirrorAry[SDL_NUM_SCANCODES];
// points at either EventThread::keyStates (which is continuously updated)
// or keyStatesMirrorAry (which is a frame-local snapshot of the former)
uint8_t *keyStatesMirror = EventThread::keyStates;
RB_METHOD(mkxpRawKeyStates) RB_METHOD(mkxpRawKeyStates)
{ {
RB_UNUSED_PARAM; RB_UNUSED_PARAM;
VALUE str = rb_str_new(0, sizeof(EventThread::keyStates)); VALUE str = rb_str_new(0, sizeof(EventThread::keyStates));
memcpy(RSTRING_PTR(str), EventThread::keyStates, sizeof(EventThread::keyStates));
// copy keystates to a shadow array so the Input module uses the same snapshot
memcpy(keyStatesMirrorAry, EventThread::keyStates, sizeof(keyStatesMirrorAry));
memcpy(RSTRING_PTR(str), keyStatesMirrorAry, sizeof(keyStatesMirrorAry));
// let the Input module use our snapshot instead (Input will take care of resetting
// the pointer back to the EventThread array)
keyStatesMirror = keyStatesMirrorAry;
return str; return str;
} }

View File

@ -66,6 +66,9 @@ struct Binding
Input::ButtonCode target; Input::ButtonCode target;
}; };
// binding-mri.cpp
extern uint8_t *keyStatesMirror;
/* Keyboard binding */ /* Keyboard binding */
struct KbBinding : public Binding struct KbBinding : public Binding
{ {
@ -80,14 +83,14 @@ struct KbBinding : public Binding
{ {
/* Special case aliases */ /* Special case aliases */
if (source == SDL_SCANCODE_LSHIFT) if (source == SDL_SCANCODE_LSHIFT)
return EventThread::keyStates[source] return keyStatesMirror[source]
|| EventThread::keyStates[SDL_SCANCODE_RSHIFT]; || keyStatesMirror[SDL_SCANCODE_RSHIFT];
if (source == SDL_SCANCODE_RETURN) if (source == SDL_SCANCODE_RETURN)
return EventThread::keyStates[source] return keyStatesMirror[source]
|| EventThread::keyStates[SDL_SCANCODE_KP_ENTER]; || keyStatesMirror[SDL_SCANCODE_KP_ENTER];
return EventThread::keyStates[source]; return keyStatesMirror[source];
} }
bool sourceRepeatable() const bool sourceRepeatable() const
@ -607,6 +610,9 @@ void Input::update()
/* Poll all bindings */ /* Poll all bindings */
p->pollBindings(repeatCand); p->pollBindings(repeatCand);
// reset keystate source from potential mirror to EventThread source array
keyStatesMirror = EventThread::keyStates;
/* Check for new repeating key */ /* Check for new repeating key */
if (repeatCand != None && repeatCand != p->repeating) if (repeatCand != None && repeatCand != p->repeating)
{ {