Пример #1
0
void ImageFile::loadPalette(Common::SeekableReadStream &stream) {
	// Check for palette
	uint16 width        = stream.readUint16LE() + 1;
	uint16 height       = stream.readUint16LE() + 1;
	byte   paletteBase  = stream.readByte();
	byte   rleEncoded   = stream.readByte();
	byte   offsetX      = stream.readByte();
	byte   offsetY      = stream.readByte();
	uint32 palSignature = 0;

	if ((width == 390) && (height == 2) && (!paletteBase) && (!rleEncoded) && (!offsetX) && (!offsetY)) {
		// We check for these specific values
		// We can't do "width * height", because at least the first German+Spanish menu bar is 60 x 13
		// which is 780, which is the size of the palette. We obviously don't want to detect it as palette.

		// As another security measure, we also check for the signature text
		palSignature = stream.readUint32BE();
		if (palSignature != MKTAG('V', 'G', 'A', ' ')) {
			// signature mismatch, rewind
			stream.seek(-12, SEEK_CUR);
			return;
		}
		// Found palette, so read it in
		stream.seek(8, SEEK_CUR); // Skip over the rest of the signature text "VGA palette"
		for (int idx = 0; idx < PALETTE_SIZE; ++idx)
			_palette[idx] = VGA_COLOR_TRANS(stream.readByte());
	} else {
		// Not a palette, so rewind to start of frame data for normal frame processing
		stream.seek(-8, SEEK_CUR);
	}
}
Пример #2
0
void DirectorEngine::loadEXE() {
    Common::SeekableReadStream *exeStream = SearchMan.createReadStreamForMember(getEXEName());
    if (!exeStream)
        error("Failed to open EXE '%s'", getEXEName().c_str());

    _lingo->processEvent(kEventStart, 0);

    exeStream->seek(-4, SEEK_END);
    exeStream->seek(exeStream->readUint32LE());

    switch (getVersion()) {
    case 3:
        loadEXEv3(exeStream);
        break;
    case 4:
        loadEXEv4(exeStream);
        break;
    case 5:
        loadEXEv5(exeStream);
        break;
    case 7:
        loadEXEv7(exeStream);
        break;
    default:
        error("Unhandled Windows EXE version %d", getVersion());
    }
}
Пример #3
0
void KEYFile::readBIFList(Common::SeekableReadStream &key, uint32 offset) {
	key.seek(offset);

	for (BIFList::iterator bif = _bifs.begin(); bif != _bifs.end(); ++bif) {
		key.skip(4); // File size of the bif

		uint32 nameOffset = key.readUint32LE();
		uint32 nameSize   = 0;

		// nameSize is expanded to 4 bytes in 1.1 and the location is dropped
		if (_version == kVersion11) {
			nameSize = key.readUint32LE();
		} else {
			nameSize = key.readUint16LE();
			key.skip(2); // Location of the bif (HD, CD, ...)
		}

		uint32 curPos = key.seek(nameOffset);

		*bif = Common::readStringFixed(key, Common::kEncodingASCII, nameSize);

		key.seek(curPos);

		bif->replaceAll('\\', '/');
		if (bif->beginsWith("/"))
			bif->erase(bif->begin());
	}
}
Пример #4
0
bool WagFileParser::checkWagVersion(Common::SeekableReadStream &stream) {
	if (stream.size() >= WINAGI_VERSION_LENGTH) { // Stream has space to contain the WinAGI version string
		// Read the last WINAGI_VERSION_LENGTH bytes of the stream and make a string out of it
		char str[WINAGI_VERSION_LENGTH+1]; // Allocate space for the trailing zero also
		uint32 oldStreamPos = stream.pos(); // Save the old stream position
		stream.seek(stream.size() - WINAGI_VERSION_LENGTH);
		uint32 readBytes = stream.read(str, WINAGI_VERSION_LENGTH);
		stream.seek(oldStreamPos); // Seek back to the old stream position
		str[readBytes] = 0; // Set the trailing zero to finish the C-style string
		if (readBytes != WINAGI_VERSION_LENGTH) { // Check that we got the whole version string
			debug(3, "WagFileParser::checkWagVersion: Error reading WAG file version from stream");
			return false;
		}
		debug(3, "WagFileParser::checkWagVersion: Read WinAGI version string (\"%s\")", str);

		// Check that the WinAGI version string is one of the two version strings
		// WinAGI 1.1.21 recognizes as acceptable in the end of a *.wag file.
		// Note that they are all of length 16 and are padded with spaces to be that long.
		return scumm_stricmp(str, "WINAGI v1.0     ") == 0 ||
			scumm_stricmp(str, "1.0 BETA        ") == 0;
	} else { // Stream is too small to contain the WinAGI version string
		debug(3, "WagFileParser::checkWagVersion: Stream is too small to contain a valid WAG file");
		return false;
	}
}
Пример #5
0
void Archive::_decryptHeader(Common::SeekableReadStream &inStream, Common::WriteStream &outStream) {
	static const uint32 addKey = 0x3C6EF35F;
	static const uint32 multKey = 0x0019660D;

	inStream.seek(0);
	uint32 size = inStream.readUint32LE();

	bool encrypted = size > 1000000;
	
	inStream.seek(0);

	if (encrypted) {
		uint32 decryptedSize = size ^ addKey;

		uint32 currentKey = 0;
		for (uint i = 0; i < decryptedSize; i++) {
			currentKey += addKey;
			outStream.writeUint32LE(inStream.readUint32LE() ^ currentKey);
			currentKey *= multKey;
		}
	} else {
		for (uint i = 0; i < size; i++) {
			outStream.writeUint32LE(inStream.readUint32LE());
		}
	}
}
Пример #6
0
bool SaveReader::getInfo(Common::SeekableReadStream &stream, SavePartInfo &info) {
	// Remeber the stream's starting position to seek back to
	uint32 startPos = stream.pos();

	// Get parts' basic information
	Common::Array<SaveContainer::PartInfo> *partsInfo = getPartsInfo(stream);

	// No parts => fail
	if (!partsInfo) {
		stream.seek(startPos);
		return false;
	}

	bool result = false;
	// Iterate over all parts
	for (Common::Array<SaveContainer::PartInfo>::iterator it = partsInfo->begin();
	     it != partsInfo->end(); ++it) {

		// Check for the info part
		if (it->id == SavePartInfo::kID) {
			if (!stream.seek(it->offset))
				break;

			// Read it
			result = info.read(stream);
			break;
		}
	}

	stream.seek(startPos);

	delete partsInfo;
	return result;
}
Пример #7
0
Common::Archive *Resource::loadArchive(const Common::String &name, Common::ArchiveMemberPtr member) {
	ArchiveMap::iterator cachedArchive = _archiveCache.find(name);
	if (cachedArchive != _archiveCache.end())
		return cachedArchive->_value;

	Common::SeekableReadStream *stream = member->createReadStream();

	if (!stream)
		return 0;

	Common::Archive *archive = 0;
	for (LoaderList::const_iterator i = _loaders.begin(); i != _loaders.end(); ++i) {
		if ((*i)->checkFilename(name)) {
			if ((*i)->isLoadable(name, *stream)) {
				stream->seek(0, SEEK_SET);
				archive = (*i)->load(member, *stream);
				break;
			} else {
				stream->seek(0, SEEK_SET);
			}
		}
	}

	delete stream;

	if (!archive)
		return 0;

	_archiveCache[name] = archive;
	return archive;
}
Пример #8
0
Common::String Resource::getMessage(uint16 id, uint16 message) {
	Common::SeekableReadStream *lookup = _text->createReadStreamForIndex(id + 6);
	Common::SeekableReadStream *strings = _text->createReadStreamForIndex(id + 7);

	char buff[1024];
	int j = 0;

	int size = lookup->size()/2;
	for (int i = 0; i < size; ++i) {
		uint16 val = lookup->readUint16LE();
		if (val == message) {
			strings->seek(i*2);
			uint16 offset = strings->readUint16LE();
			char c = 0;
			strings->seek(offset);
			do {
				c = strings->readByte();
				buff[j++] = c;
			} while (c != 0);

			return buff;
		}
	}
	return "";
}
Пример #9
0
void GameModule::loadActions(Common::SeekableReadStream &s) {
	debug(0, "GameModule::loadActions()");

	s.seek(0x180);
	_actionsCount = s.readUint32LE();
	uint32 offs = s.readUint32LE();
	_actions = new Action[_actionsCount];
	for (int i = 0; i < _actionsCount; ++i) {
		s.seek(offs + i * 72);
		debug(0, "Action(%d) offs: %08X", i, offs + i * 72);
		_actions[i].conditions = readConditions(s);
		for (int j = 0; j < 8; ++j) {
			_actions[i].results.actionResults[j].kind = s.readByte();
			_actions[i].results.actionResults[j].value1 = s.readByte();
			_actions[i].results.actionResults[j].value2 = s.readUint16LE();
		}
		const int actionListCount = s.readUint32LE();
		const uint32 actionListOffs = s.readUint32LE();
		s.seek(actionListOffs);
		for (int j = 0; j < actionListCount; ++j) {
			ActionCommand actionCommand;
			actionCommand.cmd = s.readUint16LE();
			actionCommand.sceneObjectIndex = s.readUint16LE();
			actionCommand.timeStamp = s.readUint32LE();
			actionCommand.walkDest = readPoint(s);
			actionCommand.param = s.readUint32LE();
			_actions[i].actionCommands.push_back(actionCommand);
		}
	}
}
Пример #10
0
void DrasculaEngine::playFile(const char *fname) {
	Common::SeekableReadStream *stream = _archives.open(fname);
	if (stream) {
		int soundSize = stream->size();
		byte *soundData = (byte *)malloc(soundSize);

		if (!(!strcmp(fname, "3.als") && soundSize == 145166 && _lang != kSpanish)) {
			stream->seek(32);
		} else {
			// WORKAROUND: File 3.als with English speech files has a big silence at
			// its beginning and end. We seek past the silence at the beginning,
			// and ignore the silence at the end
			// Fixes bug #2111815 - "DRASCULA: Voice delayed"
			stream->seek(73959, SEEK_SET);
			soundSize = 117158 - 73959;
		}

		stream->read(soundData, soundSize);
		delete stream;

		_subtitlesDisabled = !ConfMan.getBool("subtitles");
		if (ConfMan.getBool("speech_mute"))
			memset(soundData, 0x80, soundSize); // Mute speech but keep the pause

		Audio::AudioStream *sound = Audio::makeRawStream(soundData, soundSize - 64,
						11025, Audio::FLAG_UNSIGNED);
		_mixer->playStream(Audio::Mixer::kSpeechSoundType, &_soundHandle, sound);
	} else
		warning("playFile: Could not open %s", fname);
}
Пример #11
0
/**
 * Load animDataTable from save
 * @param fHandle Savefile open for reading
 * @param saveGameFormat The used savegame format
 * @todo Add Operation Stealth savefile support
 *
 * Unlike the old code, this one actually rebuilds the table one frame
 * at a time.
 */
