(svn r9962) -Feature: Add smooth viewport scrolling. This must be enabled with patch setting 'smooth_scroll'
authorpeter1138
Mon, 28 May 2007 16:46:16 +0000
changeset 6730 9311a208f8f7
parent 6729 302e2c8fff07
child 6731 d018207588bb
(svn r9962) -Feature: Add smooth viewport scrolling. This must be enabled with patch setting 'smooth_scroll'
src/functions.h
src/lang/english.txt
src/main_gui.cpp
src/openttd.cpp
src/settings.cpp
src/settings_gui.cpp
src/smallmap_gui.cpp
src/variables.h
src/viewport.cpp
src/window.h
--- a/src/functions.h	Mon May 28 04:15:32 2007 +0000
+++ b/src/functions.h	Mon May 28 16:46:16 2007 +0000
@@ -131,10 +131,10 @@
 
 void ResetObjectToPlace();
 
-bool ScrollWindowTo(int x, int y, Window * w);
+bool ScrollWindowTo(int x, int y, Window * w, bool instant = false);
 
-bool ScrollMainWindowToTile(TileIndex tile);
-bool ScrollMainWindowTo(int x, int y);
+bool ScrollMainWindowToTile(TileIndex tile, bool instant = false);
+bool ScrollMainWindowTo(int x, int y, bool instant = false);
 void DrawSprite(SpriteID img, SpriteID pal, int x, int y);
 bool EnsureNoVehicle(TileIndex tile);
 bool EnsureNoVehicleOnGround(TileIndex tile);
--- a/src/lang/english.txt	Mon May 28 04:15:32 2007 +0000
+++ b/src/lang/english.txt	Mon May 28 16:46:16 2007 +0000
@@ -1089,6 +1089,7 @@
 STR_CONFIG_PATCHES_SERVICEATHELIPAD                             :{LTBLUE}Service helicopters at helipads automatically: {ORANGE}{STRING1}
 STR_CONFIG_PATCHES_LINK_TERRAFORM_TOOLBAR                       :{LTBLUE}Link landscape toolbar to rail/road/water/airport toolbars: {ORANGE}{STRING1}
 STR_CONFIG_PATCHES_REVERSE_SCROLLING                            :{LTBLUE}Reverse scroll direction: {ORANGE}{STRING1}
+STR_CONFIG_PATCHES_SMOOTH_SCROLLING                             :{LTBLUE}Smooth viewport scrolling: {ORANGE}{STRING1}
 STR_CONFIG_PATCHES_MEASURE_TOOLTIP                              :{LTBLUE}Show a measurement tooltip when using various build-tools: {ORANGE}{STRING1}
 STR_CONFIG_PATCHES_LIVERIES                                     :{LTBLUE}Show company liveries: {ORANGE}{STRING1}
 STR_CONFIG_PATCHES_LIVERIES_NONE                                :None
--- a/src/main_gui.cpp	Mon May 28 04:15:32 2007 +0000
+++ b/src/main_gui.cpp	Mon May 28 16:46:16 2007 +0000
@@ -889,6 +889,8 @@
 
 			WP(w,vp_d).scrollpos_x += vp->virtual_width >> 1;
 			WP(w,vp_d).scrollpos_y += vp->virtual_height >> 1;
+			WP(w,vp_d).dest_scrollpos_x = WP(w,vp_d).scrollpos_x;
+			WP(w,vp_d).dest_scrollpos_y = WP(w,vp_d).scrollpos_y;
 			break;
 		case ZOOM_OUT:
 			if (vp->zoom == ZOOM_LVL_MAX) return false;
@@ -896,6 +898,8 @@
 
 			WP(w,vp_d).scrollpos_x -= vp->virtual_width >> 1;
 			WP(w,vp_d).scrollpos_y -= vp->virtual_height >> 1;
+			WP(w,vp_d).dest_scrollpos_x = WP(w,vp_d).scrollpos_x;
+			WP(w,vp_d).dest_scrollpos_y = WP(w,vp_d).scrollpos_y;
 
 			vp->virtual_width <<= 1;
 			vp->virtual_height <<= 1;
@@ -1058,7 +1062,7 @@
 
 		pt = GetTileZoomCenterWindow(in,w);
 		if (pt.x != -1) {
-			ScrollWindowTo(pt.x, pt.y, w);
+			ScrollWindowTo(pt.x, pt.y, w, true);
 
 			DoZoomInOutWindow(in ? ZOOM_IN : ZOOM_OUT, w);
 		}
