Keep input repeat timings independent of FPS

This commit is contained in:
Struma 2021-02-25 19:28:44 -05:00 committed by Roza
parent cb46b53982
commit d4d2b7c7cb
3 changed files with 822 additions and 801 deletions

File diff suppressed because it is too large Load diff

View file

@ -20,11 +20,12 @@
*/ */
#include "input.h" #include "input.h"
#include "config.h"
#include "sharedstate.h" #include "sharedstate.h"
#include "eventthread.h" #include "eventthread.h"
#include "keybindings.h" #include "input/keybindings.h"
#include "exception.h" #include "util/exception.h"
#include "util.h" #include "util/util.h"
#include <SDL_scancode.h> #include <SDL_scancode.h>
#include <SDL_keyboard.h> #include <SDL_keyboard.h>
@ -32,6 +33,7 @@
#include <SDL_clipboard.h> #include <SDL_clipboard.h>
#include <vector> #include <vector>
#include <cmath>
#include <unordered_map> #include <unordered_map>
#include <string.h> #include <string.h>
#include <assert.h> #include <assert.h>
@ -678,6 +680,9 @@ struct InputPrivate
int rawRepeating; int rawRepeating;
unsigned int repeatCount; unsigned int repeatCount;
unsigned int rawRepeatCount; unsigned int rawRepeatCount;
unsigned int repeatStart;
unsigned int repeatDelay;
struct struct
{ {
@ -690,6 +695,16 @@ struct InputPrivate
int active; int active;
} dir8Data; } dir8Data;
void recalcRepeatTime(unsigned int fps) {
double framems = 1.f / fps;
// Approximate time in milliseconds
double start = (rgssVer >= 2) ? 0.375 : 0.400;
double delay = 0.100;
repeatStart = ceil(start / framems);
repeatDelay = ceil(delay / framems);
}
InputPrivate(const RGSSThreadData &rtData) InputPrivate(const RGSSThreadData &rtData)
{ {
@ -698,6 +713,10 @@ struct InputPrivate
/* Main thread should have these posted by now */ /* Main thread should have these posted by now */
checkBindingChange(rtData); checkBindingChange(rtData);
int fps = rtData.config.fixedFramerate;
if (!fps) fps = (rgssVer >= 2) ? 60 : 40;
recalcRepeatTime(fps);
states = stateArray; states = stateArray;
statesOld = stateArray + BUTTON_CODE_COUNT; statesOld = stateArray + BUTTON_CODE_COUNT;
@ -712,7 +731,7 @@ struct InputPrivate
repeating = Input::None; repeating = Input::None;
repeatCount = 0; repeatCount = 0;
dir4Data.active = 0; dir4Data.active = 0;
dir4Data.previous = Input::None; dir4Data.previous = Input::None;
@ -789,15 +808,7 @@ struct InputPrivate
b.triggered = (rawStates[scancode] && !rawStatesOld[scancode]); b.triggered = (rawStates[scancode] && !rawStatesOld[scancode]);
b.released = (!rawStates[scancode] && rawStatesOld[scancode]); b.released = (!rawStates[scancode] && rawStatesOld[scancode]);
bool repeated = false; b.repeated = rawRepeatCount >= repeatStart && ((rawRepeatCount+1) % repeatDelay) == 0;
if (scancode == rawRepeating)
{
if (rgssVer >= 2)
repeated = rawRepeatCount >= 23 && ((rawRepeatCount+1) % 6) == 0;
else
repeated = rawRepeatCount >= 15 && ((rawRepeatCount+1) % 4) == 0;
}
b.repeated = repeated;
return b; return b;
} }
@ -1090,6 +1101,10 @@ Input::Input(const RGSSThreadData &rtData)
p = new InputPrivate(rtData); p = new InputPrivate(rtData);
} }
void Input::recalcRepeat(unsigned int fps) {
p->recalcRepeatTime(fps);
}
void Input::update() void Input::update()
{ {
shState->checkShutdown(); shState->checkShutdown();
@ -1121,12 +1136,14 @@ void Input::update()
{ {
p->repeatCount++; p->repeatCount++;
/*
bool repeated; bool repeated;
if (rgssVer >= 2) if (rgssVer >= 2)
repeated = p->repeatCount >= 23 && ((p->repeatCount+1) % 6) == 0; repeated = p->repeatCount >= 23 && ((p->repeatCount+1) % 6) == 0;
else else
repeated = p->repeatCount >= 15 && ((p->repeatCount+1) % 4) == 0; repeated = p->repeatCount >= 15 && ((p->repeatCount+1) % 4) == 0;
*/
bool repeated = p->repeatCount >= p->repeatStart && ((p->repeatCount+1) & p->repeatDelay) == 0;
p->getState(p->repeating).repeated |= repeated; p->getState(p->repeating).repeated |= repeated;
return; return;

View file

@ -52,6 +52,8 @@ public:
/* Non-standard extensions */ /* Non-standard extensions */
MouseLeft = 38, MouseMiddle = 39, MouseRight = 40 MouseLeft = 38, MouseMiddle = 39, MouseRight = 40
}; };
void recalcRepeat(unsigned int fps);
void update(); void update();