OpenTTD
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 
26 
28 
30 
31 char *_ini_blitter;
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 
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 {
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 
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 
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 }
const char * GetDriverParam(const char *const *parm, const char *name)
Get a string parameter the list of parameters.
Definition: driver.cpp:40
char * _ini_videodriver
The video driver a stored in the configuration file.
Definition: driver.cpp:21
virtual ~DriverFactoryBase()
Frees memory used for this->name.
Definition: driver.cpp:236
Base of all video drivers.
Helper for iteration.
Definition: driver.h:46
static Drivers & GetDrivers()
Get the map with drivers.
Definition: driver.h:76
static Driver ** GetActiveDriver(Driver::Type type)
Get the active driver for the given type.
Definition: driver.h:87
int CDECL seprintf(char *str, const char *last, const char *format,...)
Safer implementation of snprintf; same as snprintf except:
Definition: string.cpp:398
char * _ini_blitter
The blitter as stored in the configuration file.
Definition: driver.cpp:31
Functions related to debugging.
bool GetDriverParamBool(const char *const *parm, const char *name)
Get a boolean parameter the list of parameters.
Definition: driver.cpp:64
static const char * GetDriverTypeName(Driver::Type type)
Get the driver type name.
Definition: driver.h:98
Base for all sound drivers.
DriverFactoryBase(Driver::Type type, int priority, const char *name, const char *description)
Construct a new DriverFactory.
Definition: driver.cpp:219
Dimension _cur_resolution
The current resolution.
Definition: driver.cpp:24
int _num_resolutions
The number of resolutions.
Definition: driver.cpp:22
static bool SelectDriverImpl(const char *name, Driver::Type type)
Find the requested driver and return its class.
Definition: driver.cpp:104
#define lastof(x)
Get the last element of an fixed size array.
Definition: depend.cpp:50
static char * GetDriversInfo(char *p, const char *last)
Build a human readable list of available drivers, grouped by type.
Definition: driver.cpp:191
int priority
The priority of this factory.
Definition: driver.h:67
virtual Driver * CreateInstance() const =0
Create an instance of this driver-class.
Functions related to low-level strings.
const char * description
The description of this driver.
Definition: driver.h:69
char * _ini_sounddriver
The sound driver a stored in the configuration file.
Definition: driver.cpp:27
virtual const char * Start(const char *const *parm)=0
Start this driver.
Driver::Type type
The type of driver.
Definition: driver.h:66
Base for all music playback.
Definition of base types and functions in a cross-platform compatible way.
void CDECL usererror(const char *s,...)
Error handling for fatal user errors.
Definition: openttd.cpp:90
A number of safeguards to prevent using unsafe methods.
Base for all driver factories.
Definition: driver.h:60
char * stredup(const char *s, const char *last)
Create a duplicate of the given string.
Definition: string.cpp:126
#define lengthof(x)
Return the length of an fixed size array.
Definition: depend.cpp:42
Helper for iteration.
Definition: driver.h:42
A driver for communicating with the user.
Definition: driver.h:24
#define DEBUG(name, level,...)
Output a line of debugging information.
Definition: debug.h:39
Dimension _resolutions[32]
List of resolutions.
Definition: driver.cpp:23
static bool StrEmpty(const char *s)
Check if a string buffer is empty.
Definition: string_func.h:59
static void SelectDriver(const char *name, Driver::Type type)
Find the requested driver and return its class.
Definition: driver.cpp:88
Type
The type of driver.
Definition: driver.h:41
char * strecpy(char *dst, const char *src, const char *last)
Copies characters from one buffer to another.
Definition: depend.cpp:68
bool _blitter_autodetected
Was the blitter autodetected or specified by the user?
Definition: driver.cpp:32
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
Definition: depend.cpp:114
int GetDriverParamInt(const char *const *parm, const char *name, int def)
Get an integer parameter the list of parameters.
Definition: driver.cpp:76
bool _rightclick_emulate
Whether right clicking is emulated.
Definition: driver.cpp:25
char * _ini_musicdriver
The music driver a stored in the configuration file.
Definition: driver.cpp:29
const char * GetDescription() const
Get a nice description of the driver-class.
Definition: driver.h:130
Dimensions (a width and height) of a rectangle in 2D.
const char * name
The name of the drivers of this factory.
Definition: driver.h:68