driver.cpp

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

Generated on Wed Dec 30 20:40:01 2009 for OpenTTD by  doxygen 1.5.6