Beispiel #1
0
uint SoundChannel::play(uint soundNum, uint repeats, uint notify) {
	stop();
	if (repeats == 0)
		return 1;

	// Find a sound of the given name
	Audio::AudioStream *stream;
	Common::File f;
	Common::String nameSnd = Common::String::format("sound%u.snd", soundNum);
	Common::String nameWav = Common::String::format("sound%u.wav", soundNum);
	Common::String nameAiff = Common::String::format("sound%u.aiff", soundNum);
#ifdef USE_MAD
	Common::String nameMp3 = Common::String::format("sound%u.mp3", soundNum);
#endif

	if (f.exists(nameSnd) && f.open(nameSnd)) {
		if (f.readUint16BE() != (f.size() - 2))
			error("Invalid sound filesize");
		repeats = f.readByte();
		f.skip(1);
		uint freq = f.readUint16BE();
		f.skip(2);
		uint size = f.readUint16BE();

		Common::SeekableReadStream *s = f.readStream(size);
		stream = Audio::makeRawStream(s, freq, Audio::FLAG_UNSIGNED);

#ifdef USE_MAD
	} else if (f.exists(nameMp3) && f.open(nameMp3)) {
		Common::SeekableReadStream *s = f.readStream(f.size());
		stream = Audio::makeMP3Stream(s, DisposeAfterUse::YES);
#endif
	} else if (f.exists(nameWav) && f.open(nameWav)) {
		Common::SeekableReadStream *s = f.readStream(f.size());
		stream = Audio::makeWAVStream(s, DisposeAfterUse::YES);

	} else if (f.exists(nameAiff) && f.open(nameAiff)) {
		Common::SeekableReadStream *s = f.readStream(f.size());
		stream = Audio::makeAIFFStream(s, DisposeAfterUse::YES);

	} else {
		warning("Could not find sound %u", soundNum);
		return 1;
	}

	_soundNum = soundNum;
	_notify = notify;

	// Set up a repeat if multiple repeats are specified
	if (repeats > 1) {
		Audio::RewindableAudioStream *rwStream = dynamic_cast<Audio::RewindableAudioStream *>(stream);
		assert(rwStream);
		stream = new Audio::LoopingAudioStream(rwStream, repeats, DisposeAfterUse::YES);
	}

	// Start playing the audio
	g_vm->_mixer->playStream(Audio::Mixer::kPlainSoundType, &_handle, stream);
	return 0;
}
Beispiel #2
0
void Music::loadSoundEffect(const Common::String filename, bool loop, bool waitTillFinished) {
	stopSoundEffect();

	Common::File *file = _vm->_resource->openDataFile(filename, MKTAG('D', 'I', 'F', 'F'));
	if (!file)
		return;

	_vm->_anim->_doBlack = false;

	uint32 magicBytes = file->readUint32LE();
	if (magicBytes != 1219009121) {
		warning("readSound: Bad signature, skipping");
		return;
	}
	uint32 soundTag = file->readUint32LE();
	uint32 soundSize = file->readUint32LE();

	if (soundTag != 0)
		return;

	file->skip(soundSize);	// skip the header

	while (soundTag != 65535) {
		_vm->updateEvents();
		soundTag = file->readUint32LE();
		soundSize = file->readUint32LE() - 8;

		if ((soundTag == 30) || (soundTag == 31)) {
			if (waitTillFinished) {
				while (isSoundEffectActive()) {
					_vm->updateEvents();
					_vm->waitTOF();
				}
			}

			file->skip(4);

			uint16 sampleRate = file->readUint16LE();
			file->skip(2);
			playSoundEffect(sampleRate, soundSize, loop, file);
		} else if (soundTag == 65535) {
			if (waitTillFinished) {
				while (isSoundEffectActive()) {
					_vm->updateEvents();
					_vm->waitTOF();
				}
			}
		} else
			file->skip(soundSize);
	}
}
Beispiel #3
0
/**
 * Loads the contents of the mort.dat data file
 */
Common::ErrorCode MortevielleEngine::loadMortDat() {
	Common::File f;

	// Open the mort.dat file
	if (!f.open(MORT_DAT)) {
		Common::String msg = Common::String::format(_("Unable to locate the '%s' engine data file."), MORT_DAT);
		GUIErrorMessage(msg);
		return Common::kReadingFailed;
	}

	// Validate the data file header
	char fileId[4];
	f.read(fileId, 4);
	if (strncmp(fileId, "MORT", 4) != 0) {
		Common::String msg = Common::String::format(_("The '%s' engine data file is corrupt."), MORT_DAT);
		GUIErrorMessage(msg);
		return Common::kReadingFailed;
	}

	// Check the version
	int majVer = f.readByte();
	int minVer = f.readByte();

	if (majVer < MORT_DAT_REQUIRED_VERSION) {
		Common::String msg = Common::String::format(
			_("Incorrect version of the '%s' engine data file found. Expected %d.%d but got %d.%d."),
			MORT_DAT, MORT_DAT_REQUIRED_VERSION, 0, majVer, minVer);
		GUIErrorMessage(msg);
		return Common::kReadingFailed;
	}

	// Loop to load resources from the data file
	while (f.pos() < f.size()) {
		// Get the Id and size of the next resource
		char dataType[4];
		int dataSize;
		f.read(dataType, 4);
		dataSize = f.readUint16LE();

		if (!strncmp(dataType, "FONT", 4)) {
			// Font resource
			_screenSurface->readFontData(f, dataSize);
		} else if (!strncmp(dataType, "SSTR", 4)) {
			readStaticStrings(f, dataSize, kStaticStrings);
		} else if ((!strncmp(dataType, "GSTR", 4)) && (!_txxFileFl)) {
			readStaticStrings(f, dataSize, kGameStrings);
		} else if (!strncmp(dataType, "VERB", 4)) {
			_menu->readVerbNums(f, dataSize);
		} else {
			// Unknown section
			f.skip(dataSize);
		}
	}

	// Close the file
	f.close();

	assert(_engineStrings.size() > 0);
	return Common::kNoError;
}
void writeSoundNames(const char *sourceFilename, Common::File &target, uint offset) {
	Common::File source;
	if (!source.open(sourceFilename)) {
		error("Unable to open '%s'", sourceFilename);
	}

	source.seek(offset);

	// Count the sounds
	uint count = 0;
	while (1) {
		uint32 id = source.readUint32LE();

		if (!id)
			break;

		source.skip(32);
		count++;
	}

	target.writeLong(count);

	source.seek(offset);
	for (uint i = 0; i < count; i++) {
		uint32 id = source.readUint32LE();
		char name[32];
		source.read(name, sizeof(name));

		target.writeLong(id);
		target.write(name, sizeof(name));
	}

	source.close();
}
Beispiel #5
0
/**
 * Loads the contents of the mort.dat data file
 */
