summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/obg_format.txt2
-rw-r--r--src/base_media_base.h7
-rw-r--r--src/blitter/factory.hpp1
-rw-r--r--src/driver.cpp1
-rw-r--r--src/gfxinit.cpp28
-rw-r--r--src/openttd.cpp12
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);