OpenTTD Source  1.11.0-beta2
driver.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * 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.
4  * 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.
5  * 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/>.
6  */
7 
10 #include "stdafx.h"
11 #include "debug.h"
12 #include "sound/sound_driver.hpp"
13 #include "music/music_driver.hpp"
14 #include "video/video_driver.hpp"
15 #include "string_func.h"
16 #include <string>
17 #include <sstream>
18 
19 #include "safeguards.h"
20 
21 std::string _ini_videodriver;
22 std::vector<Dimension> _resolutions;
25 
26 std::string _ini_sounddriver;
27 
28 std::string _ini_musicdriver;
29 
30 std::string _ini_blitter;
32 
39 const char *GetDriverParam(const StringList &parm, const char *name)
40 {
41  if (parm.empty()) return nullptr;
42 
43  size_t len = strlen(name);
44  for (auto &p : parm) {
45  if (p.compare(0, len, name) == 0) {
46  if (p.length() == len) return "";
47  if (p[len] == '=') return p.c_str() + len + 1;
48  }
49  }
50  return nullptr;
51 }
52 
59 bool GetDriverParamBool(const StringList &parm, const char *name)
60 {
61  return GetDriverParam(parm, name) != nullptr;
62 }
63 
71 int GetDriverParamInt(const StringList &parm, const char *name, int def)
72 {
73  const char *p = GetDriverParam(parm, name);
74  return p != nullptr ? atoi(p) : def;
75 }
76 
83 void DriverFactoryBase::SelectDriver(const std::string &name, Driver::Type type)
84 {
86  name.empty() ?
87  usererror("Failed to autoprobe %s driver", GetDriverTypeName(type)) :
88  usererror("Failed to select requested %s driver '%s'", GetDriverTypeName(type), name.c_str());
89  }
90 }
91 
99 bool DriverFactoryBase::SelectDriverImpl(const std::string &name, Driver::Type type)
100 {
101  if (GetDrivers().size() == 0) return false;
102 
103  if (name.empty()) {
104  /* Probe for this driver, but do not fall back to dedicated/null! */
105  for (int priority = 10; priority > 0; priority--) {
106  Drivers::iterator it = GetDrivers().begin();
107  for (; it != GetDrivers().end(); ++it) {
108  DriverFactoryBase *d = (*it).second;
109 
110  /* Check driver type */
111  if (d->type != type) continue;
112  if (d->priority != priority) continue;
113 
114  Driver *oldd = *GetActiveDriver(type);
115  Driver *newd = d->CreateInstance();
116  *GetActiveDriver(type) = newd;
117 
118  const char *err = newd->Start({});
119  if (err == nullptr) {
120  DEBUG(driver, 1, "Successfully probed %s driver '%s'", GetDriverTypeName(type), d->name);
121  delete oldd;
122  return true;
123  }
124 
125  *GetActiveDriver(type) = oldd;
126  DEBUG(driver, 1, "Probing %s driver '%s' failed with error: %s", GetDriverTypeName(type), d->name, err);
127  delete newd;
128  }
129  }
130  usererror("Couldn't find any suitable %s driver", GetDriverTypeName(type));
131  } else {
132  /* Extract the driver name and put parameter list in parm */
133  std::istringstream buffer(name);
134  std::string dname;
135  std::getline(buffer, dname, ':');
136 
137  std::string param;
138  std::vector<std::string> parms;
139  while (std::getline(buffer, param, ',')) {
140  parms.push_back(param);
141  }
142 
143  /* Find this driver */
144  Drivers::iterator it = GetDrivers().begin();
145  for (; it != GetDrivers().end(); ++it) {
146  DriverFactoryBase *d = (*it).second;
147 
148  /* Check driver type */
149  if (d->type != type) continue;
150 
151  /* Check driver name */
152  if (strcasecmp(dname.c_str(), d->name) != 0) continue;
153 
154  /* Found our driver, let's try it */
155  Driver *newd = d->CreateInstance();
156 
157  const char *err = newd->Start(parms);
158  if (err != nullptr) {
159  delete newd;
160  usererror("Unable to load driver '%s'. The error was: %s", d->name, err);
161  }
162 
163  DEBUG(driver, 1, "Successfully loaded %s driver '%s'", GetDriverTypeName(type), d->name);
164  delete *GetActiveDriver(type);
165  *GetActiveDriver(type) = newd;
166  return true;
167  }
168  usererror("No such %s driver: %s\n", GetDriverTypeName(type), dname.c_str());
169  }
170 }
171 
178 char *DriverFactoryBase::GetDriversInfo(char *p, const char *last)
179 {
181  p += seprintf(p, last, "List of %s drivers:\n", GetDriverTypeName(type));
182 
183  for (int priority = 10; priority >= 0; priority--) {
184  Drivers::iterator it = GetDrivers().begin();
185  for (; it != GetDrivers().end(); it++) {
186  DriverFactoryBase *d = (*it).second;
187  if (d->type != type) continue;
188  if (d->priority != priority) continue;
189  p += seprintf(p, last, "%18s: %s\n", d->name, d->GetDescription());
190  }
191  }
192 
193  p += seprintf(p, last, "\n");
194  }
195 
196  return p;
197 }
198 
206 DriverFactoryBase::DriverFactoryBase(Driver::Type type, int priority, const char *name, const char *description) :
207  type(type), priority(priority), name(name), description(description)
208 {
209  /* Prefix the name with driver type to make it unique */
210  char buf[32];
211  strecpy(buf, GetDriverTypeName(type), lastof(buf));
212  strecpy(buf + 5, name, lastof(buf));
213 
214  std::pair<Drivers::iterator, bool> P = GetDrivers().insert(Drivers::value_type(buf, this));
215  assert(P.second);
216 }
217 
222 {
223  /* Prefix the name with driver type to make it unique */
224  char buf[32];
225  strecpy(buf, GetDriverTypeName(type), lastof(buf));
226  strecpy(buf + 5, this->name, lastof(buf));
227 
228  Drivers::iterator it = GetDrivers().find(buf);
229  assert(it != GetDrivers().end());
230 
231  GetDrivers().erase(it);
232  if (GetDrivers().empty()) delete &GetDrivers();
233 }
DriverFactoryBase::GetDriverTypeName
static const char * GetDriverTypeName(Driver::Type type)
Get the driver type name.
Definition: driver.h:97
DriverFactoryBase::SelectDriverImpl
static bool SelectDriverImpl(const std::string &name, Driver::Type type)
Find the requested driver and return its class.
Definition: driver.cpp:99
DriverFactoryBase::GetActiveDriver
static Driver ** GetActiveDriver(Driver::Type type)
Get the active driver for the given type.
Definition: driver.h:86
usererror
void CDECL usererror(const char *s,...)
Error handling for fatal user errors.
Definition: openttd.cpp:100
Dimension
Dimensions (a width and height) of a rectangle in 2D.
Definition: geometry_type.hpp:27
DriverFactoryBase::name
const char * name
The name of the drivers of this factory.
Definition: driver.h:67
_ini_blitter
std::string _ini_blitter
The blitter as stored in the configuration file.
Definition: driver.cpp:30
DriverFactoryBase::DriverFactoryBase
DriverFactoryBase(Driver::Type type, int priority, const char *name, const char *description)
Construct a new DriverFactory.
Definition: driver.cpp:206
DriverFactoryBase::CreateInstance
virtual Driver * CreateInstance() const =0
Create an instance of this driver-class.
DriverFactoryBase::~DriverFactoryBase
virtual ~DriverFactoryBase()
Frees memory used for this->name.
Definition: driver.cpp:221
GetDriverParam
const char * GetDriverParam(const StringList &parm, const char *name)
Get a string parameter the list of parameters.
Definition: driver.cpp:39
DriverFactoryBase::GetDrivers
static Drivers & GetDrivers()
Get the map with drivers.
Definition: driver.h:75
_ini_musicdriver
std::string _ini_musicdriver
The music driver a stored in the configuration file.
Definition: driver.cpp:28
DriverFactoryBase::priority
int priority
The priority of this factory.
Definition: driver.h:66
DriverFactoryBase::GetDriversInfo
static char * GetDriversInfo(char *p, const char *last)
Build a human readable list of available drivers, grouped by type.
Definition: driver.cpp:178
DEBUG
#define DEBUG(name, level,...)
Output a line of debugging information.
Definition: debug.h:35
Driver::Start
virtual const char * Start(const StringList &parm)=0
Start this driver.
DriverFactoryBase::type
Driver::Type type
The type of driver.
Definition: driver.h:65
StringList
std::vector< std::string > StringList
Type for a list of strings.
Definition: string_type.h:58
safeguards.h
music_driver.hpp
_resolutions
std::vector< Dimension > _resolutions
List of resolutions.
Definition: driver.cpp:22
stdafx.h
Driver::Type
Type
The type of driver.
Definition: driver.h:40
Driver::DT_END
@ DT_END
Helper for iteration.
Definition: driver.h:45
GetDriverParamInt
int GetDriverParamInt(const StringList &parm, const char *name, int def)
Get an integer parameter the list of parameters.
Definition: driver.cpp:71
sound_driver.hpp
_rightclick_emulate
bool _rightclick_emulate
Whether right clicking is emulated.
Definition: driver.cpp:24
string_func.h
Driver::DT_BEGIN
@ DT_BEGIN
Helper for iteration.
Definition: driver.h:41
video_driver.hpp
_blitter_autodetected
bool _blitter_autodetected
Was the blitter autodetected or specified by the user?
Definition: driver.cpp:31
_ini_sounddriver
std::string _ini_sounddriver
The sound driver a stored in the configuration file.
Definition: driver.cpp:26
DriverFactoryBase::GetDescription
const char * GetDescription() const
Get a nice description of the driver-class.
Definition: driver.h:129
seprintf
int CDECL seprintf(char *str, const char *last, const char *format,...)
Safer implementation of snprintf; same as snprintf except:
Definition: string.cpp:442
DriverFactoryBase::SelectDriver
static void SelectDriver(const std::string &name, Driver::Type type)
Find the requested driver and return its class.
Definition: driver.cpp:83
Driver
A driver for communicating with the user.
Definition: driver.h:23
strecpy
char * strecpy(char *dst, const char *src, const char *last)
Copies characters from one buffer to another.
Definition: string.cpp:112
lastof
#define lastof(x)
Get the last element of an fixed size array.
Definition: stdafx.h:383
GetDriverParamBool
bool GetDriverParamBool(const StringList &parm, const char *name)
Get a boolean parameter the list of parameters.
Definition: driver.cpp:59
_cur_resolution
Dimension _cur_resolution
The current resolution.
Definition: driver.cpp:23
DriverFactoryBase
Base for all driver factories.
Definition: driver.h:59
_ini_videodriver
std::string _ini_videodriver
The video driver a stored in the configuration file.
Definition: driver.cpp:21
debug.h