@@ -2438,6 +2442,8 @@
 
 			WP(w, vp_d).scrollpos_x += ScaleByZoom(e->we.scroll.delta.x, vp->zoom);
 			WP(w, vp_d).scrollpos_y += ScaleByZoom(e->we.scroll.delta.y, vp->zoom);
+			WP(w, vp_d).dest_scrollpos_x = WP(w, vp_d).scrollpos_x;
+			WP(w, vp_d).dest_scrollpos_y = WP(w, vp_d).scrollpos_y;
 		} break;
 
 		case WE_MOUSEWHEEL:
--- a/src/openttd.cpp	Mon May 28 04:15:32 2007 +0000
+++ b/src/openttd.cpp	Mon May 28 16:46:16 2007 +0000
@@ -991,8 +991,8 @@
 		Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
 		assert(w);
 
-		WP(w,vp_d).scrollpos_x += ScaleByZoom(x, w->viewport->zoom);
-		WP(w,vp_d).scrollpos_y += ScaleByZoom(y, w->viewport->zoom);
+		WP(w,vp_d).dest_scrollpos_x += ScaleByZoom(x, w->viewport->zoom);
+		WP(w,vp_d).dest_scrollpos_y += ScaleByZoom(y, w->viewport->zoom);
 	}
 }
 
@@ -1284,6 +1284,8 @@
 
 	WP(w,vp_d).scrollpos_x = _saved_scrollpos_x;
 	WP(w,vp_d).scrollpos_y = _saved_scrollpos_y;
+	WP(w,vp_d).dest_scrollpos_x = _saved_scrollpos_x;
+	WP(w,vp_d).dest_scrollpos_y = _saved_scrollpos_y;
 
 	vp = w->viewport;
 	vp->zoom = _saved_scrollpos_zoom;
--- a/src/settings.cpp	Mon May 28 04:15:32 2007 +0000
+++ b/src/settings.cpp	Mon May 28 16:46:16 2007 +0000
@@ -1328,6 +1328,7 @@
 	SDT_BOOL(Patches, show_finances,                 S, 0,  true,        STR_CONFIG_PATCHES_SHOWFINANCES,          NULL),
 	SDT_BOOL(Patches, autoscroll,                    S, 0, false,        STR_CONFIG_PATCHES_AUTOSCROLL,            NULL),
 	SDT_BOOL(Patches, reverse_scroll,                S, 0, false,        STR_CONFIG_PATCHES_REVERSE_SCROLLING,     NULL),
+	SDT_BOOL(Patches, smooth_scroll,                 S, 0, false,        STR_CONFIG_PATCHES_SMOOTH_SCROLLING,      NULL),
 	SDT_BOOL(Patches, measure_tooltip,               S, 0, false,        STR_CONFIG_PATCHES_MEASURE_TOOLTIP,       NULL),
 	 SDT_VAR(Patches, errmsg_duration,    SLE_UINT8, S, 0,  5, 0, 20, 0, STR_CONFIG_PATCHES_ERRMSG_DURATION,       NULL),
 	 SDT_VAR(Patches, toolbar_pos,        SLE_UINT8, S,MS,  0, 0,  2, 0, STR_CONFIG_PATCHES_TOOLBAR_POS,           v_PositionMainToolbar),
--- a/src/settings_gui.cpp	Mon May 28 04:15:32 2007 +0000
+++ b/src/settings_gui.cpp	Mon May 28 16:46:16 2007 +0000
@@ -583,6 +583,7 @@
 	"show_finances",
 	"autoscroll",
 	"reverse_scroll",
+	"smooth_scroll",
 	"errmsg_duration",
 	"toolbar_pos",
 	"measure_tooltip",
--- a/src/smallmap_gui.cpp	Mon May 28 04:15:32 2007 +0000
+++ b/src/smallmap_gui.cpp	Mon May 28 16:46:16 2007 +0000
@@ -806,8 +806,8 @@
 					_left_button_clicked = false;
 
 					pt = RemapCoords(WP(w,smallmap_d).scroll_x, WP(w,smallmap_d).scroll_y, 0);
-					WP(w2, vp_d).scrollpos_x = pt.x + ((_cursor.pos.x - w->left + 2) << 4) - (w2->viewport->virtual_width >> 1);
-					WP(w2, vp_d).scrollpos_y = pt.y + ((_cursor.pos.y - w->top - 16) << 4) - (w2->viewport->virtual_height >> 1);
+					WP(w2, vp_d).dest_scrollpos_x = pt.x + ((_cursor.pos.x - w->left + 2) << 4) - (w2->viewport->virtual_width >> 1);
+					WP(w2, vp_d).dest_scrollpos_y = pt.y + ((_cursor.pos.y - w->top - 16) << 4) - (w2->viewport->virtual_height >> 1);
 
 					SetWindowDirty(w);
 				} break;