Common::ErrorCode MortevielleEngine::loadMortDat() {
	Common::File f;

	// Open the mort.dat file
	if (!f.open(MORT_DAT)) {
		GUIErrorMessage("Could not locate 'mort.dat'.");
		return Common::kReadingFailed;
	}

	// Validate the data file header
	char fileId[4];
	f.read(fileId, 4);
	if (strncmp(fileId, "MORT", 4) != 0) {
		GUIErrorMessage("The located mort.dat data file is invalid");
		return Common::kReadingFailed;
	}

	// Check the version
	if (f.readByte() < MORT_DAT_REQUIRED_VERSION) {
		GUIErrorMessage("The located mort.dat data file is too old, please download an updated version on scummvm.org");
		return Common::kReadingFailed;
	}
	f.readByte();		// Minor version

	// Loop to load resources from the data file
	while (f.pos() < f.size()) {
		// Get the Id and size of the next resource
		char dataType[4];
		int dataSize;
		f.read(dataType, 4);
		dataSize = f.readUint16LE();

		if (!strncmp(dataType, "FONT", 4)) {
			// Font resource
			_screenSurface.readFontData(f, dataSize);
		} else if (!strncmp(dataType, "SSTR", 4)) {
			readStaticStrings(f, dataSize, kStaticStrings);
		} else if ((!strncmp(dataType, "GSTR", 4)) && (!_txxFileFl)) {
			readStaticStrings(f, dataSize, kGameStrings);
		} else if (!strncmp(dataType, "VERB", 4)) {
			_menu.readVerbNums(f, dataSize);
		} else {
			// Unknown section
			f.skip(dataSize);
		}
	}

	// Close the file
	f.close();

	assert(_engineStrings.size() > 0);
	return Common::kNoError;
}
Beispiel #6
0
/**
 * Read in a static strings block, and if the language matches, load up the static strings
 */
void MortevielleEngine::readStaticStrings(Common::File &f, int dataSize, DataType dataType) {
	// Figure out what language Id is needed
	byte desiredLanguageId;
	switch(getLanguage()) {
	case Common::EN_ANY:
		desiredLanguageId = MORTDAT_LANG_ENGLISH;
		break;
	case Common::FR_FRA:
		desiredLanguageId = MORTDAT_LANG_FRENCH;
		break;
	case Common::DE_DEU:
		desiredLanguageId = MORTDAT_LANG_GERMAN;
		break;
	default:
		warning("Language not supported, switching to English");
		desiredLanguageId = MORTDAT_LANG_ENGLISH;
		break;
	}

	// Read in the language
	byte languageId = f.readByte();
	--dataSize;

	// If the language isn't correct, then skip the entire block
	if (languageId != desiredLanguageId) {
		f.skip(dataSize);
		return;
	}

	// Load in each of the strings
	while (dataSize > 0) {
		Common::String s;
		char ch;
		while ((ch = (char)f.readByte()) != '\0')
			s += ch;

		if (dataType == kStaticStrings)
			_engineStrings.push_back(s);
		else if (dataType == kGameStrings)
			_gameStrings.push_back(s);

		dataSize -= s.size() + 1;
	}
	assert(dataSize == 0);
}
Beispiel #7
0
Font::Font(Common::String filename) {
	const uint32 headerFont = MKTAG('T', 'F', 'F', '\0');
	Common::File stream;

	stream.open(filename);

	uint32 header = stream.readUint32BE();

	if (header != headerFont)
		error("Invalid resource - %s", filename.c_str());

	stream.skip(4);	// total memory
	_count = stream.readUint16LE();
	_first = stream.readUint16LE();
	_last = stream.readUint16LE();
	_width = stream.readUint16LE();
	_height = stream.readUint16LE();

	_fontSurface.create(_width * _count, _height, ::Graphics::PixelFormat::createFormatCLUT8());

	byte cur;
	int bitIndex = 7;
	byte *p;

	cur = stream.readByte();

	for (uint n = 0; n < _count; n++) {
		for (uint y = 0; y < _height; y++) {
			p = (byte *)_fontSurface.getBasePtr(n * _width, y);

			for (uint x = n * _width; x < n * _width + _width; x++) {
				*p++ = (cur & (1 << bitIndex)) ? 0 : 0xFF;

				bitIndex--;
				if (bitIndex < 0) {
					bitIndex = 7;
					cur = stream.readByte();
				}
			}
		}
	}
}
Beispiel #8
0
TextFont *Resource::getFont(const Common::String fileName) {
	// TODO: Add support for the font format of the Amiga version
	Common::File *dataFile = openDataFile(fileName, MKTAG('V', 'G', 'A', 'F'));

	uint32 headerSize = 4 + 2 + 256 * 3 + 4;
	uint32 fileSize = dataFile->size();
	if (fileSize <= headerSize)
		return nullptr;

	TextFont *textfont = new TextFont();
	textfont->_dataLength = fileSize - headerSize;
	textfont->_height = dataFile->readUint16LE();
	dataFile->read(textfont->_widths, 256);
	for (int i = 0; i < 256; i++)
		textfont->_offsets[i] = dataFile->readUint16LE();
	dataFile->skip(4);
	textfont->_data = new byte[textfont->_dataLength + 4];
	dataFile->read(textfont->_data, textfont->_dataLength);
	delete dataFile;
	return textfont;
}
Beispiel #9
0
void TopMenu::loadBmpArr(Common::File &in) {
	arraySize = in.readUint16BE();

	delete arrayBmp;
	arrayBmp = new Graphics::Surface *[arraySize * 2];
	for (int i = 0; i < arraySize; i++) {
		uint16 bmpSize = in.readUint16BE();
		uint32 filPos = in.pos();
		Common::SeekableSubReadStream stream(&in, filPos, filPos + bmpSize); 
		arrayBmp[i * 2] = Graphics::ImageDecoder::loadFile(stream, g_system->getOverlayFormat());
		arrayBmp[i * 2 + 1] = new Graphics::Surface();
		arrayBmp[i * 2 + 1]->create(arrayBmp[i * 2]->w * 2, arrayBmp[i * 2]->h * 2, arrayBmp[i * 2]->bytesPerPixel);
		byte *src = (byte *)arrayBmp[i * 2]->pixels;
		byte *dst = (byte *)arrayBmp[i * 2 + 1]->pixels;
		
		for (int j = 0; j < arrayBmp[i * 2]->h; j++) {
			src = (byte *)arrayBmp[i * 2]->getBasePtr(0, j);
			dst = (byte *)arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2);
			for (int k = arrayBmp[i * 2]->w; k > 0; k--) {
				for (int m = arrayBmp[i * 2]->bytesPerPixel; m > 0; m--) {
					*dst++ = *src++;
				}
				src -= arrayBmp[i * 2]->bytesPerPixel;

				for (int m = arrayBmp[i * 2]->bytesPerPixel; m > 0; m--) {
					*dst++ = *src++;
				}
			}
			src = (byte *)arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2);
			dst = (byte *)arrayBmp[i * 2 + 1]->getBasePtr(0, j * 2 + 1);
			for (int k = arrayBmp[i * 2 + 1]->pitch; k > 0; k--) {
				*dst++ = *src++;
			}
		}
		
		in.skip(bmpSize);
	}
}
Beispiel #10
0
/**
 * Draw background animation
 * @remarks	Originally called 'show_one'
 */
