changeset 18171:00edd5060cd9 draft

(svn r23000) -Feature: Base graphics sets can now specify a preferred blitter which OpenTTD uses to decide which blitter to load.
author michi_cc <michi_cc@openttd.org>
date Tue, 04 Oct 2011 21:35:47 +0000
parents 37c6cc37533d
children 6b655732c349
files docs/obg_format.txt src/base_media_base.h src/blitter/factory.hpp src/driver.cpp src/gfxinit.cpp src/openttd.cpp
diffstat 6 files changed, 47 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/docs/obg_format.txt
+++ b/docs/obg_format.txt
@@ -42,6 +42,8 @@
 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.
--- a/src/base_media_base.h
+++ b/src/base_media_base.h
@@ -197,9 +197,16 @@
 	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);
 };
--- a/src/blitter/factory.hpp
+++ b/src/blitter/factory.hpp
@@ -174,5 +174,6 @@
 };
 
 extern char *_ini_blitter;
+extern bool _blitter_autodetected;
 
 #endif /* BLITTER_FACTORY_HPP */
--- a/src/driver.cpp
+++ b/src/driver.cpp
@@ -30,6 +30,7 @@
 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.
--- 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 @@
 }
 
 
+/**
+ * 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 @@
 
 		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;
 }
--- a/src/openttd.cpp
+++ b/src/openttd.cpp
@@ -647,10 +647,14 @@
 
 	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);