4 * This file is part of OpenTTD.
5 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
6 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
7 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
10 /** @file factory.hpp Factory to 'query' all available blitters. */
12 #ifndef BLITTER_FACTORY_HPP
13 #define BLITTER_FACTORY_HPP
17 #include "../string_func.h"
18 #include "../core/string_compare_type.hpp"
21 #if defined(WITH_COCOA)
22 bool QZ_CanDisplay8bpp();
23 #endif /* defined(WITH_COCOA) */
26 * The base factory, keeping track of all blitters.
28 class BlitterFactory
{
30 const char *name
; ///< The name of the blitter factory.
31 const char *description
; ///< The description of the blitter.
33 typedef std::map
<const char *, BlitterFactory
*, StringCompare
> Blitters
; ///< Map of blitter factories.
36 * Get the map with currently known blitters.
37 * @return The known blitters.
39 static Blitters
&GetBlitters()
41 static Blitters
&s_blitters
= *new Blitters();
46 * Get the currently active blitter.
47 * @return The currently active blitter.
49 static Blitter
**GetActiveBlitter()
51 static Blitter
*s_blitter
= NULL
;
57 * Construct the blitter, and register it.
58 * @param name The name of the blitter.
59 * @param description A longer description for the blitter.
60 * @param usable Whether the blitter is usable (on the current computer). For example for disabling SSE blitters when the CPU can't handle them.
62 * @pre description != NULL.
63 * @pre There is no blitter registered with this name.
65 BlitterFactory(const char *name
, const char *description
, bool usable
= true) :
66 name(stredup(name
)), description(stredup(description
))
70 * Only add when the blitter is usable. Do not bail out or
71 * do more special things since the blitters are always
72 * instantiated upon start anyhow and freed upon shutdown.
74 std::pair
<Blitters::iterator
, bool> P
= GetBlitters().insert(Blitters::value_type(this->name
, this));
77 DEBUG(driver
, 1, "Not registering blitter %s as it is not usable", name
);
82 virtual ~BlitterFactory()
84 GetBlitters().erase(this->name
);
85 if (GetBlitters().empty()) delete &GetBlitters();
88 free(this->description
);
92 * Find the requested blitter and return his class.
93 * @param name the blitter to select.
94 * @post Sets the blitter so GetCurrentBlitter() returns it too.
96 static Blitter
*SelectBlitter(const char *name
)
98 BlitterFactory
*b
= GetBlitterFactory(name
);
99 if (b
== NULL
) return NULL
;
101 Blitter
*newb
= b
->CreateInstance();
102 delete *GetActiveBlitter();
103 *GetActiveBlitter() = newb
;
105 DEBUG(driver
, 1, "Successfully %s blitter '%s'", StrEmpty(name
) ? "probed" : "loaded", newb
->GetName());
110 * Get the blitter factory with the given name.
111 * @param name the blitter factory to select.
112 * @return The blitter factory, or NULL when there isn't one with the wanted name.
114 static BlitterFactory
*GetBlitterFactory(const char *name
)
116 #if defined(DEDICATED)
117 const char *default_blitter
= "null";
119 const char *default_blitter
= "8bpp-optimized";
121 #if defined(WITH_COCOA)
122 /* Some people reported lack of fullscreen support in 8 bpp mode.
123 * While we prefer 8 bpp since it's faster, we will still have to test for support. */
124 if (!QZ_CanDisplay8bpp()) {
125 /* The main display can't go to 8 bpp fullscreen mode.
126 * We will have to switch to 32 bpp by default. */
127 default_blitter
= "32bpp-anim";
129 #endif /* defined(WITH_COCOA) */
130 #endif /* defined(DEDICATED) */
131 if (GetBlitters().size() == 0) return NULL
;
132 const char *bname
= (StrEmpty(name
)) ? default_blitter
: name
;
134 Blitters::iterator it
= GetBlitters().begin();
135 for (; it
!= GetBlitters().end(); it
++) {
136 BlitterFactory
*b
= (*it
).second
;
137 if (strcasecmp(bname
, b
->name
) == 0) {
145 * Get the current active blitter (always set by calling SelectBlitter).
147 static Blitter
*GetCurrentBlitter()
149 return *GetActiveBlitter();
153 * Fill a buffer with information about the blitters.
154 * @param p The buffer to fill.
155 * @param last The last element of the buffer.
156 * @return p The location till where we filled the buffer.
158 static char *GetBlittersInfo(char *p
, const char *last
)
160 p
+= seprintf(p
, last
, "List of blitters:\n");
161 Blitters::iterator it
= GetBlitters().begin();
162 for (; it
!= GetBlitters().end(); it
++) {
163 BlitterFactory
*b
= (*it
).second
;
164 p
+= seprintf(p
, last
, "%18s: %s\n", b
->name
, b
->GetDescription());
166 p
+= seprintf(p
, last
, "\n");
172 * Get the long, human readable, name for the Blitter-class.
174 const char *GetName() const
180 * Get a nice description of the blitter-class.
182 const char *GetDescription() const
184 return this->description
;
188 * Create an instance of this Blitter-class.
190 virtual Blitter
*CreateInstance() = 0;
193 extern char *_ini_blitter
;
194 extern bool _blitter_autodetected
;
196 #endif /* BLITTER_FACTORY_HPP */