void Background::draw(int16 destX, int16 destY, byte sprId) {
	assert(sprId < 40);

	if (_sprites[sprId]._x > kOnDisk) {
		if (destX < 0) {
			destX = _sprites[sprId]._x * 8;
			destY = _sprites[sprId]._y;
		}
		drawSprite(destX, destY, _sprites[sprId]);
	} else {
		Common::File f;
		if (!f.open(_filename)) // Filename was set in loadBackgroundSprites().
			return; // We skip because some rooms don't have sprites in the background.

		f.seek(_offsets[sprId]);

		SpriteType sprite;
		sprite._type = (PictureType)(f.readByte());
		sprite._x = f.readSint16LE();
		sprite._y = f.readSint16LE();
		sprite._width = f.readSint16LE();
		sprite._height = f.readSint16LE();
		sprite._size = f.readSint32LE();
		f.skip(2); // Natural and Memorize are used in Load()
		sprite._picture = _vm->_graphics->loadPictureRaw(f, sprite._width * 8, sprite._height + 1);

		if (destX < 0) {
			destX = sprite._x * 8;
			destY = sprite._y;
		}
		drawSprite(destX, destY, sprite);

		sprite._picture.free();
		f.close();
	}
}
InstallShieldCabinet::InstallShieldCabinet(const Common::String &filename) : _installShieldFilename(filename) {
	Common::File installShieldFile;

	if (!installShieldFile.open(_installShieldFilename)) {
		warning("InstallShieldCabinet::InstallShieldCabinet(): Could not find the archive file %s", _installShieldFilename.c_str());
		return;
	}

	// Note that we only support a limited subset of cabinet files
	// Only single cabinet files and ones without data shared between
	// cabinets.

	// Check for the magic uint32
	if (installShieldFile.readUint32LE() != 0x28635349) {
		warning("InstallShieldCabinet::InstallShieldCabinet(): Magic ID doesn't match");
		return;
	}

	uint32 version = installShieldFile.readUint32LE();

	if (version != 0x01000004) {
		warning("Unsupported CAB version %08x", version);
		return;
	}

	/* uint32 volumeInfo = */ installShieldFile.readUint32LE();
	uint32 cabDescriptorOffset = installShieldFile.readUint32LE();
	/* uint32 cabDescriptorSize = */ installShieldFile.readUint32LE();

	installShieldFile.seek(cabDescriptorOffset);

	installShieldFile.skip(12);
	uint32 fileTableOffset = installShieldFile.readUint32LE();
	installShieldFile.skip(4);
	uint32 fileTableSize = installShieldFile.readUint32LE();
	uint32 fileTableSize2 = installShieldFile.readUint32LE();
	uint32 directoryCount = installShieldFile.readUint32LE();
	installShieldFile.skip(8);
	uint32 fileCount = installShieldFile.readUint32LE();

	if (fileTableSize != fileTableSize2)
		warning("file table sizes do not match");

	// We're ignoring file groups and components since we
	// should not need them. Moving on to the files...

	installShieldFile.seek(cabDescriptorOffset + fileTableOffset);
	uint32 fileTableCount = directoryCount + fileCount;
	uint32 *fileTableOffsets = new uint32[fileTableCount];
	for (uint32 i = 0; i < fileTableCount; i++)
		fileTableOffsets[i] = installShieldFile.readUint32LE();

	for (uint32 i = directoryCount; i < fileCount + directoryCount; i++) {
		installShieldFile.seek(cabDescriptorOffset + fileTableOffset + fileTableOffsets[i]);
		uint32 nameOffset = installShieldFile.readUint32LE();
		/* uint32 directoryIndex = */ installShieldFile.readUint32LE();

		// First read in data needed by us to get at the file data
		FileEntry entry;
		entry.flags = installShieldFile.readUint16LE();
		entry.uncompressedSize = installShieldFile.readUint32LE();
		entry.compressedSize = installShieldFile.readUint32LE();
		installShieldFile.skip(20);
		entry.offset = installShieldFile.readUint32LE();

		// Then let's get the string
		installShieldFile.seek(cabDescriptorOffset + fileTableOffset + nameOffset);
		Common::String fileName;

		char c = installShieldFile.readByte();
		while (c) {
			fileName += c;
			c = installShieldFile.readByte();
		}
		_map[fileName] = entry;
	}

	delete[] fileTableOffsets;
}
Beispiel #12
0
ADDetectedGame DirectorMetaEngine::fallbackDetect(const FileMap &allFiles, const Common::FSList &fslist) const {
	// TODO: Handle Mac fallback

	// reset fallback description
	Director::DirectorGameDescription *desc = &s_fallbackDesc;
	desc->desc.gameId = "director";
	desc->desc.extra = "";
	desc->desc.language = Common::UNK_LANG;
	desc->desc.flags = ADGF_NO_FLAGS;
	desc->desc.platform = Common::kPlatformWindows;
	desc->desc.guiOptions = GUIO0();
	desc->desc.filesDescriptions[0].fileName = 0;
	desc->version = 0;
	desc->gameID = Director::GID_GENERIC;

	for (Common::FSList::const_iterator file = fslist.begin(); file != fslist.end(); ++file) {
		if (file->isDirectory())
			continue;

		Common::String fileName = file->getName();
		fileName.toLowercase();
		if (!fileName.hasSuffix(".exe"))
			continue;

		Common::File f;
		if (!f.open(*file))
			continue;

		f.seek(-4, SEEK_END);

		uint32 offset = f.readUint32LE();

		if (f.eos() || offset == 0 || offset >= (uint32)(f.size() - 4))
			continue;

		f.seek(offset);

		uint32 tag = f.readUint32LE();

		switch (tag) {
		case MKTAG('3', '9', 'J', 'P'):
			desc->version = 4;
			break;
		case MKTAG('P', 'J', '9', '5'):
			desc->version = 5;
			break;
		case MKTAG('P', 'J', '0', '0'):
			desc->version = 7;
			break;
		default:
			// Prior to version 4, there was no tag here. So we'll use a bit of a
			// heuristic to detect. The first field is the entry count, of which
			// there should only be one.
			if ((tag & 0xFFFF) != 1)
				continue;

			f.skip(3);

			uint32 mmmSize = f.readUint32LE();

			if (f.eos() || mmmSize == 0)
				continue;

			byte fileNameSize = f.readByte();

			if (f.eos())
				continue;

			f.skip(fileNameSize);
			byte directoryNameSize = f.readByte();

			if (f.eos())
				continue;

			f.skip(directoryNameSize);

			if (f.pos() != f.size() - 4)
				continue;

			// Assume v3 at this point (for now at least)
			desc->version = 3;
		}

		strncpy(s_fallbackFileNameBuffer, fileName.c_str(), 50);
		s_fallbackFileNameBuffer[50] = '\0';
		desc->desc.filesDescriptions[0].fileName = s_fallbackFileNameBuffer;

		warning("Director fallback detection D%d", desc->version);

		return ADDetectedGame(&desc->desc);
	}

	return ADDetectedGame();
}
Beispiel #13
0
/**
 * Opens and inits all MIDI sequence files.
 */
