driver.cpp

Go to the documentation of this file.
00001 /* $Id: driver.cpp 26107 2013-11-25 14:26:46Z 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 bool _rightclick_emulate;   
00025 
00026 SoundDriver *_sound_driver; 
00027 char *_ini_sounddriver;     
00028 
00029 MusicDriver *_music_driver; 
00030 char *_ini_musicdriver;     
00031 
00032 char *_ini_blitter;         
00033 bool _blitter_autodetected; 
00034 
00041 const char *GetDriverParam(const char * const *parm, const char *name)
00042 {
00043   size_t len;
00044 
00045   if (parm == NULL) return NULL;
00046 
00047   len = strlen(name);
00048   for (; *parm != NULL; parm++) {
00049     const char *p = *parm;
00050 
00051     if (strncmp(p, name, len) == 0) {
00052       if (p[len] == '=')  return p + len + 1;
00053       if (p[len] == '\0') return p + len;
00054     }
00055   }
00056   return NULL;
00057 }
00058 
00065 bool GetDriverParamBool(const char * const *parm, const char *name)
00066 {
00067   return GetDriverParam(parm, name) != NULL;
00068 }
00069 
00077 int GetDriverParamInt(const char * const *parm, const char *name, int def)
00078 {
00079   const char *p = GetDriverParam(parm, name);
00080   return p != NULL ? atoi(p) : def;
00081 }
00082 
00089 Driver *DriverFactoryBase::SelectDriver(const char *name, Driver::Type type)
00090 {
00091   if (GetDrivers().size() == 0) return NULL;
00092 
00093   if (StrEmpty(name)) {
00094     /* Probe for this driver, but do not fall back to dedicated/null! */
00095     for (int priority = 10; priority > 0; priority--) {
00096       Drivers::iterator it = GetDrivers().begin();
00097       for (; it != GetDrivers().end(); ++it) {
00098         DriverFactoryBase *d = (*it).second;
00099 
00100         /* Check driver type */
00101         if (d->type != type) continue;
00102         if (d->priority != priority) continue;
00103 
00104         Driver *newd = d->CreateInstance();
00105         const char *err = newd->Start(NULL);
00106         if (err == NULL) {
00107           DEBUG(driver, 1, "Successfully probed %s driver '%s'", GetDriverTypeName(type), d->name);
00108           delete *GetActiveDriver(type);
00109           *GetActiveDriver(type) = newd;
00110           return newd;
00111         }
00112 
00113         DEBUG(driver, 1, "Probing %s driver '%s' failed with error: %s", GetDriverTypeName(type), d->name, err);
00114         delete newd;
00115       }
00116     }
00117     usererror("Couldn't find any suitable %s driver", GetDriverTypeName(type));
00118   } else {
00119     char *parm;
00120     char buffer[256];
00121     const char *parms[32];
00122 
00123     /* Extract the driver name and put parameter list in parm */
00124     strecpy(buffer, name, lastof(buffer));
00125     parm = strchr(buffer, ':');
00126     parms[0] = NULL;
00127     if (parm != NULL) {
00128       uint np = 0;
00129       /* Tokenize the parm. */
00130       do {
00131         *parm++ = '\0';
00132         if (np < lengthof(parms) - 1) parms[np++] = parm;
00133         while (*parm != '\0' && *parm != ',') parm++;
00134       } while (*parm == ',');
00135       parms[np] = NULL;
00136     }
00137 
00138     /* Find this driver */
00139     Drivers::iterator it = GetDrivers().begin();
00140     for (; it != GetDrivers().end(); ++it) {
00141       DriverFactoryBase *d = (*it).second;
00142 
00143       /* Check driver type */
00144       if (d->type != type) continue;
00145 
00146       /* Check driver name */
00147       if (strcasecmp(buffer, d->name) != 0) continue;
00148 
00149       /* Found our driver, let's try it */
00150       Driver *newd = d->CreateInstance();
00151 
00152       const char *err = newd->Start(parms);
00153       if (err != NULL) {
00154         delete newd;
00155         usererror("Unable to load driver '%s'. The error was: %s", d->name, err);
00156       }
00157 
00158       DEBUG(driver, 1, "Successfully loaded %s driver '%s'", GetDriverTypeName(type), d->name);
00159       delete *GetActiveDriver(type);
00160       *GetActiveDriver(type) = newd;
00161       return newd;
00162     }
00163     usererror("No such %s driver: %s\n", GetDriverTypeName(type), buffer);
00164   }
00165 }
00166 
00173 char *DriverFactoryBase::GetDriversInfo(char *p, const char *last)
00174 {
00175   for (Driver::Type type = Driver::DT_BEGIN; type != Driver::DT_END; type++) {
00176     p += seprintf(p, last, "List of %s drivers:\n", GetDriverTypeName(type));
00177 
00178     for (int priority = 10; priority >= 0; priority--) {
00179       Drivers::iterator it = GetDrivers().begin();
00180       for (; it != GetDrivers().end(); it++) {
00181         DriverFactoryBase *d = (*it).second;
00182         if (d->type != type) continue;
00183         if (d->priority != priority) continue;
00184         p += seprintf(p, last, "%18s: %s\n", d->name, d->GetDescription());
00185       }
00186     }
00187 
00188     p += seprintf(p, last, "\n");
00189   }
00190 
00191   return p;
00192 }
00193 
00201 DriverFactoryBase::DriverFactoryBase(Driver::Type type, int priority, const char *name, const char *description) :
00202   type(type), priority(priority), name(name), description(description)
00203 {
00204   /* Prefix the name with driver type to make it unique */
00205   char buf[32];
00206   strecpy(buf, GetDriverTypeName(type), lastof(buf));
00207   strecpy(buf + 5, name, lastof(buf));
00208 
00209   const char *longname = strdup(buf);
00210 
00211   std::pair<Drivers::iterator, bool> P = GetDrivers().insert(Drivers::value_type(longname, this));
00212   assert(P.second);
00213 }
00214 
00218 DriverFactoryBase::~DriverFactoryBase()
00219 {
00220   /* Prefix the name with driver type to make it unique */
00221   char buf[32];
00222   strecpy(buf, GetDriverTypeName(type), lastof(buf));
00223   strecpy(buf + 5, this->name, lastof(buf));
00224 
00225   Drivers::iterator it = GetDrivers().find(buf);
00226   assert(it != GetDrivers().end());
00227 
00228   const char *longname = (*it).first;
00229 
00230   GetDrivers().erase(it);
00231   free(longname);
00232 
00233   if (GetDrivers().empty()) delete &GetDrivers();
00234 }