@@ -986,8 +986,8 @@
 			int y = WP(w, vp_d).scrollpos_y;
 
 			/* set this view to same location. Based on the center, adjusting for zoom */
-			WP(w2, vp_d).scrollpos_x =  x - (w2->viewport->virtual_width -  w->viewport->virtual_width) / 2;
-			WP(w2, vp_d).scrollpos_y =  y - (w2->viewport->virtual_height - w->viewport->virtual_height) / 2;
+			WP(w2, vp_d).dest_scrollpos_x =  x - (w2->viewport->virtual_width -  w->viewport->virtual_width) / 2;
+			WP(w2, vp_d).dest_scrollpos_y =  y - (w2->viewport->virtual_height - w->viewport->virtual_height) / 2;
 		} break;
 
 		case 8: { /* inverse location button (move this view to same spot as main view) 'Copy Location' */
@@ -995,8 +995,8 @@
 			int x = WP(w2, const vp_d).scrollpos_x;
 			int y = WP(w2, const vp_d).scrollpos_y;
 
-			WP(w, vp_d).scrollpos_x =  x + (w2->viewport->virtual_width -  w->viewport->virtual_width) / 2;
-			WP(w, vp_d).scrollpos_y =  y + (w2->viewport->virtual_height - w->viewport->virtual_height) / 2;
+			WP(w, vp_d).dest_scrollpos_x =  x + (w2->viewport->virtual_width -  w->viewport->virtual_width) / 2;
+			WP(w, vp_d).dest_scrollpos_y =  y + (w2->viewport->virtual_height - w->viewport->virtual_height) / 2;
 		} break;
 		}
 		break;
@@ -1018,6 +1018,8 @@
 
 			WP(w, vp_d).scrollpos_x += ScaleByZoom(e->we.scroll.delta.x, vp->zoom);
 			WP(w, vp_d).scrollpos_y += ScaleByZoom(e->we.scroll.delta.y, vp->zoom);
+			WP(w, vp_d).dest_scrollpos_x = WP(w, vp_d).scrollpos_x;
+			WP(w, vp_d).dest_scrollpos_y = WP(w, vp_d).scrollpos_y;
 		} break;
 
 		case WE_MOUSEWHEEL:
@@ -1062,5 +1064,7 @@
 		y = WP(v, vp_d).scrollpos_y;
 		WP(w, vp_d).scrollpos_x = x + (v->viewport->virtual_width  - (294)) / 2;
 		WP(w, vp_d).scrollpos_y = y + (v->viewport->virtual_height - (214)) / 2;
+		WP(w, vp_d).dest_scrollpos_x = WP(w, vp_d).scrollpos_x;
+		WP(w, vp_d).dest_scrollpos_y = WP(w, vp_d).scrollpos_y;
 	}
 }
--- a/src/variables.h	Mon May 28 04:15:32 2007 +0000
+++ b/src/variables.h	Mon May 28 16:46:16 2007 +0000
@@ -127,6 +127,7 @@
 	bool no_servicing_if_no_breakdowns; // dont send vehicles to depot when breakdowns are disabled
 	bool link_terraform_toolbar;        // display terraform toolbar when displaying rail, road, water and airport toolbars
 	bool reverse_scroll;                // Right-Click-Scrolling scrolls in the opposite direction
+	bool smooth_scroll;                 ///< Smooth scroll viewports
 	bool disable_elrails;               // when true, the elrails are disabled
 	bool measure_tooltip;               // Show a permanent tooltip when dragging tools
 	byte liveries;                      // Options for displaying company liveries, 0=none, 1=self, 2=all
--- a/src/viewport.cpp	Mon May 28 04:15:32 2007 +0000
+++ b/src/viewport.cpp	Mon May 28 16:46:16 2007 +0000
@@ -183,6 +183,9 @@
 
 	WP(w, vp_d).scrollpos_x = pt.x;
 	WP(w, vp_d).scrollpos_y = pt.y;
+	WP(w, vp_d).dest_scrollpos_x = pt.x;
+	WP(w, vp_d).dest_scrollpos_y = pt.y;
+
 	w->viewport = vp;
 	vp->virtual_left = 0;//pt.x;
 	vp->virtual_top = 0;//pt.y;
