driver.cpp

Go to the documentation of this file.
00001 /* $Id: driver.cpp 18809 2010-01-15 16:41:15Z rubidium $ */
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 #include "stdafx.h"
00013 #include "debug.h"
00014 #include "sound/sound_driver.hpp"
00015 #include "music/music_driver.hpp"
00016 #include "video/video_driver.hpp"
00017 #include "string_func.h"
00018 
00019 VideoDriver *_video_driver;
00020 char *_ini_videodriver;
00021 int _num_resolutions;
00022 Dimension _resolutions[32];
00023 Dimension _cur_resolution;
00024 
00025 SoundDriver *_sound_driver;
00026 char *_ini_sounddriver;
00027 
00028 MusicDriver *_music_driver;
00029 char *_ini_musicdriver;
00030 
00031 char *_ini_blitter;
00032 
00033 const char *GetDriverParam(const char * const *parm, const char *name)
00034 {
00035   size_t len;
00036 
00037   if (parm == NULL) return NULL;
00038 
00039   len = strlen(name);
00040   for (; *parm != NULL; parm++) {
00041     const char *p = *parm;
00042 
00043     if (strncmp(p, name, len) == 0) {
00044       if (p[len] == '=')  return p + len + 1;
00045       if (p[len] == '\0') return p + len;
00046     }
00047   }
00048   return NULL;
00049 }
00050 
00051 bool GetDriverParamBool(const char * const *parm, const char *name)
00052 {
00053   return GetDriverParam(parm, name) != NULL;
00054 }
00055 
00056 int GetDriverParamInt(const char * const *parm, const char *name, int def)
00057 {
00058   const char *p = GetDriverParam(parm, name);
00059   return p != NULL ? atoi(p) : def;
00060 }
00061 
00068 Driver *DriverFactoryBase::SelectDriver(const char *name, Driver::Type type)
00069 {
00070   if (GetDrivers().size() == 0) return NULL;
00071 
00072   if (StrEmpty(name)) {
00073     /* Probe for this driver, but do not fall back to dedicated/null! */
00074     for (int priority = 10; priority > 0; priority--) {
00075       Drivers::iterator it = GetDrivers().begin();
00076       for (; it != GetDrivers().end(); ++it) {
00077         DriverFactoryBase *d = (*it).second;
00078 
00079         /* Check driver type */
00080         if (d->type != type) continue;
00081         if (d->priority != priority) continue;
00082 
00083         Driver *newd = d->CreateInstance();
00084         const char *err = newd->Start(NULL);
00085         if (err == NULL) {
00086           DEBUG(driver, 1, "Successfully probed %s driver '%s'", GetDriverTypeName(type), d->name);
00087           delete *GetActiveDriver(type);
00088           *GetActiveDriver(type) = newd;
00089           return newd;
00090         }
00091 
00092         DEBUG(driver, 1, "Probing %s driver '%s' failed with error: %s", GetDriverTypeName(type), d->name, err);
00093         delete newd;
00094       }
00095     }
00096     usererror("Couldn't find any suitable %s driver", GetDriverTypeName(type));
00097   } else {
00098     char *parm;
00099     char buffer[256];
00100     const char *parms[32];
00101 
00102     /* Extract the driver name and put parameter list in parm */
00103     strecpy(buffer, name, lastof(buffer));
00104     parm = strchr(buffer, ':');
00105     parms[0] = NULL;
00106     if (parm != NULL) {
00107       uint np = 0;
00108       /* Tokenize the parm. */
00109       do {
00110         *parm++ = '\0';
00111         if (np < lengthof(parms) - 1) parms[np++] = parm;
00112         while (*parm != '\0' && *parm != ',') parm++;
00113       } while (*parm == ',');
00114       parms[np] = NULL;
00115     }
00116 
00117     /* Find this driver */
00118     Drivers::iterator it = GetDrivers().begin();
00119     for (; it != GetDrivers().end(); ++it) {
00120       DriverFactoryBase *d = (*it).second;
00121 
00122       /* Check driver type */
00123       if (d->type != type) continue;
00124 
00125       /* Check driver name */
00126       if (strcasecmp(buffer, d->name) != 0) continue;
00127 
00128       /* Found our driver, let's try it */
00129       Driver *newd = d->CreateInstance();
00130 
00131       const char *err = newd->Start(parms);
00132       if (err != NULL) {
00133         delete newd;
00134         usererror("Unable to load driver '%s'. The error was: %s", d->name, err);
00135       }
00136 
00137       DEBUG(driver, 1, "Successfully loaded %s driver '%s'", GetDriverTypeName(type), d->name);
00138       delete *GetActiveDriver(type);
00139       *GetActiveDriver(type) = newd;
00140       return newd;
00141     }
00142     usererror("No such %s driver: %s\n", GetDriverTypeName(type), buffer);
00143   }
00144 }
00145 
00153 void DriverFactoryBase::RegisterDriver(const char *name, Driver::Type type, int priority)
00154 {
00155   /* Don't register nameless Drivers */
00156   if (name == NULL) return;
00157 
00158   this->name = strdup(name);
00159   this->type = type;
00160   this->priority = priority;
00161 
00162   /* Prefix the name with driver type to make it unique */
00163   char buf[32];
00164   strecpy(buf, GetDriverTypeName(type), lastof(buf));
00165   strecpy(buf + 5, name, lastof(buf));
00166 
00167   const char *longname = strdup(buf);
00168 
00169   std::pair<Drivers::iterator, bool> P = GetDrivers().insert(Drivers::value_type(longname, this));
00170   assert(P.second);
00171 }
00172 
00176 char *DriverFactoryBase::GetDriversInfo(char *p, const char *last)
00177 {
00178   for (Driver::Type type = Driver::DT_BEGIN; type != Driver::DT_END; type++) {
00179     p += seprintf(p, last, "List of %s drivers:\n", GetDriverTypeName(type));
00180 
00181     for (int priority = 10; priority >= 0; priority--) {
00182       Drivers::iterator it = GetDrivers().begin();
00183       for (; it != GetDrivers().end(); it++) {
00184         DriverFactoryBase *d = (*it).second;
00185         if (d->type != type) continue;
00186         if (d->priority != priority) continue;
00187         p += seprintf(p, last, "%18s: %s\n", d->name, d->GetDescription());
00188       }
00189     }
00190 
00191     p += seprintf(p, last, "\n");
00192   }
00193 
00194   return p;
00195 }
00196 
00199 DriverFactoryBase::~DriverFactoryBase()
00200 {
00201   if (this->name == NULL) return;
00202 
00203   /* Prefix the name with driver type to make it unique */
00204   char buf[32];
00205   strecpy(buf, GetDriverTypeName(type), lastof(buf));
00206   strecpy(buf + 5, this->name, lastof(buf));
00207 
00208   Drivers::iterator it = GetDrivers().find(buf);
00209   assert(it != GetDrivers().end());
00210 
00211   const char *longname = (*it).first;
00212 
00213   GetDrivers().erase(it);
00214   free((void *)longname);
00215 
00216   if (GetDrivers().empty()) delete &GetDrivers();
00217   free((void *)this->name);
00218 }

Generated on Sat Jun 19 17:14:48 2010 for OpenTTD by  doxygen 1.6.1