# factory.hpp

Go to the documentation of this file.

    00001 /* $Id: factory.hpp 19094 2010-02-11 14:58:51Z yexo $ */
    00002
    00003 /*
    00004  * This file is part of OpenTTD.
    00005  * 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.
    00006  * 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.
    00007  * 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/>.
    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 /* defined(WITH_COCOA) */
    00024
    00028 class BlitterFactoryBase {
    00029 private:
    00030   const char *name;
    00031
    00032   typedef std::map<const char *, BlitterFactoryBase *, StringCompare> Blitters;
    00033
    00034   static Blitters &GetBlitters()
    00035   {
    00036     static Blitters &s_blitters = *new Blitters();
    00037     return s_blitters;
    00038   }
    00039
    00040   static Blitter **GetActiveBlitter()
    00041   {
    00042     static Blitter *s_blitter = NULL;
    00043     return &s_blitter;
    00044   }
    00045
    00046 protected:
    00052   void RegisterBlitter(const char *name)
    00053   {
    00054     /* Don't register nameless Blitters */
    00055     if (name == NULL) return;
    00056
    00057     this->name = strdup(name);
    00058
    00059     std::pair<Blitters::iterator, bool> P = GetBlitters().insert(Blitters::value_type(name, this));
    00060     assert(P.second);
    00061   }
    00062
    00063 public:
    00064   BlitterFactoryBase() :
    00065     name(NULL)
    00066   {}
    00067
    00068   virtual ~BlitterFactoryBase()
    00069   {
    00070     if (this->name == NULL) return;
    00071     GetBlitters().erase(this->name);
    00072     if (GetBlitters().empty()) delete &GetBlitters();
    00073     free((void *)this->name);
    00074   }
    00075
    00081   static Blitter *SelectBlitter(const char *name)
    00082   {
    00083 #if defined(DEDICATED)
    00084     const char *default_blitter = "null";
    00085 #else
    00086     const char *default_blitter = "8bpp-optimized";
    00087
    00088 #if defined(WITH_COCOA)
    00089     /* Some people reported lack of fullscreen support in 8 bpp mode.
    00090      * While we prefer 8 bpp since it's faster, we will still have to test for support. */
    00091     if (!QZ_CanDisplay8bpp()) {
    00092       /* The main display can't go to 8 bpp fullscreen mode.
    00093        * We will have to switch to 32 bpp by default. */
    00094       default_blitter = "32bpp-anim";
    00095     }
    00096 #endif /* defined(WITH_COCOA) */
    00097 #endif /* defined(DEDICATED) */
    00098     if (GetBlitters().size() == 0) return NULL;
    00099     const char *bname = (StrEmpty(name)) ? default_blitter : name;
    00100
    00101     Blitters::iterator it = GetBlitters().begin();
    00102     for (; it != GetBlitters().end(); it++) {
    00103       BlitterFactoryBase *b = (*it).second;
    00104       if (strcasecmp(bname, b->name) == 0) {
    00105         Blitter *newb = b->CreateInstance();
    00106         delete *GetActiveBlitter();
    00107         *GetActiveBlitter() = newb;
    00108
    00109         DEBUG(driver, 1, "Successfully %s blitter '%s'", StrEmpty(name) ? "probed" : "loaded", bname);
    00110         return newb;
    00111       }
    00112     }
    00113     return NULL;
    00114   }
    00115
    00119   static Blitter *GetCurrentBlitter()
    00120   {
    00121     return *GetActiveBlitter();
    00122   }
    00123
    00124
    00125   static char *GetBlittersInfo(char *p, const char *last)
    00126   {
    00127     p += seprintf(p, last, "List of blitters:\n");
    00128     Blitters::iterator it = GetBlitters().begin();
    00129     for (; it != GetBlitters().end(); it++) {
    00130       BlitterFactoryBase *b = (*it).second;
    00131       p += seprintf(p, last, "%18s: %s\n", b->name, b->GetDescription());
    00132     }
    00133     p += seprintf(p, last, "\n");
    00134
    00135     return p;
    00136   }
    00137
    00141   virtual const char *GetDescription() = 0;
    00142
    00146   virtual Blitter *CreateInstance() = 0;
    00147 };
    00148
    00152 template <class T>
    00153 class BlitterFactory: public BlitterFactoryBase {
    00154 public:
    00155   BlitterFactory() { this->RegisterBlitter(((T *)this)->GetName()); }
    00156
    00160   const char *GetName();
    00161 };
    00162
    00163 extern char *_ini_blitter;
    00164
    00165 #endif /* BLITTER_FACTORY_HPP */