void OpenMidiFiles() {
	Common::File midiStream;

	if (TinselV0) {
		// The early demo version of DW1 doesn't have MIDI
	} else if (TinselV2) {
		// DW2 uses a different music mechanism
	} else if (TinselV1Mac) {
		// open MIDI sequence file in binary mode
		if (!midiStream.open(MIDI_FILE))
			error(CANNOT_FIND_FILE, MIDI_FILE);

		uint32 curTrack = 1;
		uint32 songLength = 0;
		int32 fileSize = midiStream.size();

		// Init
		for (int i = 0; i < ARRAYSIZE(g_midiOffsets); i++)
			g_midiOffsets[i] = 0;

		midiStream.skip(4);	// skip file header

		while (!midiStream.eos() && !midiStream.err() && midiStream.pos() != fileSize) {
			assert(curTrack < ARRAYSIZE(g_midiOffsets));
			g_midiOffsets[curTrack] = midiStream.pos();
			//debug("%d: %d", curTrack, g_midiOffsets[curTrack]);

			songLength = midiStream.readUint32BE();
			midiStream.skip(songLength);

			curTrack++;
		}

		midiStream.close();
	} else {
		if (g_midiBuffer.pDat)
			// already allocated
			return;

		// open MIDI sequence file in binary mode
		if (!midiStream.open(MIDI_FILE))
			error(CANNOT_FIND_FILE, MIDI_FILE);

		// get length of the largest sequence
		g_midiBuffer.size = midiStream.readUint32LE();
		if (midiStream.eos() || midiStream.err())
			error(FILE_IS_CORRUPT, MIDI_FILE);

		if (g_midiBuffer.size) {
			// allocate a buffer big enough for the largest MIDI sequence
			if ((g_midiBuffer.pDat = (uint8 *)malloc(g_midiBuffer.size)) != NULL) {
				// clear out the buffer
				memset(g_midiBuffer.pDat, 0, g_midiBuffer.size);
			}
		}

		// Now scan through the contents of the MIDI file to find the offset
		// of each individual track, in order to create a mapping from MIDI
		// offset to track number, for the enhanced MIDI soundtrack.
		// The first song is always at position 4. The subsequent ones are
		// calculated dynamically.
		uint32 curOffset = 4;
		uint32 curTrack = 0;
		uint32 songLength = 0;

		// Init
		for (int i = 0; i < ARRAYSIZE(g_midiOffsets); i++)
			g_midiOffsets[i] = 0;

		while (!midiStream.eos() && !midiStream.err()) {
			if (curOffset + (4 * curTrack) >= (uint32)midiStream.size())
				break;

			assert(curTrack < ARRAYSIZE(g_midiOffsets));
			g_midiOffsets[curTrack] = curOffset + (4 * curTrack);
			//debug("%d: %d", curTrack, midiOffsets[curTrack]);

			songLength = midiStream.readUint32LE();
			curOffset += songLength;
			midiStream.skip(songLength);

			curTrack++;
		}

		midiStream.close();
	}
}
Beispiel #14
0
/**
 * Play Sequence type 2
 */
