diff --git a/src/settings.cpp b/src/settings.cpp index ba26eb4542..cc9968652e 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1787,19 +1787,6 @@ static bool LinkGraphDistributionSettingGUI(SettingOnGuiCtrlData &data) } } -static bool SpriteZoomMinSettingGUI(SettingOnGuiCtrlData &data) -{ - switch (data.type) { - case SOGCT_DESCRIPTION_TEXT: - SetDParam(0, data.text); - data.text = STR_CONFIG_SETTING_SPRITE_ZOOM_MIN_HELPTEXT_EXTRA; - return true; - - default: - return false; - } -} - static bool AllowRoadStopsUnderBridgesSettingGUI(SettingOnGuiCtrlData &data) { switch (data.type) { diff --git a/src/spritecache.cpp b/src/spritecache.cpp index 2c26825a82..2800c28501 100644 --- a/src/spritecache.cpp +++ b/src/spritecache.cpp @@ -107,7 +107,6 @@ PACK_N(struct SpriteCache { bool GetWarned() const { return HasBit(this->flags, SCCF_WARNED); } void SetWarned(bool warned) { SB(this->flags, SCCF_WARNED, 1, warned ? 1 : 0); } bool GetHasNonPalette() const { return HasBit(this->flags, SCCF_HAS_NON_PALETTE); } - void SetHasNonPalette(bool non_palette) { SB(this->flags, SCCF_HAS_NON_PALETTE, 1, non_palette ? 1 : 0); } }, 4); static std::vector _spritecache; @@ -523,10 +522,10 @@ static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_ty SpriteLoaderGrf sprite_loader(file.GetContainerVersion()); if (sprite_type != ST_MAPGEN && sc->GetHasNonPalette() && encoder->Is32BppSupported()) { /* Try for 32bpp sprites first. */ - sprite_avail = sprite_loader.LoadSprite(sprite, file, file_pos, sprite_type, true, sc->count); + sprite_avail = sprite_loader.LoadSprite(sprite, file, file_pos, sprite_type, true, sc->count, sc->flags); } if (sprite_avail == 0) { - sprite_avail = sprite_loader.LoadSprite(sprite, file, file_pos, sprite_type, false, sc->count); + sprite_avail = sprite_loader.LoadSprite(sprite, file, file_pos, sprite_type, false, sc->count, sc->flags); } if (sprite_avail == 0) { @@ -584,7 +583,7 @@ static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_ty struct GrfSpriteOffset { size_t file_pos; uint count; - bool has_non_palette; + byte control_flags; }; /** Map from sprite numbers to position in the GRF file. */ @@ -625,14 +624,26 @@ void ReadGRFSpriteOffsets(SpriteFile &file) _grf_sprite_offsets[prev_id] = offset; offset.file_pos = file.GetPos() - 4; offset.count = 0; - offset.has_non_palette = false; + offset.control_flags = 0; } offset.count++; prev_id = id; uint length = file.ReadDword(); if (length > 0) { - if ((file.ReadByte() & SCC_MASK) != SCC_PAL) offset.has_non_palette = true; + byte colour = file.ReadByte() & SCC_MASK; + if (colour != SCC_PAL) SetBit(offset.control_flags, SCCF_HAS_NON_PALETTE); length--; + if (length > 0) { + byte zoom = file.ReadByte(); + length--; + if (colour != 0 && zoom == 0) { // ZOOM_LVL_OUT_4X (normal zoom) + SetBit(offset.control_flags, (colour != SCC_PAL) ? SCCF_ALLOW_ZOOM_MIN_1X_32BPP : SCCF_ALLOW_ZOOM_MIN_1X_PAL); + SetBit(offset.control_flags, (colour != SCC_PAL) ? SCCF_ALLOW_ZOOM_MIN_2X_32BPP : SCCF_ALLOW_ZOOM_MIN_2X_PAL); + } + if (colour != 0 && zoom == 2) { // ZOOM_LVL_OUT_2X (2x zoomed in) + SetBit(offset.control_flags, (colour != SCC_PAL) ? SCCF_ALLOW_ZOOM_MIN_2X_32BPP : SCCF_ALLOW_ZOOM_MIN_2X_PAL); + } + } } file.SkipBytes(length); } @@ -666,7 +677,7 @@ bool LoadNextSprite(int load_index, SpriteFile &file, uint file_sprite_id) SpriteType type; void *data = nullptr; uint count = 0; - bool has_non_palette = false; + byte control_flags = 0; if (grf_type == 0xFF) { /* Some NewGRF files have "empty" pseudo-sprites which are 1 * byte long. Catch these so the sprites won't be displayed. */ @@ -687,7 +698,7 @@ bool LoadNextSprite(int load_index, SpriteFile &file, uint file_sprite_id) if (iter != _grf_sprite_offsets.end()) { file_pos = iter->second.file_pos; count = iter->second.count; - has_non_palette = iter->second.has_non_palette; + control_flags = iter->second.control_flags; } else { file_pos = SIZE_MAX; } @@ -730,8 +741,7 @@ bool LoadNextSprite(int load_index, SpriteFile &file, uint file_sprite_id) sc->id = file_sprite_id; sc->count = count; sc->SetType(type); - sc->flags = 0; - if (has_non_palette) sc->SetHasNonPalette(true); + sc->flags = control_flags; return true; } @@ -978,7 +988,7 @@ uint32 GetSpriteMainColour(SpriteID sprite_id, PaletteID palette_id) /* Try to read the 32bpp sprite first. */ if (screen_depth == 32 && sc->GetHasNonPalette()) { - sprite_avail = sprite_loader.LoadSprite(sprites, file, file_pos, ST_NORMAL, true, sc->count); + sprite_avail = sprite_loader.LoadSprite(sprites, file, file_pos, ST_NORMAL, true, sc->count, sc->flags); if (sprite_avail != 0) { SpriteLoader::Sprite *sprite = &sprites[FindFirstBit(sprite_avail)]; /* Return the average colour. */ @@ -1008,7 +1018,7 @@ uint32 GetSpriteMainColour(SpriteID sprite_id, PaletteID palette_id) } /* No 32bpp, try 8bpp. */ - sprite_avail = sprite_loader.LoadSprite(sprites, file, file_pos, ST_NORMAL, false, sc->count); + sprite_avail = sprite_loader.LoadSprite(sprites, file, file_pos, ST_NORMAL, false, sc->count, sc->flags); if (sprite_avail != 0) { SpriteLoader::Sprite *sprite = &sprites[FindFirstBit(sprite_avail)]; SpriteLoader::CommonPixel *pixel = sprite->data; diff --git a/src/spritecache.h b/src/spritecache.h index 155fa27b58..4949676069 100644 --- a/src/spritecache.h +++ b/src/spritecache.h @@ -23,8 +23,12 @@ struct Sprite { }; enum SpriteCacheCtrlFlags { - SCCF_WARNED = 0, ///< True iff the user has been warned about incorrect use of this sprite. - SCCF_HAS_NON_PALETTE = 1, ///< True iff there is at least one non-paletter sprite present (such that 32bpp mode can be used). + SCCF_WARNED = 0, ///< True iff the user has been warned about incorrect use of this sprite. + SCCF_HAS_NON_PALETTE = 1, ///< True iff there is at least one non-paletter sprite present (such that 32bpp mode can be used). + SCCF_ALLOW_ZOOM_MIN_1X_PAL = 2, ///< Allow use of sprite min zoom setting at 1x in palette mode. + SCCF_ALLOW_ZOOM_MIN_1X_32BPP = 3, ///< Allow use of sprite min zoom setting at 1x in 32bpp mode. + SCCF_ALLOW_ZOOM_MIN_2X_PAL = 4, ///< Allow use of sprite min zoom setting at 2x in palette mode. + SCCF_ALLOW_ZOOM_MIN_2X_32BPP = 5, ///< Allow use of sprite min zoom setting at 2x in 32bpp mode. }; extern uint _sprite_cache_size; diff --git a/src/spriteloader/grf.cpp b/src/spriteloader/grf.cpp index fc78a30921..a8f1d80ad9 100644 --- a/src/spriteloader/grf.cpp +++ b/src/spriteloader/grf.cpp @@ -17,6 +17,7 @@ #include "../core/math_func.hpp" #include "../core/alloc_type.hpp" #include "../core/bitmath_func.hpp" +#include "../spritecache.h" #include "grf.hpp" #include "../safeguards.h" @@ -245,7 +246,7 @@ uint8 LoadSpriteV1(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_p return 0; } -uint8 LoadSpriteV2(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint count) +uint8 LoadSpriteV2(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint count, byte control_flags) { static const ZoomLevel zoom_lvl_map[6] = {ZOOM_LVL_OUT_4X, ZOOM_LVL_NORMAL, ZOOM_LVL_OUT_2X, ZOOM_LVL_OUT_8X, ZOOM_LVL_OUT_16X, ZOOM_LVL_OUT_32X}; @@ -273,7 +274,19 @@ uint8 LoadSpriteV2(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_p bool is_wanted_zoom_lvl; if (sprite_type != ST_MAPGEN) { - is_wanted_zoom_lvl = (zoom < lengthof(zoom_lvl_map) && zoom_lvl_map[zoom] >= _settings_client.gui.sprite_zoom_min); + if (zoom < lengthof(zoom_lvl_map)) { + is_wanted_zoom_lvl = true; + if (_settings_client.gui.sprite_zoom_min >= ZOOM_LVL_OUT_2X && + HasBit(control_flags, load_32bpp ? SCCF_ALLOW_ZOOM_MIN_2X_32BPP : SCCF_ALLOW_ZOOM_MIN_2X_PAL) && zoom_lvl_map[zoom] < ZOOM_LVL_OUT_2X) { + is_wanted_zoom_lvl = false; + } + if (_settings_client.gui.sprite_zoom_min >= ZOOM_LVL_OUT_4X && + HasBit(control_flags, load_32bpp ? SCCF_ALLOW_ZOOM_MIN_1X_32BPP : SCCF_ALLOW_ZOOM_MIN_1X_PAL) && zoom_lvl_map[zoom] < ZOOM_LVL_OUT_4X) { + is_wanted_zoom_lvl = false; + } + } else { + is_wanted_zoom_lvl = false; + } } else { is_wanted_zoom_lvl = (zoom == 0); } @@ -332,10 +345,10 @@ uint8 LoadSpriteV2(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_p return loaded_sprites; } -uint8 SpriteLoaderGrf::LoadSprite(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint count) +uint8 SpriteLoaderGrf::LoadSprite(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint count, byte control_flags) { if (this->container_ver >= 2) { - return LoadSpriteV2(sprite, file, file_pos, sprite_type, load_32bpp, count); + return LoadSpriteV2(sprite, file, file_pos, sprite_type, load_32bpp, count, control_flags); } else { return LoadSpriteV1(sprite, file, file_pos, sprite_type, load_32bpp); } diff --git a/src/spriteloader/grf.hpp b/src/spriteloader/grf.hpp index 404d6e594a..246998ec96 100644 --- a/src/spriteloader/grf.hpp +++ b/src/spriteloader/grf.hpp @@ -17,7 +17,7 @@ class SpriteLoaderGrf : public SpriteLoader { byte container_ver; public: SpriteLoaderGrf(byte container_ver) : container_ver(container_ver) {} - uint8 LoadSprite(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint count); + uint8 LoadSprite(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint count, byte control_flags); }; #endif /* SPRITELOADER_GRF_HPP */ diff --git a/src/spriteloader/spriteloader.hpp b/src/spriteloader/spriteloader.hpp index 54e29f9b34..8646283048 100644 --- a/src/spriteloader/spriteloader.hpp +++ b/src/spriteloader/spriteloader.hpp @@ -72,9 +72,10 @@ public: * @param file_pos The position within the file the image begins. * @param sprite_type The type of sprite we're trying to load. * @param load_32bpp True if 32bpp sprites should be loaded, false for a 8bpp sprite. + * @param control_flags Control flags, see SpriteCacheCtrlFlags. * @return Bit mask of the zoom levels successfully loaded or 0 if no sprite could be loaded. */ - virtual uint8 LoadSprite(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint count) = 0; + virtual uint8 LoadSprite(SpriteLoader::Sprite *sprite, SpriteFile &file, size_t file_pos, SpriteType sprite_type, bool load_32bpp, uint count, byte control_flags) = 0; virtual ~SpriteLoader() { } }; diff --git a/src/table/settings/settings.ini b/src/table/settings/settings.ini index 87a2bc3f3d..2e7579eb4b 100644 --- a/src/table/settings/settings.ini +++ b/src/table/settings/settings.ini @@ -82,7 +82,6 @@ static int64 LinkGraphDistModeXrefChillPP(int64 val); static bool LinkGraphDistributionSettingGUI(SettingOnGuiCtrlData &data); static bool OrderTownGrowthRate(SettingOnGuiCtrlData &data); -static bool SpriteZoomMinSettingGUI(SettingOnGuiCtrlData &data); static bool AllowRoadStopsUnderBridgesSettingGUI(SettingOnGuiCtrlData &data); /* End - GUI callbacks */ @@ -4480,7 +4479,7 @@ startup = true [SDTC_VAR] var = gui.sprite_zoom_min type = SLE_UINT8 -flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN | SF_GUI_ADVISE_DEFAULT +flags = SF_NOT_IN_SAVE | SF_NO_NETWORK_SYNC | SF_GUI_DROPDOWN def = ZOOM_LVL_MIN min = ZOOM_LVL_MIN max = ZOOM_LVL_OUT_4X @@ -4488,7 +4487,6 @@ str = STR_CONFIG_SETTING_SPRITE_ZOOM_MIN strhelp = STR_CONFIG_SETTING_SPRITE_ZOOM_MIN_HELPTEXT strval = STR_CONFIG_SETTING_SPRITE_ZOOM_LVL_MIN post_cb = SpriteZoomMinChanged -guiproc = SpriteZoomMinSettingGUI cat = SC_EXPERT [SDTC_BOOL]