2005-07-24 14:12:37 +00:00
|
|
|
/* $Id$ */
|
|
|
|
|
2007-02-23 18:55:07 +00:00
|
|
|
/** @file driver.cpp */
|
|
|
|
|
2005-07-23 15:16:57 +00:00
|
|
|
#include "stdafx.h"
|
|
|
|
#include "openttd.h"
|
2005-07-27 19:57:12 +00:00
|
|
|
#include "debug.h"
|
2005-07-23 15:16:57 +00:00
|
|
|
#include "driver.h"
|
|
|
|
#include "functions.h"
|
|
|
|
#include "hal.h"
|
|
|
|
#include "string.h"
|
|
|
|
|
2005-07-27 19:57:12 +00:00
|
|
|
#include "music/bemidi.h"
|
|
|
|
#include "music/dmusic.h"
|
|
|
|
#include "music/extmidi.h"
|
|
|
|
#include "music/null_m.h"
|
|
|
|
#include "music/os2_m.h"
|
|
|
|
#include "music/win32_m.h"
|
2005-10-06 17:57:18 +00:00
|
|
|
#include "music/qtmidi.h"
|
2007-02-16 09:50:28 +00:00
|
|
|
#include "music/libtimidity.h"
|
2005-07-27 19:57:12 +00:00
|
|
|
|
|
|
|
#include "sound/null_s.h"
|
|
|
|
#include "sound/sdl_s.h"
|
2005-12-10 11:16:45 +00:00
|
|
|
#include "sound/cocoa_s.h"
|
2005-07-27 19:57:12 +00:00
|
|
|
#include "sound/win32_s.h"
|
|
|
|
|
|
|
|
#include "video/dedicated_v.h"
|
|
|
|
#include "video/null_v.h"
|
|
|
|
#include "video/sdl_v.h"
|
2005-12-10 11:16:45 +00:00
|
|
|
#include "video/cocoa_v.h"
|
2005-07-27 19:57:12 +00:00
|
|
|
#include "video/win32_v.h"
|
|
|
|
|
2005-07-28 09:41:09 +00:00
|
|
|
typedef struct DriverDesc {
|
|
|
|
const char* name;
|
|
|
|
const char* longname;
|
2005-07-29 06:20:28 +00:00
|
|
|
const HalCommonDriver* drv;
|
2005-07-28 09:41:09 +00:00
|
|
|
} DriverDesc;
|
|
|
|
|
|
|
|
typedef struct DriverClass {
|
2005-07-23 15:16:57 +00:00
|
|
|
const DriverDesc *descs;
|
|
|
|
const char *name;
|
2005-07-29 06:20:28 +00:00
|
|
|
const HalCommonDriver** drv;
|
2005-07-23 15:16:57 +00:00
|
|
|
} DriverClass;
|
|
|
|
|
2005-07-28 19:59:41 +00:00
|
|
|
|
2006-01-28 11:08:07 +00:00
|
|
|
#define M(x, y, z) { x, y, (const HalCommonDriver *)(void *)z }
|
2005-07-28 19:59:41 +00:00
|
|
|
static const DriverDesc _music_driver_descs[] = {
|
|
|
|
#ifdef __BEOS__
|
2005-07-29 06:20:28 +00:00
|
|
|
M("bemidi", "BeOS MIDI Driver", &_bemidi_music_driver),
|
2005-07-28 19:59:41 +00:00
|
|
|
#endif
|
2006-12-10 00:20:26 +00:00
|
|
|
#if defined(__OS2__) && !defined(__INNOTEK_LIBC__)
|
2005-07-29 06:20:28 +00:00
|
|
|
M("os2", "OS/2 Music Driver", &_os2_music_driver),
|
2005-07-28 19:59:41 +00:00
|
|
|
#endif
|
|
|
|
#ifdef WIN32_ENABLE_DIRECTMUSIC_SUPPORT
|
2005-07-29 06:20:28 +00:00
|
|
|
M("dmusic", "DirectMusic MIDI Driver", &_dmusic_midi_driver),
|
2005-07-28 19:59:41 +00:00
|
|
|
#endif
|
2007-01-21 14:19:44 +00:00
|
|
|
#if defined(WIN32) && !defined(WINCE)
|
2005-07-29 06:20:28 +00:00
|
|
|
M("win32", "Win32 MIDI Driver", &_win32_music_driver),
|
2005-07-28 19:59:41 +00:00
|
|
|
#endif
|
2005-10-07 16:48:53 +00:00
|
|
|
#if defined(__APPLE__) && !defined(DEDICATED)
|
2005-10-06 17:57:18 +00:00
|
|
|
M("qt", "QuickTime MIDI Driver", &_qtime_music_driver),
|
|
|
|
#endif
|
2005-07-28 19:59:41 +00:00
|
|
|
#ifdef UNIX
|
2007-02-16 09:50:28 +00:00
|
|
|
#if defined(LIBTIMIDITY)
|
|
|
|
M("libtimidity", "LibTimidity MIDI Driver", &_libtimidity_music_driver),
|
|
|
|
#endif /* LIBTIMIDITY */
|
|
|
|
#if !defined(__MORPHOS__) && !defined(__AMIGA__) && !defined(PSP)
|
2005-07-29 06:20:28 +00:00
|
|
|
M("extmidi", "External MIDI Driver", &_extmidi_music_driver),
|
2005-07-28 19:59:41 +00:00
|
|
|
#endif
|
|
|
|
#endif
|
2005-07-29 06:20:28 +00:00
|
|
|
M("null", "Null Music Driver", &_null_music_driver),
|
|
|
|
M(NULL, NULL, NULL)
|
2005-07-28 19:59:41 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const DriverDesc _sound_driver_descs[] = {
|
2007-01-21 14:19:44 +00:00
|
|
|
#if defined(WIN32) && !defined(WINCE)
|
2005-07-29 06:20:28 +00:00
|
|
|
M("win32", "Win32 WaveOut Driver", &_win32_sound_driver),
|
2005-07-28 19:59:41 +00:00
|
|
|
#endif
|
|
|
|
#ifdef WITH_SDL
|
2005-07-29 06:20:28 +00:00
|
|
|
M("sdl", "SDL Sound Driver", &_sdl_sound_driver),
|
2005-12-10 11:16:45 +00:00
|
|
|
#endif
|
|
|
|
#ifdef WITH_COCOA
|
|
|
|
M("cocoa", "Cocoa Sound Driver", &_cocoa_sound_driver),
|
2005-07-28 19:59:41 +00:00
|
|
|
#endif
|
2005-07-29 06:20:28 +00:00
|
|
|
M("null", "Null Sound Driver", &_null_sound_driver),
|
|
|
|
M(NULL, NULL, NULL)
|
2005-07-28 19:59:41 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const DriverDesc _video_driver_descs[] = {
|
|
|
|
#ifdef WIN32
|
2005-07-29 06:20:28 +00:00
|
|
|
M("win32", "Win32 GDI Video Driver", &_win32_video_driver),
|
2005-07-28 19:59:41 +00:00
|
|
|
#endif
|
|
|
|
#ifdef WITH_SDL
|
2005-07-29 06:20:28 +00:00
|
|
|
M("sdl", "SDL Video Driver", &_sdl_video_driver),
|
2005-12-10 11:16:45 +00:00
|
|
|
#endif
|
|
|
|
#ifdef WITH_COCOA
|
|
|
|
M("cocoa", "Cocoa Video Driver", &_cocoa_video_driver),
|
2005-07-28 19:59:41 +00:00
|
|
|
#endif
|
2005-07-29 06:20:28 +00:00
|
|
|
M("null", "Null Video Driver", &_null_video_driver),
|
2005-07-28 19:59:41 +00:00
|
|
|
#ifdef ENABLE_NETWORK
|
2005-07-29 06:20:28 +00:00
|
|
|
M("dedicated", "Dedicated Video Driver", &_dedicated_video_driver),
|
2005-07-28 19:59:41 +00:00
|
|
|
#endif
|
2005-07-29 06:20:28 +00:00
|
|
|
M(NULL, NULL, NULL)
|
2005-07-28 19:59:41 +00:00
|
|
|
};
|
2005-07-29 06:20:28 +00:00
|
|
|
#undef M
|
2005-07-28 19:59:41 +00:00
|
|
|
|
2005-07-28 09:41:09 +00:00
|
|
|
|
2006-01-28 11:08:07 +00:00
|
|
|
#define M(x, y, z) { x, y, (const HalCommonDriver **)(void *)z }
|
2005-07-28 09:41:09 +00:00
|
|
|
static const DriverClass _driver_classes[] = {
|
2005-07-29 06:20:28 +00:00
|
|
|
M(_video_driver_descs, "video", &_video_driver),
|
|
|
|
M(_sound_driver_descs, "sound", &_sound_driver),
|
|
|
|
M(_music_driver_descs, "music", &_music_driver)
|
2005-07-23 15:16:57 +00:00
|
|
|
};
|
2005-07-29 06:20:28 +00:00
|
|
|
#undef M
|
2005-07-23 15:16:57 +00:00
|
|
|
|
|
|
|
static const DriverDesc* GetDriverByName(const DriverDesc* dd, const char* name)
|
|
|
|
{
|
|
|
|
for (; dd->name != NULL; dd++) {
|
|
|
|
if (strcmp(dd->name, name) == 0) return dd;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void LoadDriver(int driver, const char *name)
|
|
|
|
{
|
|
|
|
const DriverClass *dc = &_driver_classes[driver];
|
|
|
|
const DriverDesc *dd;
|
|
|
|
const char *err;
|
|
|
|
|
2005-07-27 19:57:12 +00:00
|
|
|
if (*name == '\0') {
|
|
|
|
for (dd = dc->descs; dd->name != NULL; dd++) {
|
2005-07-29 06:20:28 +00:00
|
|
|
err = dd->drv->start(NULL);
|
2005-07-27 19:57:12 +00:00
|
|
|
if (err == NULL) break;
|
2006-12-26 17:36:18 +00:00
|
|
|
DEBUG(driver, 1, "Probing %s driver '%s' failed with error: %s",
|
2005-07-27 19:57:12 +00:00
|
|
|
dc->name, dd->name, err
|
|
|
|
);
|
|
|
|
}
|
2006-12-26 17:36:18 +00:00
|
|
|
if (dd->name == NULL) error("Couldn't find any suitable %s driver", dc->name);
|
2005-07-27 19:57:12 +00:00
|
|
|
|
2006-12-26 17:36:18 +00:00
|
|
|
DEBUG(driver, 1, "Successfully probed %s driver '%s'", dc->name, dd->name);
|
2005-07-27 19:57:12 +00:00
|
|
|
|
2005-07-29 06:20:28 +00:00
|
|
|
*dc->drv = dd->drv;
|
2005-07-23 15:16:57 +00:00
|
|
|
} else {
|
2005-07-29 06:20:28 +00:00
|
|
|
char* parm;
|
|
|
|
char buffer[256];
|
|
|
|
const char* parms[32];
|
|
|
|
|
2007-02-23 18:55:07 +00:00
|
|
|
/* Extract the driver name and put parameter list in parm */
|
2005-07-23 15:16:57 +00:00
|
|
|
ttd_strlcpy(buffer, name, sizeof(buffer));
|
|
|
|
parm = strchr(buffer, ':');
|
2005-07-29 06:20:28 +00:00
|
|
|
parms[0] = NULL;
|
|
|
|
if (parm != NULL) {
|
2005-07-23 15:16:57 +00:00
|
|
|
uint np = 0;
|
2007-02-23 18:55:07 +00:00
|
|
|
/* Tokenize the parm. */
|
2005-07-23 15:16:57 +00:00
|
|
|
do {
|
2005-07-29 06:20:28 +00:00
|
|
|
*parm++ = '\0';
|
2005-07-23 15:16:57 +00:00
|
|
|
if (np < lengthof(parms) - 1)
|
|
|
|
parms[np++] = parm;
|
2005-07-29 06:20:28 +00:00
|
|
|
while (*parm != '\0' && *parm != ',')
|
2005-07-23 15:16:57 +00:00
|
|
|
parm++;
|
|
|
|
} while (*parm == ',');
|
|
|
|
parms[np] = NULL;
|
|
|
|
}
|
|
|
|
dd = GetDriverByName(dc->descs, buffer);
|
|
|
|
if (dd == NULL)
|
|
|
|
error("No such %s driver: %s\n", dc->name, buffer);
|
2005-07-27 19:57:12 +00:00
|
|
|
|
2005-07-29 06:20:28 +00:00
|
|
|
if (*dc->drv != NULL) (*dc->drv)->stop();
|
|
|
|
*dc->drv = NULL;
|
2005-07-27 19:57:12 +00:00
|
|
|
|
2005-07-29 06:20:28 +00:00
|
|
|
err = dd->drv->start(parms);
|
2005-07-27 19:57:12 +00:00
|
|
|
if (err != NULL) {
|
|
|
|
error("Unable to load driver %s(%s). The error was: %s\n",
|
|
|
|
dd->name, dd->longname, err
|
|
|
|
);
|
|
|
|
}
|
2005-07-29 06:20:28 +00:00
|
|
|
*dc->drv = dd->drv;
|
2005-07-23 15:16:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static const char* GetDriverParam(const char* const* parm, const char* name)
|
|
|
|
{
|
2005-09-25 09:04:59 +00:00
|
|
|
size_t len;
|
2005-07-29 06:20:28 +00:00
|
|
|
|
|
|
|
if (parm == NULL) return NULL;
|
2005-07-23 15:16:57 +00:00
|
|
|
|
2005-07-29 06:20:28 +00:00
|
|
|
len = strlen(name);
|
2005-07-23 15:16:57 +00:00
|
|
|
for (; *parm != NULL; parm++) {
|
|
|
|
const char* p = *parm;
|
|
|
|
|
|
|
|
if (strncmp(p, name, len) == 0) {
|
|
|
|
if (p[len] == '=') return p + len + 1;
|
|
|
|
if (p[len] == '\0') return p + len;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool GetDriverParamBool(const char* const* parm, const char* name)
|
|
|
|
{
|
|
|
|
return GetDriverParam(parm, name) != NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int GetDriverParamInt(const char* const* parm, const char* name, int def)
|
|
|
|
{
|
|
|
|
const char* p = GetDriverParam(parm, name);
|
|
|
|
return p != NULL ? atoi(p) : def;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-11-28 20:55:16 +00:00
|
|
|
char *GetDriverList(char* p, const char *last)
|
2005-07-23 15:16:57 +00:00
|
|
|
{
|
|
|
|
const DriverClass* dc;
|
|
|
|
|
|
|
|
for (dc = _driver_classes; dc != endof(_driver_classes); dc++) {
|
|
|
|
const DriverDesc* dd;
|
|
|
|
|
2006-11-28 20:55:16 +00:00
|
|
|
p += snprintf(p, last - p, "List of %s drivers:\n", dc->name);
|
2005-07-23 15:16:57 +00:00
|
|
|
for (dd = dc->descs; dd->name != NULL; dd++) {
|
2006-11-28 20:55:16 +00:00
|
|
|
p += snprintf(p, last - p, "%10s: %s\n", dd->name, dd->longname);
|
2005-07-23 15:16:57 +00:00
|
|
|
}
|
2006-11-28 20:55:16 +00:00
|
|
|
p = strecpy(p, "\n", last);
|
2005-07-23 15:16:57 +00:00
|
|
|
}
|
2006-01-06 22:52:31 +00:00
|
|
|
|
2006-01-07 10:15:46 +00:00
|
|
|
return p;
|
2005-07-23 15:16:57 +00:00
|
|
|
}
|