void AnimationManager::playSequence2(const Common::String &file, uint32 rate1, uint32 rate2, uint32 rate3, bool skipSeqFl) {
	byte *screenP;
	int frameNumber;
	Common::File f;

	for (;;) {
		if (_vm->shouldQuit())
			return;

		_vm->_events->_mouseFl = false;
		screenP = _vm->_graphicsMan->_backBuffer;

		if (!f.open(file))
			error("File not found - %s", file.c_str());

		f.skip(6);
		f.read(_vm->_graphicsMan->_palette, 800);
		f.skip(4);
		size_t nbytes = f.readUint32LE();
		f.skip(14);
		f.read(screenP, nbytes);

		if (skipSeqFl) {
			_vm->_graphicsMan->setPaletteVGA256(_vm->_graphicsMan->_palette);
		} else {
			_vm->_graphicsMan->setPaletteVGA256(_vm->_graphicsMan->_palette);
			_vm->_graphicsMan->display8BitRect(screenP, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);

			_vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
			_vm->_graphicsMan->updateScreen();
		}
		_vm->_events->_rateCounter = 0;
		_vm->_events->_escKeyFl = false;
		_vm->_soundMan->loadAnimSound();
		if (_vm->_globals->_eventMode == EVENTMODE_IGNORE) {
			do {
				_vm->_events->refreshEvents();
				_vm->_soundMan->checkSoundEnd();
			} while (!_vm->shouldQuit() && !_vm->_events->_escKeyFl && _vm->_events->_rateCounter < rate1);
		}
		break;
	}

	if (!_vm->_events->_escKeyFl) {
		_vm->_events->_rateCounter = 0;
		frameNumber = 0;
		while (!_vm->shouldQuit()) {
			_vm->_soundMan->playAnimSound(frameNumber++);

			byte imageStr[17];
			if (f.read(imageStr, 16) != 16)
				break;
			imageStr[16] = 0;

			if (strncmp((const char *)imageStr, "IMAGE=", 6))
				break;

			f.read(screenP, READ_LE_UINT32(imageStr + 8));
			if (_vm->_globals->_eventMode == EVENTMODE_IGNORE) {
				do {
					_vm->_events->refreshEvents();
				} while (!_vm->shouldQuit() && !_vm->_events->_escKeyFl && _vm->_events->_rateCounter < rate2);
			}

			_vm->_events->_rateCounter = 0;
			if (*screenP != kByteStop)
				_vm->_graphicsMan->copyVideoVbe16a(screenP);

			_vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
			_vm->_graphicsMan->updateScreen();
			_vm->_soundMan->checkSoundEnd();
		}
	}

	if (_vm->_globals->_eventMode == EVENTMODE_IGNORE) {
		// Wait for third rate delay
		do {
			_vm->_events->refreshEvents();
			_vm->_soundMan->checkSoundEnd();
		} while (!_vm->shouldQuit() && !_vm->_events->_escKeyFl && _vm->_events->_rateCounter < rate3);
	}

	_vm->_events->_rateCounter = 0;

	if (_vm->_graphicsMan->_fadingFl) {
		byte *ptra = _vm->_globals->allocMemory(307200);

		f.seek(6);
		f.read(_vm->_graphicsMan->_palette, 800);
		f.skip(4);
		size_t nbytes = f.readUint32LE();
		f.skip(14);
		f.read(screenP, nbytes);

		memcpy(ptra, screenP, 307200);
		for (;;) {
			byte imageStr[17];
			if (f.read(imageStr, 16) != 16)
				break;
			imageStr[16] = 0;

			if (strncmp((const char *)imageStr, "IMAGE=", 6))
				break;

			f.read(screenP, READ_LE_UINT32(imageStr + 8));
			if (*screenP != kByteStop)
				_vm->_graphicsMan->copyWinscanVbe(screenP, ptra);
		}
		_vm->_graphicsMan->fadeOutDefaultLength(ptra);
		ptra = _vm->_globals->freeMemory(ptra);
	}
	_vm->_graphicsMan->_fadingFl = false;

	f.close();
	_vm->_events->_mouseFl = true;
}
Beispiel #15
0
/**
 * Play Animation
 * @param filename		Filename of animation to play
 * @param rate1			Delay amount before starting animation
 * @param rate2			Delay amount between animation frames
 * @param rate3			Delay amount after animation finishes
 */
void AnimationManager::playAnim(const Common::String &filename, uint32 rate1, uint32 rate2, uint32 rate3, bool skipSeqFl) {
	Common::File f;

	if (_vm->shouldQuit())
		return;

	_vm->_events->mouseOff();

	byte *screenP = _vm->_graphicsMan->_backBuffer;

	Common::String tmpStr;
	// The Windows 95 demo only contains the interlaced version of the BOMBE1 and BOMBE2 videos
	if (_vm->getPlatform() == Common::kPlatformWindows && _vm->getIsDemo() && filename == "BOMBE1A.ANM")
		tmpStr = "BOMBE1.ANM";
	else if (_vm->getPlatform() == Common::kPlatformWindows && _vm->getIsDemo() && filename == "BOMBE2A.ANM")
		tmpStr = "BOMBE2.ANM";
	else
		tmpStr = filename;
	if (!f.open(tmpStr))
		error("File not found - %s", tmpStr.c_str());

	f.skip(6);
	f.read(_vm->_graphicsMan->_palette, 800);
	f.skip(4);
	size_t nbytes = f.readUint32LE();
	f.skip(14);
	f.read(screenP, nbytes);

	if (_clearAnimationFl)
		_vm->_graphicsMan->clearScreen();

	if (skipSeqFl) {
		_vm->_graphicsMan->setPaletteVGA256(_vm->_graphicsMan->_palette);
	} else {
		_vm->_graphicsMan->setPaletteVGA256(_vm->_graphicsMan->_palette);
		_vm->_graphicsMan->display8BitRect(screenP, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);
		_vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
		_vm->_graphicsMan->updateScreen();
	}
	_vm->_events->_rateCounter = 0;
	_vm->_events->_escKeyFl = false;
	_vm->_soundMan->loadAnimSound();

	if (_vm->_globals->_eventMode == EVENTMODE_IGNORE) {
		// Do pre-animation delay
		do {
			if (_vm->_events->_escKeyFl)
				break;

			_vm->_events->refreshEvents();
		} while (!_vm->shouldQuit() && _vm->_events->_rateCounter < rate1);
	}

	if (!_vm->_events->_escKeyFl) {
		_vm->_events->_rateCounter = 0;
		int frameNumber = 0;
		while (!_vm->shouldQuit()) {
			++frameNumber;
			_vm->_soundMan->playAnimSound(frameNumber);

			byte imageStr[17];
			// Read frame header
			if (f.read(imageStr, 16) != 16)
				break;
			imageStr[16] = 0;
			if (strncmp((const char *)imageStr, "IMAGE=", 6))
				break;

			f.read(screenP, READ_LE_UINT32(imageStr + 8));

			if (_vm->_globals->_eventMode == EVENTMODE_IGNORE) {
				do {
					if (_vm->_events->_escKeyFl)
						break;

					_vm->_events->refreshEvents();
					_vm->_soundMan->checkSoundEnd();
				} while (!_vm->shouldQuit() && _vm->_events->_rateCounter < rate2);
			}

			if (!_vm->_events->_escKeyFl) {
				_vm->_events->_rateCounter = 0;
				if (*screenP != kByteStop)
					_vm->_graphicsMan->copyVideoVbe16(screenP);

				_vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
				_vm->_graphicsMan->updateScreen();
				_vm->_soundMan->checkSoundEnd();
			}
		}
	}

	if (_vm->_globals->_eventMode == EVENTMODE_IGNORE && !_vm->_events->_escKeyFl) {
		// Do post-animation delay
		do {
			if (_vm->_events->_escKeyFl)
				break;

			_vm->_events->refreshEvents();
			_vm->_soundMan->checkSoundEnd();
		} while (_vm->_events->_rateCounter < rate3);
	}

	if (!_vm->_events->_escKeyFl) {
		_vm->_events->_rateCounter = 0;
		_vm->_soundMan->checkSoundEnd();
	}

	if (_vm->_graphicsMan->_fadingFl) {
		byte *screenCopy = _vm->_globals->allocMemory(307200);

		f.seek(6);
		f.read(_vm->_graphicsMan->_palette, 800);
		f.skip(4);
		nbytes = f.readUint32LE();
		f.skip(14);
		f.read(screenP, nbytes);

		memcpy(screenCopy, screenP, 307200);

		for (;;) {
			byte imageStr[17];
			if (f.read(imageStr, 16) != 16)
				break;
			imageStr[16] = 0;

			if (strncmp((const char *)imageStr, "IMAGE=", 6))
				break;

			f.read(screenP, READ_LE_UINT32(imageStr + 8));
			if (*screenP != kByteStop)
				_vm->_graphicsMan->copyWinscanVbe3(screenP, screenCopy);
		}
		_vm->_graphicsMan->fadeOutDefaultLength(screenCopy);
		_vm->_globals->freeMemory(screenCopy);
	}

	_vm->_graphicsMan->_fadingFl = false;
	f.close();
	_vm->_graphicsMan->_skipVideoLockFl = false;

	_vm->_events->mouseOn();
}
Beispiel #16
0
/**
 * Play sequence
 */