void loadResourcesFromSave(Common::SeekableReadStream &fHandle, enum CineSaveGameFormat saveGameFormat) {
    int16 foundFileIdx;
    char *animName, part[256], name[10];

    strcpy(part, currentPartName);

    // We only support these variations of the savegame format at the moment.
    assert(saveGameFormat == ANIMSIZE_23 || saveGameFormat == ANIMSIZE_30_PTRS_INTACT);

    const int entrySize = ((saveGameFormat == ANIMSIZE_23) ? 23 : 30);
    const int fileStartPos = fHandle.pos();

    for(int resourceIndex=0; resourceIndex<NUM_MAX_ANIMDATA; resourceIndex++) {
        // Seek to the start of the current animation's entry
        fHandle.seek(fileStartPos + resourceIndex * entrySize);
        // Read in the current animation entry
        fHandle.readUint16BE(); // width
        fHandle.readUint16BE();
        fHandle.readUint16BE(); // bpp
        fHandle.readUint16BE(); // height

        bool validPtr = false;
        // Handle variables only present in animation entries of size 30
        if (entrySize == 30) {
            validPtr = (fHandle.readUint32BE() != 0); // Read data pointer
            fHandle.readUint32BE(); // Discard mask pointer
        }

        foundFileIdx = fHandle.readSint16BE();
        int16 frameIndex = fHandle.readSint16BE(); // frame
        fHandle.read(name, 10);

        // Handle variables only present in animation entries of size 23
        if (entrySize == 23) {
            validPtr = (fHandle.readByte() != 0);
        }

        // Don't try to load invalid entries.
        if (foundFileIdx < 0 || !validPtr) {
            //resourceIndex++; // Jump over the invalid entry
            continue;
        }

        // Alright, the animation entry looks to be valid so let's start handling it...
        if (strcmp(currentPartName, name) != 0) {
            closePart();
            loadPart(name);
        }

        animName = g_cine->_partBuffer[foundFileIdx].partName;
        loadRelatedPalette(animName); // Is this for Future Wars only?
        loadResource(animName, resourceIndex, frameIndex);
    }

    loadPart(part);

    // Make sure we jump over all the animation entries
    fHandle.seek(fileStartPos + NUM_MAX_ANIMDATA * entrySize);
}
Пример #12
0
bool Animation::loadStream(Common::SeekableReadStream &stream) {
	stream.skip(2); // skip not used x and y coord diff
	_loopCount = stream.readUint16LE();
	_phaseCount = stream.readUint16LE();
	stream.skip(2); // skip _frameCount here
	_baseX = stream.readUint16LE();
	_baseY = stream.readUint16LE();
	uint32 phaseTableOffset = stream.readUint32LE();
	uint32 tableOfFrameOffsets = stream.pos();

	stream.seek(phaseTableOffset);
	Phase tempPhase;
	_frameCount = 0;
	for (int phase = 0; phase < _phaseCount; phase++) {
		tempPhase._phaseOffsetX = stream.readSint16LE();
		tempPhase._phaseOffsetY = stream.readSint16LE();
		tempPhase._phaseToFrameIndex = stream.readUint16LE();
		if (tempPhase._phaseToFrameIndex > _frameCount) {
			_frameCount = tempPhase._phaseToFrameIndex;
		}
		_phaseList.push_back(tempPhase);
		stream.skip(2);
	}
	if (_phaseCount) {
		_frameCount++;
	}

	Frame tempFrame;
	for (int frame = 0; frame < _frameCount; frame++) {
		stream.seek(tableOfFrameOffsets + frame * 4);
		uint32 frameInfoOffset = stream.readUint32LE();
		stream.seek(frameInfoOffset);
		uint16 frameWidth = stream.readUint16LE();
		uint16 frameHeight = stream.readUint16LE();
		uint32 frameDataPos = stream.pos();
		uint32 frameDataOffset = stream.readUint32BE();

		tempFrame._surface = new Graphics::Surface();
		tempFrame._surface->create(frameWidth, frameHeight, Graphics::PixelFormat::createFormatCLUT8());
		if (frameDataOffset == MKTAG('m', 'a', 's', 'm')) {
			tempFrame._isCompressed = true;
			tempFrame._dataSize = stream.readUint32LE();
			tempFrame._compressedData = (byte *)malloc(tempFrame._dataSize);
			stream.read(tempFrame._compressedData, tempFrame._dataSize);
		} else {
			tempFrame._isCompressed = false;
			tempFrame._dataSize = 0;
			tempFrame._compressedData = nullptr;
			stream.seek(frameDataPos);
			for (uint16 i = 0; i < frameHeight; i++) {
				stream.read(tempFrame._surface->getBasePtr(0, i), frameWidth);
			}
		}
		_frameList.push_back(tempFrame);
	}

	return true;
}
Пример #13
0
void GameModule::loadInventoryItemSpriteIndices(Common::SeekableReadStream &s) {
	debug(0, "GameModule::loadInventoryItemSpriteIndices()");

	s.seek(0x18C);
	uint32 offs = s.readUint32LE();
	s.seek(offs);
	for (int i = 0; i < kInventoryItemSpriteCount; ++i)
		_inventoryItemSpriteIndices[i] = s.readUint32LE();
}
Пример #14
0
void GameModule::loadGuiSpriteIndices(Common::SeekableReadStream &s) {
	debug(0, "GameModule::loadGuiSpriteIndices()");

	s.seek(0x188);
	uint32 offs = s.readUint32LE();
	s.seek(offs);
	for (int i = 0; i < kGuiSpriteCount; ++i)
		_guiSpriteIndices[i] = s.readUint32LE();
}
Пример #15
0
void GameModule::loadDialogItemSpriteIndices(Common::SeekableReadStream &s) {
	debug(0, "GameModule::loadDialogItemSpriteIndices()");

	s.seek(0x194);
	uint32 offs = s.readUint32LE();
	s.seek(offs);
	for (int i = 0; i < kDialogItemSpriteCount; ++i) {
		_dialogItemSpriteIndices[i] = s.readUint32LE();
	}
}
Пример #16
0
void GameModule::loadWalkRects(Common::SeekableReadStream &s) {
	debug(0, "GameModule::loadWalkRects()");

	s.seek(0x150);
	_walkRectsCount = s.readUint32LE();
	uint32 offs = s.readUint32LE();
	_walkRects = new Common::Rect[_walkRectsCount];
	s.seek(offs);
	for (int i = 0; i < _walkRectsCount; ++i)
		_walkRects[i] = readRect(s);
}
Пример #17
0
void GameModule::loadPreloadSounds(Common::SeekableReadStream &s) {
	debug(0, "GameModule::loadPreloadSounds()");

	s.seek(0x198);
	_preloadSoundsCount = s.readUint32LE();
	uint32 offs = s.readUint32LE();
	_preloadSounds = new uint[_preloadSoundsCount];
	s.seek(offs);
	for (uint i = 0; i < _preloadSoundsCount; ++i)
		_preloadSounds[i] = s.readUint32LE();
}
Пример #18
0
Common::UString GFF4Struct::getString(Common::SeekableReadStream &data, Common::Encoding encoding,
                                      uint32 offset) const {

	const uint32 pos = data.seek(offset);

	Common::UString str = getString(data, encoding);

	data.seek(pos);

	return str;
}
Пример #19
0
bool skipThumbnail(Common::SeekableReadStream &in) {
	uint32 position = in.pos();
	ThumbnailHeader header;

	if (!loadHeader(in, header, false)) {
		in.seek(position, SEEK_SET);
		return false;
	}

	in.seek(header.size - (in.pos() - position), SEEK_CUR);
	return true;
}
Пример #20
0
void GameModule::loadBgObjects(Common::SeekableReadStream &s) {
	debug(0, "GameModule::loadBgObjects()");

	s.seek(0x160);
	_bgObjectsCount = s.readUint32LE();
	uint32 offs = s.readUint32LE();
	_bgObjects = new BgObject[_bgObjectsCount];
	s.seek(offs);
	for (int i = 0; i < _bgObjectsCount; ++i) {
		s.read(_bgObjects[i].name, 20);
		_bgObjects[i].rect = readRect(s);
	}
}
Пример #21
0
void GameModule::loadSceneSounds(Common::SeekableReadStream &s) {
	debug(0, "GameModule::loadSceneSounds()");

	s.seek(0x1A0);
	_sceneSoundsCount = s.readUint32LE();
	uint32 offs = s.readUint32LE();
	_sceneSounds = new SceneSound[_sceneSoundsCount];
	s.seek(offs);
	for (int i = 0; i < _sceneSoundsCount; ++i) {
		_sceneSounds[i].conditions = readConditions(s);
		_sceneSounds[i].soundNum = s.readUint32LE();
	}
}
Пример #22
0
bool ResLoaderInsMalcolm::isLoadable(const Common::String &filename, Common::SeekableReadStream &stream) const {
	stream.seek(3, SEEK_SET);
	int32 size = stream.readUint32LE();

	if (size + 7 > stream.size())
		return false;

	stream.seek(size + 5, SEEK_SET);
	uint8 buffer[2];
	stream.read(&buffer, 2);

	return (buffer[0] == 0x0D && buffer[1] == 0x0A);
}
Пример #23
0
void GameModule::loadSceneExits(Common::SeekableReadStream &s) {
	debug(0, "GameModule::loadSceneExits()");

	s.seek(0x158);
	_sceneExitsCount = s.readUint32LE();
	uint32 offs = s.readUint32LE();
	_sceneExits = new SceneExit[_sceneExitsCount];
	s.seek(offs);
	for (int i = 0; i < _sceneExitsCount; ++i) {
		_sceneExits[i].rect = readRect(s);
		_sceneExits[i].newModuleNum = s.readUint32LE();
	}
}
Пример #24
0
bool NDSFile::isNDS(Common::SeekableReadStream &stream) {
	if (!stream.seek(0))
		return false;

	Common::UString gameName;
	gameName.readFixedASCII(stream, 12);
	if (gameName != "SONICCHRON") // Should be the only game we will accept.
		return false;

	if (!stream.seek(0x40))
		return false;

	return true;
}
Пример #25
0
void GameModule::loadInventoryItemInfos(Common::SeekableReadStream &s) {
	debug(0, "GameModule::loadInventoryItemInfos()");

	s.seek(0x190);
	uint32 offs = s.readUint32LE();
	s.seek(offs);
	for (int i = 0; i < kInventoryItemCount; ++i) {
		_inventoryItemInfos[i].xOffs = s.readUint16LE();
		_inventoryItemInfos[i].yOffs = s.readUint16LE();
		_inventoryItemInfos[i].width = s.readUint16LE();
		_inventoryItemInfos[i].height = s.readUint16LE();
		s.skip(8); // Unused
	}
}
Пример #26
0
Common::UString GFF4Struct::getString(Common::SeekableReadStream &data, Common::Encoding encoding,
                                      uint32 offset) const {

	if (_parent->hasSharedStrings())
		return _parent->getSharedString(offset);

	const uint32 pos = data.seek(offset);

	Common::UString str = getString(data, encoding);

	data.seek(pos);

	return str;
}
Пример #27
0
void NewFeature::resetScript() {
	// FIXME: registrations, etc
	Common::SeekableReadStream *ourSCRB = _view->getSCRB(_data.scrbIndex, _scrbId);
	ourSCRB->seek(16);
	Common::Point scriptBase, scriptSize;
	scriptBase.x = ourSCRB->readUint16BE();
	scriptBase.y = ourSCRB->readUint16BE();
	scriptSize.x = ourSCRB->readUint16BE();
	scriptSize.y = ourSCRB->readUint16BE();
	ourSCRB->seek(26);
	Common::Point one, two;
	while (true) {
		if (ourSCRB->pos() == ourSCRB->size())
			error("resetScript (getNewXYAndReg) ran out of script");
		byte opcode = ourSCRB->readByte();
		byte size = ourSCRB->readByte();
		if (opcode != 0x10) {
			ourSCRB->skip(size - 2);
		} else if (size) {
			assert(size >= 1);
			ourSCRB->skip(2);
			int16 x = ourSCRB->readUint16BE();
			int16 y = ourSCRB->readUint16BE();
			one.x = -x;
			one.y = -y;
			two.x = scriptBase.x + x;
			two.y = scriptBase.y + y;
			break;
		}
	}
	delete ourSCRB;

	if ((_needsReset || false /* TODO: param */) && (_unknown168 == 0x7FFFFFFF || false /* TODO: param */)) {
		_data.currentPos = two;
		_data.nextPos = one;
		_unknown168 = 0;
		if (_needsReset || false /* TODO: param */) {
			_data.bounds = Common::Rect(scriptBase.x, scriptBase.y, scriptSize.x, scriptSize.y);
		}
	} else {
		if (false /* FIXME: 0 shapes? */) {
			_data.nextPos.x = one.x + two.x - _data.currentPos.x;
			_data.nextPos.y = one.y + two.y - _data.currentPos.y;
		} else if (_unknown168 != 0x7FFFFFFF) {
			_data.nextPos = one;
		}
	}
	// _needsReset = 0; (handled by caller)
}
Пример #28
0
void GameModule::loadSceneObjectDefs(Common::SeekableReadStream &s) {
	debug(0, "GameModule::loadSceneObjectDefs()");

	s.seek(0x170);
	_sceneObjectDefsCount = s.readUint32LE();
	uint32 offs = s.readUint32LE();
	_sceneObjectDefs = new SceneObjectDef[_sceneObjectDefsCount];
	s.seek(offs);
	for (int i = 0; i < _sceneObjectDefsCount; ++i) {
		s.read(_sceneObjectDefs[i].name, 20);
		_sceneObjectDefs[i].walkSpeed = s.readUint32LE();
		for (int j = 0; j < 16; ++j)
			_sceneObjectDefs[i].animIndices[j] = s.readUint32LE();
	}
}
Пример #29
0
void Model_KotOR::readStrings(Common::SeekableReadStream &mdl,
		const std::vector<uint32> &offsets, uint32 offset,
		std::vector<Common::UString> &strings) {

	size_t pos = mdl.pos();

	strings.reserve(offsets.size());
	for (std::vector<uint32>::const_iterator o = offsets.begin(); o != offsets.end(); ++o) {
		mdl.seek(offset + *o);

		strings.push_back(Common::readString(mdl, Common::kEncodingASCII));
	}

	mdl.seek(pos);
}
Пример #30
0
bool Mob::loadFromStream(Common::SeekableReadStream &stream) {
	int32 pos = stream.pos();

	uint16 visible = stream.readUint16LE();

	if (visible == 0xFFFF)
		return false;

	_visible = visible;
	_type = stream.readUint16LE();
	_rect.left = stream.readUint16LE();
	_rect.top = stream.readUint16LE();
	_rect.right = stream.readUint16LE();
	_rect.bottom = stream.readUint16LE();

	_mask = stream.readUint16LE();

	_examPosition.x = stream.readUint16LE();
	_examPosition.y = stream.readUint16LE();
	_examDirection = (Direction)stream.readUint16LE();

	_usePosition.x = stream.readByte();
	_usePosition.y = stream.readByte();
	_useDirection = (Direction)stream.readUint16LE();

	uint32 nameOffset = stream.readUint32LE();
	uint32 examTextOffset = stream.readUint32LE();

	byte c;
	stream.seek(nameOffset);
	_name.clear();
	while ((c = stream.readByte()))
		_name += c;

	stream.seek(examTextOffset);
	_examText.clear();
	c = stream.readByte();
	if (c) {
		_examText += c;
		do {
			c = stream.readByte();
			_examText += c;
		} while (c != 255);
	}
	stream.seek(pos + 32);

	return true;
}