Exemple #1
0
MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {

	const GameSettings *g;

	const char *gameid = ConfMan.get("gameid").c_str();
	for (g = madeSettings; g->gameid; ++g)
		if (!scumm_stricmp(g->gameid, gameid))
			_gameId = g->id;

	_rnd = new Common::RandomSource();
	syst->getEventManager()->registerRandomSource(*_rnd, "made");

	int cd_num = ConfMan.getInt("cdrom");
	if (cd_num >= 0)
		_system->openCD(cd_num);

	_pmvPlayer = new PmvPlayer(this, _mixer);
	_res = new ResourceReader();
	_screen = new Screen(this);

	if (getGameID() == GID_LGOP2 || getGameID() == GID_MANHOLE || getGameID() == GID_RODNEY) {
		_dat = new GameDatabaseV2(this);
	} else if (getGameID() == GID_RTZ) {
		_dat = new GameDatabaseV3(this);
	} else {
		error("Unknown GameID");
	}

	_script = new ScriptInterpreter(this);

	int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI);
	bool native_mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32"));
	//bool adlib = (midiDriver == MD_ADLIB);

	MidiDriver *driver = MidiDriver::createMidi(midiDriver);
	if (native_mt32)
		driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);

	_music = new MusicPlayer(driver);
	_music->setNativeMT32(native_mt32);
	//_music->setAdlib(adlib);

	// Set default sound frequency
	switch (getGameID()) {
	case GID_RODNEY:
		_soundRate = 11025;
		break;
	case GID_MANHOLE:
		_soundRate = 11025;
		break;
	case GID_LGOP2:
		_soundRate = 8000;
		break;
	case GID_RTZ:
		// Return to Zork sets it itself via a script funtion
		break;
	}

	syncSoundSettings();
}
Exemple #2
0
// MIDI messages can be found at http://www.midi.org/techspecs/midimessages.php
void MidiDriver_MT32::send(uint32 b) {
	byte command = b & 0xf0;
	byte channel = b & 0xf;

	if (command == 0xF0) {
		if (_driver) {
			_driver->send(b);
		}
		return;
	}

	if (_MIDIchannelActive[channel]) {
		// Only forward MIDI-data in case the channel is currently enabled via music-data
		if (_driver) {
			_driver->send(b);
		}
	}
}
Exemple #3
0
int MidiDriver_MT32::open() {
	assert(!_driver);

	debugC(kDebugLevelMT32Driver, "MT32: starting driver");

	// Setup midi driver
	MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_PREFER_MT32);
	MusicType musicType = MidiDriver::getMusicType(dev);

	switch (musicType) {
	case MT_MT32:
		_nativeMT32 = true;
		break;
	case MT_GM:
		if (ConfMan.getBool("native_mt32")) {
			_nativeMT32 = true;
		}
		break;
	default:
		break;
	}

	_driver = MidiDriver::createMidi(dev);
	if (!_driver)
		return 255;

	if (_nativeMT32)
		_driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);

	int ret = _driver->open();
	if (ret)
		return ret;

	if (_nativeMT32)
		_driver->sendMT32Reset();
	else
		_driver->sendGMReset();

	return 0;
}
Exemple #4
0
void MidiDriver_MT32::mt32SysEx(const byte *&dataPtr, int32 &bytesLeft) {
	byte   sysExMessage[270];
	uint16 sysExPos      = 0;
	byte   sysExByte     = 0;
	uint16 sysExChecksum = 0;

	memset(&sysExMessage, 0, sizeof(sysExMessage));

	sysExMessage[0] = 0x41; // Roland
	sysExMessage[1] = 0x10;
	sysExMessage[2] = 0x16; // Model MT32
	sysExMessage[3] = 0x12; // Command DT1

	sysExPos      = 4;
	sysExChecksum = 0;
	while (1) {
		assert(bytesLeft);

		sysExByte = *dataPtr++;
		bytesLeft--;
		if (sysExByte == 0xff)
			break; // Message done

		assert(sysExPos < sizeof(sysExMessage));
		sysExMessage[sysExPos++] = sysExByte;
		sysExChecksum -= sysExByte;
	}

	// Calculate checksum
	assert(sysExPos < sizeof(sysExMessage));
	sysExMessage[sysExPos++] = sysExChecksum & 0x7f;

	debugC(kDebugLevelMT32Driver, "MT32: uploading patch data, size %d", sysExPos);

	// Send SysEx
	_driver->sysEx(sysExMessage, sysExPos);

	// Wait the time it takes to send the SysEx data
	uint32 delay = (sysExPos + 2) * 1000 / 3125;

	// Plus an additional delay for the MT-32 rev00
	if (_nativeMT32)
		delay += 40;

	g_system->delayMillis(delay);
}
Exemple #5
0
TestExitStatus MidiTests::playMidiMusic() {
	Testsuite::clearScreen();
	Common::String info = "Testing Midi Sound output.\n"
						  "Here, We generate some Music by using the Midi Driver selected in the GUI.\n"
						  "You should expect to hear that. The initialization may take some time.\n";

	if (Testsuite::handleInteractiveInput(info, "OK", "Skip", kOptionRight)) {
		Testsuite::logPrintf("Info! Skipping test : Play Midi Music\n");
		return kTestSkipped;
	}

	MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB);
	// Create a driver instance
	MidiDriver *driver = MidiDriver::createMidi(dev);
	// Create a SMF parser
	MidiParser *smfParser = MidiParser::createParser_SMF();
	// Open the driver
	int errCode = driver->open();

	if (errCode) {
		Common::String errMsg = driver->getErrorName(errCode);
		Testsuite::writeOnScreen(errMsg, Common::Point(0, 100));
		Testsuite::logPrintf("Error! %s", errMsg.c_str());
		return kTestFailed;
	}

	Testsuite::logDetailedPrintf("Info! Midi: Succesfully opened the driver\n");

	Common::MemoryWriteStreamDynamic ws(DisposeAfterUse::YES);
	loadMusicInMemory(&ws);

	// start playing
	if (smfParser->loadMusic(ws.getData(), ws.size())) {
		smfParser->setTrack(0);
		smfParser->setMidiDriver(driver);
		smfParser->setTimerRate(driver->getBaseTempo());
		driver->setTimerCallback(smfParser, MidiParser::timerCallback);
		Testsuite::logDetailedPrintf("Info! Midi: Parser Successfully loaded Music data.\n");
		if (smfParser->isPlaying()) {
			Testsuite::writeOnScreen("Playing Midi Music, Click to end.", Common::Point(0, 100));
			Testsuite::logDetailedPrintf("Info! Midi: Playing music!\n");
		}
	}


	// Play until track ends or an exit is requested.
	waitForMusicToPlay(smfParser);

	// Done. Clean up.
	smfParser->unloadMusic();
	driver->setTimerCallback(NULL, NULL);
	driver->close();
	delete smfParser;
	delete driver;

	if (Testsuite::handleInteractiveInput("Were you able to hear the music as described?", "Yes", "No", kOptionRight)) {
		Testsuite::logDetailedPrintf("Error! Midi: Can't play Music\n");
		return kTestFailed;
	}
	return kTestPassed;
}
Exemple #6
0
Common::Error KyraEngine_v1::init() {
	// Setup mixer
	syncSoundSettings();

	if (!_flags.useDigSound) {
		if (_flags.platform == Common::kPlatformFMTowns) {
			if (_flags.gameID == GI_KYRA1)
				_sound = new SoundTowns(this, _mixer);
			else
				_sound = new SoundTownsPC98_v2(this, _mixer);
		} else if (_flags.platform == Common::kPlatformPC98) {
			if (_flags.gameID == GI_KYRA1)
				_sound = new SoundPC98(this, _mixer);
			else
				_sound = new SoundTownsPC98_v2(this, _mixer);
		} else if (_flags.platform == Common::kPlatformAmiga) {
			_sound = new SoundAmiga(this, _mixer);
		} else {
			// In Kyra 1 users who have specified a default MT-32 device in the launcher settings
			// will get MT-32 music, otherwise AdLib. In Kyra 2 and LoL users who have specified a
			// default GM device in the launcher will get GM music, otherwise AdLib. Users who want
			// MT-32 music in Kyra2 or LoL have to select this individually (since we assume that
			// most users rather have a GM device than a MT-32 device).
			// Users who want PC speaker sound always have to select this individually for all
			// Kyra games.
			MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_PCSPK | MDT_MIDI | MDT_ADLIB | ((_flags.gameID == GI_KYRA2 || _flags.gameID == GI_LOL) ? MDT_PREFER_GM : MDT_PREFER_MT32));
			if (MidiDriver::getMusicType(dev) == MT_ADLIB) {
				_sound = new SoundAdLibPC(this, _mixer);
			} else {
				Sound::kType type;
				const MusicType midiType = MidiDriver::getMusicType(dev);

				if (midiType == MT_PCSPK || midiType == MT_NULL)
					type = Sound::kPCSpkr;
				else if (midiType == MT_MT32 || ConfMan.getBool("native_mt32"))
					type = Sound::kMidiMT32;
				else
					type = Sound::kMidiGM;

				MidiDriver *driver = 0;

				if (MidiDriver::getMusicType(dev) == MT_PCSPK) {
					driver = new MidiDriver_PCSpeaker(_mixer);
				} else {
					driver = MidiDriver::createMidi(dev);
					if (type == Sound::kMidiMT32)
						driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
				}

				assert(driver);

				SoundMidiPC *soundMidiPc = new SoundMidiPC(this, _mixer, driver, type);
				_sound = soundMidiPc;
				assert(_sound);

				// Unlike some SCUMM games, it's not that the MIDI sounds are
				// missing. It's just that at least at the time of writing they
				// are decidedly inferior to the AdLib ones.
				if (ConfMan.getBool("multi_midi")) {
					SoundAdLibPC *adlib = new SoundAdLibPC(this, _mixer);
					assert(adlib);

					_sound = new MixedSoundDriver(this, _mixer, soundMidiPc, adlib);
				}
			}
		}

		assert(_sound);
	}

	if (_sound)
		_sound->updateVolumeSettings();

	_res = new Resource(this);
	assert(_res);
	_res->reset();

	if (_flags.isDemo) {
		// HACK: check whether this is the HOF demo or the LOL demo.
		// The LOL demo needs to be detected and run as KyraEngine_HoF,
		// but the static resource loader and the sequence player will
		// need correct IDs.
		if (_res->exists("scene1.cps"))
#ifdef ENABLE_LOL
			_flags.gameID = GI_LOL;
#else
			error("Lands of Lore demo is not supported in this build");
#endif // !ENABLE_LOL
	}

	_staticres = new StaticResource(this);
	assert(_staticres);
	if (!_staticres->init())
		error("_staticres->init() failed");
	if (!screen()->init())
		error("screen()->init() failed");
	_timer = new TimerManager(this, _system);
	assert(_timer);
	setupTimers();
	_emc = new EMCInterpreter(this);
	assert(_emc);

	setupOpcodeTable();
	readSettings();

	if (ConfMan.hasKey("save_slot")) {
		_gameToLoad = ConfMan.getInt("save_slot");
		if (!saveFileLoadable(_gameToLoad))
			_gameToLoad = -1;
	}

	setupKeyMap();

	// Prevent autosave on game startup
	_lastAutosave = _system->getMillis();

	return Common::kNoError;
}
Exemple #7
0
void MidiDriver_MT32::close() {
	if (_driver) {
		_driver->close();
	}
}