From 344e9007feac6dd1e90154b45e80907c5e49821a Mon Sep 17 00:00:00 2001 From: peter1138 Date: Mon, 28 May 2007 16:46:16 +0000 Subject: (svn r9962) -Feature: Add smooth viewport scrolling. This must be enabled with patch setting 'smooth_scroll' --- src/functions.h | 6 +++--- src/lang/english.txt | 1 + src/main_gui.cpp | 8 +++++++- src/openttd.cpp | 6 ++++-- src/settings.cpp | 1 + src/settings_gui.cpp | 1 + src/smallmap_gui.cpp | 16 ++++++++++------ src/variables.h | 1 + src/viewport.cpp | 38 ++++++++++++++++++++++++++++++-------- src/window.h | 6 ++++++ 10 files changed, 64 insertions(+), 20 deletions(-) diff --git a/src/functions.h b/src/functions.h index 2540843da..12cf9deb8 100644 --- a/src/functions.h +++ b/src/functions.h @@ -131,10 +131,10 @@ void SetObjectToPlace(CursorID icon, SpriteID pal, byte mode, WindowClass window 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); diff --git a/src/lang/english.txt b/src/lang/english.txt index 7b97f9c5a..c3f9dc0cf 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -1089,6 +1089,7 @@ STR_CONFIG_PATCHES_STATION_SPREAD :{LTBLUE}Max sta 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 diff --git a/src/main_gui.cpp b/src/main_gui.cpp index d48cd82fb..84540598d 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.cpp @@ -889,6 +889,8 @@ bool DoZoomInOutWindow(int how, Window *w) 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 @@ bool DoZoomInOutWindow(int how, Window *w) 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 @@ void ZoomInOrOutToCursorWindow(bool in, Window *w) 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 @@ static void MainWindowWndProc(Window *w, WindowEvent *e) 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: diff --git a/src/openttd.cpp b/src/openttd.cpp index 58fff0971..5d8762319 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -991,8 +991,8 @@ static void ScrollMainViewport(int x, int y) 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 @@ bool AfterLoadGame() 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; diff --git a/src/settings.cpp b/src/settings.cpp index 53c67e67f..1fd8effef 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1328,6 +1328,7 @@ const SettingDesc _patch_settings[] = { 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), diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index f24ef10ed..ce8679b60 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.cpp @@ -583,6 +583,7 @@ static const char *_patches_ui[] = { "show_finances", "autoscroll", "reverse_scroll", + "smooth_scroll", "errmsg_duration", "toolbar_pos", "measure_tooltip", diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp index 2035a8a96..e0a13991f 100644 --- a/src/smallmap_gui.cpp +++ b/src/smallmap_gui.cpp @@ -806,8 +806,8 @@ static void SmallMapWindowProc(Window *w, WindowEvent *e) _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 @@ static void ExtraViewPortWndProc(Window *w, WindowEvent *e) 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 @@ static void ExtraViewPortWndProc(Window *w, WindowEvent *e) 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 @@ static void ExtraViewPortWndProc(Window *w, WindowEvent *e) 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 @@ void ShowExtraViewPortWindow() 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; } } diff --git a/src/variables.h b/src/variables.h index 4c5aaf8e5..c8a3cd23e 100644 --- a/src/variables.h +++ b/src/variables.h @@ -127,6 +127,7 @@ struct Patches { 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 diff --git a/src/viewport.cpp b/src/viewport.cpp index a40dd2777..a06547051 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -183,6 +183,9 @@ void AssignWindowViewport(Window *w, int x, int y, 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 @@ void UpdateViewportPosition(Window *w) /* 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 @@ void PlaceObject() /* 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 ScrollMainWindowTo(int x, int y) } -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) diff --git a/src/window.h b/src/window.h index b33990420..f1888c294 100644 --- a/src/window.h +++ b/src/window.h @@ -404,6 +404,8 @@ struct vp_d { 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 @@ struct vp2_d { 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 @@ struct news_d { 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)); -- cgit v1.2.3-70-g09d2