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/>.
10 /** @file driver.cpp Base for all driver handling. */
14 #include "sound/sound_driver.hpp"
15 #include "music/music_driver.hpp"
16 #include "video/video_driver.hpp"
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
;
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
)
43 if (parm
== NULL
) return NULL
;
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
;
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
;
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(), desc(desc
), active(NULL
), name(NULL
)
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
));
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
);
109 * Find the requested driver and return its class.
110 * @param name the driver to select.
111 * @post Sets the driver so GetCurrentDriver() returns it too.
113 void DriverSystem::select (const char *name
)
115 assert (this->active
== NULL
);
116 assert (this->name
== NULL
);
118 if (this->drivers
.empty()) {
119 usererror ("No %s drivers found", this->desc
);
122 if (StrEmpty(name
)) {
123 /* Probe for this driver, but do not fall back to dedicated/null! */
124 for (int priority
= 10; priority
> 0; priority
--) {
125 map::iterator it
= this->drivers
.begin();
126 for (; it
!= this->drivers
.end(); ++it
) {
127 DriverFactoryBase
*d
= (*it
).second
;
128 if (d
->priority
!= priority
) continue;
130 Driver
*newd
= d
->create();
132 this->name
= d
->name
;
134 const char *err
= newd
->Start(NULL
);
136 DEBUG(driver
, 1, "Successfully probed %s driver '%s'", this->desc
, d
->name
);
142 DEBUG(driver
, 1, "Probing %s driver '%s' failed with error: %s", this->desc
, d
->name
, err
);
146 usererror ("Couldn't find any suitable %s driver", this->desc
);
150 const char *parms
[32];
152 /* Extract the driver name and put parameter list in parm */
153 bstrcpy (buffer
, name
);
154 parm
= strchr(buffer
, ':');
156 while (parm
!= NULL
) {
158 if (np
== lengthof(parms
) - 1) break;
160 parm
= strchr (parm
, ',');
164 /* Find this driver */
165 DriverFactoryBase
*d
;
166 for (map::iterator it
= this->drivers
.begin(); ; ) {
169 /* Check driver name */
170 if (strcasecmp (buffer
, d
->name
) == 0) break;
172 if (++it
== this->drivers
.end()) {
173 usererror ("No such %s driver: %s\n", this->desc
, buffer
);
177 /* Found our driver, let's try it */
178 Driver
*newd
= d
->create();
180 const char *err
= newd
->Start (parms
);
183 usererror ("Unable to load driver '%s'. The error was: %s", d
->name
, err
);
186 DEBUG(driver
, 1, "Successfully loaded %s driver '%s'", this->desc
, d
->name
);
188 this->name
= d
->name
;
193 * Build a human readable list of available drivers.
194 * @param buf The buffer to write to.
196 void DriverSystem::list (stringb
*buf
)
198 buf
->append_fmt ("List of %s drivers:\n", this->desc
);
200 for (int priority
= 10; priority
>= 0; priority
--) {
201 map::iterator it
= this->drivers
.begin();
202 for (; it
!= this->drivers
.end(); it
++) {
203 DriverFactoryBase
*d
= (*it
).second
;
204 if (d
->priority
!= priority
) continue;
205 buf
->append_fmt ("%18s: %s\n", d
->name
, d
->description
);