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 (new map
), 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
);
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()) {
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();
135 this->name
= d
->name
;
137 const char *err
= newd
->Start(NULL
);
139 DEBUG(driver
, 1, "Successfully probed %s driver '%s'", this->desc
, d
->name
);
146 DEBUG(driver
, 1, "Probing %s driver '%s' failed with error: %s", this->desc
, d
->name
, err
);
150 usererror ("Couldn't find any suitable %s driver", this->desc
);
154 const char *parms
[32];
156 /* Extract the driver name and put parameter list in parm */
157 bstrcpy (buffer
, name
);
158 parm
= strchr(buffer
, ':');
162 /* Tokenize the parm. */
165 if (np
< lengthof(parms
) - 1) parms
[np
++] = parm
;
166 while (*parm
!= '\0' && *parm
!= ',') parm
++;
167 } while (*parm
== ',');
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
);
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
);
191 this->name
= d
->name
;
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
);