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 BlitterFactoryBase {
00029 private:
00030 const char *name;
00031
00032 typedef std::map<const char *, BlitterFactoryBase *, StringCompare> Blitters;
00033
00038 static Blitters &GetBlitters()
00039 {
00040 static Blitters &s_blitters = *new Blitters();
00041 return s_blitters;
00042 }
00043
00048 static Blitter **GetActiveBlitter()
00049 {
00050 static Blitter *s_blitter = NULL;
00051 return &s_blitter;
00052 }
00053
00054 protected:
00060 void RegisterBlitter(const char *name)
00061 {
00062
00063 if (name == NULL) return;
00064
00065 this->name = strdup(name);
00066
00067 std::pair<Blitters::iterator, bool> P = GetBlitters().insert(Blitters::value_type(name, this));
00068 assert(P.second);
00069 }
00070
00071 public:
00072 BlitterFactoryBase() :
00073 name(NULL)
00074 {}
00075
00076 virtual ~BlitterFactoryBase()
00077 {
00078 if (this->name == NULL) return;
00079 GetBlitters().erase(this->name);
00080 if (GetBlitters().empty()) delete &GetBlitters();
00081 free(this->name);
00082 }
00083
00089 static Blitter *SelectBlitter(const char *name)
00090 {
00091 #if defined(DEDICATED)
00092 const char *default_blitter = "null";
00093 #else
00094 const char *default_blitter = "8bpp-optimized";
00095
00096 #if defined(WITH_COCOA)
00097
00098
00099 if (!QZ_CanDisplay8bpp()) {
00100
00101
00102 default_blitter = "32bpp-anim";
00103 }
00104 #endif
00105 #endif
00106 if (GetBlitters().size() == 0) return NULL;
00107 const char *bname = (StrEmpty(name)) ? default_blitter : name;
00108
00109 Blitters::iterator it = GetBlitters().begin();
00110 for (; it != GetBlitters().end(); it++) {
00111 BlitterFactoryBase *b = (*it).second;
00112 if (strcasecmp(bname, b->name) == 0) {
00113 Blitter *newb = b->CreateInstance();
00114 delete *GetActiveBlitter();
00115 *GetActiveBlitter() = newb;
00116
00117 DEBUG(driver, 1, "Successfully %s blitter '%s'", StrEmpty(name) ? "probed" : "loaded", bname);
00118 return newb;
00119 }
00120 }
00121 return NULL;
00122 }
00123
00127 static Blitter *GetCurrentBlitter()
00128 {
00129 return *GetActiveBlitter();
00130 }
00131
00138 static char *GetBlittersInfo(char *p, const char *last)
00139 {
00140 p += seprintf(p, last, "List of blitters:\n");
00141 Blitters::iterator it = GetBlitters().begin();
00142 for (; it != GetBlitters().end(); it++) {
00143 BlitterFactoryBase *b = (*it).second;
00144 p += seprintf(p, last, "%18s: %s\n", b->name, b->GetDescription());
00145 }
00146 p += seprintf(p, last, "\n");
00147
00148 return p;
00149 }
00150
00154 virtual const char *GetDescription() = 0;
00155
00159 virtual Blitter *CreateInstance() = 0;
00160 };
00161
00165 template <class T>
00166 class BlitterFactory: public BlitterFactoryBase {
00167 public:
00168 BlitterFactory() { this->RegisterBlitter(((T *)this)->GetName()); }
00169
00173 const char *GetName();
00174 };
00175
00176 extern char *_ini_blitter;
00177 extern bool _blitter_autodetected;
00178
00179 #endif