Browse Source

[controller] Make accumulator time based and correct map direction

The emulated mouse and map move at a consistent speed independant of
frame rate.
The map can now be scrolled at variable speeds and diagonally.
Mouse is now confined to the window.
pull/897/head
Anders Jenbo 6 years ago
parent
commit
cc42e9abb1
  1. 58
      SourceX/controls/plrctrls.cpp

58
SourceX/controls/plrctrls.cpp

@ -826,60 +826,56 @@ void Movement()
} }
struct RightStickAccumulator { struct RightStickAccumulator {
void start(int *x, int *y) void pool(int *x, int *y, int slowdown)
{ {
hiresDX += rightStickX * kGranularity; DWORD tc = SDL_GetTicks();
hiresDY += rightStickY * kGranularity; hiresDX += rightStickX * (tc - lastTc);
hiresDY += rightStickY * (tc - lastTc);
*x += hiresDX / slowdown; *x += hiresDX / slowdown;
*y += -hiresDY / slowdown; *y += -hiresDY / slowdown;
} lastTc = tc;
void finish()
{
// keep track of remainder for sub-pixel motion // keep track of remainder for sub-pixel motion
hiresDX %= slowdown; hiresDX %= slowdown;
hiresDY %= slowdown; hiresDY %= slowdown;
} }
static const int kGranularity = (1 << 15) - 1; void clear()
int slowdown; // < kGranularity {
int hiresDX; lastTc = SDL_GetTicks();
int hiresDY; }
DWORD lastTc = SDL_GetTicks();
int hiresDX = 0;
int hiresDY = 0;
}; };
} // namespace } // namespace
void HandleRightStickMotion() void HandleRightStickMotion()
{ {
static RightStickAccumulator acc;
// deadzone is handled in ScaleJoystickAxes() already // deadzone is handled in ScaleJoystickAxes() already
if (rightStickX == 0 && rightStickY == 0) if (rightStickX == 0 && rightStickY == 0) {
acc.clear();
return; return;
}
if (automapflag) { // move map if (automapflag) { // move map
static RightStickAccumulator acc = { /*slowdown=*/(1 << 14) + (1 << 13), 0, 0 };
int dx = 0, dy = 0; int dx = 0, dy = 0;
acc.start(&dx, &dy); acc.pool(&dx, &dy, 32);
if (dy > 1) AutoMapXOfs += dy + dx;
AutomapUp(); AutoMapYOfs += dy - dx;
else if (dy < -1) return;
AutomapDown(); }
else if (dx < -1)
AutomapRight(); { // move cursor
else if (dx > 1)
AutomapLeft();
acc.finish();
} else { // move cursor
sgbControllerActive = false; sgbControllerActive = false;
static RightStickAccumulator acc = { /*slowdown=*/(1 << 13) + (1 << 12), 0, 0 };
int x = MouseX; int x = MouseX;
int y = MouseY; int y = MouseY;
acc.start(&x, &y); acc.pool(&x, &y, 2);
if (x < 0) x = std::min(std::max(x, 0), SCREEN_WIDTH - 1);
x = 0; y = std::min(std::max(y, 0), SCREEN_HEIGHT - 1);
if (y < 0)
y = 0;
SetCursorPos(x, y); SetCursorPos(x, y);
acc.finish();
} }
} }

Loading…
Cancel
Save