--- a/src/viewport.cpp Tue Mar 27 23:27:27 2007 +0000
+++ b/src/viewport.cpp Sat Jun 02 19:59:29 2007 +0000
@@ -11,6 +11,7 @@
#include "strings.h"
#include "table/sprites.h"
#include "table/strings.h"
+#include "landscape.h"
#include "map.h"
#include "viewport.h"
#include "window.h"
@@ -26,7 +27,9 @@
#define VIEWPORT_DRAW_MEM (65536 * 2)
-// XXX - maximum viewports is maximum windows - 2 (main toolbar + status bar)
+ZoomLevel _saved_scrollpos_zoom;
+
+/* XXX - maximum viewports is maximum windows - 2 (main toolbar + status bar) */
static ViewPort _viewports[25 - 2];
static uint32 _active_viewports; ///< bitmasked variable where each bit signifies if a viewport is in use or not
assert_compile(lengthof(_viewports) < sizeof(_active_viewports) * 8);
@@ -92,8 +95,8 @@
byte zmax;
};
-// Quick hack to know how much memory to reserve when allocating from the spritelist
-// to prevent a buffer overflow.
+/* Quick hack to know how much memory to reserve when allocating from the spritelist
+ * to prevent a buffer overflow. */
#define LARGEST_SPRITELIST_STRUCT ParentSpriteToDraw
struct ViewportDrawer {
@@ -143,7 +146,7 @@
}
void AssignWindowViewport(Window *w, int x, int y,
- int width, int height, uint32 follow_flags, byte zoom)
+ int width, int height, uint32 follow_flags, ZoomLevel zoom)
{
ViewPort *vp;
Point pt;
@@ -162,8 +165,8 @@
vp->zoom = zoom;
- vp->virtual_width = width << zoom;
- vp->virtual_height = height << zoom;
+ vp->virtual_width = ScaleByZoom(width, zoom);
+ vp->virtual_height = ScaleByZoom(height, zoom);
if (follow_flags & 0x80000000) {
const Vehicle *veh;
@@ -181,6 +184,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;
@@ -267,10 +273,10 @@
vp->virtual_left = x;
vp->virtual_top = y;
- old_left >>= vp->zoom;
- old_top >>= vp->zoom;
- x >>= vp->zoom;
- y >>= vp->zoom;
+ old_left = UnScaleByZoom(old_left, vp->zoom);
+ old_top = UnScaleByZoom(old_top, vp->zoom);
+ x = UnScaleByZoom(x, vp->zoom);
+ y = UnScaleByZoom(y, vp->zoom);
old_left -= x;
old_top -= y;
@@ -331,8 +337,8 @@
return pt;
}
- x = ((x << vp->zoom) + vp->virtual_left) >> 2;
- y = ((y << vp->zoom) + vp->virtual_top) >> 1;
+ x = (ScaleByZoom(x, vp->zoom) + vp->virtual_left) >> 2;
+ y = (ScaleByZoom(y, vp->zoom) + vp->virtual_top) >> 1;
a = y-x;
b = y+x;
@@ -398,16 +404,16 @@
/** Update the status of the zoom-buttons according to the zoom-level
* of the viewport. This will update their status and invalidate accordingly
- * @param window pointer to the window that has the zoom buttons
+ * @param w Window pointer to the window that has the zoom buttons
* @param vp pointer to the viewport whose zoom-level the buttons represent
* @param widget_zoom_in widget index for window with zoom-in button
* @param widget_zoom_out widget index for window with zoom-out button */
void HandleZoomMessage(Window *w, const ViewPort *vp, byte widget_zoom_in, byte widget_zoom_out)
{
- SetWindowWidgetDisabledState(w, widget_zoom_in, vp->zoom == 0);
+ SetWindowWidgetDisabledState(w, widget_zoom_in, vp->zoom == ZOOM_LVL_MIN);
InvalidateWidget(w, widget_zoom_in);
- SetWindowWidgetDisabledState(w, widget_zoom_out, vp->zoom == 2);
+ SetWindowWidgetDisabledState(w, widget_zoom_out, vp->zoom == ZOOM_LVL_MAX);
InvalidateWidget(w, widget_zoom_out);
}
@@ -439,7 +445,7 @@
void DrawGroundSprite(SpriteID image, SpriteID pal)
{
if (_offset_ground_sprites) {
- // offset ground sprite because of foundation?
+ /* offset ground sprite because of foundation? */
AddChildSpriteScreen(image, pal, _cur_vd->offs_x, _cur_vd->offs_y);
} else {
_added_tile_sprite = true;
@@ -494,12 +500,12 @@
ps = (ParentSpriteToDraw*)vd->spritelist_mem;
if (vd->parent_list >= vd->eof_parent_list) {
- // This can happen rarely, mostly when you zoom out completely
- // and have a lot of stuff that moves (and is added to the
- // sort-list, this function). To solve it, increase
- // parent_list somewhere below to a higher number.
- // This can not really hurt you, it just gives some black
- // spots on the screen ;)
+ /* This can happen rarely, mostly when you zoom out completely
+ * and have a lot of stuff that moves (and is added to the
+ * sort-list, this function). To solve it, increase
+ * parent_list somewhere below to a higher number.
+ * This can not really hurt you, it just gives some black
+ * spots on the screen ;) */
DEBUG(sprite, 0, "Out of sprite memory (parent_list)");
return;
}
@@ -647,16 +653,16 @@
SpriteID image;
SpriteID pal;
- // Draw a red error square?
+ /* Draw a red error square? */
if (_thd.redsq != 0 && _thd.redsq == ti->tile) {
DrawSelectionSprite(SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh], PALETTE_TILE_RED_PULSATING, ti);
return;
}
- // no selection active?
+ /* no selection active? */
if (_thd.drawstyle == 0) return;
- // Inside the inner area?
+ /* Inside the inner area? */
if (IS_INSIDE_1D(ti->x, _thd.pos.x, _thd.size.x) &&
IS_INSIDE_1D(ti->y, _thd.pos.y, _thd.size.y)) {
if (_thd.drawstyle & HT_RECT) {
@@ -669,15 +675,15 @@
DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : PAL_NONE, ti);
}
} else if (_thd.drawstyle & HT_POINT) {
- // Figure out the Z coordinate for the single dot.
+ /* Figure out the Z coordinate for the single dot. */
byte z = ti->z;
if (ti->tileh & SLOPE_N) {
z += TILE_HEIGHT;
if (ti->tileh == SLOPE_STEEP_N) z += TILE_HEIGHT;
}
- DrawGroundSpriteAt(_cur_dpi->zoom != 2 ? SPR_DOT : SPR_DOT_SMALL, PAL_NONE, ti->x, ti->y, z);
+ DrawGroundSpriteAt(_cur_dpi->zoom <= ZOOM_LVL_DETAIL ? SPR_DOT : SPR_DOT_SMALL, PAL_NONE, ti->x, ti->y, z);
} else if (_thd.drawstyle & HT_RAIL /*&& _thd.place_mode == VHM_RAIL*/) {
- // autorail highlight piece under cursor
+ /* autorail highlight piece under cursor */
uint type = _thd.drawstyle & 0xF;
int offset;
@@ -695,7 +701,7 @@
DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : pal, ti);
} else if (IsPartOfAutoLine(ti->x, ti->y)) {
- // autorail highlighting long line
+ /* autorail highlighting long line */
int dir = _thd.drawstyle & ~0xF0;
int offset;
uint side;
@@ -721,12 +727,12 @@
return;
}
- // Check if it's inside the outer area?
+ /* Check if it's inside the outer area? */
if (_thd.outersize.x &&
_thd.size.x < _thd.size.x + _thd.outersize.x &&
IS_INSIDE_1D(ti->x, _thd.pos.x + _thd.offs.x, _thd.size.x + _thd.outersize.x) &&
IS_INSIDE_1D(ti->y, _thd.pos.y + _thd.offs.y, _thd.size.y + _thd.outersize.y)) {
- // Draw a blue rect.
+ /* Draw a blue rect. */
DrawSelectionSprite(SPR_SELECT_TILE + _tileh_to_sprite[ti->tileh], PALETTE_SEL_TILE_BLUE, ti);
return;
}
@@ -741,11 +747,11 @@
_cur_ti = &ti;
- // Transform into tile coordinates and round to closest full tile
+ /* Transform into tile coordinates and round to closest full tile */
x = ((vd->dpi.top >> 1) - (vd->dpi.left >> 2)) & ~0xF;
y = ((vd->dpi.top >> 1) + (vd->dpi.left >> 2) - 0x10) & ~0xF;
- // determine size of area
+ /* determine size of area */
{
Point pt = RemapCoords(x, y, 241);
width = (vd->dpi.left + vd->dpi.width - pt.x + 95) >> 6;
@@ -805,7 +811,7 @@
Town *t;
int left, top, right, bottom;
- if (!(_display_opt & DO_SHOW_TOWN_NAMES) || _game_mode == GM_MENU)
+ if (!HASBIT(_display_opt, DO_SHOW_TOWN_NAMES) || _game_mode == GM_MENU)
return;
left = dpi->left;
@@ -814,7 +820,7 @@
bottom = top + dpi->height;
switch (dpi->zoom) {
- case 0:
+ case ZOOM_LVL_NORMAL:
FOR_ALL_TOWNS(t) {
if (bottom > t->sign.top &&
top < t->sign.top + 12 &&
@@ -827,7 +833,7 @@
}
break;
- case 1:
+ case ZOOM_LVL_OUT_2X:
right += 2;
bottom += 2;
@@ -843,21 +849,26 @@
}
break;
- default: NOT_REACHED();
- case 2:
- right += 4;
- bottom += 5;
+ case ZOOM_LVL_OUT_4X:
+ case ZOOM_LVL_OUT_8X:
+ right += ScaleByZoom(1, dpi->zoom);
+ bottom += ScaleByZoom(1, dpi->zoom) + 1;
FOR_ALL_TOWNS(t) {
if (bottom > t->sign.top &&
- top < t->sign.top + 24 &&
+ top < t->sign.top + ScaleByZoom(12, dpi->zoom) &&
right > t->sign.left &&
- left < t->sign.left + t->sign.width_2*4) {
+ left < t->sign.left + ScaleByZoom(t->sign.width_2, dpi->zoom)) {
AddStringToDraw(t->sign.left + 5, t->sign.top + 1, STR_TOWN_LABEL_TINY_BLACK, t->index, 0);
AddStringToDraw(t->sign.left + 1, t->sign.top - 3, STR_TOWN_LABEL_TINY_WHITE, t->index, 0);
}
}
break;
+
+ case ZOOM_LVL_OUT_16X:
+ break;
+
+ default: NOT_REACHED();
}
}
@@ -879,7 +890,7 @@
int left, top, right, bottom;
const Station *st;
- if (!(_display_opt & DO_SHOW_STATION_NAMES) || _game_mode == GM_MENU)
+ if (!HASBIT(_display_opt, DO_SHOW_STATION_NAMES) || _game_mode == GM_MENU)
return;
left = dpi->left;
@@ -888,7 +899,7 @@
bottom = top + dpi->height;
switch (dpi->zoom) {
- case 0:
+ case ZOOM_LVL_NORMAL:
FOR_ALL_STATIONS(st) {
if (bottom > st->sign.top &&
top < st->sign.top + 12 &&
@@ -899,7 +910,7 @@
}
break;
- case 1:
+ case ZOOM_LVL_OUT_2X:
right += 2;
bottom += 2;
FOR_ALL_STATIONS(st) {
@@ -912,19 +923,25 @@
}
break;
- default: NOT_REACHED();
- case 2:
- right += 4;
- bottom += 5;
+ case ZOOM_LVL_OUT_4X:
+ case ZOOM_LVL_OUT_8X:
+ right += ScaleByZoom(1, dpi->zoom);
+ bottom += ScaleByZoom(1, dpi->zoom) + 1;
+
FOR_ALL_STATIONS(st) {
if (bottom > st->sign.top &&
- top < st->sign.top + 24 &&
+ top < st->sign.top + ScaleByZoom(12, dpi->zoom) &&
right > st->sign.left &&
- left < st->sign.left + st->sign.width_2*4) {
+ left < st->sign.left + ScaleByZoom(st->sign.width_2, dpi->zoom)) {
AddStation(st, STR_STATION_SIGN_TINY, st->sign.width_2 | 0x8000);
}
}
break;
+
+ case ZOOM_LVL_OUT_16X:
+ break;
+
+ default: NOT_REACHED();
}
}
@@ -946,7 +963,7 @@
const Sign *si;
int left, top, right, bottom;
- if (!(_display_opt & DO_SHOW_SIGNS))
+ if (!HASBIT(_display_opt, DO_SHOW_SIGNS))
return;
left = dpi->left;
@@ -955,7 +972,7 @@
bottom = top + dpi->height;
switch (dpi->zoom) {
- case 0:
+ case ZOOM_LVL_NORMAL:
FOR_ALL_SIGNS(si) {
if (bottom > si->sign.top &&
top < si->sign.top + 12 &&
@@ -966,7 +983,7 @@
}
break;
- case 1:
+ case ZOOM_LVL_OUT_2X:
right += 2;
bottom += 2;
FOR_ALL_SIGNS(si) {
@@ -979,19 +996,25 @@
}
break;
- default: NOT_REACHED();
- case 2:
- right += 4;
- bottom += 5;
+ case ZOOM_LVL_OUT_4X:
+ case ZOOM_LVL_OUT_8X:
+ right += ScaleByZoom(1, dpi->zoom);
+ bottom += ScaleByZoom(1, dpi->zoom) + 1;
+
FOR_ALL_SIGNS(si) {
if (bottom > si->sign.top &&
- top < si->sign.top + 24 &&
+ top < si->sign.top + ScaleByZoom(12, dpi->zoom) &&
right > si->sign.left &&
- left < si->sign.left + si->sign.width_2 * 4) {
+ left < si->sign.left + ScaleByZoom(si->sign.width_2, dpi->zoom)) {
AddSign(si, STR_2002, si->sign.width_2 | 0x8000);
}
}
break;
+
+ case ZOOM_LVL_OUT_16X:
+ break;
+
+ default: NOT_REACHED();
}
}
@@ -1013,7 +1036,7 @@
const Waypoint *wp;
int left, top, right, bottom;
- if (!(_display_opt & DO_WAYPOINTS))
+ if (!HASBIT(_display_opt, DO_WAYPOINTS))
return;
left = dpi->left;
@@ -1022,7 +1045,7 @@
bottom = top + dpi->height;
switch (dpi->zoom) {
- case 0:
+ case ZOOM_LVL_NORMAL:
FOR_ALL_WAYPOINTS(wp) {
if (bottom > wp->sign.top &&
top < wp->sign.top + 12 &&
@@ -1033,7 +1056,7 @@
}
break;
- case 1:
+ case ZOOM_LVL_OUT_2X:
right += 2;
bottom += 2;
FOR_ALL_WAYPOINTS(wp) {
@@ -1046,19 +1069,25 @@
}
break;
- default: NOT_REACHED();
- case 2:
- right += 4;
- bottom += 5;
+ case ZOOM_LVL_OUT_4X:
+ case ZOOM_LVL_OUT_8X:
+ right += ScaleByZoom(1, dpi->zoom);
+ bottom += ScaleByZoom(1, dpi->zoom) + 1;
+
FOR_ALL_WAYPOINTS(wp) {
if (bottom > wp->sign.top &&
- top < wp->sign.top + 24 &&
+ top < wp->sign.top + ScaleByZoom(12, dpi->zoom) &&
right > wp->sign.left &&
- left < wp->sign.left + wp->sign.width_2*4) {
+ left < wp->sign.left + ScaleByZoom(wp->sign.width_2, dpi->zoom)) {
AddWaypoint(wp, STR_WAYPOINT_VIEWPORT_TINY, wp->sign.width_2 | 0x8000);
}
}
break;
+
+ case ZOOM_LVL_OUT_16X:
+ break;
+
+ default: NOT_REACHED();
}
}
@@ -1135,7 +1164,7 @@
}
}
- // Swap the two sprites ps and ps2 using bubble-sort algorithm.
+ /* Swap the two sprites ps and ps2 using bubble-sort algorithm. */
psd3 = psd;
do {
ParentSpriteToDraw* temp = *psd3;
@@ -1169,25 +1198,25 @@
static void ViewportDrawStrings(DrawPixelInfo *dpi, const StringSpriteToDraw *ss)
{
DrawPixelInfo dp;
- byte zoom;
+ ZoomLevel zoom;
_cur_dpi = &dp;
dp = *dpi;
zoom = dp.zoom;
- dp.zoom = 0;
-
- dp.left >>= zoom;
- dp.top >>= zoom;
- dp.width >>= zoom;
- dp.height >>= zoom;
+ dp.zoom = ZOOM_LVL_NORMAL;
+
+ dp.left = UnScaleByZoom(dp.left, zoom);
+ dp.top = UnScaleByZoom(dp.top, zoom);
+ dp.width = UnScaleByZoom(dp.width, zoom);
+ dp.height = UnScaleByZoom(dp.height, zoom);
do {
uint16 colour;
if (ss->width != 0) {
- int x = (ss->x >> zoom) - 1;
- int y = (ss->y >> zoom) - 1;
+ int x = UnScaleByZoom(ss->x, zoom) - 1;
+ int y = UnScaleByZoom(ss->y, zoom) - 1;
int bottom = y + 11;
int w = ss->width;
@@ -1200,21 +1229,19 @@
/* Draw the rectangle if 'tranparent station signs' is off,
* or if we are drawing a general text sign (STR_2806) */
- if (!(_display_opt & DO_TRANS_SIGNS) || ss->string == STR_2806)
+ if (!HASBIT(_transparent_opt, TO_SIGNS) || ss->string == STR_2806) {
DrawFrameRect(
x, y, x + w, bottom, ss->color,
- (_display_opt & DO_TRANS_BUILDINGS) ? FR_TRANSPARENT : FR_NONE
+ HASBIT(_transparent_opt, TO_SIGNS) ? FR_TRANSPARENT : FR_NONE
);
+ }
}
SetDParam(0, ss->params[0]);
SetDParam(1, ss->params[1]);
/* if we didn't draw a rectangle, or if transparant building is on,
* draw the text in the color the rectangle would have */
- if ((
- (_display_opt & DO_TRANS_BUILDINGS) ||
- (_display_opt & DO_TRANS_SIGNS && ss->string != STR_2806)
- ) && ss->width != 0) {
+ if (HASBIT(_transparent_opt, TO_SIGNS) && ss->string != STR_2806 && ss->width != 0) {
/* Real colors need the IS_PALETTE_COLOR flag
* otherwise colors from _string_colormap are assumed. */
colour = _colour_gradient[ss->color][6] | IS_PALETTE_COLOR;
@@ -1222,7 +1249,7 @@
colour = 16;
}
DrawString(
- ss->x >> zoom, (ss->y >> zoom) - (ss->width & 0x8000 ? 2 : 0),
+ UnScaleByZoom(ss->x, zoom), UnScaleByZoom(ss->y, zoom) - (ss->width & 0x8000 ? 2 : 0),
ss->string, colour
);
@@ -1247,7 +1274,7 @@
_cur_dpi = &vd.dpi;
vd.dpi.zoom = vp->zoom;
- mask = (-1) << vp->zoom;
+ mask = ScaleByZoom(-1, vp->zoom);
vd.combine_sprites = 0;
@@ -1257,8 +1284,8 @@
vd.dpi.top = top & mask;
vd.dpi.pitch = old_dpi->pitch;
- x = ((vd.dpi.left - (vp->virtual_left&mask)) >> vp->zoom) + vp->left;
- y = ((vd.dpi.top - (vp->virtual_top&mask)) >> vp->zoom) + vp->top;
+ x = UnScaleByZoom(vd.dpi.left - (vp->virtual_left & mask), vp->zoom) + vp->left;
+ y = UnScaleByZoom(vd.dpi.top - (vp->virtual_top & mask), vp->zoom) + vp->top;
vd.dpi.dst_ptr = old_dpi->dst_ptr + x - old_dpi->left + (y - old_dpi->top) * old_dpi->pitch;
@@ -1280,8 +1307,8 @@
ViewportAddSigns(&vd.dpi);
ViewportAddWaypoints(&vd.dpi);
- // This assert should never happen (because the length of the parent_list
- // is checked)
+ /* This assert should never happen (because the length of the parent_list
+ * is checked) */
assert(vd.parent_list <= endof(parent_list));
if (vd.first_tile != NULL) ViewportDrawTileSprites(vd.first_tile);
@@ -1297,11 +1324,11 @@
_cur_dpi = old_dpi;
}
-// Make sure we don't draw a too big area at a time.
-// If we do, the sprite memory will overflow.
+/** Make sure we don't draw a too big area at a time.
+ * If we do, the sprite memory will overflow. */
static void ViewportDrawChk(const ViewPort *vp, int left, int top, int right, int bottom)
{
- if (((bottom - top) * (right - left) << (2 * vp->zoom)) > 180000) {
+ if (ScaleByZoom(bottom - top, vp->zoom) * ScaleByZoom(right - left, vp->zoom) > 180000) {
if ((bottom - top) > (right - left)) {
int t = (top + bottom) >> 1;
ViewportDrawChk(vp, left, top, right, t);
@@ -1313,10 +1340,10 @@
}
} else {
ViewportDoDraw(vp,
- ((left - vp->left) << vp->zoom) + vp->virtual_left,
- ((top - vp->top) << vp->zoom) + vp->virtual_top,
- ((right - vp->left) << vp->zoom) + vp->virtual_left,
- ((bottom - vp->top) << vp->zoom) + vp->virtual_top
+ ScaleByZoom(left - vp->left, vp->zoom) + vp->virtual_left,
+ ScaleByZoom(top - vp->top, vp->zoom) + vp->virtual_top,
+ ScaleByZoom(right - vp->left, vp->zoom) + vp->virtual_left,
+ ScaleByZoom(bottom - vp->top, vp->zoom) + vp->virtual_top
);
}
}
@@ -1366,20 +1393,39 @@
int vx;
int vy;
- // Center of the viewport is hot spot
+ /* 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;
- // Convert viewport coordinates to map coordinates
- // Calculation is scaled by 4 to avoid rounding errors
+
+ 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) {
+ if (_patches.smooth_scroll) {
+ 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);
+ } else {
+ x = dest_x;
+ y = dest_y;
+ }
+ }
+
+ /* Convert viewport coordinates to map coordinates
+ * Calculation is scaled by 4 to avoid rounding errors */
vx = -x + y * 2;
vy = x + y * 2;
- // clamp to size of map
+ /* clamp to size of map */
vx = clamp(vx, 0 * 4, MapMaxX() * TILE_SIZE * 4);
vy = clamp(vy, 0 * 4, MapMaxY() * TILE_SIZE * 4);
- // Convert map coordinates to viewport coordinates
+ /* Convert map coordinates to viewport coordinates */
x = (-vx + vy) / 2;
y = ( vx + vy) / 4;
- // Set position
+ /* Set position */
WP(w, vp_d).scrollpos_x = x - vp->virtual_width / 2;
WP(w, vp_d).scrollpos_y = y - vp->virtual_height / 2;
@@ -1404,10 +1450,10 @@
if (top >= vp->virtual_height) return;
SetDirtyBlocks(
- (left >> vp->zoom) + vp->left,
- (top >> vp->zoom) + vp->top,
- (right >> vp->zoom) + vp->left,
- (bottom >> vp->zoom) + vp->top
+ UnScaleByZoom(left, vp->zoom) + vp->left,
+ UnScaleByZoom(top, vp->zoom) + vp->top,
+ UnScaleByZoom(right, vp->zoom) + vp->left,
+ UnScaleByZoom(bottom, vp->zoom) + vp->top
);
}
@@ -1495,10 +1541,10 @@
{
const Town *t;
- if (!(_display_opt & DO_SHOW_TOWN_NAMES)) return false;
+ if (!HASBIT(_display_opt, DO_SHOW_TOWN_NAMES)) return false;
switch (vp->zoom) {
- case 0:
+ case ZOOM_LVL_NORMAL:
x = x - vp->left + vp->virtual_left;
y = y - vp->top + vp->virtual_top;
FOR_ALL_TOWNS(t) {
@@ -1512,7 +1558,7 @@
}
break;
- case 1:
+ case ZOOM_LVL_OUT_2X:
x = (x - vp->left + 1) * 2 + vp->virtual_left;
y = (y - vp->top + 1) * 2 + vp->virtual_top;
FOR_ALL_TOWNS(t) {
@@ -1526,19 +1572,26 @@
}
break;
- default:
- x = (x - vp->left + 3) * 4 + vp->virtual_left;
- y = (y - vp->top + 3) * 4 + vp->virtual_top;
+ case ZOOM_LVL_OUT_4X:
+ case ZOOM_LVL_OUT_8X:
+ x = ScaleByZoom(x - vp->left + ScaleByZoom(1, vp->zoom) - 1, vp->zoom) + vp->virtual_left;
+ y = ScaleByZoom(y - vp->top + ScaleByZoom(1, vp->zoom) - 1, vp->zoom) + vp->virtual_top;
+
FOR_ALL_TOWNS(t) {
if (y >= t->sign.top &&
- y < t->sign.top + 24 &&
+ y < t->sign.top + ScaleByZoom(12, vp->zoom) &&
x >= t->sign.left &&
- x < t->sign.left + t->sign.width_2 * 4) {
+ x < t->sign.left + ScaleByZoom(t->sign.width_2, vp->zoom)) {
ShowTownViewWindow(t->index);
return true;
}
}
break;
+
+ case ZOOM_LVL_OUT_16X:
+ break;
+
+ default: NOT_REACHED();
}
return false;
@@ -1549,10 +1602,10 @@
{
const Station *st;
- if (!(_display_opt & DO_SHOW_STATION_NAMES)) return false;
+ if (!HASBIT(_display_opt, DO_SHOW_STATION_NAMES)) return false;
switch (vp->zoom) {
- case 0:
+ case ZOOM_LVL_NORMAL:
x = x - vp->left + vp->virtual_left;
y = y - vp->top + vp->virtual_top;
FOR_ALL_STATIONS(st) {
@@ -1566,7 +1619,7 @@
}
break;
- case 1:
+ case ZOOM_LVL_OUT_2X:
x = (x - vp->left + 1) * 2 + vp->virtual_left;
y = (y - vp->top + 1) * 2 + vp->virtual_top;
FOR_ALL_STATIONS(st) {
@@ -1580,19 +1633,26 @@
}
break;
- default:
- x = (x - vp->left + 3) * 4 + vp->virtual_left;
- y = (y - vp->top + 3) * 4 + vp->virtual_top;
+ case ZOOM_LVL_OUT_4X:
+ case ZOOM_LVL_OUT_8X:
+ x = ScaleByZoom(x - vp->left + ScaleByZoom(1, vp->zoom) - 1, vp->zoom) + vp->virtual_left;
+ y = ScaleByZoom(y - vp->top + ScaleByZoom(1, vp->zoom) - 1, vp->zoom) + vp->virtual_top;
+
FOR_ALL_STATIONS(st) {
if (y >= st->sign.top &&
- y < st->sign.top + 24 &&
+ y < st->sign.top + ScaleByZoom(12, vp->zoom) &&
x >= st->sign.left &&
- x < st->sign.left + st->sign.width_2 * 4) {
+ x < st->sign.left + ScaleByZoom(st->sign.width_2, vp->zoom)) {
ShowStationViewWindow(st->index);
return true;
}
}
break;
+
+ case ZOOM_LVL_OUT_16X:
+ break;
+
+ default: NOT_REACHED();
}
return false;
@@ -1603,10 +1663,10 @@
{
const Sign *si;
- if (!(_display_opt & DO_SHOW_SIGNS) || _current_player == PLAYER_SPECTATOR) return false;
+ if (!HASBIT(_display_opt, DO_SHOW_SIGNS) || _current_player == PLAYER_SPECTATOR) return false;
switch (vp->zoom) {
- case 0:
+ case ZOOM_LVL_NORMAL:
x = x - vp->left + vp->virtual_left;
y = y - vp->top + vp->virtual_top;
FOR_ALL_SIGNS(si) {
@@ -1620,7 +1680,7 @@
}
break;
- case 1:
+ case ZOOM_LVL_OUT_2X:
x = (x - vp->left + 1) * 2 + vp->virtual_left;
y = (y - vp->top + 1) * 2 + vp->virtual_top;
FOR_ALL_SIGNS(si) {
@@ -1634,19 +1694,26 @@
}
break;
- default:
- x = (x - vp->left + 3) * 4 + vp->virtual_left;
- y = (y - vp->top + 3) * 4 + vp->virtual_top;
+ case ZOOM_LVL_OUT_4X:
+ case ZOOM_LVL_OUT_8X:
+ x = ScaleByZoom(x - vp->left + ScaleByZoom(1, vp->zoom) - 1, vp->zoom) + vp->virtual_left;
+ y = ScaleByZoom(y - vp->top + ScaleByZoom(1, vp->zoom) - 1, vp->zoom) + vp->virtual_top;
+
FOR_ALL_SIGNS(si) {
if (y >= si->sign.top &&
- y < si->sign.top + 24 &&
+ y < si->sign.top + ScaleByZoom(12, vp->zoom) &&
x >= si->sign.left &&
- x < si->sign.left + si->sign.width_2 * 4) {
+ x < si->sign.left + ScaleByZoom(si->sign.width_2, vp->zoom)) {
ShowRenameSignWindow(si);
return true;
}
}
break;
+
+ case ZOOM_LVL_OUT_16X:
+ break;
+
+ default: NOT_REACHED();
}
return false;
@@ -1657,10 +1724,10 @@
{
const Waypoint *wp;
- if (!(_display_opt & DO_WAYPOINTS)) return false;
+ if (!HASBIT(_display_opt, DO_WAYPOINTS)) return false;
switch (vp->zoom) {
- case 0:
+ case ZOOM_LVL_NORMAL:
x = x - vp->left + vp->virtual_left;
y = y - vp->top + vp->virtual_top;
FOR_ALL_WAYPOINTS(wp) {
@@ -1674,7 +1741,7 @@
}
break;
- case 1:
+ case ZOOM_LVL_OUT_2X:
x = (x - vp->left + 1) * 2 + vp->virtual_left;
y = (y - vp->top + 1) * 2 + vp->virtual_top;
FOR_ALL_WAYPOINTS(wp) {
@@ -1688,19 +1755,26 @@
}
break;
- default:
- x = (x - vp->left + 3) * 4 + vp->virtual_left;
- y = (y - vp->top + 3) * 4 + vp->virtual_top;
+ case ZOOM_LVL_OUT_4X:
+ case ZOOM_LVL_OUT_8X:
+ x = ScaleByZoom(x - vp->left + ScaleByZoom(1, vp->zoom) - 1, vp->zoom) + vp->virtual_left;
+ y = ScaleByZoom(y - vp->top + ScaleByZoom(1, vp->zoom) - 1, vp->zoom) + vp->virtual_top;
+
FOR_ALL_WAYPOINTS(wp) {
if (y >= wp->sign.top &&
- y < wp->sign.top + 24 &&
+ y < wp->sign.top + ScaleByZoom(12, vp->zoom) &&
x >= wp->sign.left &&
- x < wp->sign.left + wp->sign.width_2 * 4) {
+ x < wp->sign.left + ScaleByZoom(wp->sign.width_2, vp->zoom)) {
ShowRenameWaypointWindow(wp);
return true;
}
}
break;
+
+ case ZOOM_LVL_OUT_16X:
+ break;
+
+ default: NOT_REACHED();
}
return false;
@@ -1796,26 +1870,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 (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,
@@ -1832,9 +1911,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)
@@ -1866,13 +1945,13 @@
_thd.new_outersize.y = sy * TILE_SIZE;
}
-/* returns the best autorail highlight type from map coordinates */
+/** returns the best autorail highlight type from map coordinates */
static byte GetAutorailHT(int x, int y)
{
return HT_RAIL | _AutorailPiece[x & 0xF][y & 0xF];
}
-// called regular to update tile highlighting in all cases
+/** called regular to update tile highlighting in all cases */
void UpdateTileSelection()
{
int x1;
@@ -1919,13 +1998,13 @@
}
}
- // redraw selection
+ /* redraw selection */
if (_thd.drawstyle != _thd.new_drawstyle ||
_thd.pos.x != _thd.new_pos.x || _thd.pos.y != _thd.new_pos.y ||
_thd.size.x != _thd.new_size.x || _thd.size.y != _thd.new_size.y ||
_thd.outersize.x != _thd.new_outersize.x ||
_thd.outersize.y != _thd.new_outersize.y) {
- // clear the old selection?
+ /* clear the old selection? */
if (_thd.drawstyle) SetSelectionTilesDirty();
_thd.drawstyle = _thd.new_drawstyle;
@@ -1934,15 +2013,16 @@
_thd.outersize = _thd.new_outersize;
_thd.dirty = 0xff;
- // draw the new selection?
+ /* draw the new selection? */
if (_thd.new_drawstyle) SetSelectionTilesDirty();
}
}
-// highlighting tiles while only going over them with the mouse
-void VpStartPlaceSizing(TileIndex tile, int user)
+/** highlighting tiles while only going over them with the mouse */
+void VpStartPlaceSizing(TileIndex tile, byte method, byte process)
{
- _thd.userdata = user;
+ _thd.select_method = method;
+ _thd.select_proc = process;
_thd.selend.x = TileX(tile) * TILE_SIZE;
_thd.selstart.x = TileX(tile) * TILE_SIZE;
_thd.selend.y = TileY(tile) * TILE_SIZE;
@@ -1989,7 +2069,7 @@
_special_mouse_mode = WSM_PRESIZE;
}
-/* returns information about the 2x1 piece to be build.
+/** returns information about the 2x1 piece to be build.
* The lower bits (0-3) are the track type. */
static byte Check2x1AutoRail(int mode)
{
@@ -2031,8 +2111,9 @@
* north-south (DIR_S) to obtain the same results with less code. This is what
* the return value signifies.
* @param style HighLightStyle dragging style
- * @param start_tile, end_tile start and end tile of drag
- * @param boolean value which when true means start/end should be swapped */
+ * @param start_tile start tile of drag
+ * @param end_tile end tile of drag
+ * @return boolean value which when true means start/end should be swapped */
static bool SwapDirection(HighLightStyle style, TileIndex start_tile, TileIndex end_tile)
{
uint start_x = TileX(start_tile);
@@ -2057,7 +2138,7 @@
* To correctly get the height difference we need the direction we are dragging
* in, as well as with what kind of tool we are dragging. For example a horizontal
* autorail tool that starts in bottom and ends at the top of a tile will need the
-* maximum of SW,S and SE,N corners respectively. This is handled by the lookup table below
+* maximum of SW, S and SE, N corners respectively. This is handled by the lookup table below
* See _tileoffs_by_dir in map.c for the direction enums if you can't figure out
* the values yourself.
* @param style HightlightStyle of drag. This includes direction and style (autorail, rect, etc.)
@@ -2140,7 +2221,7 @@
static const StringID measure_strings_length[] = {STR_NULL, STR_MEASURE_LENGTH, STR_MEASURE_LENGTH_HEIGHTDIFF};
-// while dragging
+/** while dragging */
static void CalcRaildirsDrawstyle(TileHighlightData *thd, int x, int y, int method)
{
HighLightStyle b;
@@ -2391,7 +2472,7 @@
_thd.selend.y = y;
}
-// while dragging
+/** while dragging */
bool VpHandlePlaceSizingDrag()
{
Window *w;
@@ -2399,16 +2480,17 @@
if (_special_mouse_mode != WSM_SIZING) return true;
- e.we.place.userdata = _thd.userdata;
-
- // stop drag mode if the window has been closed
- w = FindWindowById(_thd.window_class,_thd.window_number);
+ e.we.place.select_method = _thd.select_method;
+ e.we.place.select_proc = _thd.select_proc;
+
+ /* stop drag mode if the window has been closed */
+ w = FindWindowById(_thd.window_class, _thd.window_number);
if (w == NULL) {
ResetObjectToPlace();
return false;
}
- // while dragging execute the drag procedure of the corresponding window (mostly VpSelectTilesWithMethod() )
+ /* while dragging execute the drag procedure of the corresponding window (mostly VpSelectTilesWithMethod() ) */
if (_left_button_down) {
e.event = WE_PLACE_DRAG;
e.we.place.pt = GetTileBelowCursor();
@@ -2416,12 +2498,12 @@
return false;
}
- // mouse button released..
- // keep the selected tool, but reset it to the original mode.
+ /* mouse button released..
+ * keep the selected tool, but reset it to the original mode. */
_special_mouse_mode = WSM_NONE;
if (_thd.next_drawstyle == HT_RECT) {
_thd.place_mode = VHM_RECT;
- } else if ((e.we.place.userdata & 0xF) == VPM_SIGNALDIRS) { // some might call this a hack... -- Dominik
+ } else if (e.we.place.select_method == VPM_SIGNALDIRS) { // some might call this a hack... -- Dominik
_thd.place_mode = VHM_RECT;
} else if (_thd.next_drawstyle & HT_LINE) {
_thd.place_mode = VHM_RAIL;
@@ -2432,7 +2514,7 @@
}
SetTileSelectSize(1, 1);
- // and call the mouseup event.
+ /* and call the mouseup event. */
e.event = WE_PLACE_MOUSEUP;
e.we.place.pt = _thd.selend;
e.we.place.tile = TileVirtXY(e.we.place.pt.x, e.we.place.pt.y);
@@ -2453,7 +2535,7 @@
{
Window *w;
- // undo clicking on button
+ /* undo clicking on button */
if (_thd.place_mode != 0) {
_thd.place_mode = 0;
w = FindWindowById(_thd.window_class, _thd.window_number);