diff options
-rw-r--r-- | docs/obg_format.txt | 2 | ||||
-rw-r--r-- | src/base_media_base.h | 7 | ||||
-rw-r--r-- | src/blitter/factory.hpp | 1 | ||||
-rw-r--r-- | src/driver.cpp | 1 | ||||
-rw-r--r-- | src/gfxinit.cpp | 28 | ||||
-rw-r--r-- | src/openttd.cpp | 12 |
6 files changed, 47 insertions, 4 deletions
diff --git a/docs/obg_format.txt b/docs/obg_format.txt index 25f020c10..f43ea7edd 100644 --- a/docs/obg_format.txt +++ b/docs/obg_format.txt @@ -42,6 +42,8 @@ description = foo description.en_US = howdie ; palette used by the set; either DOS or Windows palette = DOS +; preferred blitter, optional; either 8bpp (default) or 32bpp. +blitter = 8bpp ; The files section lists the files that replace sprites. ; The file names are case sensitive. diff --git a/src/base_media_base.h b/src/base_media_base.h index 2a990ad0d..f026e4b1e 100644 --- a/src/base_media_base.h +++ b/src/base_media_base.h @@ -197,9 +197,16 @@ enum GraphicsFileType { MAX_GFT ///< We are looking for this amount of GRFs }; +/** Blitter type for base graphics sets. */ +enum BlitterType { + BLT_8BPP, ///< Base set has 8 bpp sprites only. + BLT_32BPP, ///< Base set has both 8 bpp and 32 bpp sprites. +}; + /** All data of a graphics set. */ struct GraphicsSet : BaseSet<GraphicsSet, MAX_GFT, BASESET_DIR> { PaletteType palette; ///< Palette of this graphics set + BlitterType blitter; ///< Blitter of this graphics set bool FillSetDetails(struct IniFile *ini, const char *path, const char *full_filename); }; diff --git a/src/blitter/factory.hpp b/src/blitter/factory.hpp index 7d25823a6..956b39c9d 100644 --- a/src/blitter/factory.hpp +++ b/src/blitter/factory.hpp @@ -174,5 +174,6 @@ public: }; extern char *_ini_blitter; +extern bool _blitter_autodetected; #endif /* BLITTER_FACTORY_HPP */ diff --git a/src/driver.cpp b/src/driver.cpp index 448320c83..8ff3e361b 100644 --- a/src/driver.cpp +++ b/src/driver.cpp @@ -30,6 +30,7 @@ MusicDriver *_music_driver; ///< The currently active music driver. char *_ini_musicdriver; ///< The music driver a stored in the configuration file. char *_ini_blitter; ///< The blitter as stored in the configuration file. +bool _blitter_autodetected; ///< Was the blitter autodetected or specified by the user? /** * Get a string parameter the list of parameters. diff --git a/src/gfxinit.cpp b/src/gfxinit.cpp index 0dd3276db..b941a53dd 100644 --- a/src/gfxinit.cpp +++ b/src/gfxinit.cpp @@ -15,12 +15,15 @@ #include "3rdparty/md5/md5.h" #include "fontcache.h" #include "gfx_func.h" +#include "blitter/factory.hpp" +#include "video/video_driver.hpp" /* The type of set we're replacing */ #define SET_TYPE "graphics" #include "base_media_func.h" #include "table/sprites.h" +#include "table/strings.h" /** Whether the given NewGRFs must get a palette remap from windows to DOS or not. */ bool _palette_remap_grf[MAX_FILE_SLOTS]; @@ -203,11 +206,32 @@ static void LoadSpriteTables() } +/** + * Check blitter needed by NewGRF config and switch if needed. + */ +static void SwitchNewGRFBlitter() +{ + /* Get blitter of base set. */ + bool is_32bpp = BaseGraphics::GetUsedSet()->blitter == BLT_32BPP; + + /* A GRF would like a 32 bpp blitter, switch blitter if needed. Never switch if the blitter was specified by the user. */ + if (_blitter_autodetected && is_32bpp && BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth() != 0 && BlitterFactoryBase::GetCurrentBlitter()->GetScreenDepth() < 16) { + const char *cur_blitter = BlitterFactoryBase::GetCurrentBlitter()->GetName(); + if (BlitterFactoryBase::SelectBlitter("32bpp-anim") != NULL) { + if (!_video_driver->AfterBlitterChange()) { + /* Failed to switch blitter, let's hope we can return to the old one. */ + if (BlitterFactoryBase::SelectBlitter(cur_blitter) == NULL || !_video_driver->AfterBlitterChange()) usererror("Failed to reinitialize video driver for 32 bpp blitter. Specify a fixed blitter in the config"); + } + } + } +} + /** Initialise and load all the sprites. */ void GfxLoadSprites() { DEBUG(sprite, 2, "Loading sprite set %d", _settings_game.game_creation.landscape); + SwitchNewGRFBlitter(); GfxInitSpriteMem(); LoadSpriteTables(); GfxInitPalettes(); @@ -224,6 +248,10 @@ bool GraphicsSet::FillSetDetails(IniFile *ini, const char *path, const char *ful fetch_metadata("palette"); this->palette = (*item->value == 'D' || *item->value == 'd') ? PAL_DOS : PAL_WINDOWS; + + /* Get optional blitter information. */ + item = metadata->GetItem("blitter", false); + this->blitter = (item != NULL && *item->value == '3') ? BLT_32BPP : BLT_8BPP; } return ret; } diff --git a/src/openttd.cpp b/src/openttd.cpp index af1f77f4e..1f63fe558 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -647,10 +647,14 @@ int ttd_main(int argc, char *argv[]) DEBUG(misc, 1, "Loading blitter..."); if (blitter == NULL && _ini_blitter != NULL) blitter = strdup(_ini_blitter); - if (BlitterFactoryBase::SelectBlitter(blitter) == NULL) { - StrEmpty(blitter) ? - usererror("Failed to autoprobe blitter") : - usererror("Failed to select requested blitter '%s'; does it exist?", blitter); + _blitter_autodetected = StrEmpty(blitter); + /* If we have a 32 bpp base set, try to select the 32 bpp blitter first, but only if we autoprobe the blitter. */ + if (!_blitter_autodetected || BaseGraphics::GetUsedSet()->blitter == BLT_8BPP || BlitterFactoryBase::SelectBlitter("32bpp-anim") == NULL) { + if (BlitterFactoryBase::SelectBlitter(blitter) == NULL) { + StrEmpty(blitter) ? + usererror("Failed to autoprobe blitter") : + usererror("Failed to select requested blitter '%s'; does it exist?", blitter); + } } free(blitter); |