@@ -1386,6 +1389,20 @@
 		/* Center of the viewport is hot spot */
 		x = WP(w,vp_d).scrollpos_x + vp->virtual_width / 2;
 		y = WP(w,vp_d).scrollpos_y + vp->virtual_height / 2;
+
+		int dest_x = WP(w,vp_d).dest_scrollpos_x + vp->virtual_width / 2;
+		int dest_y = WP(w,vp_d).dest_scrollpos_y + vp->virtual_height / 2;
+
+		int delta_x = dest_x - x;
+		int delta_y = dest_y - y;
+
+		if (delta_x != 0 || delta_y != 0) {
+			int max_scroll = ScaleByMapSize1D(512);
+			/* Not at our desired positon yet... */
+			x += clamp(delta_x / 8, -max_scroll, max_scroll);
+			y += clamp(delta_y / 8, -max_scroll, max_scroll);
+		}
+
 		/* Convert viewport coordinates to map coordinates
 		 * Calculation is scaled by 4 to avoid rounding errors */
 		vx = -x + y * 2;
@@ -1841,26 +1858,31 @@
 
 
 /* scrolls the viewport in a window to a given location */
-bool ScrollWindowTo(int x , int y, Window *w)
+bool ScrollWindowTo(int x , int y, Window *w, bool instant)
 {
 	Point pt;
 
 	pt = MapXYZToViewport(w->viewport, x, y, GetSlopeZ(x, y));
 	WP(w, vp_d).follow_vehicle = INVALID_VEHICLE;
 
-	if (WP(w, vp_d).scrollpos_x == pt.x && WP(w, vp_d).scrollpos_y == pt.y)
+	if (WP(w, vp_d).dest_scrollpos_x == pt.x && WP(w, vp_d).dest_scrollpos_y == pt.y)
 		return false;
 
-	WP(w, vp_d).scrollpos_x = pt.x;
-	WP(w, vp_d).scrollpos_y = pt.y;
+	if (!_patches.smooth_scroll || instant) {
+		WP(w, vp_d).scrollpos_x = pt.x;
+		WP(w, vp_d).scrollpos_y = pt.y;
+	}
+
+	WP(w, vp_d).dest_scrollpos_x = pt.x;
+	WP(w, vp_d).dest_scrollpos_y = pt.y;
 	return true;
 }
 
 
-bool ScrollMainWindowTo(int x, int y)
+bool ScrollMainWindowTo(int x, int y, bool instant)
 {
 	Window *w;
-	bool res = ScrollWindowTo(x, y, FindWindowById(WC_MAIN_WINDOW, 0));
+	bool res = ScrollWindowTo(x, y, FindWindowById(WC_MAIN_WINDOW, 0), instant);
 
 	/* If a user scrolls to a tile (via what way what so ever) and already is on
 	 *  that tile (e.g.: pressed twice), move the smallmap to that location,
@@ -1877,9 +1899,9 @@
 }
 
 
-bool ScrollMainWindowToTile(TileIndex tile)
+bool ScrollMainWindowToTile(TileIndex tile, bool instant)
 {
-	return ScrollMainWindowTo(TileX(tile) * TILE_SIZE + TILE_SIZE / 2, TileY(tile) * TILE_SIZE + TILE_SIZE / 2);
+	return ScrollMainWindowTo(TileX(tile) * TILE_SIZE + TILE_SIZE / 2, TileY(tile) * TILE_SIZE + TILE_SIZE / 2, instant);
 }
 
 void SetRedErrorSquare(TileIndex tile)
--- a/src/window.h	Mon May 28 04:15:32 2007 +0000
+++ b/src/window.h	Mon May 28 16:46:16 2007 +0000
@@ -404,6 +404,8 @@
 	VehicleID follow_vehicle;
 	int32 scrollpos_x;
 	int32 scrollpos_y;
+	int32 dest_scrollpos_x;
+	int32 dest_scrollpos_y;
 };
 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(vp_d));
 
@@ -412,6 +414,8 @@
 	VehicleID follow_vehicle;
 	int32 scrollpos_x;
 	int32 scrollpos_y;
+	int32 dest_scrollpos_x;
+	int32 dest_scrollpos_y;
 	byte data_1;
 	byte data_2;
 	byte data_3;
@@ -422,6 +426,8 @@
 	uint16 follow_vehicle;
 	int32 scrollpos_x;
 	int32 scrollpos_y;
+	int32 dest_scrollpos_x;
+	int32 dest_scrollpos_y;
 	NewsItem *ni;
 };
 assert_compile(WINDOW_CUSTOM_SIZE >= sizeof(news_d));