Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #ifndef BLITTER_FACTORY_HPP
00013 #define BLITTER_FACTORY_HPP
00014
00015 #include "base.hpp"
00016 #include "../debug.h"
00017 #include "../string_func.h"
00018 #include "../core/string_compare_type.hpp"
00019 #include <map>
00020
00021 #if defined(WITH_COCOA)
00022 bool QZ_CanDisplay8bpp();
00023 #endif
00024
00028 class BlitterFactory {
00029 private:
00030 const char *name;
00031 const char *description;
00032
00033 typedef std::map<const char *, BlitterFactory *, StringCompare> Blitters;
00034
00039 static Blitters &GetBlitters()
00040 {
00041 static Blitters &s_blitters = *new Blitters();
00042 return s_blitters;
00043 }
00044
00049 static Blitter **GetActiveBlitter()
00050 {
00051 static Blitter *s_blitter = NULL;
00052 return &s_blitter;
00053 }
00054
00055 protected:
00065 BlitterFactory(const char *name, const char *description, bool usable = true) :
00066 name(strdup(name)), description(strdup(description))
00067 {
00068 if (usable) {
00069
00070
00071
00072
00073
00074 std::pair<Blitters::iterator, bool> P = GetBlitters().insert(Blitters::value_type(this->name, this));
00075 assert(P.second);
00076 } else {
00077 DEBUG(driver, 1, "Not registering blitter %s as it is not usable", name);
00078 }
00079 }
00080
00081 public:
00082 virtual ~BlitterFactory()
00083 {
00084 GetBlitters().erase(this->name);
00085 if (GetBlitters().empty()) delete &GetBlitters();
00086
00087 free(this->name);
00088 free(this->description);
00089 }
00090
00096 static Blitter *SelectBlitter(const char *name)
00097 {
00098 BlitterFactory *b = GetBlitterFactory(name);
00099 if (b == NULL) return NULL;
00100
00101 Blitter *newb = b->CreateInstance();
00102 delete *GetActiveBlitter();
00103 *GetActiveBlitter() = newb;
00104
00105 DEBUG(driver, 1, "Successfully %s blitter '%s'", StrEmpty(name) ? "probed" : "loaded", newb->GetName());
00106 return newb;
00107 }
00108
00114 static BlitterFactory *GetBlitterFactory(const char *name)
00115 {
00116 #if defined(DEDICATED)
00117 const char *default_blitter = "null";
00118 #else
00119 const char *default_blitter = "8bpp-optimized";
00120
00121 #if defined(WITH_COCOA)
00122
00123
00124 if (!QZ_CanDisplay8bpp()) {
00125
00126
00127 default_blitter = "32bpp-anim";
00128 }
00129 #endif
00130 #endif
00131 if (GetBlitters().size() == 0) return NULL;
00132 const char *bname = (StrEmpty(name)) ? default_blitter : name;
00133
00134 Blitters::iterator it = GetBlitters().begin();
00135 for (; it != GetBlitters().end(); it++) {
00136 BlitterFactory *b = (*it).second;
00137 if (strcasecmp(bname, b->name) == 0) {
00138 return b;
00139 }
00140 }
00141 return NULL;
00142 }
00143
00147 static Blitter *GetCurrentBlitter()
00148 {
00149 return *GetActiveBlitter();
00150 }
00151
00158 static char *GetBlittersInfo(char *p, const char *last)
00159 {
00160 p += seprintf(p, last, "List of blitters:\n");
00161 Blitters::iterator it = GetBlitters().begin();
00162 for (; it != GetBlitters().end(); it++) {
00163 BlitterFactory *b = (*it).second;
00164 p += seprintf(p, last, "%18s: %s\n", b->name, b->GetDescription());
00165 }
00166 p += seprintf(p, last, "\n");
00167
00168 return p;
00169 }
00170
00174 const char *GetName() const
00175 {
00176 return this->name;
00177 }
00178
00182 const char *GetDescription() const
00183 {
00184 return this->description;
00185 }
00186
00190 virtual Blitter *CreateInstance() = 0;
00191 };
00192
00193 extern char *_ini_blitter;
00194 extern bool _blitter_autodetected;
00195
00196 #endif