Ticket #8003: gameDetector.cpp

File gameDetector.cpp, 18.1 KB (added by SF/trinity78, 22 years ago)
Line 
1/* ScummVM - Scumm Interpreter
2 * Copyright (C) 2001 Ludvig Strigeus
3 * Copyright (C) 2001/2002 The ScummVM project
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 *
19 * $Header: /cvsroot/scummvm/scummvm/gameDetector.cpp,v 1.81 2002/08/04 00:26:07 fingolfin Exp $
20 *
21 */
22
23
24#include "stdafx.h"
25#include "scumm.h"
26#include "sound/mididrv.h"
27#include "sound/imuse.h"
28#include "gameDetector.h"
29#include "config-file.h"
30
31
32#define CHECK_OPTION() if ((current_option != NULL) || (*s != '\0')) goto ShowHelpAndExit
33#define HANDLE_OPTION() if ((*s == '\0') && (current_option == NULL)) goto ShowHelpAndExit; \
34 if ((*s != '\0') && (current_option != NULL)) goto ShowHelpAndExit; \
35 option = (*s == '\0' ? current_option : s); \
36 current_option = NULL
37#define HANDLE_OPT_OPTION() if ((*s != '\0') && (current_option != NULL)) goto ShowHelpAndExit; \
38 if ((*s == '\0') && (current_option == NULL)) option = NULL; \
39 else option = (*s == '\0' ? current_option : s); \
40 current_option = NULL
41
42static const char USAGE_STRING[] =
43 "ScummVM - Scumm Interpreter\n"
44 "Syntax:\n"
45 "\tscummvm [-v] [-d[<num>]] [-n] [-b<num>] [-t<num>] [-s<num>] [-p<path>] [-m<num>] [-f] game\n"
46 "Flags:\n"
47 "\t-a - specify game is amiga version\n"
48 "\t-b<num> - start in room <num>\n"
49 "\t-c<num> - use cdrom <num> for cd audio\n"
50 "\t-d[<num>] - enable debug output (debug level [1])\n"
51 "\t-e<mode> - set music engine (see readme.txt for details)\n"
52 "\t-f - fullscreen mode\n"
53 "\t-g<mode> - graphics mode (normal,2x,3x,2xsai,super2xsai,supereagle,advmame2x)\n"
54 "\t-l<file> - load config file instead of default\n"
55 "\t-m<num> - set music volume to <num> (0-100)\n"
56 "\t-n - no subtitles for speech\n"
57 "\t-p<path> - look for game in <path>\n"
58 "\t-s<num> - set sfx volume to <num> (0-255)\n"
59 "\t-t<num> - set music tempo (default- adlib: 0x1F0000, midi: 0x460000)\n"
60 "\t-v - show version info and exit\n"
61#if defined(UNIX)
62 "\t-w[<file>] - write to config file [~/.scummvmrc]\n"
63#else
64 "\t-w[<file>] - write to config file [scummvm.ini]\n"
65#endif
66 "\t-x[<num>] - save game slot to load (default: autosave)\n"
67 "\t-y - set text speed (default: 60)\n"
68;
69
70void GameDetector::updateconfig()
71{
72 const char * val;
73
74 if ((val = scummcfg->get("amiga")))
75 if (!scumm_stricmp(val, "true"))
76 _amiga = true;
77 else
78 _amiga = false;
79 if ((val = scummcfg->get("save_slot")))
80 _save_slot = atoi(val);
81
82 if ((val = scummcfg->get("cdrom")))
83 _cdrom = atoi(val);
84
85 if ((val = scummcfg->get("music_driver")))
86 if (!parseMusicDriver(val)) {
87 printf("Error in the config file: invalid music_driver.\n");
88 printf(USAGE_STRING);
89 exit(-1);
90 }
91
92 if ((val = scummcfg->get("fullscreen", "scummvm")))
93 if (!scumm_stricmp(val, "true"))
94 _fullScreen = true;
95 else
96 _fullScreen = false;
97
98 if ((val = scummcfg->get("gfx_mode")))
99 if ((_gfx_mode = parseGraphicsMode(val)) == -1) {
100 printf("Error in the config file: invalid gfx_mode.\n");
101 printf(USAGE_STRING);
102 exit(-1);
103 }
104
105 if ((val = scummcfg->get("music_volume")))
106 _music_volume = atoi(val);
107
108 if ((val = scummcfg->get("nosubtitles")))
109 if (!scumm_stricmp(val, "true"))
110 _noSubtitles = true;
111 else
112 _noSubtitles = false;
113
114 if ((val = scummcfg->get("path")))
115 _gameDataPath = strdup(val);
116
117 if ((val = scummcfg->get("sfx_volume")))
118 _sfx_volume = atoi(val);
119
120 if ((val = scummcfg->get("master_volume")))
121 _master_volume = atoi(val);
122
123 if ((val = scummcfg->get("tempo")))
124 _gameTempo = strtol(val, NULL, 0);
125
126 if ((val = scummcfg->get("talkspeed")))
127 _talkSpeed = atoi(val);
128}
129
130void GameDetector::parseCommandLine(int argc, char **argv)
131{
132#if !defined(MACOS_CARBON)
133 int i;
134 char *s;
135 char *current_option = NULL;
136 char *option = NULL;
137 _save_slot = -1;
138
139 // check for arguments
140 if (argc < 2) {
141 printf(USAGE_STRING);
142 //exit(1);
143 }
144
145 scummcfg->set_domain("game-specific");
146 /* Parse the arguments */
147 for (i = argc - 1; i >= 1; i--) {
148 s = argv[i];
149
150 if (s[0] == '-') {
151 s++;
152 switch (tolower(*s++)) {
153 case 'a':
154 CHECK_OPTION();
155 _amiga = true;
156 scummcfg->set("amiga", "true");
157 break;
158 case 'b':
159 HANDLE_OPTION();
160 _bootParam = atoi(option);
161 break;
162 case 'c':
163 HANDLE_OPTION();
164 _cdrom = atoi(option);
165 scummcfg->set("cdrom", _cdrom);
166 break;
167 case 'd':
168 _debugMode = true;
169 HANDLE_OPT_OPTION();
170 if (option != NULL)
171 _debugLevel = atoi(option);
172 debug(1,"Debugmode (level %d) on", _debugLevel);
173 break;
174 case 'e':
175 HANDLE_OPTION();
176 if (!parseMusicDriver(option))
177 goto ShowHelpAndExit;
178 scummcfg->set("music_driver", option);
179 break;
180 case 'f':
181 CHECK_OPTION();
182 _fullScreen = true;
183 scummcfg->set("fullscreen", "true", "scummvm");
184 break;
185 case 'g':
186 HANDLE_OPTION();
187 _gfx_mode = parseGraphicsMode(option);
188 if (_gfx_mode == -1)
189 goto ShowHelpAndExit;
190 scummcfg->set("gfx_mode", option, "scummvm");
191 break;
192 case 'l':
193 HANDLE_OPTION();
194 {
195 Config * newconfig = new Config(option, "scummvm");
196 scummcfg->merge_config(newconfig);
197 delete newconfig;
198 updateconfig();
199 break;
200 }
201 break;
202 case 'm':
203 HANDLE_OPTION();
204 _music_volume = atoi(option);
205 scummcfg->set("music_volume", _music_volume);
206 break;
207 case 'o': // overall music volume
208 HANDLE_OPTION();
209 _master_volume = atoi(option);
210 scummcfg->set("master_volume", _master_volume);
211 break;
212 case 'n':
213 CHECK_OPTION();
214 _noSubtitles = true;
215 scummcfg->set("nosubtitles", "true");
216 break;
217 case 'p':
218 HANDLE_OPTION();
219 _gameDataPath = option;
220 scummcfg->set("path", _gameDataPath);
221 break;
222 case 'r':
223 HANDLE_OPTION();
224 // Ignore -r for now, to ensure backward compatibility.
225 break;
226 case 's':
227 HANDLE_OPTION();
228 _sfx_volume = atoi(option);
229 scummcfg->set("sfx_volume", _sfx_volume);
230 break;
231 case 't':
232 HANDLE_OPTION();
233 _gameTempo = strtol(option, 0, 0);
234 scummcfg->set("tempo", option);
235 break;
236 case 'v':
237 CHECK_OPTION();
238 printf("ScummVM " SCUMMVM_VERSION "\nBuilt on " __DATE__ " "
239 __TIME__ "\n");
240#ifdef SCUMMVM_PLATFORM_VERSION
241 printf(" " SCUMMVM_PLATFORM_VERSION "\n");
242#endif
243 exit(1);
244 case 'w':
245 _saveconfig = true;
246 scummcfg->set_writing(true);
247 HANDLE_OPT_OPTION();
248 if (option != NULL)
249 scummcfg->change_filename(option);
250 break;
251 case 'x':
252 _save_slot = 0;
253 HANDLE_OPT_OPTION();
254 if (option != NULL) {
255 _save_slot = atoi(option);
256 scummcfg->set("save_slot", _save_slot);
257 }
258 break;
259 case 'y':
260 HANDLE_OPTION();
261 _talkSpeed = atoi(option);
262 scummcfg->set("talkspeed", _talkSpeed);
263 break;
264 default:
265 goto ShowHelpAndExit;
266 }
267 } else {
268 if (i == (argc - 1)) {
269 _exe_name = s;
270 scummcfg->set_domain(s);
271 scummcfg->rename_domain("game-specific");
272 scummcfg->rename_domain(s);
273 updateconfig();
274 } else {
275 if (current_option == NULL)
276 current_option = s;
277 else
278 goto ShowHelpAndExit;
279 }
280 }
281 }
282
283 if (_exe_name)
284 scummcfg->flush();
285
286 return;
287
288 ShowHelpAndExit:
289 printf(USAGE_STRING);
290 exit(1);
291
292#else
293 _midi_driver = MD_QTMUSIC;
294 _exe_name = *argv;
295 _gameDataPath = (char *)malloc(strlen(_exe_name) + 3);
296 sprintf(_gameDataPath, ":%s:", _exe_name);
297#endif
298
299}
300
301int GameDetector::parseGraphicsMode(const char *s) {
302 struct GraphicsModes {
303 const char *name;
304 int id;
305 };
306
307 const struct GraphicsModes gfx_modes[] = {
308 {"normal",GFX_NORMAL},
309 {"1x",GFX_NORMAL},
310 {"2x",GFX_DOUBLESIZE},
311 {"3x",GFX_TRIPLESIZE},
312 {"2xsai",GFX_2XSAI},
313 {"super2xsai",GFX_SUPER2XSAI},
314 {"supereagle",GFX_SUPEREAGLE},
315 {"advmame2x",GFX_ADVMAME2X}
316 };
317
318 const GraphicsModes *gm = gfx_modes;
319 int i;
320 for(i=0; i!=ARRAYSIZE(gfx_modes); i++,gm++) {
321 if (!scumm_stricmp(gm->name, s))
322 return gm->id;
323 }
324
325 return -1;
326}
327
328bool GameDetector::parseMusicDriver(const char *s) {
329 struct MusicDrivers {
330 const char *name;
331 int id;
332 };
333
334 const struct MusicDrivers music_drivers[] = {
335 {"auto",MD_AUTO},
336 {"null",MD_NULL},
337 {"windows",MD_WINDOWS},
338 {"seq",MD_SEQ},
339 {"qt",MD_QTMUSIC},
340 {"core",MD_COREAUDIO},
341 {"amidi",MD_AMIDI},
342 {"midiemu",MD_MIDIEMU},
343 {"alsa", MD_ALSA},
344 {"adlib",-1},
345 };
346
347 const MusicDrivers *md = music_drivers;
348 int i;
349
350 _use_adlib = false;
351
352 for(i=0; i!=ARRAYSIZE(music_drivers); i++,md++) {
353 if (!scumm_stricmp(md->name, s)) {
354 if (md->id == -1) {
355 _use_adlib = true;
356 }
357 _midi_driver = md->id;
358 return true;
359 }
360 }
361
362 return false;
363}
364
365
366struct VersionSettings {
367 const char *filename;
368 const char *gamename;
369 byte id, major, middle, minor;
370 uint32 features;
371};
372
373/*
374 This is a list of all known SCUMM games. Commented games are not
375 supported at this time */
376
377static const VersionSettings version_settings[] = {
378 /* Scumm Version 1 */
379// {"maniac", "Maniac Mansion (C64)", GID_MANIAC64, 1, 0, 0,},
380// {"zak", "Zak McKracken and the Alien Mindbenders (C64)", GID_ZAK64, 1, 0, 0,},
381
382 /* Scumm Version 2 */
383// {"maniac", "Maniac Mansion", GID_MANIAC, 2, 0, 0,},
384// {"zak", "Zak McKracken and the Alien Mindbenders", GID_ZAK, 2, 0, 0,},
385// {"indy3", "Indiana Jones and the Last Crusade", GID_INDY3, 2, 0, 0,},
386
387 /* Scumm Version 3 */
388 {"indy3", "Indiana Jones and the Last Crusade (256)", GID_INDY3_256, 3, 0,
389 22,
390 GF_SMALL_HEADER | GF_USE_KEY | GF_SMALL_NAMES | GF_OLD256 |
391 GF_NO_SCALLING},
392 {"zak256", "Zak McKracken and the Alien Mindbenders (256)", GID_ZAK256, 3,
393 0, 0,
394 GF_SMALL_HEADER | GF_USE_KEY | GF_SMALL_NAMES | GF_OLD256 | GF_AUDIOTRACKS
395 | GF_NO_SCALLING},
396 {"loom", "Loom", GID_LOOM, 3, 5, 40,
397 GF_SMALL_HEADER | GF_USE_KEY | GF_SMALL_NAMES | GF_OLD_BUNDLE | GF_16COLOR
398 | GF_NO_SCALLING},
399
400 /* Scumm Version 4 */
401 {"monkeyEGA", "Monkey Island 1 (EGA)", GID_MONKEY_EGA, 4, 0, 67, GF_SMALL_HEADER | GF_USE_KEY | GF_16COLOR}, // EGA version
402
403 /* Scumm version 5 */
404 {"monkeyVGA", "Monkey Island 1 (256 color Floppy version)", GID_MONKEY_VGA, 5, 0, 16,
405 GF_SMALL_HEADER | GF_USE_KEY | GF_AUDIOTRACKS | GF_ADLIB_DEFAULT},
406 {"loomcd", "Loom (256 color CD version)", GID_LOOM256, 5, 1, 42,
407 GF_SMALL_HEADER | GF_USE_KEY | GF_AUDIOTRACKS | GF_ADLIB_DEFAULT},
408 {"monkey", "Monkey Island 1", GID_MONKEY, 5, 2, 2,
409 GF_USE_KEY | GF_AUDIOTRACKS | GF_ADLIB_DEFAULT},
410 {"monkey1", "Monkey Island 1 (alt)", GID_MONKEY, 5, 2, 2,
411 GF_USE_KEY | GF_AUDIOTRACKS | GF_ADLIB_DEFAULT},
412 {"monkey2", "Monkey Island 2: LeChuck's revenge", GID_MONKEY2, 5, 2, 2,
413 GF_USE_KEY | GF_ADLIB_DEFAULT},
414 {"atlantis", "Indiana Jones and the Fate of Atlantis", GID_INDY4, 5, 5, 0,
415 GF_USE_KEY | GF_ADLIB_DEFAULT},
416 {"playfate", "Indiana Jones and the Fate of Atlantis (Demo)", GID_INDY4,
417 5, 5, 0, GF_USE_KEY | GF_ADLIB_DEFAULT},
418
419 /* Scumm Version 6 */
420 {"tentacle", "Day Of The Tentacle", GID_TENTACLE, 6, 4, 2,
421 GF_NEW_OPCODES | GF_AFTER_V6 | GF_USE_KEY | GF_ADLIB_DEFAULT},
422 {"dottdemo", "Day Of The Tentacle (Demo)", GID_TENTACLE, 6, 3, 2,
423 GF_NEW_OPCODES | GF_AFTER_V6 | GF_USE_KEY | GF_ADLIB_DEFAULT},
424 {"samnmax", "Sam & Max", GID_SAMNMAX, 6, 4, 2,
425 GF_NEW_OPCODES | GF_AFTER_V6 | GF_USE_KEY | GF_DRAWOBJ_OTHER_ORDER},
426 {"snmdemo", "Sam & Max (Demo)", GID_SAMNMAX, 6, 3, 0,
427 GF_NEW_OPCODES | GF_AFTER_V6 | GF_USE_KEY | GF_DRAWOBJ_OTHER_ORDER | GF_ADLIB_DEFAULT},
428
429 {"puttdemo", "Putt Putt joins the parade (demo)", GID_SAMNMAX, 6, 3, 0,
430 GF_NEW_OPCODES | GF_AFTER_V6 | GF_USE_KEY | GF_ADLIB_DEFAULT | GF_HUMONGOUS},
431 {"moondemo", "Putt Putt goes to the moon (demo)", GID_SAMNMAX, 6, 3, 0,
432 GF_NEW_OPCODES | GF_AFTER_V6 | GF_USE_KEY | GF_ADLIB_DEFAULT | GF_HUMONGOUS},
433
434 {"test", "Test demo game", GID_SAMNMAX, 6, 6, 6, GF_NEW_OPCODES | GF_AFTER_V6},
435
436 /* Scumm Version 7 */
437 {"ft", "Full Throttle", GID_FT, 7, 3, 0,
438 GF_NEW_OPCODES | GF_AFTER_V6 | GF_AFTER_V7},
439 {"dig", "The Dig", GID_DIG, 7, 5, 0,
440 GF_NEW_OPCODES | GF_AFTER_V6 | GF_AFTER_V7},
441
442 /* Simon the Sorcerer 1 & 2 (not SCUMM games) */
443 {"simon1dos", "Simon the Sorcerer 1 for DOS", GID_SIMON_FIRST+0, 99, 99, 99, 0},
444 {"simon2dos", "Simon the Sorcerer 2 for Dos", GID_SIMON_FIRST+1, 99, 99, 99, 0},
445 {"simon1win", "Simon the Sorcerer 1 for Windows", GID_SIMON_FIRST+2, 99, 99, 99, 0},
446 {"simon2win", "Simon the Sorcerer 2 for Windows", GID_SIMON_FIRST+3, 99, 99, 99, 0},
447
448 /* Scumm Version 8 */
449 {"comi", "The Curse of Monkey Island", GID_CMI, 8, 1, 0, GF_NEW_OPCODES|GF_AFTER_V6|GF_AFTER_V7|GF_AFTER_V8},
450 {NULL, NULL}
451};
452
453bool GameDetector::detectGame()
454{
455 const VersionSettings *gnl = version_settings;
456
457 _gameId = 0;
458 _gameText = NULL;
459 do {
460 if (!scumm_stricmp(_exe_name, gnl->filename)) {
461 _gameId = gnl->id;
462 _scummVersion = gnl->major;
463
464 _features = gnl->features;
465 _gameText = gnl->gamename;
466 debug(1, "Detected game '%s', version %d.%d.%d",
467 gnl->gamename, gnl->major, gnl->middle, gnl->minor);
468 return true;
469 }
470 } while ((++gnl)->filename);
471
472 debug(1, "Failed game detection");
473
474 return true;
475}
476
477char *GameDetector::getGameName()
478{
479 if (_gameText == NULL) {
480 char buf[256];
481 sprintf(buf, "Unknown game: \"%s\"", _exe_name);
482 return strdup(buf);
483 }
484 return strdup(_gameText);
485}
486
487int GameDetector::detectMain(int argc, char **argv)
488{
489 _debugMode = 0; // off by default...
490
491 _noSubtitles = 0; // use by default - should this depend on soundtrack?
492
493 _talkSpeed = 60;
494
495#ifndef _WIN32_WCE
496 _gfx_mode = GFX_DOUBLESIZE;
497#else
498 _gfx_mode = GFX_NORMAL;
499#endif
500 _sfx_volume = kDefaultSFXVolume;
501 _music_volume = kDefaultMusicVolume;
502 _master_volume = kDefaultMasterVolume;
503
504#if defined(USE_NULL_DRIVER)
505 _gfx_driver = GD_NULL;
506#elif defined(__DC__)
507 _gfx_driver = GD_DC;
508#elif defined(X11_BACKEND)
509 _gfx_driver = GD_X;
510#elif defined(__MORPHOS__)
511 _gfx_driver = GD_MORPHOS;
512#elif defined(_WIN32_WCE)
513 _gfx_driver = GD_WINCE;
514#elif defined(MACOS_CARBON)
515 _gfx_driver = GD_MAC;
516#else
517 /* SDL is the default driver for now */
518 _gfx_driver = GD_SDL;
519#endif
520
521 _gameDataPath = NULL;
522 _gameTempo = 0;
523 _soundCardType = 3;
524
525
526
527 _midi_driver = MD_AUTO;
528
529#if defined(__DC__)
530 extern int dc_setup(GameDetector &detector);
531 dc_setup(*this);
532#elif defined(MACOS_CARBON)
533 extern char* SelectGame();
534 char *game_name = SelectGame();
535 printf(game_name);
536#else
537 _saveconfig = false;
538 updateconfig();
539 parseCommandLine(argc, argv);
540#endif
541
542 if (_exe_name == NULL) {
543 //launcherLoop();
544 //setWindowName(this);
545 warning("No game was specified...");
546 return (-1);
547 }
548
549
550 if (!detectGame()) {
551 warning("Game detection failed. Using default settings");
552 _features = GF_DEFAULT;
553 _gameText = "Please choose a game";
554 }
555
556 /* Use the adlib sound driver if auto mode is selected,
557 * and the game is one of those that want adlib as
558 * default */
559 if (_midi_driver == MD_AUTO && _features&GF_ADLIB_DEFAULT) {
560 _use_adlib = true;
561 }
562
563 if (!_gameDataPath) {
564 warning("No path was provided. Assuming the data files are in the current directory");
565 _gameDataPath = strdup("");
566 } else if (_gameDataPath[strlen(_gameDataPath)-1] != '/'
567#ifdef __MORPHOS__
568 && _gameDataPath[strlen(_gameDataPath)-1] != ':'
569#endif
570 && _gameDataPath[strlen(_gameDataPath)-1] != '\\') {
571 char slashless[1024]; /* Append slash to path */
572 strcpy(slashless, _gameDataPath);
573 _gameDataPath = (char *)malloc((strlen(slashless) + 1) * sizeof(char));
574 sprintf(_gameDataPath, "%s/", slashless);
575 }
576
577 if (_amiga)
578 _features = _features | GF_AMIGA;
579
580 return (0);
581}
582
583OSystem *GameDetector::createSystem() {
584 /* auto is to use SDL */
585 switch(_gfx_driver) {
586#if defined(UNIX_X11)
587 case GD_X:
588 return OSystem_X11_create();
589#elif defined(__DC__)
590 case GD_DC:
591 return OSystem_Dreamcast_create();
592#elif defined(_WIN32_WCE)
593 case GD_WINCE:
594 return OSystem_WINCE3_create();
595#elif defined(__MORPHOS__)
596 case GD_MORPHOS:
597 return OSystem_MorphOS_create(_gameId, _gfx_mode, _fullScreen);
598#elif defined(MACOS_CARBON)
599 case GD_MAC:
600 return OSystem_MAC_create(_gfx_mode, _fullScreen);
601#elif defined(USE_NULL_DRIVER)
602 case GD_NULL:
603 return OSystem_NULL_create();
604#else
605 case GD_SDL:
606 return OSystem_SDL_create(_gfx_mode, _fullScreen);
607#endif
608 }
609
610 error("Invalid graphics driver");
611 return NULL;
612}
613
614MidiDriver *GameDetector::createMidi() {
615 int drv = _midi_driver;
616
617#if defined (_WIN32_WCE)
618 /* Always use MIDI emulation on CE devices */
619 if (drv == MD_AUTO) drv = MD_MIDIEMU;
620#endif
621
622#if defined (WIN32) && !defined(_WIN32_WCE)
623 /* MD_WINDOWS is default MidiDriver on windows targets */
624 if (drv == MD_AUTO) drv = MD_WINDOWS;
625#elif defined(__APPLE__) || defined(macintosh)
626 /* MD_QTMUSIC is default MidiDriver on MacOS targets */
627 if (drv == MD_AUTO) drv = MD_QTMUSIC;
628#elif defined(UNIX) || defined(UNIX_X11)
629 /* MD_MIDIEMU is default MidiDriver on UNIX targets. */
630 /* FIXME: Attempt to detect if sequencer is available,
631 and use it in preference. */
632 if (drv == MD_AUTO) drv = MD_MIDIEMU;
633#endif
634
635 switch(drv) {
636 case MD_AUTO:
637 case MD_NULL: return MidiDriver_NULL_create();
638 case MD_MIDIEMU: return MidiDriver_MIDIEMU_create();
639#if defined(WIN32) && !defined(_WIN32_WCE)
640 case MD_WINDOWS: return MidiDriver_WIN_create();
641#endif
642#if defined(__MORPHOS__)
643 case MD_AMIDI: return MidiDriver_AMIDI_create();
644#endif
645#if defined(UNIX) && !defined(__BEOS__)
646 case MD_SEQ: return MidiDriver_SEQ_create();
647#endif
648#if defined(__APPLE__) || defined(macintosh)
649 case MD_QTMUSIC: return MidiDriver_QT_create();
650#endif
651#if defined(__APPLE__)
652 case MD_COREAUDIO: return MidiDriver_CORE_create();
653#endif
654#if defined(UNIX) && defined(USE_ALSA)
655 case MD_ALSA: return MidiDriver_ALSA_create();
656#endif
657 }
658
659 error("Invalid midi driver selected");
660 return NULL;
661}