void AnimationManager::playSequence(const Common::String &file, uint32 rate1, uint32 rate2, uint32 rate3, bool skipEscFl, bool skipSeqFl, bool noColFl) {
	if (_vm->shouldQuit())
		return;

	_vm->_events->_mouseFl = false;
	if (!noColFl) {
		_vm->_events->refreshScreenAndEvents();

		_vm->_graphicsMan->backupScreen();

		if (!_vm->_graphicsMan->_lineNbr)
			_vm->_graphicsMan->_scrollOffset = 0;
	}
	byte *screenP = _vm->_graphicsMan->_backBuffer;
	Common::File f;
	if (!f.open(file))
		error("Error opening file - %s", file.c_str());

	f.skip(6);
	f.read(_vm->_graphicsMan->_palette, 800);
	f.skip(4);
	size_t nbytes = f.readUint32LE();
	f.skip(14);
	f.read(screenP, nbytes);

	if (skipSeqFl) {
		if (!_vm->getIsDemo()) {
			_vm->_graphicsMan->setColorPercentage(252, 100, 100, 100);
			_vm->_graphicsMan->setColorPercentage(253, 100, 100, 100);
			_vm->_graphicsMan->setColorPercentage(251, 100, 100, 100);
			_vm->_graphicsMan->setColorPercentage(254, 0, 0, 0);
		}
		_vm->_graphicsMan->setPaletteVGA256(_vm->_graphicsMan->_palette);
	} else {
		_vm->_graphicsMan->display8BitRect(screenP, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);
		_vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
		_vm->_graphicsMan->updateScreen();
	}
	bool skipFl = false;
	if (noColFl)
		_vm->_graphicsMan->fadeInDefaultLength(screenP);
	_vm->_events->_rateCounter = 0;
	_vm->_events->_escKeyFl = false;
	_vm->_soundMan->loadAnimSound();
	if (_vm->_globals->_eventMode == EVENTMODE_IGNORE) {
		do {
			if (_vm->shouldQuit() || (_vm->_events->_escKeyFl && !skipEscFl)) {
				skipFl = true;
				break;
			}

			_vm->_events->_escKeyFl = false;
			_vm->_events->refreshEvents();
			_vm->_soundMan->checkSoundEnd();
		} while (_vm->_events->_rateCounter < rate1);
	}
	_vm->_events->_rateCounter = 0;
	if (!skipFl) {
		int soundNumber = 0;
		for (;;) {
			++soundNumber;
			_vm->_soundMan->playAnimSound(soundNumber);
			byte imageStr[17];
			if (f.read(imageStr, 16) != 16)
				break;
			imageStr[16] = 0;

			if (strncmp((const char *)imageStr, "IMAGE=", 6))
				break;

			f.read(screenP, READ_LE_UINT32(imageStr + 8));
			if (_vm->_globals->_eventMode == EVENTMODE_IGNORE) {
				do {
					if (_vm->shouldQuit() || (_vm->_events->_escKeyFl && !skipEscFl)) {
						skipFl = true;
						break;
					}

					_vm->_events->_escKeyFl = false;
					_vm->_events->refreshEvents();
					_vm->_soundMan->checkSoundEnd();
				} while (_vm->_events->_rateCounter < rate2);
			}

			if (skipFl)
				break;

			_vm->_events->_rateCounter = 0;
			if (*screenP != kByteStop)
				_vm->_graphicsMan->copyVideoVbe16a(screenP);

			_vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
			_vm->_graphicsMan->updateScreen();
			_vm->_soundMan->checkSoundEnd();
		}
	}

	if (_vm->_globals->_eventMode == EVENTMODE_IGNORE && !skipFl) {
		do {
			if (_vm->shouldQuit() || (_vm->_events->_escKeyFl && !skipEscFl)) {
				skipFl = true;
				break;
			}

			_vm->_events->_escKeyFl = false;
			_vm->_events->refreshEvents();
			_vm->_soundMan->checkSoundEnd();
		} while (_vm->_events->_rateCounter < rate3);
	}

	if (!skipFl)
		_vm->_events->_rateCounter = 0;

	_vm->_graphicsMan->_skipVideoLockFl = false;
	f.close();

	if (!noColFl) {
		_vm->_graphicsMan->restoreScreen();

		_vm->_events->_mouseFl = true;
	}
}
Beispiel #17
0
/**
 * Play Animation, type 2
 */
