src/driver.cpp
changeset 5584 1111b4d36e35
parent 5475 2e6990a8c7c4
child 5756 1caf4ff6fadc
equal deleted inserted replaced
5583:136d8764c7e6 5584:1111b4d36e35
       
     1 /* $Id$ */
       
     2 
       
     3 #include "stdafx.h"
       
     4 #include "openttd.h"
       
     5 #include "debug.h"
       
     6 #include "driver.h"
       
     7 #include "functions.h"
       
     8 #include "hal.h"
       
     9 #include "string.h"
       
    10 
       
    11 #include "music/bemidi.h"
       
    12 #include "music/dmusic.h"
       
    13 #include "music/extmidi.h"
       
    14 #include "music/null_m.h"
       
    15 #include "music/os2_m.h"
       
    16 #include "music/win32_m.h"
       
    17 #include "music/qtmidi.h"
       
    18 
       
    19 #include "sound/null_s.h"
       
    20 #include "sound/sdl_s.h"
       
    21 #include "sound/cocoa_s.h"
       
    22 #include "sound/win32_s.h"
       
    23 
       
    24 #include "video/dedicated_v.h"
       
    25 #include "video/null_v.h"
       
    26 #include "video/sdl_v.h"
       
    27 #include "video/cocoa_v.h"
       
    28 #include "video/win32_v.h"
       
    29 
       
    30 typedef struct DriverDesc {
       
    31 	const char* name;
       
    32 	const char* longname;
       
    33 	const HalCommonDriver* drv;
       
    34 } DriverDesc;
       
    35 
       
    36 typedef struct DriverClass {
       
    37 	const DriverDesc *descs;
       
    38 	const char *name;
       
    39 	const HalCommonDriver** drv;
       
    40 } DriverClass;
       
    41 
       
    42 
       
    43 #define M(x, y, z) { x, y, (const HalCommonDriver *)(void *)z }
       
    44 static const DriverDesc _music_driver_descs[] = {
       
    45 #ifdef __BEOS__
       
    46 	M("bemidi",  "BeOS MIDI Driver",        &_bemidi_music_driver),
       
    47 #endif
       
    48 #if defined(__OS2__) && !defined(__INNOTEK_LIBC__)
       
    49 	M("os2",     "OS/2 Music Driver",       &_os2_music_driver),
       
    50 #endif
       
    51 #ifdef WIN32_ENABLE_DIRECTMUSIC_SUPPORT
       
    52 	M("dmusic",  "DirectMusic MIDI Driver", &_dmusic_midi_driver),
       
    53 #endif
       
    54 #ifdef WIN32
       
    55 	M("win32",   "Win32 MIDI Driver",       &_win32_music_driver),
       
    56 #endif
       
    57 #if defined(__APPLE__) && !defined(DEDICATED)
       
    58 	M("qt",      "QuickTime MIDI Driver",   &_qtime_music_driver),
       
    59 #endif
       
    60 #ifdef UNIX
       
    61 #if !defined(__MORPHOS__) && !defined(__AMIGA__)
       
    62 	M("extmidi", "External MIDI Driver",    &_extmidi_music_driver),
       
    63 #endif
       
    64 #endif
       
    65 	M("null",    "Null Music Driver",       &_null_music_driver),
       
    66 	M(NULL, NULL, NULL)
       
    67 };
       
    68 
       
    69 static const DriverDesc _sound_driver_descs[] = {
       
    70 #ifdef WIN32
       
    71 	M("win32", "Win32 WaveOut Driver", &_win32_sound_driver),
       
    72 #endif
       
    73 #ifdef WITH_SDL
       
    74 	M("sdl",   "SDL Sound Driver",     &_sdl_sound_driver),
       
    75 #endif
       
    76 #ifdef WITH_COCOA
       
    77 	M("cocoa", "Cocoa Sound Driver",   &_cocoa_sound_driver),
       
    78 #endif
       
    79 	M("null",  "Null Sound Driver",    &_null_sound_driver),
       
    80 	M(NULL, NULL, NULL)
       
    81 };
       
    82 
       
    83 static const DriverDesc _video_driver_descs[] = {
       
    84 #ifdef WIN32
       
    85 	M("win32",      "Win32 GDI Video Driver", &_win32_video_driver),
       
    86 #endif
       
    87 #ifdef WITH_SDL
       
    88 	M("sdl",        "SDL Video Driver",       &_sdl_video_driver),
       
    89 #endif
       
    90 #ifdef WITH_COCOA
       
    91 	M("cocoa",      "Cocoa Video Driver",       &_cocoa_video_driver),
       
    92 #endif
       
    93 	M("null",       "Null Video Driver",      &_null_video_driver),
       
    94 #ifdef ENABLE_NETWORK
       
    95 	M("dedicated",  "Dedicated Video Driver", &_dedicated_video_driver),
       
    96 #endif
       
    97 	M(NULL, NULL, NULL)
       
    98 };
       
    99 #undef M
       
   100 
       
   101 
       
   102 #define M(x, y, z) { x, y, (const HalCommonDriver **)(void *)z }
       
   103 static const DriverClass _driver_classes[] = {
       
   104 	M(_video_driver_descs, "video", &_video_driver),
       
   105 	M(_sound_driver_descs, "sound", &_sound_driver),
       
   106 	M(_music_driver_descs, "music", &_music_driver)
       
   107 };
       
   108 #undef M
       
   109 
       
   110 static const DriverDesc* GetDriverByName(const DriverDesc* dd, const char* name)
       
   111 {
       
   112 	for (; dd->name != NULL; dd++) {
       
   113 		if (strcmp(dd->name, name) == 0) return dd;
       
   114 	}
       
   115 	return NULL;
       
   116 }
       
   117 
       
   118 void LoadDriver(int driver, const char *name)
       
   119 {
       
   120 	const DriverClass *dc = &_driver_classes[driver];
       
   121 	const DriverDesc *dd;
       
   122 	const char *err;
       
   123 
       
   124 	if (*name == '\0') {
       
   125 		for (dd = dc->descs; dd->name != NULL; dd++) {
       
   126 			err = dd->drv->start(NULL);
       
   127 			if (err == NULL) break;
       
   128 			DEBUG(driver, 1, "Probing %s driver '%s' failed with error: %s",
       
   129 				dc->name, dd->name, err
       
   130 			);
       
   131 		}
       
   132 		if (dd->name == NULL) error("Couldn't find any suitable %s driver", dc->name);
       
   133 
       
   134 		DEBUG(driver, 1, "Successfully probed %s driver '%s'", dc->name, dd->name);
       
   135 
       
   136 		*dc->drv = dd->drv;
       
   137 	} else {
       
   138 		char* parm;
       
   139 		char buffer[256];
       
   140 		const char* parms[32];
       
   141 
       
   142 		// Extract the driver name and put parameter list in parm
       
   143 		ttd_strlcpy(buffer, name, sizeof(buffer));
       
   144 		parm = strchr(buffer, ':');
       
   145 		parms[0] = NULL;
       
   146 		if (parm != NULL) {
       
   147 			uint np = 0;
       
   148 			// Tokenize the parm.
       
   149 			do {
       
   150 				*parm++ = '\0';
       
   151 				if (np < lengthof(parms) - 1)
       
   152 					parms[np++] = parm;
       
   153 				while (*parm != '\0' && *parm != ',')
       
   154 					parm++;
       
   155 			} while (*parm == ',');
       
   156 			parms[np] = NULL;
       
   157 		}
       
   158 		dd = GetDriverByName(dc->descs, buffer);
       
   159 		if (dd == NULL)
       
   160 			error("No such %s driver: %s\n", dc->name, buffer);
       
   161 
       
   162 		if (*dc->drv != NULL) (*dc->drv)->stop();
       
   163 		*dc->drv = NULL;
       
   164 
       
   165 		err = dd->drv->start(parms);
       
   166 		if (err != NULL) {
       
   167 			error("Unable to load driver %s(%s). The error was: %s\n",
       
   168 				dd->name, dd->longname, err
       
   169 			);
       
   170 		}
       
   171 		*dc->drv = dd->drv;
       
   172 	}
       
   173 }
       
   174 
       
   175 
       
   176 static const char* GetDriverParam(const char* const* parm, const char* name)
       
   177 {
       
   178 	size_t len;
       
   179 
       
   180 	if (parm == NULL) return NULL;
       
   181 
       
   182 	len = strlen(name);
       
   183 	for (; *parm != NULL; parm++) {
       
   184 		const char* p = *parm;
       
   185 
       
   186 		if (strncmp(p, name, len) == 0) {
       
   187 			if (p[len] == '=')  return p + len + 1;
       
   188 			if (p[len] == '\0') return p + len;
       
   189 		}
       
   190 	}
       
   191 	return NULL;
       
   192 }
       
   193 
       
   194 bool GetDriverParamBool(const char* const* parm, const char* name)
       
   195 {
       
   196 	return GetDriverParam(parm, name) != NULL;
       
   197 }
       
   198 
       
   199 int GetDriverParamInt(const char* const* parm, const char* name, int def)
       
   200 {
       
   201 	const char* p = GetDriverParam(parm, name);
       
   202 	return p != NULL ? atoi(p) : def;
       
   203 }
       
   204 
       
   205 
       
   206 char *GetDriverList(char* p, const char *last)
       
   207 {
       
   208 	const DriverClass* dc;
       
   209 
       
   210 	for (dc = _driver_classes; dc != endof(_driver_classes); dc++) {
       
   211 		const DriverDesc* dd;
       
   212 
       
   213 		p += snprintf(p, last - p, "List of %s drivers:\n", dc->name);
       
   214 		for (dd = dc->descs; dd->name != NULL; dd++) {
       
   215 			p += snprintf(p, last - p, "%10s: %s\n", dd->name, dd->longname);
       
   216 		}
       
   217 		p = strecpy(p, "\n", last);
       
   218 	}
       
   219 
       
   220 	return p;
       
   221 }