# driver.cpp

Go to the documentation of this file.

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