diff --git a/regression/regression/main.nut b/regression/regression/main.nut index 5aafaa4e71..7621c49c6f 100644 --- a/regression/regression/main.nut +++ b/regression/regression/main.nut @@ -1703,6 +1703,7 @@ function Regression::Vehicle() print(" BuildVehicle(): " + AIVehicle.BuildVehicle(33417, 153)); print(" IsValidVehicle(12): " + AIVehicle.IsValidVehicle(12)); print(" CloneVehicle(): " + AIVehicle.CloneVehicle(33417, 12, true)); + print(" BuildVehicle(): " + AIVehicle.BuildVehicle(-1, 153)); local bank_after = AICompany.GetBankBalance(AICompany.COMPANY_SELF); diff --git a/regression/regression/result.txt b/regression/regression/result.txt index d9b946f71a..dc3e294844 100644 --- a/regression/regression/result.txt +++ b/regression/regression/result.txt @@ -9295,6 +9295,7 @@ ERROR: IsEnd() is invalid as Begin() is never called BuildVehicle(): 12 IsValidVehicle(12): true CloneVehicle(): 13 + BuildVehicle(): 1048575 --Accounting-- GetCosts(): 11894 Should be: 11894 diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 567061d435..731069bd3e 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -24,6 +24,7 @@ #include "settings_func.h" #include "fios.h" #include "fileio_func.h" +#include "fontcache.h" #include "screenshot.h" #include "genworld.h" #include "strings_func.h" @@ -2211,6 +2212,82 @@ DEF_CONSOLE_CMD(ConContent) } #endif /* defined(WITH_ZLIB) */ +DEF_CONSOLE_CMD(ConFont) +{ + if (argc == 0) { + IConsoleHelp("Manage the fonts configuration."); + IConsoleHelp("Usage 'font'."); + IConsoleHelp(" Print out the fonts configuration."); + IConsoleHelp("Usage 'font [medium|small|large|mono] [] [] [aa|noaa]'."); + IConsoleHelp(" Change the configuration for a font."); + IConsoleHelp(" Omitting an argument will keep the current value."); + IConsoleHelp(" Set to \"\" for the sprite font (size and aa have no effect on sprite font)."); + return true; + } + + FontSize argfs; + for (argfs = FS_BEGIN; argfs < FS_END; argfs++) { + if (argc > 1 && strcasecmp(argv[1], FontSizeToName(argfs)) == 0) break; + } + + /* First argument must be a FontSize. */ + if (argc > 1 && argfs == FS_END) return false; + + if (argc > 2) { + FontCacheSubSetting *setting = GetFontCacheSubSetting(argfs); + std::string font = setting->font; + uint size = setting->size; + bool aa = setting->aa; + + byte arg_index = 2; + + if (argc > arg_index) { + /* We may encounter "aa" or "noaa" but it must be the last argument. */ + if (strcasecmp(argv[arg_index], "aa") == 0 || strcasecmp(argv[arg_index], "noaa") == 0) { + aa = strncasecmp(argv[arg_index++], "no", 2) != 0; + if (argc > arg_index) return false; + } else { + /* For we want a string. */ + uint v; + if (!GetArgumentInteger(&v, argv[arg_index])) { + font = argv[arg_index++]; + } + } + } + + if (argc > arg_index) { + /* For we want a number. */ + uint v; + if (GetArgumentInteger(&v, argv[arg_index])) { + size = v; + arg_index++; + } + } + + if (argc > arg_index) { + /* Last argument must be "aa" or "noaa". */ + if (strcasecmp(argv[arg_index], "aa") != 0 && strcasecmp(argv[arg_index], "noaa") != 0) return false; + aa = strncasecmp(argv[arg_index++], "no", 2) != 0; + if (argc > arg_index) return false; + } + + SetFont(argfs, font, size, aa); + } + + for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) { + FontCache *fc = FontCache::Get(fs); + FontCacheSubSetting *setting = GetFontCacheSubSetting(fs); + /* Make sure all non sprite fonts are loaded. */ + if (!setting->font.empty() && !fc->HasParent()) { + InitFontCache(fs == FS_MONO); + fc = FontCache::Get(fs); + } + IConsolePrintF(CC_DEFAULT, "%s: \"%s\" %d %s [\"%s\" %d %s]", FontSizeToName(fs), fc->GetFontName(), fc->GetFontSize(), GetFontAAState(fs) ? "true" : "false", setting->font.c_str(), setting->size, setting->aa ? "true" : "false"); + } + + return true; +} + DEF_CONSOLE_CMD(ConSetting) { if (argc == 0) { @@ -3627,6 +3704,7 @@ void IConsoleStdLibRegister() IConsole::CmdRegister("cd", ConChangeDirectory); IConsole::CmdRegister("pwd", ConPrintWorkingDirectory); IConsole::CmdRegister("clear", ConClearBuffer); + IConsole::CmdRegister("font", ConFont); IConsole::CmdRegister("setting", ConSetting); IConsole::CmdRegister("setting_newgame", ConSettingNewgame); IConsole::CmdRegister("list_settings", ConListSettings); diff --git a/src/engine_type.h b/src/engine_type.h index 92f6f73065..8d008c4586 100644 --- a/src/engine_type.h +++ b/src/engine_type.h @@ -155,7 +155,7 @@ enum EngineMiscFlags { EF_ROAD_TRAM = 0, ///< Road vehicle is a tram/light rail vehicle EF_USES_2CC = 1, ///< Vehicle uses two company colours EF_RAIL_IS_MU = 2, ///< Rail vehicle is a multiple-unit (DMU/EMU) - EF_RAIL_FLIPS = 3, ///< Rail vehicle can be flipped in the depot + EF_RAIL_FLIPS = 3, ///< Rail vehicle has old depot-flip handling EF_AUTO_REFIT = 4, ///< Automatic refitting is allowed EF_NO_DEFAULT_CARGO_MULTIPLIER = 5, ///< Use the new capacity algorithm. The default cargotype of the vehicle does not affect capacity multipliers. CB 15 is also called in purchase list. EF_NO_BREAKDOWN_SMOKE = 6, ///< Do not show black smoke during a breakdown. diff --git a/src/fontcache.cpp b/src/fontcache.cpp index dd917938d0..533d6b6892 100644 --- a/src/fontcache.cpp +++ b/src/fontcache.cpp @@ -13,6 +13,11 @@ #include "blitter/factory.hpp" #include "gfx_layout.h" #include "fontcache/spritefontcache.h" +#include "openttd.h" +#include "settings_func.h" +#include "strings_func.h" +#include "viewport_func.h" +#include "window_func.h" #include "safeguards.h" @@ -65,15 +70,51 @@ bool GetFontAAState(FontSize size, bool check_blitter) /* AA is only supported for 32 bpp */ if (check_blitter && BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 32) return false; - switch (size) { - default: NOT_REACHED(); - case FS_NORMAL: return _fcsettings.medium.aa; - case FS_SMALL: return _fcsettings.small.aa; - case FS_LARGE: return _fcsettings.large.aa; - case FS_MONO: return _fcsettings.mono.aa; - } + return GetFontCacheSubSetting(size)->aa; } +void SetFont(FontSize fontsize, const std::string& font, uint size, bool aa) +{ + FontCacheSubSetting *setting = GetFontCacheSubSetting(fontsize); + bool changed = false; + + if (setting->font != font) { + setting->font = font; + changed = true; + } + + if (setting->size != size) { + setting->size = size; + changed = true; + } + + if (setting->aa != aa) { + setting->aa = aa; + changed = true; + } + + if (!changed) return; + + if (fontsize != FS_MONO) { + /* Try to reload only the modified font. */ + FontCacheSettings backup = _fcsettings; + for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) { + if (fs == fontsize) continue; + FontCache *fc = FontCache::Get(fs); + GetFontCacheSubSetting(fs)->font = fc->HasParent() ? fc->GetFontName() : ""; + } + CheckForMissingGlyphs(); + _fcsettings = backup; + } else { + InitFontCache(true); + } + + LoadStringWidthTable(); + UpdateAllVirtCoords(); + ReInitAllWindows(true); + + if (_save_config) SaveToConfig(); +} /** * (Re)initialize the font cache related things, i.e. load the non-sprite fonts. diff --git a/src/fontcache.h b/src/fontcache.h index 3818517af0..4b2bfb2337 100644 --- a/src/fontcache.h +++ b/src/fontcache.h @@ -222,10 +222,27 @@ struct FontCacheSettings { extern FontCacheSettings _fcsettings; +/** + * Get the settings of a given font size. + * @param fs The font size to look up. + * @return The settings. + */ +static inline FontCacheSubSetting *GetFontCacheSubSetting(FontSize fs) +{ + switch (fs) { + default: NOT_REACHED(); + case FS_SMALL: return &_fcsettings.small; + case FS_NORMAL: return &_fcsettings.medium; + case FS_LARGE: return &_fcsettings.large; + case FS_MONO: return &_fcsettings.mono; + } +} + void InitFontCache(bool monospace); void UninitFontCache(); bool HasAntialiasedFonts(); bool GetFontAAState(FontSize size, bool check_blitter = true); +void SetFont(FontSize fontsize, const std::string &font, uint size, bool aa); #endif /* FONTCACHE_H */ diff --git a/src/fontcache/freetypefontcache.cpp b/src/fontcache/freetypefontcache.cpp index 275daefd35..b114252138 100644 --- a/src/fontcache/freetypefontcache.cpp +++ b/src/fontcache/freetypefontcache.cpp @@ -124,14 +124,7 @@ void FreeTypeFontCache::SetFontSize(FontSize fs, FT_Face face, int pixels) */ void LoadFreeTypeFont(FontSize fs) { - FontCacheSubSetting *settings = nullptr; - switch (fs) { - default: NOT_REACHED(); - case FS_SMALL: settings = &_fcsettings.small; break; - case FS_NORMAL: settings = &_fcsettings.medium; break; - case FS_LARGE: settings = &_fcsettings.large; break; - case FS_MONO: settings = &_fcsettings.mono; break; - } + FontCacheSubSetting *settings = GetFontCacheSubSetting(fs); if (settings->font.empty()) return; @@ -199,8 +192,7 @@ void LoadFreeTypeFont(FontSize fs) FT_Done_Face(face); - static const char *SIZE_TO_NAME[] = { "medium", "small", "large", "mono" }; - ShowInfoF("Unable to use '%s' for %s font, FreeType reported error 0x%X, using sprite font instead", font_name, SIZE_TO_NAME[fs], error); + ShowInfoF("Unable to use '%s' for %s font, FreeType reported error 0x%X, using sprite font instead", font_name, FontSizeToName(fs), error); return; found_face: diff --git a/src/gfx_type.h b/src/gfx_type.h index 30fcbc67b8..00fb951351 100644 --- a/src/gfx_type.h +++ b/src/gfx_type.h @@ -215,6 +215,13 @@ enum FontSize { }; DECLARE_POSTFIX_INCREMENT(FontSize) +static inline const char *FontSizeToName(FontSize fs) +{ + static const char *SIZE_TO_NAME[] = { "medium", "small", "large", "mono" }; + assert(fs < FS_END); + return SIZE_TO_NAME[fs]; +} + /** * Used to only draw a part of the sprite. * Draw the subsprite in the rect (sprite_x_offset + left, sprite_y_offset + top) to (sprite_x_offset + right, sprite_y_offset + bottom). diff --git a/src/landscape.cpp b/src/landscape.cpp index 3c0f2299c7..d1d6f0bb70 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -520,7 +520,7 @@ void DrawFoundation(TileInfo *ti, Foundation f) if (!IsNonContinuousFoundation(f)) { /* Lower part of foundation */ AddSortableSpriteToDraw( - leveled_base + (ti->tileh & ~SLOPE_STEEP), PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z + leveled_base + (ti->tileh & ~SLOPE_STEEP), PAL_NONE, ti->x, ti->y, TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1, ti->z ); } @@ -532,38 +532,44 @@ void DrawFoundation(TileInfo *ti, Foundation f) byte inclined = highest_corner * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0); AddSortableSpriteToDraw(inclined_base + inclined, PAL_NONE, ti->x, ti->y, - f == FOUNDATION_INCLINED_X ? 16 : 1, - f == FOUNDATION_INCLINED_Y ? 16 : 1, + f == FOUNDATION_INCLINED_X ? TILE_SIZE : 1, + f == FOUNDATION_INCLINED_Y ? TILE_SIZE : 1, TILE_HEIGHT, ti->z ); - OffsetGroundSprite(31, 9); + OffsetGroundSprite(0, 0); } else if (IsLeveledFoundation(f)) { - AddSortableSpriteToDraw(leveled_base + SlopeWithOneCornerRaised(highest_corner), PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z - TILE_HEIGHT); - OffsetGroundSprite(31, 1); + AddSortableSpriteToDraw(leveled_base + SlopeWithOneCornerRaised(highest_corner), PAL_NONE, ti->x, ti->y, TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1, ti->z - TILE_HEIGHT); + OffsetGroundSprite(0, -(int)TILE_HEIGHT); } else if (f == FOUNDATION_STEEP_LOWER) { /* one corner raised */ - OffsetGroundSprite(31, 1); + OffsetGroundSprite(0, -(int)TILE_HEIGHT); } else { /* halftile foundation */ - int x_bb = (((highest_corner == CORNER_W) || (highest_corner == CORNER_S)) ? 8 : 0); - int y_bb = (((highest_corner == CORNER_S) || (highest_corner == CORNER_E)) ? 8 : 0); + int x_bb = (((highest_corner == CORNER_W) || (highest_corner == CORNER_S)) ? TILE_SIZE / 2 : 0); + int y_bb = (((highest_corner == CORNER_S) || (highest_corner == CORNER_E)) ? TILE_SIZE / 2 : 0); - AddSortableSpriteToDraw(halftile_base + highest_corner, PAL_NONE, ti->x + x_bb, ti->y + y_bb, 8, 8, 7, ti->z + TILE_HEIGHT); - OffsetGroundSprite(31, 9); + AddSortableSpriteToDraw(halftile_base + highest_corner, PAL_NONE, ti->x + x_bb, ti->y + y_bb, TILE_SIZE / 2, TILE_SIZE / 2, TILE_HEIGHT - 1, ti->z + TILE_HEIGHT); + /* Reposition ground sprite back to original position after bounding box change above. This is similar to + * RemapCoords() but without zoom scaling. */ + Point pt = {(y_bb - x_bb) * 2, y_bb + x_bb}; + OffsetGroundSprite(-pt.x, -pt.y); } } else { if (IsLeveledFoundation(f)) { /* leveled foundation */ - AddSortableSpriteToDraw(leveled_base + ti->tileh, PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z); - OffsetGroundSprite(31, 1); + AddSortableSpriteToDraw(leveled_base + ti->tileh, PAL_NONE, ti->x, ti->y, TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1, ti->z); + OffsetGroundSprite(0, -(int)TILE_HEIGHT); } else if (IsNonContinuousFoundation(f)) { /* halftile foundation */ Corner halftile_corner = GetHalftileFoundationCorner(f); - int x_bb = (((halftile_corner == CORNER_W) || (halftile_corner == CORNER_S)) ? 8 : 0); - int y_bb = (((halftile_corner == CORNER_S) || (halftile_corner == CORNER_E)) ? 8 : 0); + int x_bb = (((halftile_corner == CORNER_W) || (halftile_corner == CORNER_S)) ? TILE_SIZE / 2 : 0); + int y_bb = (((halftile_corner == CORNER_S) || (halftile_corner == CORNER_E)) ? TILE_SIZE / 2 : 0); - AddSortableSpriteToDraw(halftile_base + halftile_corner, PAL_NONE, ti->x + x_bb, ti->y + y_bb, 8, 8, 7, ti->z); - OffsetGroundSprite(31, 9); + AddSortableSpriteToDraw(halftile_base + halftile_corner, PAL_NONE, ti->x + x_bb, ti->y + y_bb, TILE_SIZE / 2, TILE_SIZE / 2, TILE_HEIGHT - 1, ti->z); + /* Reposition ground sprite back to original position after bounding box change above. This is similar to + * RemapCoords() but without zoom scaling. */ + Point pt = {(y_bb - x_bb) * 2, y_bb + x_bb}; + OffsetGroundSprite(-pt.x, -pt.y); } else if (IsSpecialRailFoundation(f)) { /* anti-zig-zag foundation */ SpriteID spr; @@ -574,18 +580,18 @@ void DrawFoundation(TileInfo *ti, Foundation f) /* tile-slope = sloped along X/Y, foundation-slope = three corners raised */ spr = inclined_base + 2 * GetRailFoundationCorner(f) + ((ti->tileh == SLOPE_SW || ti->tileh == SLOPE_NE) ? 1 : 0); } - AddSortableSpriteToDraw(spr, PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z); - OffsetGroundSprite(31, 9); + AddSortableSpriteToDraw(spr, PAL_NONE, ti->x, ti->y, TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1, ti->z); + OffsetGroundSprite(0, 0); } else { /* inclined foundation */ byte inclined = GetHighestSlopeCorner(ti->tileh) * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0); AddSortableSpriteToDraw(inclined_base + inclined, PAL_NONE, ti->x, ti->y, - f == FOUNDATION_INCLINED_X ? 16 : 1, - f == FOUNDATION_INCLINED_Y ? 16 : 1, + f == FOUNDATION_INCLINED_X ? TILE_SIZE : 1, + f == FOUNDATION_INCLINED_Y ? TILE_SIZE : 1, TILE_HEIGHT, ti->z ); - OffsetGroundSprite(31, 9); + OffsetGroundSprite(0, 0); } ti->z += ApplyPixelFoundationToSlope(f, &ti->tileh); } diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index dc52224c20..2e7caca57e 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -758,7 +758,7 @@ STR_SMALLMAP_TOOLTIP_SHOW_INDUSTRIES_ON_MAP :{BLACK}Exibir i STR_SMALLMAP_TOOLTIP_SHOW_LINK_STATS_ON_MAP :{BLACK}Exibir fluxo de carga no mapa STR_SMALLMAP_TOOLTIP_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Exibir rotas de transporte no mapa STR_SMALLMAP_TOOLTIP_SHOW_VEGETATION_ON_MAP :{BLACK}Exibir vegetação no mapa -STR_SMALLMAP_TOOLTIP_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Exibir proprietários de terreno no mapa +STR_SMALLMAP_TOOLTIP_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Exibir proprietários de terrenos no mapa STR_SMALLMAP_TOOLTIP_INDUSTRY_SELECTION :{BLACK}Clique em um tipo de indústria para alternar sua exibição. Ctrl+Clique desabilita todos os tipos exceto a selecionada. Ctrl+Clique nela novamente para habilitar todos os tipos de indústrias STR_SMALLMAP_TOOLTIP_COMPANY_SELECTION :{BLACK}Clique em uma compania para alternar a exibição de suas propriedades. Ctrl+Clique desabilita todas as companias exceto a selecionada. Ctrl+Clique nela novamente para habilitar todas as companias STR_SMALLMAP_TOOLTIP_CARGO_SELECTION :{BLACK}Clique numa carga para alternar a exibição de sua propriedade. Ctrl+Clique desativa todas as cargas exceto a selecionada. Ctrl+Clique novamente para exibir todas @@ -1019,7 +1019,7 @@ STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE}A config STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Marque esta caixa para habilitar o v-sync na tela. Qualquer mudança nesta configuração só será aplicada após reiniciar o jogo. Só funciona com a aceleração de hardware habilitada -STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Motorista atual: {STRING} +STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Driver de vídeo atual: {STRING} STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Tamanho da interface STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Arraste o controle deslizante para definir o tamanho do interface. Mantenha pressionada a tecla Ctrl para um ajuste contínuo @@ -2512,7 +2512,7 @@ STR_NETWORK_ERROR_COORDINATOR_ISOLATED :{WHITE}Seu serv STR_NETWORK_ERROR_COORDINATOR_ISOLATED_DETAIL :{WHITE}Outros jogadores não poderão se conectar ao seu servidor # Content downloading window -STR_CONTENT_TITLE :{WHITE}Baixando conteúdo +STR_CONTENT_TITLE :{WHITE}Download de conteúdo STR_CONTENT_TYPE_CAPTION :{BLACK}Tipo STR_CONTENT_TYPE_CAPTION_TOOLTIP :{BLACK}Tipo do conteúdo STR_CONTENT_NAME_CAPTION :{BLACK}Nome @@ -2534,7 +2534,7 @@ STR_CONTENT_OPEN_URL_TOOLTIP :{BLACK}Visitar STR_CONTENT_DOWNLOAD_CAPTION :{BLACK}Baixar STR_CONTENT_DOWNLOAD_CAPTION_TOOLTIP :{BLACK}Baixa o conteúdo selecionado STR_CONTENT_TOTAL_DOWNLOAD_SIZE :{SILVER}Tamanho total do download: {WHITE}{BYTES} -STR_CONTENT_DETAIL_TITLE :{SILVER}INFO DO CONT. +STR_CONTENT_DETAIL_TITLE :{SILVER}INFORMAÇÕES DO CONTEÚDO ###length 5 STR_CONTENT_DETAIL_SUBTITLE_UNSELECTED :{SILVER}Você não selecionou para ser baixado @@ -2834,13 +2834,13 @@ STR_PLANT_TREE_TOOLTIP :{BLACK}Selecion STR_TREES_RANDOM_TYPE :{BLACK}Árvores de tipo aleatório STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Plantar árvores de tipo aleatório, Shift alterna entre construção/preço estimado STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Plantar Aleatoriamente -STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Planta árvores aleatoriamente pelo terreno +STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Plantar árvores aleatoriamente pelo terreno STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normal STR_TREES_MODE_NORMAL_TOOLTIP :{BLACK}Planta árvores isoladas ao arrastar pelo terreno. STR_TREES_MODE_FOREST_SM_BUTTON :{BLACK}Bosque -STR_TREES_MODE_FOREST_SM_TOOLTIP :{BLACK}Planta pequenas florestas ao arrastar pelo terreno. +STR_TREES_MODE_FOREST_SM_TOOLTIP :{BLACK}Plantar pequenas florestas ao arrastar sobre o terreno. STR_TREES_MODE_FOREST_LG_BUTTON :{BLACK}Floresta -STR_TREES_MODE_FOREST_LG_TOOLTIP :{BLACK}Planta florestas grandes ao arrastar pelo terreno. +STR_TREES_MODE_FOREST_LG_TOOLTIP :{BLACK}Plantar florestas grandes ao arrastar pelo terreno. # Land generation window (SE) STR_TERRAFORM_TOOLBAR_LAND_GENERATION_CAPTION :{WHITE}Gerar Terreno @@ -3344,7 +3344,10 @@ STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Represen STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Move o "sprite", alterando os offsets X e Y. Ctrl+Clique para mover o sprite 8 unidades por vez ###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Deslocamento centralizado +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite centralizado +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Mira STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Resetar relativo STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Reseta os offsets relativos atuais @@ -4643,11 +4646,11 @@ STR_AI_SETTINGS_START_DELAY :Número de dias # Textfile window STR_TEXTFILE_WRAP_TEXT :{WHITE}Quebra de linha STR_TEXTFILE_WRAP_TEXT_TOOLTIP :[BLACK}Quebra linhas automaticamente para que o texto caiba na janela -STR_TEXTFILE_VIEW_README :{BLACK}Ler o Leiame +STR_TEXTFILE_VIEW_README :{BLACK}Ver o leia-me STR_TEXTFILE_VIEW_CHANGELOG :{BLACK}Log de mudanças STR_TEXTFILE_VIEW_LICENCE :{BLACK}Licença ###length 3 -STR_TEXTFILE_README_CAPTION :{WHITE}{STRING} Leiame de {STRING} +STR_TEXTFILE_README_CAPTION :{WHITE}{STRING} Leia-me de {STRING} STR_TEXTFILE_CHANGELOG_CAPTION :{WHITE}{STRING} log de mudanças de {STRING} STR_TEXTFILE_LICENCE_CAPTION :{WHITE}{STRING} licença de {STRING} @@ -4956,7 +4959,7 @@ STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Remova a STR_ERROR_CAN_T_START_AND_END_ON :{WHITE}Impossível iniciar e terminar no mesmo ponto STR_ERROR_BRIDGEHEADS_NOT_SAME_HEIGHT :{WHITE}Extremidades da ponte não estão no mesmo nível STR_ERROR_BRIDGE_TOO_LOW_FOR_TERRAIN :{WHITE}Ponte é muito baixa para o terreno -STR_ERROR_BRIDGE_TOO_HIGH_FOR_TERRAIN :{WHITE}A ponte está muito alta para esse terreno. +STR_ERROR_BRIDGE_TOO_HIGH_FOR_TERRAIN :{WHITE}A ponte está muito alta para este terreno. STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Inicio e fim devem estar alinhados STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... os extremos da ponte devem estar sobre a terra STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... ponte muito longa diff --git a/src/lang/dutch.txt b/src/lang/dutch.txt index 1fbb355c29..71ce6f844c 100644 --- a/src/lang/dutch.txt +++ b/src/lang/dutch.txt @@ -3345,7 +3345,10 @@ STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Voorbeel STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Sprite verplaatsen, dit verandert X en Y offsets. Ctr+klik om de sprite 8 eenheden per keer te verplaatsen. ###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Op offset gecentreerd +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Op sprite gecentreerd +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Richtkruis STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Relatief herstellen STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Herstel de huidige relatieve offsets diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt index 1abaf940c9..f25c7a023d 100644 --- a/src/lang/finnish.txt +++ b/src/lang/finnish.txt @@ -515,8 +515,8 @@ STR_ABOUT_MENU_SCREENSHOT :Kuvakaappaus STR_ABOUT_MENU_SHOW_FRAMERATE :Näytä kuvataajuus STR_ABOUT_MENU_ABOUT_OPENTTD :Tietoja OpenTTD:stä STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite-kohdistaja -STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Reunat päälle/pois -STR_ABOUT_MENU_TOGGLE_DIRTY_BLOCKS :Likaisten ruutujen värjäys päälle/pois +STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Rajakehikot päälle/pois +STR_ABOUT_MENU_TOGGLE_DIRTY_BLOCKS :Likaisten lohkojen värjäys päälle/pois # Place in highscore window ###length 15 @@ -1910,9 +1910,9 @@ STR_CONFIG_SETTING_ZOOM_LVL_OUT_8X :8x STR_CONFIG_SETTING_SPRITE_ZOOM_MIN :Korkein käytettävä sprite-resoluutio: {STRING} STR_CONFIG_SETTING_SPRITE_ZOOM_MIN_HELPTEXT :Rajoita suurinta spriteille käytettävää resoluutiota. Resoluution rajoittaminen estää korkean tarkkuuden grafiikoiden käyttämisen vaikka niitä olisi saatavilla. Tämä voi auttaa pitämään pelin ulkoasun yhtenäisenä käytettäessä sekaisin GRF-tiedostoja, joista osalla on ja osalla ei ole korkean tarkkuuden grafiikoita. ###length 3 -STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_MIN :4x -STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_IN_2X :2x -STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_NORMAL :1x +STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_MIN :4× +STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_IN_2X :2× +STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_NORMAL :1× STR_CONFIG_SETTING_TOWN_GROWTH :Kuntien kasvunopeus: {STRING} STR_CONFIG_SETTING_TOWN_GROWTH_HELPTEXT :Kunnan kasvunopeus @@ -2060,7 +2060,7 @@ STR_CONFIG_ERROR_INVALID_BASE_GRAPHICS_NOT_FOUND :{WHITE}... ohit STR_CONFIG_ERROR_INVALID_BASE_SOUNDS_NOT_FOUND :{WHITE}... ohitetaan äänipaketti ”{STRING}”: ei löydetty STR_CONFIG_ERROR_INVALID_BASE_MUSIC_NOT_FOUND :{WHITE}... ohitetaan musiikkipaketti ”{STRING}”: ei löydetty STR_CONFIG_ERROR_OUT_OF_MEMORY :{WHITE}Muisti lopussa -STR_CONFIG_ERROR_SPRITECACHE_TOO_BIG :{WHITE}{BYTES} sprite-välimuistin varaaminen epäonnistui. Sprite-välimuistin kooksi valittiin {BYTES}. Tämä heikentää OpenTTD:n suorituskykyä. Vähentääksesi muistivaatimuksia voit kokeilla poistaa käytöstä 32bpp-grafiikat ja/tai lähennystasoja +STR_CONFIG_ERROR_SPRITECACHE_TOO_BIG :{WHITE}{BYTES} sprite-välimuistin varaaminen epäonnistui. Sprite-välimuistin kooksi valittiin {BYTES}. Tämä heikentää OpenTTD:n suorituskykyä. Vähentääksesi muistivaatimuksia voit kokeilla poistaa käytöstä 32 bpp -grafiikat ja/tai lähennystasoja # Video initalization errors STR_VIDEO_DRIVER_ERROR :{WHITE}Virhe näyttöasetuksissa… @@ -3334,12 +3334,12 @@ STR_NEWGRF_INSPECT_QUERY_CAPTION :{WHITE}NewGRF m # Sprite aligner window STR_SPRITE_ALIGNER_CAPTION :{WHITE}Kohdistetaan spriteä {COMMA} ({STRING}) STR_SPRITE_ALIGNER_NEXT_BUTTON :{BLACK}Seuraava sprite -STR_SPRITE_ALIGNER_NEXT_TOOLTIP :{BLACK}Mene seuraavaan tavalliseen spriteen ja hyppää yli pseudo-/uudelleenväritetyt/fontti- spritet ja mene alkuun kun päästään viimeiseen +STR_SPRITE_ALIGNER_NEXT_TOOLTIP :{BLACK}Siirry seuraavaan tavalliseen spriteen; mahdolliset pseudo-, uudelleenväritys- ja fonttispritet ohitetaan; viimeisen spriten jälkeen siirrytään ensimmäiseen STR_SPRITE_ALIGNER_GOTO_BUTTON :{BLACK}Mene spriteen -STR_SPRITE_ALIGNER_GOTO_TOOLTIP :{BLACK}Mene valittuun spriteen. Jos sprite ei ole tavallinen, jatka seuraavaan tavalliseen spriteen -STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Edelinen sprite +STR_SPRITE_ALIGNER_GOTO_TOOLTIP :{BLACK}Siirry valittuun spriteen. Jos sprite ei ole tavallinen, jatka seuraavaan tavalliseen spriteen +STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Edellinen sprite STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Jatka edelliseen tavalliseen spriteen ja hyppää yli kaikki pseudo-/uudelleenväritetyt/fontti- spritet ja mene loppuun kun päästään ensimmäiseen -STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Valitun spriten näyttö. Sijaintia ei huomioida spriteä piirrettäessä +STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Valitun spriten esitys. Siirrosta ei huomioida tätä spriteä piirrettäessä STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Liikuta spriteä ympäriinsä, muuttaen X- ja Y-sijainteja. Ctrl+napsautus siirtää spriteä kahdeksan yksikköä kerralla. ###length 2 @@ -3349,9 +3349,9 @@ STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite k STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Hiusristikko STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Nollaa suhteelliset -STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Nollaa suhteelliset erotukset -STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X-erotus: {NUM}, Y-erotus: {NUM} (absoluuttinen) -STR_SPRITE_ALIGNER_OFFSETS_REL :{BLACK}X-erotus: {NUM}, Y-erotus: {NUM} (suhteellinen) +STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Nollaa tämänhetkiset suhteelliset siirrokset +STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X-siirros: {NUM}, Y-siirros: {NUM} (absoluuttinen) +STR_SPRITE_ALIGNER_OFFSETS_REL :{BLACK}X-siirros: {NUM}, Y-siirros: {NUM} (suhteellinen) STR_SPRITE_ALIGNER_PICKER_BUTTON :{BLACK}Valitse sprite STR_SPRITE_ALIGNER_PICKER_TOOLTIP :{BLACK}Valitse sprite ruudulta diff --git a/src/lang/latvian.txt b/src/lang/latvian.txt index 5e2adcc0d2..eed6500e7d 100644 --- a/src/lang/latvian.txt +++ b/src/lang/latvian.txt @@ -207,6 +207,10 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}ZS STR_UNITS_POWER_METRIC :{COMMA}{NBSP}ZS STR_UNITS_POWER_SI :{COMMA}{NBSP}kW +STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}zs/Mg +STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}zs/l +STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/l +STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t @@ -1011,8 +1015,13 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Atzīmē STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Esošais vadītājs: {STRING} +STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Velciet slīdni, lai iestatītu interfeisa izmēru. Turiet nospiestu taustiņu Ctrl, lai veiktu nepārtrauktu regulēšanu +STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Automātiski noteikt izmēru +STR_GAME_OPTIONS_GUI_SCALE_2X :2x +STR_GAME_OPTIONS_GUI_SCALE_3X :3x +STR_GAME_OPTIONS_GUI_SCALE_5X :5x STR_GAME_OPTIONS_GRAPHICS :{BLACK}Grafika @@ -2061,6 +2070,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Sasniegu STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Iestatījumi STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF iestatījumi STR_INTRO_ONLINE_CONTENT :{BLACK}Pārbaudīt tiešsaistes saturu +STR_INTRO_AI_SETTINGS :{BLACK}AI Iestatījumi +STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Spēles Skripta Iestatījumi STR_INTRO_QUIT :{BLACK}Iziet STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Sākt jaunu spēli. Ctrl+klikšķis izlaiž kartes konfigurēšanu @@ -2591,6 +2602,8 @@ STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLA STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}pārslogots # Linkgraph tooltip +STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} jātransportē atpakaļ ({COMMA}% no pārvadājuma) +STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Vidējais ceļojuma laiks: {NUM}{NBSP}dienas # Base for station construction window(s) STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Pārklājuma iezīmēšana @@ -3310,6 +3323,7 @@ STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Atlasīt STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Pārvietot gariņu, lai mainītu X un Y vērtības. Ctrl+klikšķis, lai vienā piegājienā pārvietotu gariņu par astoņām vienībām ###length 2 +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Spraits centrēts STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Atiestatīt relatīvi @@ -3655,13 +3669,16 @@ STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Aizdevuma STR_FINANCES_SECTION_OTHER :{GOLD}Citi STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG} +STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG} +STR_FINANCES_PROFIT :{WHITE}Peļņa STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Bankas bilance STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Pašu līdzekļi STR_FINANCES_LOAN_TITLE :{WHITE}Aizdevums STR_FINANCES_INTEREST_RATE :{WHITE}Aizdevuma procenti: {BLACK}{NUM}% STR_FINANCES_MAX_LOAN :{WHITE}Maksimālais aizdevums: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} +STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}Aizņemties {CURRENCY_LONG} STR_FINANCES_BORROW_TOOLTIP :{BLACK}Palielināt aizdevuma apmēru. Ctrl+klikšķis lai aizņemtos cik daudz vien iespējams STR_FINANCES_REPAY_BUTTON :{BLACK}Atmaksāt {CURRENCY_LONG} @@ -3793,6 +3810,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Sūtīt STR_VEHICLE_LIST_REPLACE_VEHICLES :Nomainīt transportlīdzekļus STR_VEHICLE_LIST_SEND_FOR_SERVICING :Sūtīt uz apkopi STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Peļņa šogad: {CURRENCY_LONG} (pērn: {CURRENCY_LONG}) +STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}] +STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING} STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Sūtīt uz depo STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Sūtīt uz depo @@ -4560,6 +4579,7 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Nolaist STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Nolaist izvēlētos MI sarakstā uz leju STR_AI_CONFIG_GAMESCRIPT :{SILVER}Spēles skripti +STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parametri STR_AI_CONFIG_AI :{SILVER}MI STR_AI_CONFIG_CHANGE_AI :MI @@ -4937,6 +4957,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Traucēj STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... traucē uzņēmuma birojs STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Nevar nopirkt šo zemes platību... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... tā jums jau pieder! +STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... sasniegts objektu būvniecības limits # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Nevar izveidot grupu... diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index a45504b4c2..c9628f318b 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -3346,7 +3346,10 @@ STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Represen STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Desloca o gráfico, alterando os intervalos X e Y. Ctrl+Clique desloca o gráfico 8 unidades de uma só vez ###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Deslocamento centrado +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite centrado +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Mira STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Repor relativo STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Repor intervalos relativos atuais diff --git a/src/lang/russian.txt b/src/lang/russian.txt index 003f35abbe..f5b219579a 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -3527,7 +3527,10 @@ STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Пред STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Двигайте спрайт, изменяя смещение по осям X и Y. С помощью Ctrl+щелчка можно сдвигать спрайты на 8 единиц. ###length 2 +STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Смещение в центре +STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Спрайт в центре +STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Перекрестие STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Сброс смещения STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Сбросить значения относительного смещения diff --git a/src/lang/spanish.txt b/src/lang/spanish.txt index 77736270ec..ba27df85e0 100644 --- a/src/lang/spanish.txt +++ b/src/lang/spanish.txt @@ -1081,7 +1081,7 @@ STR_CURRENCY_SET_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Configur STR_CURRENCY_DECREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Cambia al Euro antes STR_CURRENCY_INCREASE_CUSTOM_CURRENCY_TO_EURO_TOOLTIP :{BLACK}Cambia al Euro después -STR_CURRENCY_PREVIEW :{LTBLUE}Previa: {ORANGE}{CURRENCY_LONG} +STR_CURRENCY_PREVIEW :{LTBLUE}Vista preliminar: {ORANGE} {CURRENCY_LONG} STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 Libras(£) en tu moneda STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Cambiar parámetro de moneda personalizada diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 828c96df85..8b1c3a18e7 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.cpp @@ -862,6 +862,11 @@ void QueryString::HandleEditBox(Window *w, int wid) } } +static int GetCaretWidth() +{ + return GetCharacterWidth(FS_NORMAL, '_'); +} + void QueryString::DrawEditBox(const Window *w, int wid) const { const NWidgetLeaf *wi = w->GetWidget(wid); @@ -894,7 +899,7 @@ void QueryString::DrawEditBox(const Window *w, int wid) const /* We will take the current widget length as maximum width, with a small * space reserved at the end for the caret to show */ const Textbuf *tb = &this->text; - int delta = std::min(0, (fr.right - fr.left) - tb->pixels - 10); + int delta = std::min(0, (fr.right - fr.left) - tb->pixels - GetCaretWidth()); if (tb->caretxoffs + delta < 0) delta = -tb->caretxoffs; @@ -931,7 +936,7 @@ Point QueryString::GetCaretPosition(const Window *w, int wid) const /* Clamp caret position to be inside out current width. */ const Textbuf *tb = &this->text; - int delta = std::min(0, (r.right - r.left) - tb->pixels - 10); + int delta = std::min(0, (r.right - r.left) - tb->pixels - GetCaretWidth()); if (tb->caretxoffs + delta < 0) delta = -tb->caretxoffs; Point pt = {r.left + tb->caretxoffs + delta, r.top}; @@ -960,7 +965,7 @@ Rect QueryString::GetBoundingRect(const Window *w, int wid, const char *from, co /* Clamp caret position to be inside our current width. */ const Textbuf *tb = &this->text; - int delta = std::min(0, r.Width() - tb->pixels - 10); + int delta = std::min(0, r.Width() - tb->pixels - GetCaretWidth()); if (tb->caretxoffs + delta < 0) delta = -tb->caretxoffs; /* Get location of first and last character. */ @@ -993,7 +998,7 @@ const char *QueryString::GetCharAtPosition(const Window *w, int wid, const Point /* Clamp caret position to be inside our current width. */ const Textbuf *tb = &this->text; - int delta = std::min(0, r.Width() - tb->pixels - 10); + int delta = std::min(0, r.Width() - tb->pixels - GetCaretWidth()); if (tb->caretxoffs + delta < 0) delta = -tb->caretxoffs; return ::GetCharAtPosition(tb->buf, pt.x - delta - r.left); diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 4f007a9a40..0511dace9f 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -227,7 +227,6 @@ struct GRFTempEngineData { uint8 roadtramtype; const GRFFile *defaultcargo_grf; ///< GRF defining the cargo translation table to use if the default cargo is the 'first refittable'. Refittability refittability; ///< Did the newgrf set any refittability property? If not, default refittability will be applied. - bool prop27_set; ///< Did the NewGRF set property 27 (misc flags)? uint8 rv_max_speed; ///< Temporary storage of RV prop 15, maximum speed in mph/0.8 CargoTypes ctt_include_mask; ///< Cargo types always included in the refit mask. CargoTypes ctt_exclude_mask; ///< Cargo types always excluded from the refit mask. @@ -1237,7 +1236,6 @@ static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop case 0x27: // Miscellaneous flags ei->misc_flags = buf->ReadByte(); _loaded_newgrf_features.has_2CC |= HasBit(ei->misc_flags, EF_USES_2CC); - _gted[e->index].prop27_set = true; break; case 0x28: // Cargo classes allowed @@ -10559,13 +10557,6 @@ static void FinaliseEngineArray() if (!HasBit(e->info.climates, _settings_game.game_creation.landscape)) continue; - /* When the train does not set property 27 (misc flags), but it - * is overridden by a NewGRF graphically we want to disable the - * flipping possibility. */ - if (e->type == VEH_TRAIN && !_gted[e->index].prop27_set && e->GetGRF() != nullptr && is_custom_sprite(e->u.rail.image_index)) { - ClrBit(e->info.misc_flags, EF_RAIL_FLIPS); - } - /* Skip wagons, there livery is defined via the engine */ if (e->type != VEH_TRAIN || e->u.rail.railveh_type != RAILVEH_WAGON) { LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, nullptr); diff --git a/src/os/macosx/font_osx.cpp b/src/os/macosx/font_osx.cpp index d8186f8228..bbc0450754 100644 --- a/src/os/macosx/font_osx.cpp +++ b/src/os/macosx/font_osx.cpp @@ -352,16 +352,7 @@ const Sprite *CoreTextFontCache::InternalGetGlyph(GlyphID key, bool use_aa) */ void LoadCoreTextFont(FontSize fs) { - static const char *SIZE_TO_NAME[] = { "medium", "small", "large", "mono" }; - - FontCacheSubSetting *settings = nullptr; - switch (fs) { - default: NOT_REACHED(); - case FS_SMALL: settings = &_fcsettings.small; break; - case FS_NORMAL: settings = &_fcsettings.medium; break; - case FS_LARGE: settings = &_fcsettings.large; break; - case FS_MONO: settings = &_fcsettings.mono; break; - } + FontCacheSubSetting *settings = GetFontCacheSubSetting(fs); if (settings->font.empty()) return; @@ -397,7 +388,7 @@ void LoadCoreTextFont(FontSize fs) font_ref.reset((CTFontDescriptorRef)CFArrayGetValueAtIndex(descs.get(), 0)); CFRetain(font_ref.get()); } else { - ShowInfoF("Unable to load file '%s' for %s font, using default OS font selection instead", settings->font.c_str(), SIZE_TO_NAME[fs]); + ShowInfoF("Unable to load file '%s' for %s font, using default OS font selection instead", settings->font.c_str(), FontSizeToName(fs)); } } } @@ -421,7 +412,7 @@ void LoadCoreTextFont(FontSize fs) } if (!font_ref) { - ShowInfoF("Unable to use '%s' for %s font, using sprite font instead", settings->font.c_str(), SIZE_TO_NAME[fs]); + ShowInfoF("Unable to use '%s' for %s font, using sprite font instead", settings->font.c_str(), FontSizeToName(fs)); return; } diff --git a/src/os/windows/font_win32.cpp b/src/os/windows/font_win32.cpp index cbad3ce69d..bfe0929c6f 100644 --- a/src/os/windows/font_win32.cpp +++ b/src/os/windows/font_win32.cpp @@ -378,7 +378,6 @@ Win32FontCache::Win32FontCache(FontSize fs, const LOGFONT &logfont, int pixels) { this->dc = CreateCompatibleDC(nullptr); this->SetFontSize(fs, pixels); - this->fontname = FS2OTTD(this->logfont.lfFaceName); } Win32FontCache::~Win32FontCache() @@ -443,7 +442,9 @@ void Win32FontCache::SetFontSize(FontSize fs, int pixels) font_height_cache[this->fs] = this->GetHeight(); - DEBUG(fontcache, 2, "Loaded font '%s' with size %d", FS2OTTD((LPWSTR)((BYTE *)otm + (ptrdiff_t)otm->otmpFullName)).c_str(), pixels); + this->fontname = FS2OTTD((LPWSTR)((BYTE *)otm + (ptrdiff_t)otm->otmpFaceName)); + + DEBUG(fontcache, 2, "Loaded font '%s' with size %d", this->fontname.c_str(), pixels); } /** @@ -582,16 +583,7 @@ void Win32FontCache::ClearFontCache() */ void LoadWin32Font(FontSize fs) { - static const char *SIZE_TO_NAME[] = { "medium", "small", "large", "mono" }; - - FontCacheSubSetting *settings = nullptr; - switch (fs) { - case FS_SMALL: settings = &_fcsettings.small; break; - case FS_NORMAL: settings = &_fcsettings.medium; break; - case FS_LARGE: settings = &_fcsettings.large; break; - case FS_MONO: settings = &_fcsettings.mono; break; - default: NOT_REACHED(); - } + FontCacheSubSetting *settings = GetFontCacheSubSetting(fs); if (settings->font.empty()) return; @@ -648,7 +640,7 @@ void LoadWin32Font(FontSize fs) logfont.lfWeight = strcasestr(font_name, " bold") != nullptr || strcasestr(font_name, "-bold") != nullptr ? FW_BOLD : FW_NORMAL; // Poor man's way to allow selecting bold fonts. } } else { - ShowInfoF("Unable to load file '%s' for %s font, using default windows font selection instead", font_name, SIZE_TO_NAME[fs]); + ShowInfoF("Unable to load file '%s' for %s font, using default windows font selection instead", font_name, FontSizeToName(fs)); } } } @@ -660,7 +652,7 @@ void LoadWin32Font(FontSize fs) HFONT font = CreateFontIndirect(&logfont); if (font == nullptr) { - ShowInfoF("Unable to use '%s' for %s font, Win32 reported error 0x%lX, using sprite font instead", font_name, SIZE_TO_NAME[fs], GetLastError()); + ShowInfoF("Unable to use '%s' for %s font, Win32 reported error 0x%lX, using sprite font instead", font_name, FontSizeToName(fs), GetLastError()); return; } DeleteObject(font); diff --git a/src/os/windows/font_win32.h b/src/os/windows/font_win32.h index 070c6eb35e..b83b2c5f35 100644 --- a/src/os/windows/font_win32.h +++ b/src/os/windows/font_win32.h @@ -21,7 +21,7 @@ private: HDC dc = nullptr; ///< Cached GDI device context. HGDIOBJ old_font; ///< Old font selected into the GDI context. SIZE glyph_size; ///< Maximum size of regular glyphs. - std::string fontname; ///< Cached copy of this->logfont.lfFaceName + std::string fontname; ///< Cached copy of loaded font facename void SetFontSize(FontSize fs, int pixels); diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 869ddd8ea6..48973e43ad 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -3445,7 +3445,7 @@ static void DrawTile_Station(TileInfo *ti, DrawTileProcParams params) EndSpriteCombine(); } - OffsetGroundSprite(31, 1); + OffsetGroundSprite(0, -8); ti->z += ApplyPixelFoundationToSlope(FOUNDATION_LEVELED, &ti->tileh); } else { draw_default_foundation: diff --git a/src/table/engines.h b/src/table/engines.h index ab6ba77467..2a207dd760 100644 --- a/src/table/engines.h +++ b/src/table/engines.h @@ -24,7 +24,7 @@ * @param f Bitmask of the climates * @note the 5 between b and f is the load amount */ -#define MT(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 1 << EF_RAIL_FLIPS, 0, 0, STR_EMPTY, CARGO_AGING_TICKS } +#define MT(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 0, 0, 0, STR_EMPTY, CARGO_AGING_TICKS } /** * Writes the properties of a multiple-unit train into the EngineInfo struct. @@ -37,7 +37,7 @@ * @param f Bitmask of the climates * @note the 5 between b and f is the load amount */ -#define MM(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 1 << EF_RAIL_FLIPS | 1 << EF_RAIL_IS_MU, 0, 0, STR_EMPTY, CARGO_AGING_TICKS } +#define MM(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 1 << EF_RAIL_IS_MU, 0, 0, STR_EMPTY, CARGO_AGING_TICKS } /** * Writes the properties of a train carriage into the EngineInfo struct. @@ -50,7 +50,7 @@ * @see MT * @note the 5 between b and f is the load amount */ -#define MW(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 1 << EF_RAIL_FLIPS, 0, 0, STR_EMPTY, CARGO_AGING_TICKS } +#define MW(a, b, c, d, e, f) { DAYS_TILL_ORIGINAL_BASE_YEAR + a, c, d, b, 5, f, e, 0, 8, 0, 0, 0, STR_EMPTY, CARGO_AGING_TICKS } /** * Writes the properties of a road vehicle into the EngineInfo struct. diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 3aed46a97c..517383b009 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -525,7 +525,7 @@ void Town::UpdateVirtCoord() SetDParam(0, this->index); SetDParam(1, this->cache.population); - this->cache.sign.UpdatePosition(HasBit(_display_opt, DO_SHOW_TOWN_NAMES) ? ZOOM_LVL_OUT_128X : ZOOM_LVL_END, pt.x, pt.y - 24 * ZOOM_LVL_BASE, this->Label(), STR_VIEWPORT_TOWN); + this->cache.sign.UpdatePosition(HasBit(_display_opt, DO_SHOW_TOWN_NAMES) ? ZOOM_LVL_OUT_128X : ZOOM_LVL_END, pt.x, pt.y - 24 * ZOOM_LVL_BASE, this->Label(), STR_VIEWPORT_TOWN_TINY_WHITE); if (_viewport_sign_kdtree_valid) _viewport_sign_kdtree.Insert(ViewportSignKdtreeItem::MakeTown(this->index)); diff --git a/src/train.h b/src/train.h index b687387ac4..da92e701de 100644 --- a/src/train.h +++ b/src/train.h @@ -169,6 +169,7 @@ struct Train FINAL : public GroundVehicle { int GetDisplaySpeed() const override { return this->gcache.last_speed; } int GetDisplayMaxSpeed() const override { return this->vcache.cached_max_speed; } Money GetRunningCost() const override; + int GetCursorImageOffset() const; int GetDisplayImageWidth(Point *offset = nullptr) const; bool IsInDepot() const override { return this->track == TRACK_BIT_DEPOT; } bool Tick() override; diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 56912e0712..45aa3694e4 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -1260,6 +1260,21 @@ bool Train::ConsistNeedsRepair() const return false; } +int Train::GetCursorImageOffset() const +{ + if (this->gcache.cached_veh_length != 8 && HasBit(this->flags, VRF_REVERSE_DIRECTION) && !HasBit(EngInfo(this->engine_type)->misc_flags, EF_RAIL_FLIPS)) { + int reference_width = TRAININFO_DEFAULT_VEHICLE_WIDTH; + + const Engine *e = this->GetEngine(); + if (e->GetGRF() != nullptr && is_custom_sprite(e->u.rail.image_index)) { + reference_width = e->GetGRF()->traininfo_vehicle_width; + } + + return ScaleSpriteTrad((this->gcache.cached_veh_length - (int)VEHICLE_LENGTH) * reference_width / (int)VEHICLE_LENGTH); + } + return 0; +} + /** * Get the width of a train vehicle image in the GUI. * @param offset Additional offset for positioning the sprite; set to nullptr if not needed @@ -1277,7 +1292,11 @@ int Train::GetDisplayImageWidth(Point *offset) const } if (offset != nullptr) { - offset->x = ScaleSpriteTrad(reference_width) / 2; + if (HasBit(this->flags, VRF_REVERSE_DIRECTION) && !HasBit(EngInfo(this->engine_type)->misc_flags, EF_RAIL_FLIPS)) { + offset->x = ScaleSpriteTrad((this->gcache.cached_veh_length - VEHICLE_LENGTH / 2) * reference_width / VEHICLE_LENGTH); + } else { + offset->x = ScaleSpriteTrad(reference_width) / 2; + } offset->y = ScaleSpriteTrad(vehicle_pitch); } return ScaleSpriteTrad(this->gcache.cached_veh_length * reference_width / VEHICLE_LENGTH); @@ -2355,7 +2374,15 @@ void Train::UpdateDeltaXY() this->x_bb_offs = 0; this->y_bb_offs = 0; - if (!IsDiagonalDirection(this->direction)) { + /* Set if flipped and engine is NOT flagged with custom flip handling. */ + int flipped = HasBit(this->flags, VRF_REVERSE_DIRECTION) && !HasBit(EngInfo(this->engine_type)->misc_flags, EF_RAIL_FLIPS); + /* If flipped and vehicle length is odd, we need to adjust the bounding box offset slightly. */ + int flip_offs = flipped && (this->gcache.cached_veh_length & 1); + + Direction dir = this->direction; + if (flipped) dir = ReverseDir(dir); + + if (!IsDiagonalDirection(dir)) { static const int _sign_table[] = { /* x, y */ @@ -2365,25 +2392,25 @@ void Train::UpdateDeltaXY() 1, -1, // DIR_W }; - int half_shorten = (VEHICLE_LENGTH - this->gcache.cached_veh_length) / 2; + int half_shorten = (VEHICLE_LENGTH - this->gcache.cached_veh_length + flipped) / 2; /* For all straight directions, move the bound box to the centre of the vehicle, but keep the size. */ - this->x_offs -= half_shorten * _sign_table[this->direction]; - this->y_offs -= half_shorten * _sign_table[this->direction + 1]; - this->x_extent += this->x_bb_offs = half_shorten * _sign_table[direction]; - this->y_extent += this->y_bb_offs = half_shorten * _sign_table[direction + 1]; + this->x_offs -= half_shorten * _sign_table[dir]; + this->y_offs -= half_shorten * _sign_table[dir + 1]; + this->x_extent += this->x_bb_offs = half_shorten * _sign_table[dir]; + this->y_extent += this->y_bb_offs = half_shorten * _sign_table[dir + 1]; } else { - switch (this->direction) { + switch (dir) { /* Shorten southern corner of the bounding box according the vehicle length * and center the bounding box on the vehicle. */ case DIR_NE: - this->x_offs = 1 - (this->gcache.cached_veh_length + 1) / 2; + this->x_offs = 1 - (this->gcache.cached_veh_length + 1) / 2 + flip_offs; this->x_extent = this->gcache.cached_veh_length - 1; this->x_bb_offs = -1; break; case DIR_NW: - this->y_offs = 1 - (this->gcache.cached_veh_length + 1) / 2; + this->y_offs = 1 - (this->gcache.cached_veh_length + 1) / 2 + flip_offs; this->y_extent = this->gcache.cached_veh_length - 1; this->y_bb_offs = -1; break; @@ -2391,13 +2418,13 @@ void Train::UpdateDeltaXY() /* Move northern corner of the bounding box down according to vehicle length * and center the bounding box on the vehicle. */ case DIR_SW: - this->x_offs = 1 + (this->gcache.cached_veh_length + 1) / 2 - VEHICLE_LENGTH; + this->x_offs = 1 + (this->gcache.cached_veh_length + 1) / 2 - VEHICLE_LENGTH - flip_offs; this->x_extent = VEHICLE_LENGTH - 1; this->x_bb_offs = VEHICLE_LENGTH - this->gcache.cached_veh_length - 1; break; case DIR_SE: - this->y_offs = 1 + (this->gcache.cached_veh_length + 1) / 2 - VEHICLE_LENGTH; + this->y_offs = 1 + (this->gcache.cached_veh_length + 1) / 2 - VEHICLE_LENGTH - flip_offs; this->y_extent = VEHICLE_LENGTH - 1; this->y_bb_offs = VEHICLE_LENGTH - this->gcache.cached_veh_length - 1; break; @@ -3066,7 +3093,6 @@ CommandCost CmdReverseTrainDirection(TileIndex tile, DoCommandFlag flags, uint32 if (v->IsMultiheaded() || HasBit(EngInfo(v->engine_type)->callback_mask, CBM_VEHICLE_ARTIC_ENGINE)) { return_cmd_error(STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE_MULTIPLE_UNITS); } - if (!HasBit(EngInfo(v->engine_type)->misc_flags, EF_RAIL_FLIPS) && !_settings_game.vehicle.flip_direction_all_trains) return CMD_ERROR; Train *front = v->First(); /* make sure the vehicle is stopped in the depot */ @@ -6837,27 +6863,6 @@ void DeleteVisibleTrain(Train *v) UpdateSignalsInBuffer(); } -/* Get the pixel-width of the image that is used for the train vehicle - * @return: the image width number in pixel - */ -int GetDisplayImageWidth(Train *t, Point *offset) -{ - int reference_width = TRAININFO_DEFAULT_VEHICLE_WIDTH; - int vehicle_pitch = 0; - - const Engine *e = Engine::Get(t->engine_type); - if (e->grf_prop.grffile != nullptr && is_custom_sprite(e->u.rail.image_index)) { - reference_width = e->grf_prop.grffile->traininfo_vehicle_width; - vehicle_pitch = e->grf_prop.grffile->traininfo_vehicle_pitch; - } - - if (offset != nullptr) { - offset->x = reference_width / 2; - offset->y = vehicle_pitch; - } - return t->gcache.cached_veh_length * reference_width / VEHICLE_LENGTH; -} - Train* CmdBuildVirtualRailWagon(const Engine *e, uint32 user, bool no_consist_change) { const RailVehicleInfo *rvi = &e->u.rail; diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 5802ff3c8d..e7ae8e760d 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.cpp @@ -4266,11 +4266,14 @@ void SetMouseCursorVehicle(const Vehicle *v, EngineImageType image_type) if (_cursor.sprite_count + seq.count > lengthof(_cursor.sprite_seq)) break; + int x_offs = 0; + if (v->type == VEH_TRAIN) x_offs = Train::From(v)->GetCursorImageOffset(); + for (uint i = 0; i < seq.count; ++i) { PaletteID pal2 = (v->vehstatus & VS_CRASHED) || !seq.seq[i].pal ? pal : seq.seq[i].pal; _cursor.sprite_seq[_cursor.sprite_count].sprite = seq.seq[i].sprite; _cursor.sprite_seq[_cursor.sprite_count].pal = pal2; - _cursor.sprite_pos[_cursor.sprite_count].x = rtl ? -total_width : total_width; + _cursor.sprite_pos[_cursor.sprite_count].x = rtl ? (-total_width + x_offs) : (total_width + x_offs); _cursor.sprite_pos[_cursor.sprite_count].y = y_offset; _cursor.sprite_count++; } diff --git a/src/viewport.cpp b/src/viewport.cpp index fa9fb94ae1..8814c74ebf 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -171,8 +171,8 @@ struct ChildScreenSpriteToDraw { const SubSprite *sub; ///< only draw a rectangular part of the sprite int32 x; int32 y; - int next; ///< next child to draw (-1 at the end) bool relative; + int next; ///< next child to draw (-1 at the end) }; /** @@ -950,7 +950,7 @@ static void AddChildSpriteToFoundation(SpriteID image, PaletteID pal, const SubS int *old_child = _vd.last_child; _vd.last_child = _vd.last_foundation_child[foundation_part]; - AddChildSpriteScreen(image, pal, offs.x + extra_offs_x, offs.y + extra_offs_y, false, sub, false); + AddChildSpriteScreen(image, pal, offs.x + extra_offs_x, offs.y + extra_offs_y, false, sub, false, false); /* Switch back to last ChildSprite list */ _vd.last_child = old_child; @@ -1264,7 +1264,8 @@ static bool IsInsideSelectedRectangle(int x, int y) * @param y sprite y-offset (screen coordinates), optionally relative to parent sprite. * @param transparent if true, switch the palette between the provided palette and the transparent palette, * @param sub Only draw a part of the sprite. - * @param relative Whether coordinates are relative. + * @param scale if true, scale offsets to base zoom level. + * @param relative if true, draw sprite relative to parent sprite offsets. */ void AddChildSpriteScreen(SpriteID image, PaletteID pal, int x, int y, bool transparent, const SubSprite *sub, bool scale, bool relative) { @@ -1287,8 +1288,8 @@ void AddChildSpriteScreen(SpriteID image, PaletteID pal, int x, int y, bool tran cs.sub = sub; cs.x = scale ? x * ZOOM_LVL_BASE : x; cs.y = scale ? y * ZOOM_LVL_BASE : y; - cs.next = -1; cs.relative = relative; + cs.next = -1; /* Append the sprite to the active ChildSprite list. * If the active ParentSprite is a foundation, update last_foundation_child as well. @@ -1322,17 +1323,19 @@ static void AddStringToDraw(ViewportDrawerDynamic *vdd, int x, int y, StringID s * @param ti TileInfo Tile that is being drawn * @param z_offset Z offset relative to the groundsprite. Only used for the sprite position, not for sprite sorting. * @param foundation_part Foundation part the sprite belongs to. + * @param extra_offs_x Pixel X offset for the sprite position. + * @param extra_offs_y Pixel Y offset for the sprite position. * @param sub Sub-section of sprite to draw. */ -void DrawSelectionSprite(SpriteID image, PaletteID pal, const TileInfo *ti, int z_offset, FoundationPart foundation_part, const SubSprite *sub) +void DrawSelectionSprite(SpriteID image, PaletteID pal, const TileInfo *ti, int z_offset, FoundationPart foundation_part, int extra_offs_x, int extra_offs_y, const SubSprite *sub) { /* FIXME: This is not totally valid for some autorail highlights that extend over the edges of the tile. */ if (_vd.foundation[foundation_part] == -1) { /* draw on real ground */ - AddTileSpriteToDraw(image, pal, ti->x, ti->y, ti->z + z_offset, sub); + AddTileSpriteToDraw(image, pal, ti->x, ti->y, ti->z + z_offset, sub, extra_offs_x, extra_offs_y); } else { /* draw on top of foundation */ - AddChildSpriteToFoundation(image, pal, sub, foundation_part, 0, -z_offset * ZOOM_LVL_BASE); + AddChildSpriteToFoundation(image, pal, sub, foundation_part, extra_offs_x, extra_offs_y - z_offset * ZOOM_LVL_BASE); } } @@ -1774,7 +1777,7 @@ void ViewportAddString(ViewportDrawerDynamic *vdd, const DrawPixelInfo *dpi, Zoo int right = left + dpi->width; int bottom = top + dpi->height; - int sign_height = ScaleByZoom(WidgetDimensions::scaled.framerect.top + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.framerect.bottom, dpi->zoom); + int sign_height = ScaleByZoom(WidgetDimensions::scaled.fullbevel.top + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.fullbevel.bottom, dpi->zoom); int sign_half_width = ScaleByZoom((small ? sign->width_small : sign->width_normal) / 2, dpi->zoom); if (bottom < sign->top || @@ -1790,7 +1793,7 @@ void ViewportAddString(ViewportDrawerDynamic *vdd, const DrawPixelInfo *dpi, Zoo int shadow_offset = 0; if (string_small_shadow != STR_NULL) { shadow_offset = 4; - AddStringToDraw(vdd, sign->center - sign_half_width + shadow_offset, sign->top, string_small_shadow, params_1, params_2, INVALID_COLOUR, sign->width_small); + AddStringToDraw(vdd, sign->center - sign_half_width + shadow_offset, sign->top, string_small_shadow, params_1, params_2, INVALID_COLOUR, sign->width_small | 0x8000); } AddStringToDraw(vdd, sign->center - sign_half_width, sign->top - shadow_offset, string_small, params_1, params_2, colour, sign->width_small | 0x8000); @@ -1802,8 +1805,8 @@ static Rect ExpandRectWithViewportSignMargins(Rect r, ZoomLevel zoom) /* Pessimistically always use normal font, but also assume small font is never larger in either dimension */ const int fh = FONT_HEIGHT_NORMAL; const int max_tw = _viewport_sign_maxwidth / 2 + 1; - const int expand_y = ScaleByZoom(WidgetDimensions::scaled.framerect.top + fh + WidgetDimensions::scaled.framerect.bottom, zoom); - const int expand_x = ScaleByZoom(WidgetDimensions::scaled.framerect.left + max_tw + WidgetDimensions::scaled.framerect.right, zoom); + const int expand_y = ScaleByZoom(WidgetDimensions::scaled.fullbevel.top + fh + WidgetDimensions::scaled.fullbevel.bottom, zoom); + const int expand_x = ScaleByZoom(WidgetDimensions::scaled.fullbevel.left + max_tw + WidgetDimensions::scaled.fullbevel.right, zoom); r.left -= expand_x; r.right += expand_x; @@ -1925,14 +1928,14 @@ void ViewportSign::UpdatePosition(ZoomLevel maxzoom, int center, int top, String char buffer[DRAW_STRING_BUFFER]; GetString(buffer, str, lastof(buffer)); - this->width_normal = WidgetDimensions::scaled.framerect.left + Align(GetStringBoundingBox(buffer).width, 2) + WidgetDimensions::scaled.framerect.right; + this->width_normal = WidgetDimensions::scaled.fullbevel.left + Align(GetStringBoundingBox(buffer).width, 2) + WidgetDimensions::scaled.fullbevel.right; this->center = center; /* zoomed out version */ if (str_small != STR_NULL) { GetString(buffer, str_small, lastof(buffer)); } - this->width_small = WidgetDimensions::scaled.framerect.left + Align(GetStringBoundingBox(buffer, FS_SMALL).width, 2) + WidgetDimensions::scaled.framerect.right; + this->width_small = WidgetDimensions::scaled.fullbevel.left + Align(GetStringBoundingBox(buffer, FS_SMALL).width, 2) + WidgetDimensions::scaled.fullbevel.right; this->MarkDirty(maxzoom); } @@ -1955,7 +1958,7 @@ void ViewportSign::MarkDirty(ZoomLevel maxzoom) const zoomlevels[zoom].left = this->center - ScaleByZoom(width / 2 + 1, zoom); zoomlevels[zoom].top = this->top - ScaleByZoom(1, zoom); zoomlevels[zoom].right = this->center + ScaleByZoom(width / 2 + 1, zoom); - zoomlevels[zoom].bottom = this->top + ScaleByZoom(WidgetDimensions::scaled.framerect.top + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.framerect.bottom + 1, zoom); + zoomlevels[zoom].bottom = this->top + ScaleByZoom(WidgetDimensions::scaled.fullbevel.top + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.fullbevel.bottom + 1, zoom); } for (Viewport *vp : _viewport_window_cache) { @@ -2046,13 +2049,11 @@ static void ViewportDrawParentSprites(const ViewportDrawerDynamic *vdd, const Dr while (child_idx >= 0) { const ChildScreenSpriteToDraw *cs = csstdv->data() + child_idx; child_idx = cs->next; - int x = cs->x; - int y = cs->y; if (cs->relative) { - x += ps->left; - y += ps->top; + DrawSpriteViewport(vdd->sprite_data, dpi, cs->image, cs->pal, ps->left + cs->x, ps->top + cs->y, cs->sub); + } else { + DrawSpriteViewport(vdd->sprite_data, dpi, cs->image, cs->pal, ps->x + cs->x, ps->y + cs->y, cs->sub); } - DrawSpriteViewport(vdd->sprite_data, dpi, cs->image, cs->pal, x, y, cs->sub); } } } @@ -2235,7 +2236,7 @@ static void ViewportDrawStrings(ViewportDrawerDynamic *vdd, ZoomLevel zoom, cons int w = GB(ss.width, 0, 15); int x = UnScaleByZoom(ss.x, zoom); int y = UnScaleByZoom(ss.y, zoom); - int h = WidgetDimensions::scaled.framerect.Vertical() + (small ? FONT_HEIGHT_SMALL : FONT_HEIGHT_NORMAL); + int h = WidgetDimensions::scaled.fullbevel.Vertical() + (small ? FONT_HEIGHT_SMALL : FONT_HEIGHT_NORMAL); SetDParam(0, ss.params[0]); SetDParam(1, ss.params[1]); @@ -2259,7 +2260,7 @@ static void ViewportDrawStrings(ViewportDrawerDynamic *vdd, ZoomLevel zoom, cons } } - DrawString(x + WidgetDimensions::scaled.framerect.left, x + w - 1 - WidgetDimensions::scaled.framerect.right, y + WidgetDimensions::scaled.framerect.top, ss.string, colour, SA_HOR_CENTER); + DrawString(x + WidgetDimensions::scaled.fullbevel.left, x + w - 1 - WidgetDimensions::scaled.fullbevel.right, y + WidgetDimensions::scaled.fullbevel.top, ss.string, colour, SA_HOR_CENTER, false, small ? FS_SMALL : FS_NORMAL); } } @@ -4519,7 +4520,7 @@ static bool CheckClickOnViewportSign(const Viewport *vp, int x, int y, const Vie { 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(WidgetDimensions::scaled.framerect.top + (small ? FONT_HEIGHT_SMALL : FONT_HEIGHT_NORMAL) + WidgetDimensions::scaled.framerect.bottom, vp->zoom); + int sign_height = ScaleByZoom(WidgetDimensions::scaled.fullbevel.top + (small ? FONT_HEIGHT_SMALL : FONT_HEIGHT_NORMAL) + WidgetDimensions::scaled.fullbevel.bottom, vp->zoom); return y >= sign->top && y < sign->top + sign_height && x >= sign->center - sign_half_width && x < sign->center + sign_half_width; diff --git a/src/viewport_func.h b/src/viewport_func.h index f90efb2675..7959e60dbf 100644 --- a/src/viewport_func.h +++ b/src/viewport_func.h @@ -136,7 +136,7 @@ void ViewportMapInvalidateTunnelCacheByTile(const TileIndex tile, const Axis axi void ViewportMapBuildTunnelCache(); void DrawTileSelectionRect(const TileInfo *ti, PaletteID pal); -void DrawSelectionSprite(SpriteID image, PaletteID pal, const TileInfo *ti, int z_offset, FoundationPart foundation_part, const SubSprite *sub = nullptr); +void DrawSelectionSprite(SpriteID image, PaletteID pal, const TileInfo *ti, int z_offset, FoundationPart foundation_part, int extra_offs_x = 0, int extra_offs_y = 0, const SubSprite *sub = nullptr); struct Town; struct TraceRestrictProgram; diff --git a/src/window.cpp b/src/window.cpp index 85c46b1c3e..fe7377b20a 100644 --- a/src/window.cpp +++ b/src/window.cpp @@ -352,6 +352,17 @@ QueryString *Window::GetQueryString(uint widnum) return query != this->querystrings.End() ? query->second : nullptr; } +/** + * Update size of all QueryStrings of this window. + */ +void Window::UpdateQueryStringSize() +{ + for (auto &qs : this->querystrings) + { + qs.second->text.UpdateSize(); + } +} + /** * Get the current input text if an edit box has the focus. * @return The currently focused input text or nullptr if no input focused. @@ -3542,7 +3553,10 @@ void HideVitalWindows() void ReInitWindow(Window *w, bool zoom_changed) { if (w == nullptr) return; - if (zoom_changed) w->nested_root->AdjustPaddingForZoom(); + if (zoom_changed) { + w->nested_root->AdjustPaddingForZoom(); + w->UpdateQueryStringSize(); + } w->ReInit(); } diff --git a/src/window_gui.h b/src/window_gui.h index bfc611b810..9f48c26086 100644 --- a/src/window_gui.h +++ b/src/window_gui.h @@ -349,6 +349,7 @@ public: const QueryString *GetQueryString(uint widnum) const; QueryString *GetQueryString(uint widnum); + void UpdateQueryStringSize(); virtual const char *GetFocusedText() const; virtual const char *GetCaret() const; diff --git a/src/zoning_cmd.cpp b/src/zoning_cmd.cpp index 34c7d2fe43..1df077ce6c 100644 --- a/src/zoning_cmd.cpp +++ b/src/zoning_cmd.cpp @@ -442,7 +442,7 @@ void DrawTileZoning(const TileInfo *ti) { -INF , -INF , INF , 30 - 8 } // CORNER_N, clip 8 pixels from bottom }; - DrawSelectionSprite(sprite, colour, ti, 7 + TILE_HEIGHT, FOUNDATION_PART_HALFTILE, &(sub_sprites[GetHalftileSlopeCorner(ti->tileh)])); + DrawSelectionSprite(sprite, colour, ti, 7 + TILE_HEIGHT, FOUNDATION_PART_HALFTILE, 0, 0, &(sub_sprites[GetHalftileSlopeCorner(ti->tileh)])); } else { sprite += SlopeToSpriteOffset(ti->tileh); }