(svn r27167) -Fix: [SDL, Windows] Right-mouse-button scrolling scrolled/jumped way to far, when OpenTTD lagged during mouse event processing.

This commit is contained in:
frosch
2015-02-22 23:06:45 +00:00
parent 74b0e2b73e
commit 3cceb21a94
6 changed files with 65 additions and 64 deletions

View File

@@ -1603,6 +1603,53 @@ void SetAnimatedMouseCursor(const AnimCursor *table)
SwitchAnimatedCursor();
}
/**
* Update cursor position on mouse movement.
* @param x New X position.
* @param y New Y position.
* @param queued True, if the OS queues mouse warps after pending mouse movement events.
* False, if the warp applies instantaneous.
* @return true, if the OS cursor position should be warped back to this->pos.
*/
bool CursorVars::UpdateCursorPosition(int x, int y, bool queued_warp)
{
/* Detecting relative mouse movement is somewhat tricky.
* - There may be multiple mouse move events in the video driver queue (esp. when OpenTTD lags a bit).
* - When we request warping the mouse position (return true), a mouse move event is appended at the end of the queue.
*
* So, when this->fix_at is active, we use the following strategy:
* - The first movement triggers the warp to reset the mouse position.
* - Subsequent events have to compute movement relative to the previous event.
* - The relative movement is finished, when we receive the event matching the warp.
*/
if (x == this->pos.x && y == this->pos.y) {
/* Warp finished. */
this->queued_warp = false;
}
this->delta.x = x - (this->queued_warp ? this->last_position.x : this->pos.x);
this->delta.y = y - (this->queued_warp ? this->last_position.y : this->pos.y);
this->last_position.x = x;
this->last_position.y = y;
bool need_warp = false;
if (this->fix_at) {
if (!this->queued_warp && (this->delta.x != 0 || this->delta.y != 0)) {
/* Trigger warp. */
this->queued_warp = queued_warp;
need_warp = true;
}
} else if (this->pos.x != x || this->pos.y != y) {
this->queued_warp = false; // Cancel warping, we are no longer confining the position.
this->dirty = true;
this->pos.x = x;
this->pos.y = y;
}
return need_warp;
}
bool ChangeResInGame(int width, int height)
{
return (_screen.width == width && _screen.height == height) || VideoDriver::GetInstance()->ChangeResolution(width, height);