summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorpeter1138 <peter1138@openttd.org>2011-11-24 12:38:48 +0000
committerpeter1138 <peter1138@openttd.org>2011-11-24 12:38:48 +0000
commit81598273e9b6bb2ee20ebdd82f3d4646a02999ba (patch)
tree2d13cc93dc84f2d99cff6fc2bb02214d4453f033 /src
parent15d0a22aac6b90a2055e68d019cab4350376a8fd (diff)
downloadopenttd-81598273e9b6bb2ee20ebdd82f3d4646a02999ba.tar.xz
(svn r23316) -Feature: Add ability to zoom in to 2x and 4x level.
Diffstat (limited to 'src')
-rw-r--r--src/aircraft_cmd.cpp7
-rw-r--r--src/aircraft_gui.cpp11
-rw-r--r--src/depot_gui.cpp11
-rw-r--r--src/fontcache.cpp1
-rw-r--r--src/gfx.cpp172
-rw-r--r--src/gfx_func.h5
-rw-r--r--src/landscape.h7
-rw-r--r--src/lang/english.txt4
-rw-r--r--src/newgrf_debug_gui.cpp2
-rw-r--r--src/roadveh_cmd.cpp3
-rw-r--r--src/saveload/afterload.cpp7
-rw-r--r--src/saveload/misc_sl.cpp9
-rw-r--r--src/screenshot.cpp2
-rw-r--r--src/ship_cmd.cpp7
-rw-r--r--src/ship_gui.cpp11
-rw-r--r--src/smallmap_gui.cpp14
-rw-r--r--src/sound.cpp2
-rw-r--r--src/sprite.cpp7
-rw-r--r--src/spritecache.h10
-rw-r--r--src/spriteloader/grf.cpp18
-rw-r--r--src/spriteloader/png.cpp19
-rw-r--r--src/table/misc_settings.ini4
-rw-r--r--src/table/settings.ini4
-rw-r--r--src/texteff.cpp4
-rw-r--r--src/train_cmd.cpp5
-rw-r--r--src/vehicle.cpp18
-rw-r--r--src/vehicle_gui.cpp7
-rw-r--r--src/viewport.cpp60
-rw-r--r--src/zoom_type.h30
29 files changed, 332 insertions, 129 deletions
diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp
index 861a88a08..de0182782 100644
--- a/src/aircraft_cmd.cpp
+++ b/src/aircraft_cmd.cpp
@@ -35,6 +35,7 @@
#include "engine_base.h"
#include "core/random_func.hpp"
#include "core/backup_type.hpp"
+#include "zoom_func.h"
#include "table/strings.h"
@@ -190,7 +191,7 @@ void DrawAircraftEngine(int left, int right, int preferred_x, int y, EngineID en
{
SpriteID sprite = GetAircraftIcon(engine, image_type);
const Sprite *real_sprite = GetSprite(sprite, ST_NORMAL);
- preferred_x = Clamp(preferred_x, left - real_sprite->x_offs, right - real_sprite->width - real_sprite->x_offs);
+ preferred_x = Clamp(preferred_x, left - UnScaleByZoom(real_sprite->x_offs, ZOOM_LVL_GUI), right - UnScaleByZoom(real_sprite->width, ZOOM_LVL_GUI) - UnScaleByZoom(real_sprite->x_offs, ZOOM_LVL_GUI));
DrawSprite(sprite, pal, preferred_x, y);
if (!(AircraftVehInfo(engine)->subtype & AIR_CTOL)) {
@@ -210,8 +211,8 @@ void GetAircraftSpriteSize(EngineID engine, uint &width, uint &height, EngineIma
{
const Sprite *spr = GetSprite(GetAircraftIcon(engine, image_type), ST_NORMAL);
- width = spr->width;
- height = spr->height;
+ width = UnScaleByZoom(spr->width, ZOOM_LVL_GUI);
+ height = UnScaleByZoom(spr->height, ZOOM_LVL_GUI);
}
/**
diff --git a/src/aircraft_gui.cpp b/src/aircraft_gui.cpp
index 360c02a7f..faefaa907 100644
--- a/src/aircraft_gui.cpp
+++ b/src/aircraft_gui.cpp
@@ -17,6 +17,7 @@
#include "vehicle_func.h"
#include "window_gui.h"
#include "spritecache.h"
+#include "zoom_func.h"
#include "table/strings.h"
@@ -83,7 +84,9 @@ void DrawAircraftImage(const Vehicle *v, int left, int right, int y, VehicleID s
SpriteID sprite = v->GetImage(rtl ? DIR_E : DIR_W, image_type);
const Sprite *real_sprite = GetSprite(sprite, ST_NORMAL);
- int x = rtl ? right - real_sprite->width - real_sprite->x_offs : left - real_sprite->x_offs;
+ int width = UnScaleByZoom(real_sprite->width, ZOOM_LVL_GUI);
+ int x_offs = UnScaleByZoom(real_sprite->x_offs, ZOOM_LVL_GUI);
+ int x = rtl ? right - width - x_offs : left - x_offs;
bool helicopter = v->subtype == AIR_HELICOPTER;
PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
@@ -95,8 +98,8 @@ void DrawAircraftImage(const Vehicle *v, int left, int right, int y, VehicleID s
DrawSprite(rotor_sprite, PAL_NONE, x, y + 5);
}
if (v->index == selection) {
- x += real_sprite->x_offs;
- y += real_sprite->y_offs + 10 - (helicopter ? 5 : 0);
- DrawFrameRect(x - 1, y - 1, x + real_sprite->width + 1, y + real_sprite->height + (helicopter ? 5 : 0) + 1, COLOUR_WHITE, FR_BORDERONLY);
+ x += x_offs;
+ y += UnScaleByZoom(real_sprite->y_offs, ZOOM_LVL_GUI) + 10 - (helicopter ? 5 : 0);
+ DrawFrameRect(x - 1, y - 1, x + width + 1, y + UnScaleByZoom(real_sprite->height, ZOOM_LVL_GUI) + (helicopter ? 5 : 0) + 1, COLOUR_WHITE, FR_BORDERONLY);
}
}
diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp
index 07fd635a8..cd0b4671d 100644
--- a/src/depot_gui.cpp
+++ b/src/depot_gui.cpp
@@ -28,6 +28,7 @@
#include "window_gui.h"
#include "vehiclelist.h"
#include "order_backup.h"
+#include "zoom_func.h"
#include "table/strings.h"
@@ -297,7 +298,7 @@ struct DepotWindow : Window {
case VEH_AIRCRAFT: {
const Sprite *spr = GetSprite(v->GetImage(DIR_W, EIT_IN_DEPOT), ST_NORMAL);
DrawAircraftImage(v, image_left, image_right,
- y + max(spr->height + spr->y_offs - 14, 0), // tall sprites needs an y offset
+ y + max(UnScaleByZoom(spr->height, ZOOM_LVL_GUI) + UnScaleByZoom(spr->y_offs, ZOOM_LVL_GUI) - 14, 0), // tall sprites needs an y offset
this->sel, EIT_IN_DEPOT);
break;
}
@@ -608,14 +609,14 @@ struct DepotWindow : Window {
Dimension unumber = { GetDigitWidth() * 4, FONT_HEIGHT_NORMAL };
const Sprite *spr = GetSprite(SPR_FLAG_VEH_STOPPED, ST_NORMAL);
- this->flag_width = spr->width + WD_FRAMERECT_RIGHT;
- this->flag_height = spr->height;
+ this->flag_width = UnScaleByZoom(spr->width, ZOOM_LVL_GUI) + WD_FRAMERECT_RIGHT;
+ this->flag_height = UnScaleByZoom(spr->height, ZOOM_LVL_GUI);
if (this->type == VEH_TRAIN || this->type == VEH_ROAD) {
- min_height = max<uint>(unumber.height + WD_MATRIX_TOP, spr->height);
+ min_height = max<uint>(unumber.height + WD_MATRIX_TOP, UnScaleByZoom(spr->height, ZOOM_LVL_GUI));
this->header_width = unumber.width + this->flag_width + WD_FRAMERECT_LEFT;
} else {
- min_height = unumber.height + spr->height + WD_MATRIX_TOP + WD_PAR_VSEP_NORMAL + WD_MATRIX_BOTTOM;
+ min_height = unumber.height + UnScaleByZoom(spr->height, ZOOM_LVL_GUI) + WD_MATRIX_TOP + WD_PAR_VSEP_NORMAL + WD_MATRIX_BOTTOM;
this->header_width = max<uint>(unumber.width, this->flag_width) + WD_FRAMERECT_RIGHT;
}
int base_width = this->count_width + this->header_width;
diff --git a/src/fontcache.cpp b/src/fontcache.cpp
index 2e1882147..d203a4513 100644
--- a/src/fontcache.cpp
+++ b/src/fontcache.cpp
@@ -14,6 +14,7 @@
#include "blitter/factory.hpp"
#include "core/math_func.hpp"
#include "strings_func.h"
+#include "zoom_type.h"
#include "table/sprites.h"
#include "table/control_codes.h"
diff --git a/src/gfx.cpp b/src/gfx.cpp
index 17fa1c9a0..b840fed3e 100644
--- a/src/gfx.cpp
+++ b/src/gfx.cpp
@@ -55,7 +55,8 @@ static byte _stringwidth_table[FS_END][224]; ///< Cache containing width of ofte
DrawPixelInfo *_cur_dpi;
byte _colour_gradient[COLOUR_END][8];
-static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub = NULL, SpriteID sprite_id = SPR_CURSOR_MOUSE);
+static void GfxMainBlitterViewport(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub = NULL, SpriteID sprite_id = SPR_CURSOR_MOUSE);
+static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub = NULL, SpriteID sprite_id = SPR_CURSOR_MOUSE, ZoomLevel zoom = ZOOM_LVL_NORMAL);
/**
* Text drawing parameters, which can change while drawing a line, but are kept between multiple parts
@@ -1132,53 +1133,76 @@ skip_cont:;
* @return Sprite size in pixels.
* @note The size assumes (0, 0) as top-left coordinate and ignores any part of the sprite drawn at the left or above that position.
*/
-Dimension GetSpriteSize(SpriteID sprid, Point *offset)
+Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom)
{
const Sprite *sprite = GetSprite(sprid, ST_NORMAL);
if (offset != NULL) {
- offset->x = sprite->x_offs;
- offset->y = sprite->y_offs;
+ offset->x = UnScaleByZoom(sprite->x_offs, zoom);
+ offset->y = UnScaleByZoom(sprite->y_offs, zoom);
}
Dimension d;
- d.width = max<int>(0, sprite->x_offs + sprite->width);
- d.height = max<int>(0, sprite->y_offs + sprite->height);
+ d.width = max<int>(0, UnScaleByZoom(sprite->x_offs + sprite->width, zoom));
+ d.height = max<int>(0, UnScaleByZoom(sprite->y_offs + sprite->height, zoom));
return d;
}
/**
- * Draw a sprite.
+ * Draw a sprite in a viewport.
* @param img Image number to draw
* @param pal Palette to use.
- * @param x Left coordinate of image
- * @param y Top coordinate of image
+ * @param x Left coordinate of image in viewport, scaled by zoom
+ * @param y Top coordinate of image in viewport, scaled by zoom
* @param sub If available, draw only specified part of the sprite
*/
-void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub)
+void DrawSpriteViewport(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub)
{
SpriteID real_sprite = GB(img, 0, SPRITE_WIDTH);
if (HasBit(img, PALETTE_MODIFIER_TRANSPARENT)) {
_colour_remap_ptr = GetNonSprite(GB(pal, 0, PALETTE_WIDTH), ST_RECOLOUR) + 1;
- GfxMainBlitter(GetSprite(real_sprite, ST_NORMAL), x, y, BM_TRANSPARENT, sub, real_sprite);
+ GfxMainBlitterViewport(GetSprite(real_sprite, ST_NORMAL), x, y, BM_TRANSPARENT, sub, real_sprite);
} else if (pal != PAL_NONE) {
_colour_remap_ptr = GetNonSprite(GB(pal, 0, PALETTE_WIDTH), ST_RECOLOUR) + 1;
- GfxMainBlitter(GetSprite(real_sprite, ST_NORMAL), x, y, BM_COLOUR_REMAP, sub, real_sprite);
+ GfxMainBlitterViewport(GetSprite(real_sprite, ST_NORMAL), x, y, BM_COLOUR_REMAP, sub, real_sprite);
} else {
- GfxMainBlitter(GetSprite(real_sprite, ST_NORMAL), x, y, BM_NORMAL, sub, real_sprite);
+ GfxMainBlitterViewport(GetSprite(real_sprite, ST_NORMAL), x, y, BM_NORMAL, sub, real_sprite);
}
}
-static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub, SpriteID sprite_id)
+/**
+ * Draw a sprite, not in a viewport
+ * @param img Image number to draw
+ * @param pal Palette to use.
+ * @param x Left coordinate of image in pixels
+ * @param y Top coordinate of image in pixels
+ * @param sub If available, draw only specified part of the sprite
+ * @param zoom Zoom level of sprite
+ */
+void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub, ZoomLevel zoom)
+{
+ SpriteID real_sprite = GB(img, 0, SPRITE_WIDTH);
+ if (HasBit(img, PALETTE_MODIFIER_TRANSPARENT)) {
+ _colour_remap_ptr = GetNonSprite(GB(pal, 0, PALETTE_WIDTH), ST_RECOLOUR) + 1;
+ GfxMainBlitter(GetSprite(real_sprite, ST_NORMAL), x, y, BM_TRANSPARENT, sub, real_sprite, zoom);
+ } else if (pal != PAL_NONE) {
+ _colour_remap_ptr = GetNonSprite(GB(pal, 0, PALETTE_WIDTH), ST_RECOLOUR) + 1;
+ GfxMainBlitter(GetSprite(real_sprite, ST_NORMAL), x, y, BM_COLOUR_REMAP, sub, real_sprite, zoom);
+ } else {
+ GfxMainBlitter(GetSprite(real_sprite, ST_NORMAL), x, y, BM_NORMAL, sub, real_sprite, zoom);
+ }
+}
+
+static void GfxMainBlitterViewport(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub, SpriteID sprite_id)
{
const DrawPixelInfo *dpi = _cur_dpi;
Blitter::BlitterParams bp;
/* Amount of pixels to clip from the source sprite */
- int clip_left = (sub != NULL ? max(0, -sprite->x_offs + sub->left ) : 0);
- int clip_top = (sub != NULL ? max(0, -sprite->y_offs + sub->top ) : 0);
- int clip_right = (sub != NULL ? max(0, sprite->width - (-sprite->x_offs + sub->right + 1)) : 0);
- int clip_bottom = (sub != NULL ? max(0, sprite->height - (-sprite->y_offs + sub->bottom + 1)) : 0);
+ int clip_left = (sub != NULL ? max(0, -sprite->x_offs + sub->left * ZOOM_LVL_BASE ) : 0);
+ int clip_top = (sub != NULL ? max(0, -sprite->y_offs + sub->top * ZOOM_LVL_BASE ) : 0);
+ int clip_right = (sub != NULL ? max(0, sprite->width - (-sprite->x_offs + (sub->right + 1) * ZOOM_LVL_BASE)) : 0);
+ int clip_bottom = (sub != NULL ? max(0, sprite->height - (-sprite->y_offs + (sub->bottom + 1) * ZOOM_LVL_BASE)) : 0);
if (clip_left + clip_right >= sprite->width) return;
if (clip_top + clip_bottom >= sprite->height) return;
@@ -1269,6 +1293,110 @@ static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode,
BlitterFactoryBase::GetCurrentBlitter()->Draw(&bp, mode, dpi->zoom);
}
+static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub, SpriteID sprite_id, ZoomLevel zoom)
+{
+ const DrawPixelInfo *dpi = _cur_dpi;
+ Blitter::BlitterParams bp;
+
+ /* Amount of pixels to clip from the source sprite */
+ int clip_left = (sub != NULL ? max(0, -sprite->x_offs + sub->left ) : 0);
+ int clip_top = (sub != NULL ? max(0, -sprite->y_offs + sub->top ) : 0);
+ int clip_right = (sub != NULL ? max(0, sprite->width - (-sprite->x_offs + sub->right + 1)) : 0);
+ int clip_bottom = (sub != NULL ? max(0, sprite->height - (-sprite->y_offs + sub->bottom + 1)) : 0);
+
+ if (clip_left + clip_right >= sprite->width) return;
+ if (clip_top + clip_bottom >= sprite->height) return;
+
+ /* Scale it */
+ x = ScaleByZoom(x, zoom);
+ y = ScaleByZoom(y, zoom);
+
+ /* Move to the correct offset */
+ x += sprite->x_offs;
+ y += sprite->y_offs;
+
+ /* Copy the main data directly from the sprite */
+ bp.sprite = sprite->data;
+ bp.sprite_width = sprite->width;
+ bp.sprite_height = sprite->height;
+ bp.width = UnScaleByZoom(sprite->width - clip_left - clip_right, zoom);
+ bp.height = UnScaleByZoom(sprite->height - clip_top - clip_bottom, zoom);
+ bp.top = 0;
+ bp.left = 0;
+ bp.skip_left = UnScaleByZoomLower(clip_left, zoom);
+ bp.skip_top = UnScaleByZoomLower(clip_top, zoom);
+
+ x += ScaleByZoom(bp.skip_left, zoom);
+ y += ScaleByZoom(bp.skip_top, zoom);
+
+ bp.dst = dpi->dst_ptr;
+ bp.pitch = dpi->pitch;
+ bp.remap = _colour_remap_ptr;
+
+ assert(sprite->width > 0);
+ assert(sprite->height > 0);
+
+ if (bp.width <= 0) return;
+ if (bp.height <= 0) return;
+
+ y -= ScaleByZoom(dpi->top, zoom);
+ /* Check for top overflow */
+ if (y < 0) {
+ bp.height -= -UnScaleByZoom(y, zoom);
+ if (bp.height <= 0) return;
+ bp.skip_top += -UnScaleByZoom(y, zoom);
+ y = 0;
+ } else {
+ bp.top = UnScaleByZoom(y, zoom);
+ }
+
+ /* Check for bottom overflow */
+ y += ScaleByZoom(bp.height - dpi->height, zoom);
+ if (y > 0) {
+ bp.height -= UnScaleByZoom(y, zoom);
+ if (bp.height <= 0) return;
+ }
+
+ x -= ScaleByZoom(dpi->left, zoom);
+ /* Check for left overflow */
+ if (x < 0) {
+ bp.width -= -UnScaleByZoom(x, zoom);
+ if (bp.width <= 0) return;
+ bp.skip_left += -UnScaleByZoom(x, zoom);
+ x = 0;
+ } else {
+ bp.left = UnScaleByZoom(x, zoom);
+ }
+
+ /* Check for right overflow */
+ x += ScaleByZoom(bp.width - dpi->width, zoom);
+ if (x > 0) {
+ bp.width -= UnScaleByZoom(x, zoom);
+ if (bp.width <= 0) return;
+ }
+
+ assert(bp.skip_left + bp.width <= UnScaleByZoom(sprite->width, zoom));
+ assert(bp.skip_top + bp.height <= UnScaleByZoom(sprite->height, zoom));
+
+ /* We do not want to catch the mouse. However we also use that spritenumber for unknown (text) sprites. */
+ if (_newgrf_debug_sprite_picker.mode == SPM_REDRAW && sprite_id != SPR_CURSOR_MOUSE) {
+ Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter();
+ void *topleft = blitter->MoveTo(bp.dst, bp.left, bp.top);
+ void *bottomright = blitter->MoveTo(topleft, bp.width - 1, bp.height - 1);
+
+ void *clicked = _newgrf_debug_sprite_picker.clicked_pixel;
+
+ if (topleft <= clicked && clicked <= bottomright) {
+ uint offset = (((size_t)clicked - (size_t)topleft) / (blitter->GetScreenDepth() / 8)) % bp.pitch;
+ if (offset < (uint)bp.width) {
+ _newgrf_debug_sprite_picker.sprites.Include(sprite_id);
+ }
+ }
+ }
+
+ BlitterFactoryBase::GetCurrentBlitter()->Draw(&bp, mode, zoom);
+}
+
void DoPaletteAnimations();
void GfxInitPalettes()
@@ -1785,10 +1913,10 @@ void UpdateCursorSize()
CursorVars *cv = &_cursor;
const Sprite *p = GetSprite(GB(cv->sprite, 0, SPRITE_WIDTH), ST_NORMAL);
- cv->size.y = p->height;
- cv->size.x = p->width;
- cv->offs.x = p->x_offs;
- cv->offs.y = p->y_offs;
+ cv->size.y = UnScaleByZoom(p->height, ZOOM_LVL_GUI);
+ cv->size.x = UnScaleByZoom(p->width, ZOOM_LVL_GUI);
+ cv->offs.x = UnScaleByZoom(p->x_offs, ZOOM_LVL_GUI);
+ cv->offs.y = UnScaleByZoom(p->y_offs, ZOOM_LVL_GUI);
cv->dirty = true;
}
diff --git a/src/gfx_func.h b/src/gfx_func.h
index 8023c3ee1..2061c9310 100644
--- a/src/gfx_func.h
+++ b/src/gfx_func.h
@@ -88,8 +88,9 @@ static const int DRAW_STRING_BUFFER = 2048;
void RedrawScreenRect(int left, int top, int right, int bottom);
void GfxScroll(int left, int top, int width, int height, int xo, int yo);
-Dimension GetSpriteSize(SpriteID sprid, Point *offset = NULL);
-void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = NULL);
+Dimension GetSpriteSize(SpriteID sprid, Point *offset = NULL, ZoomLevel zoom = ZOOM_LVL_GUI);
+void DrawSpriteViewport(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = NULL);
+void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = NULL, ZoomLevel zoom = ZOOM_LVL_GUI);
/** How to align the to-be drawn text. */
enum StringAlignment {
diff --git a/src/landscape.h b/src/landscape.h
index c1680d1be..7a3dc03a8 100644
--- a/src/landscape.h
+++ b/src/landscape.h
@@ -14,6 +14,7 @@
#include "core/geometry_type.hpp"
#include "tile_cmd.h"
+#include "zoom_type.h"
static const uint SNOW_LINE_MONTHS = 12; ///< Number of months in the snow line table.
static const uint SNOW_LINE_DAYS = 32; ///< Number of days in each month in the snow line table.
@@ -83,8 +84,8 @@ static inline Slope GetFoundationPixelSlope(TileIndex tile, int *z)
static inline Point RemapCoords(int x, int y, int z)
{
Point pt;
- pt.x = (y - x) * 2;
- pt.y = y + x - z;
+ pt.x = (y - x) * 2 * ZOOM_LVL_BASE;
+ pt.y = (y + x - z) * ZOOM_LVL_BASE;
return pt;
}
@@ -111,7 +112,7 @@ static inline Point RemapCoords2(int x, int y)
*/
static inline Point InverseRemapCoords(int x, int y)
{
- Point pt = {(y * 2 - x) >> 2, (y * 2 + x) >> 2};
+ Point pt = {(y * 2 - x) >> (2 + ZOOM_LVL_SHIFT), (y * 2 + x) >> (2 + ZOOM_LVL_SHIFT)};
return pt;
}
diff --git a/src/lang/english.txt b/src/lang/english.txt
index eb565c066..3e33db7ee 100644
--- a/src/lang/english.txt
+++ b/src/lang/english.txt
@@ -1323,7 +1323,9 @@ STR_CONFIG_SETTING_SOFT_LIMIT :{LTBLUE}Maximum
STR_CONFIG_SETTING_SOFT_LIMIT_DISABLED :{LTBLUE}Maximum number of non-sticky windows: {ORANGE}disabled
STR_CONFIG_SETTING_ZOOM_MIN :{LTBLUE}Maximum zoom in level: {ORANGE}{STRING1}
STR_CONFIG_SETTING_ZOOM_MAX :{LTBLUE}Maximum zoom out level: {ORANGE}{STRING1}
-STR_CONFIG_SETTING_ZOOM_LVL_MIN :Normal
+STR_CONFIG_SETTING_ZOOM_LVL_MIN :4x
+STR_CONFIG_SETTING_ZOOM_LVL_IN_2X :2x
+STR_CONFIG_SETTING_ZOOM_LVL_NORMAL :Normal
STR_CONFIG_SETTING_ZOOM_LVL_OUT_2X :2x
STR_CONFIG_SETTING_ZOOM_LVL_OUT_4X :4x
STR_CONFIG_SETTING_ZOOM_LVL_OUT_8X :8x
diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp
index 46a885a6f..c5c1705f3 100644
--- a/src/newgrf_debug_gui.cpp
+++ b/src/newgrf_debug_gui.cpp
@@ -725,7 +725,7 @@ struct SpriteAlignerWindow : Window {
spr->y_offs + (spr->height + height) / 2 - 1,
};
- DrawSprite(this->current_sprite, PAL_NONE, x, y, &subspr);
+ DrawSprite(this->current_sprite, PAL_NONE, x, y, &subspr, ZOOM_LVL_NORMAL);
break;
}
diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp
index ff18089a5..0198dac82 100644
--- a/src/roadveh_cmd.cpp
+++ b/src/roadveh_cmd.cpp
@@ -35,6 +35,7 @@
#include "company_base.h"
#include "core/backup_type.hpp"
#include "newgrf.h"
+#include "zoom_func.h"
#include "table/strings.h"
@@ -151,7 +152,7 @@ void DrawRoadVehEngine(int left, int right, int preferred_x, int y, EngineID eng
{
SpriteID sprite = GetRoadVehIcon(engine, image_type);
const Sprite *real_sprite = GetSprite(sprite, ST_NORMAL);
- preferred_x = Clamp(preferred_x, left - real_sprite->x_offs, right - real_sprite->width - real_sprite->x_offs);
+ preferred_x = Clamp(preferred_x, left - UnScaleByZoom(real_sprite->x_offs, ZOOM_LVL_GUI), right - UnScaleByZoom(real_sprite->width, ZOOM_LVL_GUI) - UnScaleByZoom(real_sprite->x_offs, ZOOM_LVL_GUI));
DrawSprite(sprite, pal, preferred_x, y);
}
diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp
index 5b86f4d0b..d231f6912 100644
--- a/src/saveload/afterload.cpp
+++ b/src/saveload/afterload.cpp
@@ -2688,6 +2688,13 @@ bool AfterLoadGame()
}
}
+ if (IsSavegameVersionBefore(165)) {
+ /* Adjust zoom level to account for new levels */
+ _saved_scrollpos_zoom = _saved_scrollpos_zoom + ZOOM_LVL_SHIFT;
+ _saved_scrollpos_x *= ZOOM_LVL_BASE;
+ _saved_scrollpos_y *= ZOOM_LVL_BASE;
+ }
+
/* When any NewGRF has been changed the availability of some vehicles might
* have been changed too. e->company_avail must be set to 0 in that case
* which is done by StartupEngines(). */
diff --git a/src/saveload/misc_sl.cpp b/src/saveload/misc_sl.cpp
index 9ca806701..877fa1269 100644
--- a/src/saveload/misc_sl.cpp
+++ b/src/saveload/misc_sl.cpp
@@ -56,9 +56,12 @@ void ResetViewportAfterLoadGame()
vp->virtual_width = ScaleByZoom(vp->width, vp->zoom);
vp->virtual_height = ScaleByZoom(vp->height, vp->zoom);
- /* Ensure zoom level is allowed */
- while (vp->zoom < _settings_client.gui.zoom_min) DoZoomInOutWindow(ZOOM_OUT, w);
- while (vp->zoom > _settings_client.gui.zoom_max) DoZoomInOutWindow(ZOOM_IN, w);
+ /* If zoom_max is ZOOM_LVL_MIN then the setting has not been loaded yet, therefore all levels are allowed. */
+ if (_settings_client.gui.zoom_max != ZOOM_LVL_MIN) {
+ /* Ensure zoom level is allowed */
+ while (vp->zoom < _settings_client.gui.zoom_min) DoZoomInOutWindow(ZOOM_OUT, w);
+ while (vp->zoom > _settings_client.gui.zoom_max) DoZoomInOutWindow(ZOOM_IN, w);
+ }
DoZoomInOutWindow(ZOOM_NONE, w); // update button status
MarkWholeScreenDirty();
diff --git a/src/screenshot.cpp b/src/screenshot.cpp
index 9cee75820..e1f83eb47 100644
--- a/src/screenshot.cpp
+++ b/src/screenshot.cpp
@@ -736,7 +736,7 @@ static bool MakeZoomedInScreenshot()
Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
ViewPort vp;
- vp.zoom = ZOOM_LVL_WORLD_SCREENSHOT;
+ vp.zoom = ZOOM_LVL_NORMAL;
vp.left = w->viewport->left;
vp.top = w->viewport->top;
vp.virtual_left = w->viewport->virtual_left;
diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp
index 66f7746ad..c6d5ca47a 100644
--- a/src/ship_cmd.cpp
+++ b/src/ship_cmd.cpp
@@ -33,6 +33,7 @@
#include "engine_base.h"
#include "company_base.h"
#include "tunnelbridge_map.h"
+#include "zoom_func.h"
#include "table/strings.h"
@@ -81,7 +82,7 @@ void DrawShipEngine(int left, int right, int preferred_x, int y, EngineID engine
{
SpriteID sprite = GetShipIcon(engine, image_type);
const Sprite *real_sprite = GetSprite(sprite, ST_NORMAL);
- preferred_x = Clamp(preferred_x, left - real_sprite->x_offs, right - real_sprite->width - real_sprite->x_offs);
+ preferred_x = Clamp(preferred_x, left - UnScaleByZoom(real_sprite->x_offs, ZOOM_LVL_GUI), right - UnScaleByZoom(real_sprite->width, ZOOM_LVL_GUI) - UnScaleByZoom(real_sprite->x_offs, ZOOM_LVL_GUI));
DrawSprite(sprite, pal, preferred_x, y);
}
@@ -95,8 +96,8 @@ void GetShipSpriteSize(EngineID engine, uint &width, uint &height, EngineImageTy
{
const Sprite *spr = GetSprite(GetShipIcon(engine, image_type), ST_NORMAL);
- width = spr->width;
- height = spr->height;
+ width = UnScaleByZoom(spr->width, ZOOM_LVL_GUI);
+ height = UnScaleByZoom(spr->height, ZOOM_LVL_GUI);
}
SpriteID Ship::GetImage(Direction direction, EngineImageType image_type) const
diff --git a/src/ship_gui.cpp b/src/ship_gui.cpp
index 4cdfb5f81..d036cef43 100644
--- a/src/ship_gui.cpp
+++ b/src/ship_gui.cpp
@@ -17,6 +17,7 @@
#include "strings_func.h"
#include "vehicle_func.h"
#include "spritecache.h"
+#include "zoom_func.h"
#include "table/strings.h"
@@ -35,14 +36,16 @@ void DrawShipImage(const Vehicle *v, int left, int right, int y, VehicleID selec
SpriteID sprite = v->GetImage(rtl ? DIR_E : DIR_W, image_type);
const Sprite *real_sprite = GetSprite(sprite, ST_NORMAL);
- int x = rtl ? right - real_sprite->width - real_sprite->x_offs : left - real_sprite->x_offs;
+ int width = UnScaleByZoom(real_sprite->width, ZOOM_LVL_GUI);
+ int x_offs = UnScaleByZoom(real_sprite->x_offs, ZOOM_LVL_GUI);
+ int x = rtl ? right - width - x_offs : left - x_offs;
DrawSprite(sprite, GetVehiclePalette(v), x, y + 10);
if (v->index == selection) {
- x += real_sprite->x_offs;
- y += real_sprite->y_offs + 10;
- DrawFrameRect(x - 1, y - 1, x + real_sprite->width + 1, y + real_sprite->height + 1, COLOUR_WHITE, FR_BORDERONLY);
+ x += x_offs;
+ y += UnScaleByZoom(real_sprite->y_offs, ZOOM_LVL_GUI) + 10;
+ DrawFrameRect(x - 1, y - 1, x + width + 1, y + UnScaleByZoom(real_sprite->height, ZOOM_LVL_GUI) + 1, COLOUR_WHITE, FR_BORDERONLY);
}
}
diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp
index 871fff252..c8b38f86e 100644
--- a/src/smallmap_gui.cpp
+++ b/src/smallmap_gui.cpp
@@ -618,6 +618,14 @@ class SmallMapWindow : public Window {
static const uint8 FORCE_REFRESH_PERIOD = 0x1F; ///< map is redrawn after that many ticks
uint8 refresh; ///< refresh counter, zeroed every FORCE_REFRESH_PERIOD ticks
+ FORCEINLINE Point SmallmapRemapCoords(int x, int y) const
+ {
+ Point pt;
+ pt.x = (y - x) * 2;
+ pt.y = y + x;
+ return pt;
+ }
+
/**
* Remap tile to location on this smallmap.
* @param tile_x X coordinate of the tile.
@@ -629,13 +637,13 @@ class SmallMapWindow : public Window {
int x_offset = tile_x - this->scroll_x / (int)TILE_SIZE;
int y_offset = tile_y - this->scroll_y / (int)TILE_SIZE;
- if (this->zoom == 1) return RemapCoords(x_offset, y_offset, 0);
+ if (this->zoom == 1) return SmallmapRemapCoords(x_offset, y_offset);
/* For negative offsets, round towards -inf. */
if (x_offset < 0) x_offset -= this->zoom - 1;
if (y_offset < 0) y_offset -= this->zoom - 1;
- return RemapCoords(x_offset / this->zoom, y_offset / this->zoom, 0);
+ return SmallmapRemapCoords(x_offset / this->zoom, y_offset / this->zoom);
}
/**
@@ -1505,7 +1513,7 @@ public:
void SetNewScroll(int sx, int sy, int sub)
{
const NWidgetBase *wi = this->GetWidget<NWidgetBase>(SM_WIDGET_MAP);
- Point hv = InverseRemapCoords(wi->current_x * TILE_SIZE / 2, wi->current_y * TILE_SIZE / 2);
+ Point hv = InverseRemapCoords(wi->current_x * ZOOM_LVL_BASE * TILE_SIZE / 2, wi->current_y * ZOOM_LVL_BASE * TILE_SIZE / 2);
hv.x *= this->zoom;
hv.y *= this->zoom;
diff --git a/src/sound.cpp b/src/sound.cpp
index fe4ba0057..d572050bf 100644
--- a/src/sound.cpp
+++ b/src/sound.cpp
@@ -178,7 +178,7 @@ static void StartSound(SoundID sound_id, float pan, uint volume)
}
-static const byte _vol_factor_by_zoom[] = {255, 190, 134, 87};
+static const byte _vol_factor_by_zoom[] = {255, 255, 255, 190, 134, 87};
assert_compile(lengthof(_vol_factor_by_zoom) == ZOOM_LVL_COUNT);
static const byte _sound_base_vol[] = {
diff --git a/src/sprite.cpp b/src/sprite.cpp
index a991d315f..69a8ed92e 100644
--- a/src/sprite.cpp
+++ b/src/sprite.cpp
@@ -16,6 +16,7 @@
#include "spritecache.h"
#include "core/alloc_func.hpp"
#include "core/mem_func.hpp"
+#include "zoom_func.h"
/**
@@ -118,11 +119,11 @@ void DrawCommonTileSeqInGUI(int x, int y, const DrawTileSprites *dts, int32 orig
if (dtss->IsParentSprite()) {
Point pt = RemapCoords(dtss->delta_x, dtss->delta_y, dtss->delta_z);
- DrawSprite(image, pal, x + pt.x, y + pt.y);
+ DrawSprite(image, pal, x + UnScaleByZoom(pt.x, ZOOM_LVL_GUI), y + UnScaleByZoom(pt.y, ZOOM_LVL_GUI));
const Sprite *spr = GetSprite(image & SPRITE_MASK, ST_NORMAL);
- child_offset.x = pt.x + spr->x_offs;
- child_offset.y = pt.y + spr->y_offs;
+ child_offset.x = UnScaleByZoom(pt.x + spr->x_offs, ZOOM_LVL_GUI);
+ child_offset.y = UnScaleByZoom(pt.y + spr->y_offs, ZOOM_LVL_GUI);
} else {
int offs_x = child_offset_is_unsigned ? (uint8)dtss->delta_x : dtss->delta_x;
int offs_y = child_offset_is_unsigned ? (uint8)dtss->delta_y : dtss->delta_y;
diff --git a/src/spritecache.h b/src/spritecache.h
index 0b1a08b19..02be3b4ca 100644
--- a/src/spritecache.h
+++ b/src/spritecache.h
@@ -16,11 +16,11 @@
/** Data structure describing a sprite. */
struct Sprite {
- byte height; ///< Height of the sprite.
- uint16 width; ///< Width of the sprite.
- int16 x_offs; ///< Number of pixels to shift the sprite to the right.
- int16 y_offs; ///< Number of pixels to shift the sprite downwards.
- byte data[]; ///< Sprite data.
+ uint16 height; ///< Height of the sprite.
+ uint16 width; ///< Width of the sprite.
+ int16 x_offs; ///< Number of pixels to shift the sprite to the right.
+ int16 y_offs; ///< Number of pixels to shift the sprite downwards.
+ byte data[]; ///< Sprite data.
};
extern uint _sprite_cache_size;
diff --git a/src/spriteloader/grf.cpp b/src/spriteloader/grf.cpp
index a0f5c8632..2876f2f35 100644
--- a/src/spriteloader/grf.cpp
+++ b/src/spriteloader/grf.cpp
@@ -95,7 +95,7 @@ bool SpriteLoaderGrf::LoadSprite(SpriteLoader::Sprite *sprite, uint8 file_slot,
if (num != 0) return WarnCorruptSprite(file_slot, file_pos, __LINE__);
- sprite->AllocateData(sprite->width * sprite->height);
+ sprite->AllocateData(sprite->width * sprite->height * ZOOM_LVL_BASE * ZOOM_LVL_BASE);
/* When there are transparency pixels, this format has another trick.. decode it */
if (type & 0x08) {
@@ -163,6 +163,22 @@ bool SpriteLoaderGrf::LoadSprite(SpriteLoader::Sprite *sprite, uint8 file_slot,
}
}
+ if (ZOOM_LVL_BASE != 1 && sprite_type == ST_NORMAL) {
+ /* Simple scaling, back-to-front so that no intermediate buffers are needed. */
+ int width = sprite->width * ZOOM_LVL_BASE;
+ int height = sprite->height * ZOOM_LVL_BASE;
+ for (int y = height - 1; y >= 0; y--) {
+ for (int x = width - 1; x >= 0; x--) {
+ sprite->data[y * width + x] = sprite->data[y / ZOOM_LVL_BASE * sprite->width + x / ZOOM_LVL_BASE];
+ }
+ }
+
+ sprite->width *= ZOOM_LVL_BASE;
+ sprite->height *= ZOOM_LVL_BASE;
+ sprite->x_offs *= ZOOM_LVL_BASE;
+ sprite->y_offs *= ZOOM_LVL_BASE;
+ }
+
/* Make sure to mark all transparent pixels transparent on the alpha channel too */
for (int i = 0; i < sprite->width * sprite->height; i++) {
if (sprite->data[i].m != 0) sprite->data[i].a = 0xFF;
diff --git a/src/spriteloader/png.cpp b/src/spriteloader/png.cpp
index 790b2a2c9..abc9592e0 100644
--- a/src/spriteloader/png.cpp
+++ b/src/spriteloader/png.cpp
@@ -115,7 +115,7 @@ static bool LoadPNG(SpriteLoader::Sprite *sprite, const char *filename, uint32 i
}
sprite->height = height;
sprite->width = width;
- sprite->AllocateData(sprite->width * sprite->height);
+ sprite->AllocateData(sprite->width * sprite->height * ZOOM_LVL_BASE * ZOOM_LVL_BASE);
} else if (sprite->height != png_get_image_height(png_ptr, info_ptr) || sprite->width != png_get_image_width(png_ptr, info_ptr)) {
/* Make sure the mask image isn't larger than the sprite image. */
DEBUG(misc, 0, "Ignoring mask for SpriteID %d as it isn't the same dimension as the masked sprite", id);
@@ -214,6 +214,23 @@ bool SpriteLoaderPNG::LoadSprite(SpriteLoader::Sprite *sprite, uint8 file_slot,
const char *filename = FioGetFilename(file_slot);
if (!LoadPNG(sprite, filename, (uint32)file_pos, false)) return false;
if (!LoadPNG(sprite, filename, (uint32)file_pos, true)) return false;
+
+ if (ZOOM_LVL_BASE != 1 && sprite_type == ST_NORMAL) {
+ /* Simple scaling, back-to-front so that no intermediate buffers are needed. */
+ int width = sprite->width * ZOOM_LVL_BASE;
+ int height = sprite->height * ZOOM_LVL_BASE;
+ for (int y = height - 1; y >= 0; y--) {
+ for (int x = width - 1; x >= 0; x--) {
+ sprite->data[y * width + x] = sprite->data[y / ZOOM_LVL_BASE * sprite->width + x / ZOOM_LVL_BASE];
+ }
+ }
+
+ sprite->width *= ZOOM_LVL_BASE;
+ sprite->height *= ZOOM_LVL_BASE;
+ sprite->x_offs *= ZOOM_LVL_BASE;
+ sprite->y_offs *= ZOOM_LVL_BASE;
+ }
+
return true;
}
diff --git a/src/table/misc_settings.ini b/src/table/misc_settings.ini
index 1a5780018..a3f0f618f 100644
--- a/src/table/misc_settings.ini
+++ b/src/table/misc_settings.ini
@@ -215,9 +215,9 @@ def = false
name = ""sprite_cache_size""
type = SLE_UINT
var = _sprite_cache_size
-def = 4
+def = 64
min = 1
-max = 64
+max = 512
[SDTG_VAR]
name = ""player_face""
diff --git a/src/table/settings.ini b/src/table/settings.ini
index 3d57f868f..0e37e7c5b 100644
--- a/src/table/settings.ini
+++ b/src/table/settings.ini
@@ -2079,7 +2079,7 @@ flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
guiflags = SGF_MULTISTRING
def = ZOOM_LVL_MIN
min = ZOOM_LVL_MIN
-max = ZOOM_LVL_MIN
+max = ZOOM_LVL_GUI
str = STR_CONFIG_SETTING_ZOOM_MIN
strval = STR_CONFIG_SETTING_ZOOM_LVL_MIN
proc = ZoomMinMaxChanged
@@ -2090,7 +2090,7 @@ type = SLE_UINT8
flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC
guiflags = SGF_MULTISTRING
def = ZOOM_LVL_MAX
-min = ZOOM_LVL_OUT_2X
+min = ZOOM_LVL_OUT_8X
max = ZOOM_LVL_MAX
str = STR_CONFIG_SETTING_ZOOM_MAX
strval = STR_CONFIG_SETTING_ZOOM_LVL_OUT_2X
diff --git a/src/texteff.cpp b/src/texteff.cpp
index 0feb522db..eac45eafb 100644
--- a/src/texteff.cpp
+++ b/src/texteff.cpp
@@ -102,13 +102,13 @@ void InitTextEffects()
void DrawTextEffects(DrawPixelInfo *dpi)
{
/* Don't draw the text effects when zoomed out a lot */
- if (dpi->zoom > ZOOM_LVL_OUT_2X) return;
+ if (dpi->zoom > ZOOM_LVL_OUT_8X) return;
const TextEffect *end = _text_effects.End();
for (TextEffect *te = _text_effects.Begin(); te != end; te++) {
if (te->string_id == INVALID_STRING_ID) continue;
if (te->mode == TE_RISING || (_settings_client.gui.loading_indicators && !IsTransparencySet(TO_LOADING))) {
- ViewportAddString(dpi, ZOOM_LVL_OUT_2X, te, te->string_id, te->string_id - 1, 0, te->params_1);
+ ViewportAddString(dpi, ZOOM_LVL_OUT_8X, te, te->string_id, te->string_id - 1, 0, te->params_1);
}
}
}
diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp
index bd245cafd..0cc2bc745 100644
--- a/src/train_cmd.cpp
+++ b/src/train_cmd.cpp
@@ -36,6 +36,7 @@
#include "company_base.h"
#include "newgrf.h"
#include "order_backup.h"
+#include "zoom_func.h"
#include "table/strings.h"
#include "table/train_cmd.h"
@@ -516,14 +517,14 @@ void DrawTrainEngine(int left, int right, int preferred_x, int y, EngineID engin
const Sprite *real_spritef = GetSprite(spritef, ST_NORMAL);
const Sprite *real_spriter = GetSprite(spriter, ST_NORMAL);
- preferred_x = Clamp(preferred_x, left - real_spritef->x_offs + 14, right - real_spriter->width - real_spriter->x_offs - 15);
+ preferred_x = Clamp(preferred_x, left - UnScaleByZoom(real_spritef->x_offs, ZOOM_LVL_GUI) + 14, right - UnScaleByZoom(real_spriter->width, ZOOM_LVL_GUI) - UnScaleByZoom(real_spriter->x_offs, ZOOM_LVL_GUI) - 15);
DrawSprite(spritef, pal, preferred_x - 14, yf);
DrawSprite(spriter, pal, preferred_x + 15, yr);
} else {
SpriteID sprite = GetRailIcon(engine, false, y, image_type);
const Sprite *real_sprite = GetSprite(sprite, ST_NORMAL);
- preferred_x = Clamp(preferred_x, left - real_sprite->x_offs, right - real_sprite->width - real_sprite->x_offs);
+ preferred_x = Clamp(preferred_x, left - UnScaleByZoom(real_sprite->x_offs, ZOOM_LVL_GUI), right - UnScaleByZoom(real_sprite->width, ZOOM_LVL_GUI) - UnScaleByZoom(real_sprite->x_offs, ZOOM_LVL_GUI));
DrawSprite(sprite, pal, preferred_x, y);
}
}
diff --git a/src/vehicle.cpp b/src/vehicle.cpp
index 4d16fc3a7..be9ea58fd 100644
--- a/src/vehicle.cpp
+++ b/src/vehicle.cpp
@@ -980,8 +980,8 @@ void ViewportAddVehicles(DrawPixelInfo *dpi)
/* The hash area to scan */
int xl, xu, yl, yu;
- if (dpi->width + 70 < (1 << (7 + 6))) {
- xl = GB(l - 70, 7, 6);
+ if (dpi->width + (70 * ZOOM_LVL_BASE) < (1 << (7 + 6))) {
+ xl = GB(l - (70 * ZOOM_LVL_BASE), 7, 6);
xu = GB(r, 7, 6);
} else {
/* scan whole hash row */
@@ -989,8 +989,8 @@ void ViewportAddVehicles(DrawPixelInfo *dpi)
xu = 0x3F;
}
- if (dpi->height + 70 < (1 << (6 + 6))) {
- yl = GB(t - 70, 6, 6) << 6;
+ if (dpi->height + (70 * ZOOM_LVL_BASE) < (1 << (6 + 6))) {
+ yl = GB(t - (70 * ZOOM_LVL_BASE), 6, 6) << 6;
yu = GB(b, 6, 6) << 6;
} else {
/* scan whole column */
@@ -1407,15 +1407,15 @@ void VehicleMove(Vehicle *v, bool update_viewport)
Rect old_coord = v->coord;
v->coord.left = pt.x;
v->coord.top = pt.y;
- v->coord.right = pt.x + spr->width + 2;
- v->coord.bottom = pt.y + spr->height + 2;
+ v->coord.right = pt.x + spr->width + 2 * ZOOM_LVL_BASE;
+ v->coord.bottom = pt.y + spr->height + 2 * ZOOM_LVL_BASE;
if (update_viewport) {
MarkAllViewportsDirty(
min(old_coord.left, v->coord.left),
min(old_coord.top, v->coord.top),
- max(old_coord.right, v->coord.right) + 1,
- max(old_coord.bottom, v->coord.bottom) + 1
+ max(old_coord.right, v->coord.right) + 1 * ZOOM_LVL_BASE,
+ max(old_coord.bottom, v->coord.bottom) + 1 * ZOOM_LVL_BASE
);
}
}
@@ -1430,7 +1430,7 @@ void VehicleMove(Vehicle *v, bool update_viewport)
*/
void MarkSingleVehicleDirty(const Vehicle *v)
{
- MarkAllViewportsDirty(v->coord.left, v->coord.top, v->coord.right + 1, v->coord.bottom + 1);
+ MarkAllViewportsDirty(v->coord.left, v->coord.top, v->coord.right + 1 * ZOOM_LVL_BASE, v->coord.bottom + 1 * ZOOM_LVL_BASE);
}
/**
diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp
index cbf6e1c08..519f39c19 100644
--- a/src/vehicle_gui.cpp
+++ b/src/vehicle_gui.cpp
@@ -39,6 +39,7 @@
#include "engine_func.h"
#include "station_base.h"
#include "tilehighlight_func.h"
+#include "zoom_func.h"
#include "table/strings.h"
@@ -2014,7 +2015,7 @@ struct VehicleDetailsWindow : Window {
case VLD_WIDGET_MIDDLE_DETAILS: {
/* For other vehicles, at the place of the matrix. */
bool rtl = _current_text_dir == TD_RTL;
- uint sprite_width = max<uint>(GetSprite(v->GetImage(rtl ? DIR_E : DIR_W, EIT_IN_DETAILS), ST_NORMAL)->width, 70U) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
+ uint sprite_width = max<uint>(UnScaleByZoom(GetSprite(v->GetImage(rtl ? DIR_E : DIR_W, EIT_IN_DETAILS), ST_NORMAL)->width, ZOOM_LVL_GUI), 70U) + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
uint text_left = r.left + (rtl ? 0 : sprite_width);
uint text_right = r.right - (rtl ? sprite_width : 0);
@@ -2551,7 +2552,7 @@ public:
case VVW_WIDGET_CENTER_MAIN_VIEH: {// center main view
const Window *mainwindow = FindWindowById(WC_MAIN_WINDOW, 0);
/* code to allow the main window to 'follow' the vehicle if the ctrl key is pressed */
- if (_ctrl_pressed && mainwindow->viewport->zoom == ZOOM_LVL_NORMAL) {
+ if (_ctrl_pressed && mainwindow->viewport->zoom <= ZOOM_LVL_OUT_4X) {
mainwindow->viewport->follow_vehicle = v->index;
} else {
ScrollMainWindowTo(v->x_pos, v->y_pos, v->z_pos);
@@ -2725,7 +2726,7 @@ int GetVehicleWidth(Vehicle *v, EngineImageType image_type)
bool rtl = _current_text_dir == TD_RTL;
SpriteID sprite = v->GetImage(rtl ? DIR_E : DIR_W, image_type);
const Sprite *real_sprite = GetSprite(sprite, ST_NORMAL);
- vehicle_width = real_sprite->width;
+ vehicle_width = UnScaleByZoom(real_sprite->width, ZOOM_LVL_GUI);
break;
}
diff --git a/src/viewport.cpp b/src/viewport.cpp
index b42acfdfc..56b2941aa 100644
--- a/src/viewport.cpp
+++ b/src/viewport.cpp
@@ -377,8 +377,8 @@ static Point TranslateXYToTileCoord(const ViewPort *vp, int x, int y)
return pt;
}
- x = (ScaleByZoom(x, vp->zoom) + vp->virtual_left) >> 2;
- y = (ScaleByZoom(y, vp->zoom) + vp->virtual_top) >> 1;
+ x = (ScaleByZoom(x, vp->zoom) + vp->virtual_left) >> (2 + ZOOM_LVL_SHIFT);
+ y = (ScaleByZoom(y, vp->zoom) + vp->virtual_top) >> (1 + ZOOM_LVL_SHIFT);
a = y - x;
b = y + x;
@@ -539,9 +539,9 @@ void DrawGroundSpriteAt(SpriteID image, PaletteID pal, int32 x, int32 y, int z,
if (_vd.foundation[_vd.foundation_part] != -1) {
Point pt = RemapCoords(x, y, z);
- AddChildSpriteToFoundation(image, pal, sub, _vd.foundation_part, pt.x + extra_offs_x, pt.y + extra_offs_y);
+ AddChildSpriteToFoundation(image, pal, sub, _vd.foundation_part, pt.x + extra_offs_x * ZOOM_LVL_BASE, pt.y + extra_offs_y * ZOOM_LVL_BASE);
} else {
- AddTileSpriteToDraw(image, pal, _cur_ti->x + x, _cur_ti->y + y, _cur_ti->z + z, sub, extra_offs_x, extra_offs_y);
+ AddTileSpriteToDraw(image, pal, _cur_ti->x + x, _cur_ti->y + y, _cur_ti->z + z, sub, extra_offs_x * ZOOM_LVL_BASE, extra_offs_y * ZOOM_LVL_BASE);
}
}
@@ -583,8 +583,8 @@ void OffsetGroundSprite(int x, int y)
/* _vd.last_child == NULL if foundation sprite was clipped by the viewport bounds */
if (_vd.last_child != NULL) _vd.foundation[_vd.foundation_part] = _vd.parent_sprites_to_draw.Length() - 1;
- _vd.foundation_offset[_vd.foundation_part].x = x;
- _vd.foundation_offset[_vd.foundation_part].y = y;
+ _vd.foundation_offset[_vd.foundation_part].x = x * ZOOM_LVL_BASE;
+ _vd.foundation_offset[_vd.foundation_part].y = y * ZOOM_LVL_BASE;
_vd.last_foundation_child[_vd.foundation_part] = _vd.last_child;
}
@@ -858,7 +858,7 @@ static void DrawSelectionSprite(SpriteID image, PaletteID pal, const TileInfo *t
AddTileSpriteToDraw(image, pal, ti->x, ti->y, ti->z + z_offset);
} else {
/* draw on top of foundation */
- AddChildSpriteToFoundation(image, pal, NULL, foundation_part, 0, -z_offset);
+ AddChildSpriteToFoundation(image, pal, NULL, foundation_part, 0, -z_offset * ZOOM_LVL_BASE);
}
}
@@ -1040,14 +1040,14 @@ static void ViewportAddLandscape()
_cur_ti = &ti;
/* Transform into tile coordinates and round to closest full tile */
- x = ((_vd.dpi.top >> 1) - (_vd.dpi.left >> 2)) & ~TILE_UNIT_MASK;
- y = ((_vd.dpi.top >> 1) + (_vd.dpi.left >> 2) - TILE_SIZE) & ~TILE_UNIT_MASK;
+ x = ((_vd.dpi.top >> (1 + ZOOM_LVL_SHIFT)) - (_vd.dpi.left >> (2 + ZOOM_LVL_SHIFT))) & ~TILE_UNIT_MASK;
+ y = ((_vd.dpi.top >> (1 + ZOOM_LVL_SHIFT)) + (_vd.dpi.left >> (2 + ZOOM_LVL_SHIFT)) - TILE_SIZE) & ~TILE_UNIT_MASK;
/* determine size of area */
{
Point pt = RemapCoords(x, y, 241);
- width = (_vd.dpi.left + _vd.dpi.width - pt.x + 95) >> 6;
- height = (_vd.dpi.top + _vd.dpi.height - pt.y) >> 5 << 1;
+ width = (_vd.dpi.left + _vd.dpi.width - pt.x + 95 * ZOOM_LVL_BASE) >> (6 + ZOOM_LVL_SHIFT);
+ height = (_vd.dpi.top + _vd.dpi.height - pt.y) >> (5 + ZOOM_LVL_SHIFT) << 1;
}
assert(width > 0);
@@ -1166,7 +1166,7 @@ static void ViewportAddTownNames(DrawPixelInfo *dpi)
const Town *t;
FOR_ALL_TOWNS(t) {
- ViewportAddString(dpi, ZOOM_LVL_OUT_4X, &t->sign,
+ ViewportAddString(dpi, ZOOM_LVL_OUT_16X, &t->sign,
_settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_POP : STR_VIEWPORT_TOWN,
STR_VIEWPORT_TOWN_TINY_WHITE, STR_VIEWPORT_TOWN_TINY_BLACK,
t->index, t->population);
@@ -1189,7 +1189,7 @@ static void ViewportAddStationNames(DrawPixelInfo *dpi)
/* Don't draw if station is owned by another company and competitor station names are hidden. Stations owned by none are never ignored. */
if (!HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS) && _local_company != st->owner && st->owner != OWNER_NONE) continue;
- ViewportAddString(dpi, ZOOM_LVL_OUT_4X, &st->sign,
+ ViewportAddString(dpi, ZOOM_LVL_OUT_16X, &st->sign,
is_station ? STR_VIEWPORT_STATION : STR_VIEWPORT_WAYPOINT,
(is_station ? STR_VIEWPORT_STATION : STR_VIEWPORT_WAYPOINT) + 1, STR_NULL,
st->index, st->facilities, (st->owner == OWNER_NONE || !st->IsInUse()) ? COLOUR_GREY : _company_colours[st->owner]);
@@ -1209,7 +1209,7 @@ static void ViewportAddSigns(DrawPixelInfo *dpi)
* companies can leave OWNER_NONE signs after them. */
if (!HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS) && _local_company != si->owner) continue;
- ViewportAddString(dpi, ZOOM_LVL_OUT_4X, &si->sign,
+ ViewportAddString(dpi, ZOOM_LVL_OUT_16X, &si->sign,
STR_WHITE_SIGN,
IsTransparencySet(TO_SIGNS) ? STR_VIEWPORT_SIGN_SMALL_WHITE : STR_VIEWPORT_SIGN_SMALL_BLACK, STR_NULL,
si->index, 0, (si->owner == OWNER_NONE) ? COLOUR_GREY : _company_colours[si->owner]);
@@ -1262,7 +1262,7 @@ static void ViewportDrawTileSprites(const TileSpriteToDrawVector *tstdv)
{
const TileSpriteToDraw *tsend = tstdv->End();
for (const TileSpriteToDraw *ts = tstdv->Begin(); ts != tsend; ++ts) {
- DrawSprite(ts->image, ts->pal, ts->x, ts->y, ts->sub);
+ DrawSpriteViewport(ts->image, ts->pal, ts->x, ts->y, ts->sub);
}
}
@@ -1329,13 +1329,13 @@ static void ViewportDrawParentSprites(const ParentSpriteToSortVector *psd, const
const ParentSpriteToDraw * const *psd_end = psd->End();
for (const ParentSpriteToDraw * const *it = psd->Begin(); it != psd_end; it++) {
const ParentSpriteToDraw *ps = *it;
- if (ps->image != SPR_EMPTY_BOUNDING_BOX) DrawSprite(ps->image, ps->pal, ps->x, ps->y, ps->sub);
+ if (ps->image != SPR_EMPTY_BOUNDING_BOX) DrawSpriteViewport(ps->image, ps->pal, ps->x, ps->y, ps->sub);
int child_idx = ps->first_child;
while (child_idx >= 0) {
const ChildScreenSpriteToDraw *cs = csstdv->Get(child_idx);
child_idx = cs->next;
- DrawSprite(cs->image, cs->pal, ps->left + cs->x, ps->top + cs->y, cs->sub);
+ DrawSpriteViewport(cs->image, cs->pal, ps->left + cs->x, ps->top + cs->y, cs->sub);
}
}
}
@@ -1475,7 +1475,7 @@ void ViewportDoDraw(const ViewPort *vp, int left, int top, int right, int bottom
*/
static void ViewportDrawChk(const ViewPort *vp, int left, int top, int right, int bottom)
{
- if (ScaleByZoom(bottom - top, vp->zoom) * ScaleByZoom(right - left, vp->zoom) > 180000) {
+ if (ScaleByZoom(bottom - top, vp->zoom) * ScaleByZoom(right - left, vp->zoom) > 180000 * ZOOM_LVL_BASE * ZOOM_LVL_BASE) {
if ((bottom - top) > (right - left)) {
int t = (top + bottom) >> 1;
ViewportDrawChk(vp, left, top, right, t);
@@ -1540,8 +1540,8 @@ static inline void ClampViewportToMap(const ViewPort *vp, int &x, int &y)
int vy = x + y * 2;
/* clamp to size of map */
- vx = Clamp(vx, 0, MapMaxX() * TILE_SIZE * 4);
- vy = Clamp(vy, 0, MapMaxY() * TILE_SIZE * 4);
+ vx = Clamp(vx, 0, MapMaxX() * TILE_SIZE * 4 * ZOOM_LVL_BASE);
+ vy = Clamp(vy, 0, MapMaxY() * TILE_SIZE * 4 * ZOOM_LVL_BASE);
/* Convert map coordinates to viewport coordinates */
x = (-vx + vy) / 2;
@@ -1576,7 +1576,7 @@ void UpdateViewportPosition(Window *w)
if (delta_x != 0 || delta_y != 0) {
if (_settings_client.gui.smooth_scroll) {
- int max_scroll = ScaleByMapSize1D(512);
+ int max_scroll = ScaleByMapSize1D(512 * ZOOM_LVL_BASE);
/* Not at our desired position yet... */
w->viewport->scrollpos_x += Clamp(delta_x / 4, -max_scroll, max_scroll);
w->viewport->scrollpos_y += Clamp(delta_y / 4, -max_scroll, max_scroll);
@@ -1668,10 +1668,10 @@ void MarkTileDirtyByTile(TileIndex tile)
{
Point pt = RemapCoords(TileX(tile) * TILE_SIZE, TileY(tile) * TILE_SIZE, GetTilePixelZ(tile));
MarkAllViewportsDirty(
- pt.x - 31,
- pt.y - 122,
- pt.x - 31 + 67,
- pt.y - 122 + 154
+ pt.x - 31 * ZOOM_LVL_BASE,
+ pt.y - 122 * ZOOM_LVL_BASE,
+ pt.x - 31 * ZOOM_LVL_BASE + 67 * ZOOM_LVL_BASE,
+ pt.y - 122 * ZOOM_LVL_BASE + 154 * ZOOM_LVL_BASE
);
}
@@ -1748,15 +1748,15 @@ static void SetSelectionTilesDirty()
/* the 'x' coordinate of 'top' and 'bot' is the same (and always in the same distance from tile middle),
* tile height/slope affects only the 'y' on-screen coordinate! */
- int l = top.x - (TILE_PIXELS - 2); // 'x' coordinate of left side of dirty rectangle
+ int l = top.x - (TILE_PIXELS - 2) * ZOOM_LVL_BASE; // 'x' coordinate of left side of dirty rectangle
int t = top.y; // 'y' coordinate of top side -//-
- int r = top.x + (TILE_PIXELS - 2); // right side of dirty rectangle
+ int r = top.x + (TILE_PIXELS - 2) * ZOOM_LVL_BASE; // right side of dirty rectangle
int b = bot.y; // bottom -//-
- static const int OVERLAY_WIDTH = 4; // part of selection sprites is drawn outside the selected area
+ static const int OVERLAY_WIDTH = 4 * ZOOM_LVL_BASE; // part of selection sprites is drawn outside the selected area
/* For halftile foundations on SLOPE_STEEP_S the sprite extents some more towards the top */
- MarkAllViewportsDirty(l - OVERLAY_WIDTH, t - OVERLAY_WIDTH - TILE_HEIGHT, r + OVERLAY_WIDTH, b + OVERLAY_WIDTH);
+ MarkAllViewportsDirty(l - OVERLAY_WIDTH, t - OVERLAY_WIDTH - TILE_HEIGHT * ZOOM_LVL_BASE, r + OVERLAY_WIDTH, b + OVERLAY_WIDTH * ZOOM_LVL_BASE);
/* haven't we reached the topmost tile yet? */
if (top_x != x_start) {
@@ -1809,7 +1809,7 @@ void SetSelectionRed(bool b)
*/
static bool CheckClickOnViewportSign(const ViewPort *vp, int x, int y, const ViewportSign *sign)
{
- bool small = (vp->zoom >= ZOOM_LVL_OUT_4X);
+ bool small = (vp->zoom >= ZOOM_LVL_OUT_16X);
int sign_half_width = ScaleByZoom((small ? sign->width_small : sign->width_normal) / 2, vp->zoom);
int sign_height = ScaleByZoom(VPSM_TOP + (small ? FONT_HEIGHT_SMALL : FONT_HEIGHT_NORMAL) + VPSM_BOTTOM, vp->zoom);
diff --git a/src/zoom_type.h b/src/zoom_type.h
index 8b5761408..37ffc153c 100644
--- a/src/zoom_type.h
+++ b/src/zoom_type.h
@@ -14,6 +14,9 @@
#include "core/enum_type.hpp"
+static int const ZOOM_LVL_SHIFT = 2;
+static int const ZOOM_LVL_BASE = 1 << ZOOM_LVL_SHIFT;
+
/** All zoom levels we know. */
enum ZoomLevel {
/* Our possible zoom-levels */
@@ -22,25 +25,28 @@ enum ZoomLevel {
ZOOM_LVL_OUT_2X, ///< Zoomed 2 times out.
ZOOM_LVL_OUT_4X, ///< Zoomed 4 times out.
ZOOM_LVL_OUT_8X, ///< Zoomed 8 times out.
+ ZOOM_LVL_OUT_16X, ///< Zoomed 16 times out.
+ ZOOM_LVL_OUT_32X, ///< Zoomed 32 times out.
ZOOM_LVL_END, ///< End for iteration.
ZOOM_LVL_COUNT = ZOOM_LVL_END - ZOOM_LVL_BEGIN, ///< Number of zoom levels.
/* Here we define in which zoom viewports are */
- ZOOM_LVL_VIEWPORT = ZOOM_LVL_NORMAL, ///< Default zoom level for viewports.
- ZOOM_LVL_NEWS = ZOOM_LVL_NORMAL, ///< Default zoom level for the news messages.
- ZOOM_LVL_INDUSTRY = ZOOM_LVL_OUT_2X, ///< Default zoom level for the industry view.
- ZOOM_LVL_TOWN = ZOOM_LVL_OUT_2X, ///< Default zoom level for the town view.
- ZOOM_LVL_AIRCRAFT = ZOOM_LVL_NORMAL, ///< Default zoom level for the aircraft view.
- ZOOM_LVL_SHIP = ZOOM_LVL_NORMAL, ///< Default zoom level for the ship view.
- ZOOM_LVL_TRAIN = ZOOM_LVL_NORMAL, ///< Default zoom level for the train view.
- ZOOM_LVL_ROADVEH = ZOOM_LVL_NORMAL, ///< Default zoom level for the road vehicle view.
- ZOOM_LVL_WORLD_SCREENSHOT = ZOOM_LVL_NORMAL, ///< Default zoom level for the world screen shot.
-
- ZOOM_LVL_DETAIL = ZOOM_LVL_OUT_2X, ///< All zoomlevels below or equal to this, will result in details on the screen, like road-work, ...
+ ZOOM_LVL_VIEWPORT = ZOOM_LVL_OUT_4X, ///< Default zoom level for viewports.
+ ZOOM_LVL_GUI = ZOOM_LVL_OUT_4X, ///< Default zoom level for GUI sprites.
+ ZOOM_LVL_NEWS = ZOOM_LVL_OUT_4X, ///< Default zoom level for the news messages.
+ ZOOM_LVL_INDUSTRY = ZOOM_LVL_OUT_8X, ///< Default zoom level for the industry view.
+ ZOOM_LVL_TOWN = ZOOM_LVL_OUT_8X, ///< Default zoom level for the town view.
+ ZOOM_LVL_AIRCRAFT = ZOOM_LVL_OUT_4X, ///< Default zoom level for the aircraft view.
+ ZOOM_LVL_SHIP = ZOOM_LVL_OUT_4X, ///< Default zoom level for the ship view.
+ ZOOM_LVL_TRAIN = ZOOM_LVL_OUT_4X, ///< Default zoom level for the train view.
+ ZOOM_LVL_ROADVEH = ZOOM_LVL_OUT_4X, ///< Default zoom level for the road vehicle view.
+ ZOOM_LVL_WORLD_SCREENSHOT = ZOOM_LVL_OUT_4X, ///< Default zoom level for the world screen shot.
+
+ ZOOM_LVL_DETAIL = ZOOM_LVL_OUT_8X, ///< All zoomlevels below or equal to this, will result in details on the screen, like road-work, ...
ZOOM_LVL_MIN = ZOOM_LVL_NORMAL, ///< Minimum zoom level.
- ZOOM_LVL_MAX = ZOOM_LVL_OUT_8X, ///< Maximum zoom level.
+ ZOOM_LVL_MAX = ZOOM_LVL_OUT_32X, ///< Maximum zoom level.
};
DECLARE_POSTFIX_INCREMENT(ZoomLevel)