void AnimationManager::playAnim2(const Common::String &filename, uint32 rate1, uint32 rate2, uint32 rate3) {
	int oldScrollPosX = 0;
	byte *screenP = NULL;
	Common::File f;

	if (_vm->shouldQuit())
		return;

	_vm->_events->mouseOff();

	while (!_vm->shouldQuit()) {
		memcpy(_vm->_graphicsMan->_oldPalette, _vm->_graphicsMan->_palette, 769);

		_vm->_graphicsMan->backupScreen();

		if (!_vm->_graphicsMan->_lineNbr)
			_vm->_graphicsMan->_scrollOffset = 0;

		screenP = _vm->_graphicsMan->_backBuffer;
		if (!f.open(filename))
			error("Error opening file - %s", filename.c_str());

		f.skip(6);
		f.read(_vm->_graphicsMan->_palette, 800);
		f.skip(4);
		size_t nbytes = f.readUint32LE();
		f.skip(14);

		f.read(screenP, nbytes);

		_vm->_graphicsMan->clearPalette();
		oldScrollPosX = _vm->_graphicsMan->_scrollPosX;
		_vm->_graphicsMan->setScreenWidth(SCREEN_WIDTH);
		_vm->_graphicsMan->scrollScreen(0);
		_vm->_graphicsMan->clearScreen();
		_vm->_graphicsMan->_maxX = SCREEN_WIDTH;

		_vm->_graphicsMan->setPaletteVGA256(_vm->_graphicsMan->_palette);
		_vm->_graphicsMan->display8BitRect(screenP, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);
		_vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
		_vm->_graphicsMan->updateScreen();

		_vm->_events->_rateCounter = 0;
		_vm->_events->_escKeyFl = false;
		_vm->_soundMan->loadAnimSound();
		if (_vm->_globals->_eventMode == EVENTMODE_IGNORE) {
			while (!_vm->_events->_escKeyFl && _vm->_events->_rateCounter < rate1) {
				_vm->_events->refreshEvents();
			}
		}
		break;
	}

	if (!_vm->_events->_escKeyFl) {
		_vm->_events->_rateCounter = 0;
		int frameNumber = 0;
		for (;;) {
			if (_vm->_events->_escKeyFl)
				break;
			++frameNumber;
			_vm->_soundMan->playAnimSound(frameNumber);
			byte imageStr[17];
			if (f.read(imageStr, 16) != 16)
				break;
			imageStr[16] = 0;

			if (strncmp((const char *)imageStr, "IMAGE=", 6))
				break;

			f.read(screenP, READ_LE_UINT32(imageStr + 8));
			if (_vm->_globals->_eventMode == EVENTMODE_IGNORE) {
				while (!_vm->_events->_escKeyFl && _vm->_events->_rateCounter < rate2) {
					_vm->_events->refreshEvents();
					_vm->_soundMan->checkSoundEnd();
				}
			}

			_vm->_events->_rateCounter = 0;
			if (*screenP != kByteStop)
				_vm->_graphicsMan->copyVideoVbe16(screenP);

			_vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
			_vm->_graphicsMan->updateScreen();
			_vm->_soundMan->checkSoundEnd();
		}

		if (_vm->_globals->_eventMode == EVENTMODE_IGNORE) {
			while (!_vm->_events->_escKeyFl && _vm->_events->_rateCounter < rate3) {
				_vm->_events->refreshEvents();
				_vm->_soundMan->checkSoundEnd();
			}
		}
	}

	_vm->_graphicsMan->_skipVideoLockFl = false;
	f.close();

	if (_vm->_graphicsMan->_fadingFl) {
		f.seek(6);
		f.read(_vm->_graphicsMan->_palette, 800);
		f.skip(4);
		size_t nbytes = f.readUint32LE();
		f.skip(14);
		f.read(screenP, nbytes);
		byte *ptra = _vm->_globals->allocMemory(307200);
		memcpy(ptra, screenP, 307200);

		for (;;) {
			byte imageStr[17];
			if (f.read(imageStr, 16) != 16)
				break;
			imageStr[16] = 0;

			if (strncmp((const char *)imageStr, "IMAGE=", 6))
				break;

			f.read(screenP, READ_LE_UINT32(imageStr + 8));
			if (*screenP != kByteStop)
				_vm->_graphicsMan->copyWinscanVbe3(screenP, ptra);
		}
		_vm->_graphicsMan->fadeOutDefaultLength(ptra);
		ptra = _vm->_globals->freeMemory(ptra);
	}
	_vm->_graphicsMan->_fadingFl = false;

	_vm->_graphicsMan->restoreScreen();

	memcpy(_vm->_graphicsMan->_palette, _vm->_graphicsMan->_oldPalette, 769);
	_vm->_graphicsMan->clearPalette();
	_vm->_graphicsMan->clearScreen();

	_vm->_graphicsMan->_scrollPosX = oldScrollPosX;
	_vm->_graphicsMan->scrollScreen(oldScrollPosX);
	if (_vm->_graphicsMan->_largeScreenFl) {
		_vm->_graphicsMan->setScreenWidth(2 * SCREEN_WIDTH);
		_vm->_graphicsMan->_maxX = 2 * SCREEN_WIDTH;
		_vm->_graphicsMan->display8BitRect(_vm->_graphicsMan->_frontBuffer, _vm->_events->_startPos.x, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);
	} else {
		_vm->_graphicsMan->setScreenWidth(SCREEN_WIDTH);
		_vm->_graphicsMan->_maxX = SCREEN_WIDTH;
		_vm->_graphicsMan->clearScreen();
		_vm->_graphicsMan->display8BitRect(_vm->_graphicsMan->_frontBuffer, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);
	}
	_vm->_graphicsMan->addRefreshRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);

	_vm->_graphicsMan->fadeInShort();
	_vm->_graphicsMan->updateScreen();

	_vm->_events->mouseOn();
}
Beispiel #18
0
/**
 * Opens and inits all MIDI sequence files.
 */
