From e706131e1671fcf84977425a7c3dc8e1481f7e8c Mon Sep 17 00:00:00 2001 From: rubidium Date: Sat, 22 Oct 2011 21:06:58 +0000 Subject: [PATCH] (svn r23053) [1.1] -Backport from trunk: - Fix: [NewGRF] When vehicles break down, update the image cache after changing the vehicle state to make fish happy (r23050) - Fix: Use the same forest-check for the vegetation-map colour as for nearby station names [FS#4810] (r23049) - Fix: Check that the selected font size is valid the font face in use and choose the nearest size to that selected if not. Font metrics should then just work (r23038) - Fix: The last custom playlist items went lost when the files in the .obm are not contiguous [FS#4776] (r23035, r23034, r23033) --- src/fontcache.cpp | 25 ++++++++++++++++--------- src/industry.h | 2 ++ src/industry_cmd.cpp | 24 ++++++++++++++++++++++++ src/music_gui.cpp | 19 ++++++++++++------- src/newgrf.cpp | 2 +- src/smallmap_gui.cpp | 2 +- src/station_cmd.cpp | 25 +------------------------ src/vehicle.cpp | 9 +++++---- 8 files changed, 62 insertions(+), 46 deletions(-) diff --git a/src/fontcache.cpp b/src/fontcache.cpp index 616c54a9ef..c960b78818 100644 --- a/src/fontcache.cpp +++ b/src/fontcache.cpp @@ -746,18 +746,25 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i static void SetFontGeometry(FT_Face face, FontSize size, int pixels) { - FT_Set_Pixel_Sizes(face, 0, pixels); + FT_Error err = FT_Set_Pixel_Sizes(face, 0, pixels); + if (err == FT_Err_Invalid_Pixel_Size) { - if (FT_IS_SCALABLE(face)) { - int asc = face->ascender * pixels / face->units_per_EM; - int dec = face->descender * pixels / face->units_per_EM; + /* Find nearest size to that requested */ + FT_Bitmap_Size *bs = face->available_sizes; + int i = face->num_fixed_sizes; + int n = bs->height; + for (; --i; bs++) { + if (abs(pixels - bs->height) < abs(pixels - n)) n = bs->height; + } - _ascender[size] = asc; - _font_height[size] = asc - dec; - } else { - _ascender[size] = pixels; - _font_height[size] = pixels; + FT_Set_Pixel_Sizes(face, 0, n); } + + int asc = face->size->metrics.ascender >> 6; + int dec = face->size->metrics.descender >> 6; + + _ascender[size] = asc; + _font_height[size] = asc - dec; } /** diff --git a/src/industry.h b/src/industry.h index 18a20a7753..221c3ac66e 100644 --- a/src/industry.h +++ b/src/industry.h @@ -140,6 +140,8 @@ void PlantRandomFarmField(const Industry *i); void ReleaseDisastersTargetingIndustry(IndustryID); +bool IsTileForestIndustry(TileIndex tile); + #define FOR_ALL_INDUSTRIES_FROM(var, start) FOR_ALL_ITEMS_FROM(Industry, industry_index, var, start) #define FOR_ALL_INDUSTRIES(var) FOR_ALL_INDUSTRIES_FROM(var, 0) diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 9a47a43c56..e2bc4c0468 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -908,6 +908,30 @@ static void ChangeTileOwner_Industry(TileIndex tile, Owner old_owner, Owner new_ if (i->founder == old_owner) i->founder = (new_owner == INVALID_OWNER) ? OWNER_NONE : new_owner; } +/** + * Check whether the tile is a forest. + * @param tile the tile to investigate. + * @return true if and only if the tile is a forest + */ +bool IsTileForestIndustry(TileIndex tile) +{ + /* Check for industry tile */ + if (!IsTileType(tile, MP_INDUSTRY)) return false; + + const Industry *ind = Industry::GetByTile(tile); + + /* Check for organic industry (i.e. not processing or extractive) */ + if ((GetIndustrySpec(ind->type)->life_type & INDUSTRYLIFE_ORGANIC) == 0) return false; + + /* Check for wood production */ + for (uint i = 0; i < lengthof(ind->produced_cargo); i++) { + /* The industry produces wood. */ + if (ind->produced_cargo[i] != CT_INVALID && CargoSpec::Get(ind->produced_cargo[i])->label == 'WOOD') return true; + } + + return false; +} + static const byte _plantfarmfield_type[] = {1, 1, 1, 1, 1, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6}; static bool IsBadFarmFieldTile(TileIndex tile) diff --git a/src/music_gui.cpp b/src/music_gui.cpp index 5a823aa2dd..737fa5e487 100644 --- a/src/music_gui.cpp +++ b/src/music_gui.cpp @@ -78,19 +78,24 @@ static byte * const _playlists[] = { /** * Validate a playlist. - * @param playlist the playlist to validate + * @param playlist The playlist to validate. + * @param last The last location in the list. */ -void ValidatePlaylist(byte *playlist) +void ValidatePlaylist(byte *playlist, byte *last) { - while (*playlist != 0) { - if (*playlist <= BaseMusic::GetUsedSet()->num_available) { + while (*playlist != 0 && playlist <= last) { + /* Song indices are saved off-by-one so 0 is "nothing". */ + if (*playlist <= NUM_SONGS_AVAILABLE && !StrEmpty(GetSongName(*playlist - 1))) { playlist++; continue; } - for (byte *p = playlist; *p != 0; p++) { + for (byte *p = playlist; *p != 0 && p <= last; p++) { p[0] = p[1]; } } + + /* Make sure the list is null terminated. */ + *last = 0; } /** Initialize the playlists */ @@ -116,8 +121,8 @@ void InitializeMusic() _playlists[k + 1][j] = 0; } - ValidatePlaylist(_msf.custom_1); - ValidatePlaylist(_msf.custom_2); + ValidatePlaylist(_msf.custom_1, lastof(_msf.custom_1)); + ValidatePlaylist(_msf.custom_2, lastof(_msf.custom_2)); if (BaseMusic::GetUsedSet()->num_available < _music_wnd_cursong) { /* If there are less songs than the currently played song, diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 25830d4bef..a9d4212408 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -4713,7 +4713,7 @@ static void FeatureNewName(ByteReader *buf) if (!generic) { Engine *e = GetNewEngine(_cur_grffile, (VehicleType)feature, id, HasBit(_cur_grfconfig->flags, GCF_STATIC)); if (e == NULL) break; - StringID string = AddGRFString(_cur_grffile->grfid, e->index, lang, false, new_scheme, name, e->info.string_id); + StringID string = AddGRFString(_cur_grffile->grfid, e->index, lang, new_scheme, false, name, e->info.string_id); e->info.string_id = string; } else { AddGRFString(_cur_grffile->grfid, id, lang, new_scheme, true, name, STR_UNDEFINED); diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp index 2fd86623dc..dc492bc002 100644 --- a/src/smallmap_gui.cpp +++ b/src/smallmap_gui.cpp @@ -508,7 +508,7 @@ static inline uint32 GetSmallMapVegetationPixels(TileIndex tile, TileType t) return (IsClearGround(tile, CLEAR_GRASS) && GetClearDensity(tile) < 3) ? MKCOLOUR(0x37373737) : _vegetation_clear_bits[GetClearGround(tile)]; case MP_INDUSTRY: - return GetIndustrySpec(Industry::GetByTile(tile)->type)->check_proc == CHECK_FOREST ? MKCOLOUR(0xD0D0D0D0) : MKCOLOUR(0xB5B5B5B5); + return IsTileForestIndustry(tile) ? MKCOLOUR(0xD0D0D0D0) : MKCOLOUR(0xB5B5B5B5); case MP_TREES: if (GetTreeGround(tile) == TREE_GROUND_SNOW_DESERT || GetTreeGround(tile) == TREE_GROUND_ROUGH_SNOW) { diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 4d482b65c3..87fd62b719 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -180,29 +180,6 @@ static bool CMSATree(TileIndex tile) return IsTileType(tile, MP_TREES); } -/** - * Check whether the tile is a forest. - * @param tile the tile to investigate. - * @return true if and only if the tile is a mine - */ -static bool CMSAForest(TileIndex tile) -{ - /* No industry */ - if (!IsTileType(tile, MP_INDUSTRY)) return false; - - const Industry *ind = Industry::GetByTile(tile); - - /* No extractive industry */ - if ((GetIndustrySpec(ind->type)->life_type & INDUSTRYLIFE_ORGANIC) == 0) return false; - - for (uint i = 0; i < lengthof(ind->produced_cargo); i++) { - /* The industry produces wood. */ - if (ind->produced_cargo[i] != CT_INVALID && CargoSpec::Get(ind->produced_cargo[i])->label == 'WOOD') return true; - } - - return false; -} - #define M(x) ((x) - STR_SV_STNAME) enum StationNaming { @@ -322,7 +299,7 @@ static StringID GenerateStationName(Station *st, TileIndex tile, StationNaming n /* Check woods */ if (HasBit(free_names, M(STR_SV_STNAME_WOODS)) && ( CountMapSquareAround(tile, CMSATree) >= 8 || - CountMapSquareAround(tile, CMSAForest) >= 2) + CountMapSquareAround(tile, IsTileForestIndustry) >= 2) ) { return _settings_game.game_creation.landscape == LT_TROPIC ? STR_SV_STNAME_FOREST : STR_SV_STNAME_WOODS; } diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 0ed2475d86..c4be00cc0c 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -1091,10 +1091,6 @@ bool Vehicle::HandleBreakdown() this->breakdowns_since_last_service++; } - this->MarkDirty(); - SetWindowDirty(WC_VEHICLE_VIEW, this->index); - SetWindowDirty(WC_VEHICLE_DETAILS, this->index); - if (this->type == VEH_AIRCRAFT) { /* Aircraft just need this flag, the rest is handled elsewhere */ this->vehstatus |= VS_AIRCRAFT_BROKEN; @@ -1112,6 +1108,11 @@ bool Vehicle::HandleBreakdown() if (u != NULL) u->animation_state = this->breakdown_delay * 2; } } + + this->MarkDirty(); // Update graphics after speed is zeroed + SetWindowDirty(WC_VEHICLE_VIEW, this->index); + SetWindowDirty(WC_VEHICLE_DETAILS, this->index); + /* FALL THROUGH */ case 1: /* Aircraft breakdowns end only when arriving at the airport */