Changeset - r22011:0dc7eed331dd
[Not reviewed]
master
0 6 0
frosch - 9 years ago 2015-02-22 23:06:45
frosch@openttd.org
(svn r27167) -Fix: [SDL, Windows] Right-mouse-button scrolling scrolled/jumped way to far, when OpenTTD lagged during mouse event processing.
6 files changed with 65 insertions and 64 deletions:
0 comments (0 inline, 0 general)
src/gfx.cpp
Show inline comments
 
@@ -1603,6 +1603,53 @@ void SetAnimatedMouseCursor(const AnimCu
 
	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);
src/gfx_type.h
Show inline comments
 
@@ -138,6 +138,12 @@ struct CursorVars {
 
	bool in_window;  ///< mouse inside this window, determines drawing logic
 

	
 
	bool vehchain;   ///< vehicle chain is dragged
 

	
 
	bool UpdateCursorPosition(int x, int y, bool queued_warp);
 

	
 
private:
 
	bool queued_warp;
 
	Point last_position;
 
};
 

	
 
/** Data about how and where to blit pixels. */
src/video/allegro_v.cpp
Show inline comments
 
@@ -388,22 +388,10 @@ static void PollEvent()
 
	}
 

	
 
	/* Mouse movement */
 
	int dx = mouse_x - _cursor.pos.x;
 
	int dy = mouse_y - _cursor.pos.y;
 
	if (dx != 0 || dy != 0) {
 
		if (_cursor.fix_at) {
 
			_cursor.delta.x = dx;
 
			_cursor.delta.y = dy;
 
			position_mouse(_cursor.pos.x, _cursor.pos.y);
 
		} else {
 
			_cursor.delta.x = dx;
 
			_cursor.delta.y = dy;
 
			_cursor.pos.x = mouse_x;
 
			_cursor.pos.y = mouse_y;
 
			_cursor.dirty = true;
 
		}
 
		mouse_action = true;
 
	if (_cursor.UpdateCursorPosition(mouse_x, mouse_y, false)) {
 
		position_mouse(_cursor.pos.x, _cursor.pos.y);
 
	}
 
	if (_cursor.delta.x != 0 || _cursor.delta.y) mouse_action = true;
 

	
 
	static int prev_mouse_z = 0;
 
	if (prev_mouse_z != mouse_z) {
src/video/cocoa/event.mm
Show inline comments
 
@@ -362,22 +362,8 @@ static void QZ_DoUnsidedModifiers(unsign
 

	
 
static void QZ_MouseMovedEvent(int x, int y)
 
{
 
	if (_cursor.fix_at) {
 
		int dx = x - _cursor.pos.x;
 
		int dy = y - _cursor.pos.y;
 

	
 
		if (dx != 0 || dy != 0) {
 
			_cursor.delta.x += dx;
 
			_cursor.delta.y += dy;
 

	
 
			QZ_WarpCursor(_cursor.pos.x, _cursor.pos.y);
 
		}
 
	} else {
 
		_cursor.delta.x = x - _cursor.pos.x;
 
		_cursor.delta.y = y - _cursor.pos.y;
 
		_cursor.pos.x = x;
 
		_cursor.pos.y = y;
 
		_cursor.dirty = true;
 
	if (_cursor.UpdateCursorPosition(x, y, false)) {
 
		QZ_WarpCursor(_cursor.pos.x, _cursor.pos.y);
 
	}
 
	HandleMouseEvents();
 
}
src/video/sdl_v.cpp
Show inline comments
 
@@ -545,20 +545,8 @@ int VideoDriver_SDL::PollEvent()
 

	
 
	switch (ev.type) {
 
		case SDL_MOUSEMOTION:
 
			if (_cursor.fix_at) {
 
				int dx = ev.motion.x - _cursor.pos.x;
 
				int dy = ev.motion.y - _cursor.pos.y;
 
				if (dx != 0 || dy != 0) {
 
					_cursor.delta.x = dx;
 
					_cursor.delta.y = dy;
 
					SDL_CALL SDL_WarpMouse(_cursor.pos.x, _cursor.pos.y);
 
				}
 
			} else {
 
				_cursor.delta.x = ev.motion.x - _cursor.pos.x;
 
				_cursor.delta.y = ev.motion.y - _cursor.pos.y;
 
				_cursor.pos.x = ev.motion.x;
 
				_cursor.pos.y = ev.motion.y;
 
				_cursor.dirty = true;
 
			if (_cursor.UpdateCursorPosition(ev.motion.x, ev.motion.y, true)) {
 
				SDL_CALL SDL_WarpMouse(_cursor.pos.x, _cursor.pos.y);
 
			}
 
			HandleMouseEvents();
 
			break;
src/video/win32_v.cpp
Show inline comments
 
@@ -747,25 +747,11 @@ static LRESULT CALLBACK WndProcGdi(HWND 
 
				SetTimer(hwnd, TID_POLLMOUSE, MOUSE_POLL_DELAY, (TIMERPROC)TrackMouseTimerProc);
 
			}
 

	
 
			if (_cursor.fix_at) {
 
				int dx = x - _cursor.pos.x;
 
				int dy = y - _cursor.pos.y;
 
				if (dx != 0 || dy != 0) {
 
					_cursor.delta.x = dx;
 
					_cursor.delta.y = dy;
 

	
 
					pt.x = _cursor.pos.x;
 
					pt.y = _cursor.pos.y;
 

	
 
					ClientToScreen(hwnd, &pt);
 
					SetCursorPos(pt.x, pt.y);
 
				}
 
			} else {
 
				_cursor.delta.x = x - _cursor.pos.x;
 
				_cursor.delta.y = y - _cursor.pos.y;
 
				_cursor.pos.x = x;
 
				_cursor.pos.y = y;
 
				_cursor.dirty = true;
 
			if (_cursor.UpdateCursorPosition(x, y, true)) {
 
				pt.x = _cursor.pos.x;
 
				pt.y = _cursor.pos.y;
 
				ClientToScreen(hwnd, &pt);
 
				SetCursorPos(pt.x, pt.y);
 
			}
 
			MyShowCursor(false);
 
			HandleMouseEvents();
0 comments (0 inline, 0 general)