OpenTTD: src/driver.cpp Source File

OpenTTD

- Main Page
- Related Pages
- Modules
- Namespaces
- Data Structures
- Files

- File List
- Globals

driver.cpp
Go to the documentation of this file.
1 /* $Id: driver.cpp 26539 2014-04-28 21:09:19Z rubidium $ */
2
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 */
9
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_func.h"
18
19 #include "safeguards.h"
20
21 char *_ini_videodriver;
22 int _num_resolutions;
23 Dimension _resolutions[32];
24 Dimension _cur_resolution;
25 bool _rightclick_emulate;
26
27 char *_ini_sounddriver;
28
29 char *_ini_musicdriver;
30
31 char *_ini_blitter;
32 bool _blitter_autodetected;
33
40 const char *GetDriverParam(const char * const *parm, const char *name)
41 {
42 size_t len;
43
44 if (parm == NULL) return NULL;
45
46 len = strlen(name);
47 for (; *parm != NULL; parm++) {
48 const char *p = *parm;
49
50 if (strncmp(p, name, len) == 0) {
51 if (p[len] == '=') return p + len + 1;
52 if (p[len] == '\0') return p + len;
53 }
54 }
55 return NULL;
56 }
57
64 bool GetDriverParamBool(const char * const *parm, const char *name)
65 {
66 return GetDriverParam(parm, name) != NULL;
67 }
68
76 int GetDriverParamInt(const char * const *parm, const char *name, int def)
77 {
78 const char *p = GetDriverParam(parm, name);
79 return p != NULL ? atoi(p) : def;
80 }
81
88 void DriverFactoryBase::SelectDriver(const char *name, Driver::Type type)
89 {
90 if (!DriverFactoryBase::SelectDriverImpl(name, type)) {
91 StrEmpty(name) ?
92 usererror("Failed to autoprobe %s driver", GetDriverTypeName(type)) :
93 usererror("Failed to select requested %s driver '%s'", GetDriverTypeName(type), name);
94 }
95 }
96
104 bool DriverFactoryBase::SelectDriverImpl(const char *name, Driver::Type type)
105 {
106 if (GetDrivers().size() == 0) return false;
107
108 if (StrEmpty(name)) {
109 /* Probe for this driver, but do not fall back to dedicated/null! */
110 for (int priority = 10; priority > 0; priority--) {
111 Drivers::iterator it = GetDrivers().begin();
112 for (; it != GetDrivers().end(); ++it) {
113 DriverFactoryBase *d = (*it).second;
114
115 /* Check driver type */
116 if (d->type != type) continue;
117 if (d->priority != priority) continue;
118
119 Driver *oldd = *GetActiveDriver(type);
120 Driver *newd = d->CreateInstance();
121 *GetActiveDriver(type) = newd;
122
123 const char *err = newd->Start(NULL);
124 if (err == NULL) {
125 DEBUG(driver, 1, "Successfully probed %s driver '%s'", GetDriverTypeName(type), d->name);
126 delete oldd;
127 return true;
128 }
129
130 *GetActiveDriver(type) = oldd;
131 DEBUG(driver, 1, "Probing %s driver '%s' failed with error: %s", GetDriverTypeName(type), d->name, err);
132 delete newd;
133 }
134 }
135 usererror("Couldn't find any suitable %s driver", GetDriverTypeName(type));
136 } else {
137 char *parm;
138 char buffer[256];
139 const char *parms[32];
140
141 /* Extract the driver name and put parameter list in parm */
142 strecpy(buffer, name, lastof(buffer));
143 parm = strchr(buffer, ':');
144 parms[0] = NULL;
145 if (parm != NULL) {
146 uint np = 0;
147 /* Tokenize the parm. */
148 do {
149 *parm++ = '\0';
150 if (np < lengthof(parms) - 1) parms[np++] = parm;
151 while (*parm != '\0' && *parm != ',') parm++;
152 } while (*parm == ',');
153 parms[np] = NULL;
154 }
155
156 /* Find this driver */
157 Drivers::iterator it = GetDrivers().begin();
158 for (; it != GetDrivers().end(); ++it) {
159 DriverFactoryBase *d = (*it).second;
160
161 /* Check driver type */
162 if (d->type != type) continue;
163
164 /* Check driver name */
165 if (strcasecmp(buffer, d->name) != 0) continue;
166
167 /* Found our driver, let's try it */
168 Driver *newd = d->CreateInstance();
169
170 const char *err = newd->Start(parms);
171 if (err != NULL) {
172 delete newd;
173 usererror("Unable to load driver '%s'. The error was: %s", d->name, err);
174 }
175
176 DEBUG(driver, 1, "Successfully loaded %s driver '%s'", GetDriverTypeName(type), d->name);
177 delete *GetActiveDriver(type);
178 *GetActiveDriver(type) = newd;
179 return true;
180 }
181 usererror("No such %s driver: %s\n", GetDriverTypeName(type), buffer);
182 }
183 }
184
191 char *DriverFactoryBase::GetDriversInfo(char *p, const char *last)
192 {
193 for (Driver::Type type = Driver::DT_BEGIN; type != Driver::DT_END; type++) {
194 p += seprintf(p, last, "List of %s drivers:\n", GetDriverTypeName(type));
195
196 for (int priority = 10; priority >= 0; priority--) {
197 Drivers::iterator it = GetDrivers().begin();
198 for (; it != GetDrivers().end(); it++) {
199 DriverFactoryBase *d = (*it).second;
200 if (d->type != type) continue;
201 if (d->priority != priority) continue;
202 p += seprintf(p, last, "%18s: %s\n", d->name, d->GetDescription());
203 }
204 }
205
206 p += seprintf(p, last, "\n");
207 }
208
209 return p;
210 }
211
219 DriverFactoryBase::DriverFactoryBase(Driver::Type type, int priority, const char *name, const char *description) :
220 type(type), priority(priority), name(name), description(description)
221 {
222 /* Prefix the name with driver type to make it unique */
223 char buf[32];
224 strecpy(buf, GetDriverTypeName(type), lastof(buf));
225 strecpy(buf + 5, name, lastof(buf));
226
227 const char *longname = stredup(buf);
228
229 std::pair<Drivers::iterator, bool> P = GetDrivers().insert(Drivers::value_type(longname, this));
230 assert(P.second);
231 }
232
236 DriverFactoryBase::~DriverFactoryBase()
237 {
238 /* Prefix the name with driver type to make it unique */
239 char buf[32];
240 strecpy(buf, GetDriverTypeName(type), lastof(buf));
241 strecpy(buf + 5, this->name, lastof(buf));
242
243 Drivers::iterator it = GetDrivers().find(buf);
244 assert(it != GetDrivers().end());
245
246 const char *longname = (*it).first;
247
248 GetDrivers().erase(it);
249 free(longname);
250
251 if (GetDrivers().empty()) delete &GetDrivers();
252 }