void OpenMidiFiles() {
	Common::File midiStream;

	// Demo version has no midi file
	// Also, Discworld PSX uses still unsupported psx SEQ format for music...
	if ((_vm->getFeatures() & GF_DEMO) || (TinselVersion == TINSEL_V2) || TinselV1PSX)
		return;

	if (midiBuffer.pDat)
		// already allocated
		return;

	// open MIDI sequence file in binary mode
	if (!midiStream.open(MIDI_FILE))
		error(CANNOT_FIND_FILE, MIDI_FILE);

	// gen length of the largest sequence
	midiBuffer.size = midiStream.readUint32LE();
	if (midiStream.eos() || midiStream.err())
		error(FILE_IS_CORRUPT, MIDI_FILE);

	if (midiBuffer.size) {
		// allocate a buffer big enough for the largest MIDI sequence
		if ((midiBuffer.pDat = (uint8 *)malloc(midiBuffer.size)) != NULL) {
			// clear out the buffer
			memset(midiBuffer.pDat, 0, midiBuffer.size);
//			VMM_lock(midiBuffer.pDat, midiBuffer.size);
		} else {
			//mSeqHandle = NULL;
		}
	}

	// Now scan through the contents of the MIDI file to find the offset
	// of each individual track, in order to create a mapping from MIDI
	// offset to track number, for the enhanced MIDI soundtrack.
	// The first song is always at position 4. The subsequent ones are
	// calculated dynamically.
	uint32 curOffset = 4;
	uint32 curTrack = 0;
	uint32 songLength = 0;

	// Init
	for (int i = 0; i < ARRAYSIZE(midiOffsets); i++)
		midiOffsets[i] = 0;

	while (!midiStream.eos() && !midiStream.err()) {
		if (curOffset + (4 * curTrack) >= (uint32)midiStream.size())
			break;

		assert(curTrack < ARRAYSIZE(midiOffsets));
		midiOffsets[curTrack] = curOffset + (4 * curTrack);
		//debug("%d: %d", curTrack, midiOffsets[curTrack]);

		songLength = midiStream.readUint32LE();
		curOffset += songLength;
		midiStream.skip(songLength);

		curTrack++;
	}

	midiStream.close();
}
Beispiel #19
0
void Menu::readVerbNums(Common::File &f, int dataSize) {
	// Figure out what language Id is needed
	byte desiredLanguageId;
	switch(_vm->getLanguage()) {
	case Common::EN_ANY:
		desiredLanguageId = MORTDAT_LANG_ENGLISH;
		break;
	case Common::FR_FRA:
		desiredLanguageId = MORTDAT_LANG_FRENCH;
		break;
	case Common::DE_DEU:
		desiredLanguageId = MORTDAT_LANG_GERMAN;
		break;
	default:
		warning("Language not supported, switching to English");
		desiredLanguageId = MORTDAT_LANG_ENGLISH;
		break;
	}
	// Read in the language
	byte languageId = f.readByte();
	--dataSize;

	// If the language isn't correct, then skip the entire block
	if (languageId != desiredLanguageId) {
		f.skip(dataSize);
		return;
	}

	assert(dataSize == 52);
	_opcodeAttach  = f.readUint16LE();
	_opcodeWait    = f.readUint16LE();
	_opcodeForce   = f.readUint16LE();
	_opcodeSleep   = f.readUint16LE();
	_opcodeListen  = f.readUint16LE();
	_opcodeEnter   = f.readUint16LE();
	_opcodeClose   = f.readUint16LE();
	_opcodeSearch  = f.readUint16LE();
	_opcodeKnock   = f.readUint16LE();
	_opcodeScratch = f.readUint16LE();
	_opcodeRead    = f.readUint16LE();
	_opcodeEat     = f.readUint16LE();
	_opcodePlace   = f.readUint16LE();
	_opcodeOpen    = f.readUint16LE();
	_opcodeTake    = f.readUint16LE();
	_opcodeLook    = f.readUint16LE();
	_opcodeSmell   = f.readUint16LE();
	_opcodeSound   = f.readUint16LE();
	_opcodeLeave   = f.readUint16LE();
	_opcodeLift    = f.readUint16LE();
	_opcodeTurn    = f.readUint16LE();
	_opcodeSHide   = f.readUint16LE();
	_opcodeSSearch = f.readUint16LE();
	_opcodeSRead   = f.readUint16LE();
	_opcodeSPut    = f.readUint16LE();
	_opcodeSLook   = f.readUint16LE();

	_actionMenu[0]._menuId    = OPCODE_NONE   >> 8;
	_actionMenu[0]._actionId  = OPCODE_NONE   & 0xFF;

	_actionMenu[1]._menuId    = _opcodeSHide  >> 8;
	_actionMenu[1]._actionId  = _opcodeSHide  & 0xFF;

	_actionMenu[2]._menuId    = _opcodeAttach >> 8;
	_actionMenu[2]._actionId  = _opcodeAttach & 0xFF;

	_actionMenu[3]._menuId    = _opcodeForce  >> 8;
	_actionMenu[3]._actionId  = _opcodeForce  & 0xFF;

	_actionMenu[4]._menuId    = _opcodeSleep  >> 8;
	_actionMenu[4]._actionId  = _opcodeSleep  & 0xFF;

	_actionMenu[5]._menuId    = _opcodeEnter  >> 8;
	_actionMenu[5]._actionId  = _opcodeEnter  & 0xFF;

	_actionMenu[6]._menuId    = _opcodeClose  >> 8;
	_actionMenu[6]._actionId  = _opcodeClose  & 0xFF;

	_actionMenu[7]._menuId    = _opcodeKnock  >> 8;
	_actionMenu[7]._actionId  = _opcodeKnock  & 0xFF;

	_actionMenu[8]._menuId    = _opcodeEat    >> 8;
	_actionMenu[8]._actionId  = _opcodeEat    & 0xFF;

	_actionMenu[9]._menuId    = _opcodePlace  >> 8;
	_actionMenu[9]._actionId  = _opcodePlace  & 0xFF;

	_actionMenu[10]._menuId   = _opcodeOpen   >> 8;
	_actionMenu[10]._actionId = _opcodeOpen   & 0xFF;

	_actionMenu[11]._menuId   = _opcodeLeave  >> 8;
	_actionMenu[11]._actionId = _opcodeLeave  & 0xFF;
}