Translations update
[openttd/fttd.git] / src / driver.cpp
blobaf4165e06aa6c462d20dc1d8d8ea11135166e43b
1 /* $Id$ */
3 /*
4 * This file is part of OpenTTD.
5 * 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.
6 * 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.
7 * 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/>.
8 */
10 /** @file driver.cpp Base for all driver handling. */
12 #include "stdafx.h"
13 #include "debug.h"
14 #include "sound/sound_driver.hpp"
15 #include "music/music_driver.hpp"
16 #include "video/video_driver.hpp"
17 #include "string.h"
19 /** The video driver as stored in the configuration file. */
20 char *VideoDriver::ini;
22 int _num_resolutions; ///< The number of resolutions.
23 Dimension _resolutions[32]; ///< List of resolutions.
24 Dimension _cur_resolution; ///< The current resolution.
25 bool _rightclick_emulate; ///< Whether right clicking is emulated.
27 /** The sound driver as stored in the configuration file. */
28 char *SoundDriver::ini;
30 /** The music driver as stored in the configuration file. */
31 char *MusicDriver::ini;
33 /**
34 * Get a string parameter the list of parameters.
35 * @param parm The parameters.
36 * @param name The parameter name we're looking for.
37 * @return The parameter value.
39 const char *GetDriverParam(const char * const *parm, const char *name)
41 size_t len;
43 if (parm == NULL) return NULL;
45 len = strlen(name);
46 for (; *parm != NULL; parm++) {
47 const char *p = *parm;
49 if (strncmp(p, name, len) == 0) {
50 if (p[len] == '=') return p + len + 1;
51 if (p[len] == '\0') return p + len;
54 return NULL;
57 /**
58 * Get a boolean parameter the list of parameters.
59 * @param parm The parameters.
60 * @param name The parameter name we're looking for.
61 * @return The parameter value.
63 bool GetDriverParamBool(const char * const *parm, const char *name)
65 return GetDriverParam(parm, name) != NULL;
68 /**
69 * Get an integer parameter the list of parameters.
70 * @param parm The parameters.
71 * @param name The parameter name we're looking for.
72 * @param def The default value if the parameter doesn't exist.
73 * @return The parameter value.
75 int GetDriverParamInt(const char * const *parm, const char *name, int def)
77 const char *p = GetDriverParam(parm, name);
78 return p != NULL ? atoi(p) : def;
82 /** Construct a DriverSystem. */
83 DriverSystem::DriverSystem (const char *desc)
84 : drivers (new map), desc(desc), active(NULL), name(NULL)
88 /**
89 * Insert a driver factory into the list.
90 * @param name The name of the driver.
91 * @param factory The factory of the driver.
93 void DriverSystem::insert (const char *name, DriverFactoryBase *factory)
95 std::pair <map::iterator, bool> ins = this->drivers->insert (map::value_type (name, factory));
96 assert (ins.second);
99 /** Remove a driver factory from the list. */
100 void DriverSystem::erase (const char *name)
102 map::iterator it = this->drivers->find (name);
103 assert (it != this->drivers->end());
105 this->drivers->erase (it);
107 if (this->drivers->empty()) delete this->drivers;
111 * Find the requested driver and return its class.
112 * @param name the driver to select.
113 * @post Sets the driver so GetCurrentDriver() returns it too.
115 void DriverSystem::select (const char *name)
117 if (this->drivers->empty()) {
118 StrEmpty(name) ?
119 usererror ("Failed to autoprobe %s driver", this->desc) :
120 usererror ("Failed to select requested %s driver '%s'", this->desc, name);
123 if (StrEmpty(name)) {
124 /* Probe for this driver, but do not fall back to dedicated/null! */
125 for (int priority = 10; priority > 0; priority--) {
126 map::iterator it = this->drivers->begin();
127 for (; it != this->drivers->end(); ++it) {
128 DriverFactoryBase *d = (*it).second;
129 if (d->priority != priority) continue;
131 Driver *oldd = this->active;
132 const char *oldn = this->name;
133 Driver *newd = d->CreateInstance();
134 this->active = newd;
135 this->name = d->name;
137 const char *err = newd->Start(NULL);
138 if (err == NULL) {
139 DEBUG(driver, 1, "Successfully probed %s driver '%s'", this->desc, d->name);
140 delete oldd;
141 return;
144 this->active = oldd;
145 this->name = oldn;
146 DEBUG(driver, 1, "Probing %s driver '%s' failed with error: %s", this->desc, d->name, err);
147 delete newd;
150 usererror ("Couldn't find any suitable %s driver", this->desc);
151 } else {
152 char *parm;
153 char buffer[256];
154 const char *parms[32];
156 /* Extract the driver name and put parameter list in parm */
157 bstrcpy (buffer, name);
158 parm = strchr(buffer, ':');
159 parms[0] = NULL;
160 if (parm != NULL) {
161 uint np = 0;
162 /* Tokenize the parm. */
163 do {
164 *parm++ = '\0';
165 if (np < lengthof(parms) - 1) parms[np++] = parm;
166 while (*parm != '\0' && *parm != ',') parm++;
167 } while (*parm == ',');
168 parms[np] = NULL;
171 /* Find this driver */
172 map::iterator it = this->drivers->begin();
173 for (; it != this->drivers->end(); ++it) {
174 DriverFactoryBase *d = (*it).second;
176 /* Check driver name */
177 if (strcasecmp(buffer, d->name) != 0) continue;
179 /* Found our driver, let's try it */
180 Driver *newd = d->CreateInstance();
182 const char *err = newd->Start(parms);
183 if (err != NULL) {
184 delete newd;
185 usererror("Unable to load driver '%s'. The error was: %s", d->name, err);
188 DEBUG(driver, 1, "Successfully loaded %s driver '%s'", this->desc, d->name);
189 delete this->active;
190 this->active = newd;
191 this->name = d->name;
192 return;
194 usererror ("No such %s driver: %s\n", this->desc, buffer);
199 * Build a human readable list of available drivers.
200 * @param buf The buffer to write to.
202 void DriverSystem::list (stringb *buf)
204 buf->append_fmt ("List of %s drivers:\n", this->desc);
206 for (int priority = 10; priority >= 0; priority--) {
207 map::iterator it = this->drivers->begin();
208 for (; it != this->drivers->end(); it++) {
209 DriverFactoryBase *d = (*it).second;
210 if (d->priority != priority) continue;
211 buf->append_fmt ("%18s: %s\n", d->name, d->description);
215 buf->append ('\n');