(svn r23316) -Feature: Add ability to zoom in to 2x and 4x level.

This commit is contained in:
peter1138 2011-11-24 12:38:48 +00:00
parent 15d0a22aac
commit 81598273e9
29 changed files with 331 additions and 128 deletions

View File

@ -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);
}
/**

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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"

View File

@ -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;
}

View File

@ -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 {

View File

@ -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;
}

View File

@ -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

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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(). */

View File

@ -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();

View File

@ -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;

View File

@ -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

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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[] = {

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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""

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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);
}
/**

View File

@ -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;
}

View File

@ -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);

View File

@ -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_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_2X, ///< All zoomlevels below or equal to this, will result in details on the screen, like road-work, ...
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)