Loading

Paste #pbnxi2xvy

  1. Index: src/gfx_type.h
  2. ===================================================================
  3. --- src/gfx_type.h  (revision 27164)
  4. +++ src/gfx_type.h  (working copy)
  5. @@ -138,6 +138,12 @@
  6.     bool in_window;  ///< mouse inside this window, determines drawing logic
  7.  
  8.     bool vehchain;   ///< vehicle chain is dragged
  9. +
  10. +   bool UpdateCursorPosition(int x, int y, bool queued_warp);
  11. +
  12. +private:
  13. +   bool queued_warp;
  14. +   Point last_position;
  15.  };
  16.  
  17.  /** Data about how and where to blit pixels. */
  18. Index: src/video/sdl_v.cpp
  19. ===================================================================
  20. --- src/video/sdl_v.cpp (revision 27164)
  21. +++ src/video/sdl_v.cpp (working copy)
  22. @@ -545,20 +545,8 @@
  23.  
  24.     switch (ev.type) {
  25.         case SDL_MOUSEMOTION:
  26. -           if (_cursor.fix_at) {
  27. -               int dx = ev.motion.x - _cursor.pos.x;
  28. -               int dy = ev.motion.y - _cursor.pos.y;
  29. -               if (dx != 0 || dy != 0) {
  30. -                   _cursor.delta.x = dx;
  31. -                   _cursor.delta.y = dy;
  32. -                   SDL_CALL SDL_WarpMouse(_cursor.pos.x, _cursor.pos.y);
  33. -               }
  34. -           } else {
  35. -               _cursor.delta.x = ev.motion.x - _cursor.pos.x;
  36. -               _cursor.delta.y = ev.motion.y - _cursor.pos.y;
  37. -               _cursor.pos.x = ev.motion.x;
  38. -               _cursor.pos.y = ev.motion.y;
  39. -               _cursor.dirty = true;
  40. +           if (_cursor.UpdateCursorPosition(ev.motion.x, ev.motion.y, true)) {
  41. +               SDL_CALL SDL_WarpMouse(_cursor.pos.x, _cursor.pos.y);
  42.             }
  43.             HandleMouseEvents();
  44.             break;
  45. Index: src/video/win32_v.cpp
  46. ===================================================================
  47. --- src/video/win32_v.cpp   (revision 27164)
  48. +++ src/video/win32_v.cpp   (working copy)
  49. @@ -747,25 +747,11 @@
  50.                 SetTimer(hwnd, TID_POLLMOUSE, MOUSE_POLL_DELAY, (TIMERPROC)TrackMouseTimerProc);
  51.             }
  52.  
  53. -           if (_cursor.fix_at) {
  54. -               int dx = x - _cursor.pos.x;
  55. -               int dy = y - _cursor.pos.y;
  56. -               if (dx != 0 || dy != 0) {
  57. -                   _cursor.delta.x = dx;
  58. -                   _cursor.delta.y = dy;
  59. -
  60. -                   pt.x = _cursor.pos.x;
  61. -                   pt.y = _cursor.pos.y;
  62. -
  63. -                   ClientToScreen(hwnd, &pt);
  64. -                   SetCursorPos(pt.x, pt.y);
  65. -               }
  66. -           } else {
  67. -               _cursor.delta.x = x - _cursor.pos.x;
  68. -               _cursor.delta.y = y - _cursor.pos.y;
  69. -               _cursor.pos.x = x;
  70. -               _cursor.pos.y = y;
  71. -               _cursor.dirty = true;
  72. +           if (_cursor.UpdateCursorPosition(x, y, true)) {
  73. +               pt.x = _cursor.pos.x;
  74. +               pt.y = _cursor.pos.y;
  75. +               ClientToScreen(hwnd, &pt);
  76. +               SetCursorPos(pt.x, pt.y);
  77.             }
  78.             MyShowCursor(false);
  79.             HandleMouseEvents();
  80. Index: src/video/allegro_v.cpp
  81. ===================================================================
  82. --- src/video/allegro_v.cpp (revision 27164)
  83. +++ src/video/allegro_v.cpp (working copy)
  84. @@ -388,22 +388,10 @@
  85.     }
  86.  
  87.     /* Mouse movement */
  88. -   int dx = mouse_x - _cursor.pos.x;
  89. -   int dy = mouse_y - _cursor.pos.y;
  90. -   if (dx != 0 || dy != 0) {
  91. -       if (_cursor.fix_at) {
  92. -           _cursor.delta.x = dx;
  93. -           _cursor.delta.y = dy;
  94. -           position_mouse(_cursor.pos.x, _cursor.pos.y);
  95. -       } else {
  96. -           _cursor.delta.x = dx;
  97. -           _cursor.delta.y = dy;
  98. -           _cursor.pos.x = mouse_x;
  99. -           _cursor.pos.y = mouse_y;
  100. -           _cursor.dirty = true;
  101. -       }
  102. -       mouse_action = true;
  103. +   if (_cursor.UpdateCursorPosition(mouse_x, mouse_y, false)) {
  104. +       position_mouse(_cursor.pos.x, _cursor.pos.y);
  105.     }
  106. +   if (_cursor.delta.x != 0 || _cursor.delta.y) mouse_action = true;
  107.  
  108.     static int prev_mouse_z = 0;
  109.     if (prev_mouse_z != mouse_z) {
  110. Index: src/video/cocoa/event.mm
  111. ===================================================================
  112. --- src/video/cocoa/event.mm    (revision 27164)
  113. +++ src/video/cocoa/event.mm    (working copy)
  114. @@ -362,22 +362,8 @@
  115.  
  116.  static void QZ_MouseMovedEvent(int x, int y)
  117.  {
  118. -   if (_cursor.fix_at) {
  119. -       int dx = x - _cursor.pos.x;
  120. -       int dy = y - _cursor.pos.y;
  121. -
  122. -       if (dx != 0 || dy != 0) {
  123. -           _cursor.delta.x += dx;
  124. -           _cursor.delta.y += dy;
  125. -
  126. -           QZ_WarpCursor(_cursor.pos.x, _cursor.pos.y);
  127. -       }
  128. -   } else {
  129. -       _cursor.delta.x = x - _cursor.pos.x;
  130. -       _cursor.delta.y = y - _cursor.pos.y;
  131. -       _cursor.pos.x = x;
  132. -       _cursor.pos.y = y;
  133. -       _cursor.dirty = true;
  134. +   if (_cursor.UpdateCursorPosition(x, y, false)) {
  135. +       QZ_WarpCursor(_cursor.pos.x, _cursor.pos.y);
  136.     }
  137.     HandleMouseEvents();
  138.  }
  139. Index: src/gfx.cpp
  140. ===================================================================
  141. --- src/gfx.cpp (revision 27164)
  142. +++ src/gfx.cpp (working copy)
  143. @@ -1603,6 +1603,53 @@
  144.     SwitchAnimatedCursor();
  145.  }
  146.  
  147. +/**
  148. + * Update cursor position on mouse movement.
  149. + * @param x New X position.
  150. + * @param y New Y position.
  151. + * @param queued True, if the OS queues mouse warps after pending mouse movement events.
  152. + *               False, if the warp applies instantaneous.
  153. + * @return true, when the OS cursor position should be warped back to this->pos.
  154. + */
  155. +bool CursorVars::UpdateCursorPosition(int x, int y, bool queued_warp)
  156. +{
  157. +   /* Detecting relative mouse movement is somewhat tricky.
  158. +    *  - There may be multiple mouse move events in the video driver queue (esp. when OpenTTD lags a bit).
  159. +    *  - When we request warping the mouse position (return true), a mouse move event is appended at the end of the queue.
  160. +    *
  161. +    * So, when this->fix_at is active, we use the following strategy:
  162. +    *  - The first movement triggers the warp to reset the mouse position.
  163. +    *  - Subsequent events have to compute movement relative to the previous event.
  164. +    *  - The relative movement is finished, when we receive the event matching the warp.
  165. +    */
  166. +
  167. +   if (x == this->pos.x && y == this->pos.y) {
  168. +       /* Warp finished. */
  169. +       this->queued_warp = false;
  170. +   }
  171. +
  172. +   this->delta.x = x - (this->queued_warp ? this->last_position.x : this->pos.x);
  173. +   this->delta.y = y - (this->queued_warp ? this->last_position.y : this->pos.y);
  174. +
  175. +   this->last_position.x = x;
  176. +   this->last_position.y = y;
  177. +
  178. +   bool need_warp = false;
  179. +   if (this->fix_at) {
  180. +       if (!this->queued_warp && (this->delta.x != 0 || this->delta.y != 0)) {
  181. +           /* Trigger warp. */
  182. +           this->queued_warp = queued_warp;
  183. +           need_warp = true;
  184. +       }
  185. +   } else if (this->pos.x != x || this->pos.y != y) {
  186. +       this->queued_warp = false; // Cancel warping, we are no longer confining the position.
  187. +       this->dirty = true;
  188. +       this->pos.x = x;
  189. +       this->pos.y = y;
  190. +   }
  191. +   return need_warp;
  192. +}
  193. +
  194.  bool ChangeResInGame(int width, int height)
  195.  {
  196.     return (_screen.width == width && _screen.height == height) || VideoDriver::GetInstance()->ChangeResolution(width, height);
  197.  

Comments