Пример #1
0
bool ComposerEngine::initSprite(Sprite &sprite) {
	Common::SeekableReadStream *stream = getStreamForSprite(sprite._id);
	if (!stream)
		return false;

	uint16 type = stream->readUint16LE();
	int16 height = stream->readSint16LE();
	int16 width = stream->readSint16LE();
	uint32 size = stream->readUint32LE();
	debug(1, "loading BMAP: type %d, width %d, height %d, size %d", type, width, height, size);

	if (width > 0 && height > 0) {
		sprite._surface.create(width, height, Graphics::PixelFormat::createFormatCLUT8());
		decompressBitmap(type, stream, (byte *)sprite._surface.getPixels(), size, width, height);
	} else {
		// there are some sprites (e.g. a -998x-998 one in Gregory's title screen)
		// which have an invalid size, but the original engine doesn't notice for
		// RLE sprites since the width/height is ignored until the actual draw
		if (type != kBitmapRLESLWM)
			error("sprite (type %d) had invalid size %dx%d", type, width, height);
		delete stream;
		return false;
	}
	delete stream;

	return true;
}
Пример #2
0
void KyraEngine_MR::loadSceneMsc() {
	char filename[16];
	strcpy(filename, _sceneList[_mainCharacter.sceneId].filename1);
	strcat(filename, ".MSC");

	_res->exists(filename, true);
	Common::SeekableReadStream *stream = _res->createReadStream(filename);
	assert(stream);
	int16 minY = 0, height = 0;
	minY = stream->readSint16LE();
	height = stream->readSint16LE();
	delete stream;
	stream = 0;
	musicUpdate(0);
	_maskPageMinY = minY;
	_maskPageMaxY = minY + height - 1;

	_screen->setShapePages(5, 3, _maskPageMinY, _maskPageMaxY);

	musicUpdate(0);
	_screen->loadBitmap(filename, 5, 5, 0, true);

	// HACK
	uint8 *data = new uint8[320*200];
	_screen->copyRegionToBuffer(5, 0, 0, 320, 200, data);
	_screen->clearPage(5);
	_screen->copyBlockToPage(5, 0, _maskPageMinY, 320, height, data);
	delete[] data;

	musicUpdate(0);
}
Пример #3
0
void WidthHeight::load(Common::SeekableReadStream &stream) {
	_width = stream.readSint16LE();
	_height = stream.readSint16LE();

	debug(5, "WidthHeight::load() _width: %d; _height: %d",
		_width, _height);
}
Пример #4
0
void AmazonResources::load(Common::SeekableReadStream &s) {
	Resources::load(s);
	uint count;

	// Load the version specific data
	NO_HELP_MESSAGE = readString(s);
	NO_HINTS_MESSAGE = readString(s);
	RIVER_HIT1 = readString(s);
	RIVER_HIT2 = readString(s);
	BAR_MESSAGE = readString(s);

	for (int idx = 0; idx < 3; ++idx)
		HELPLVLTXT[idx] = readString(s);
	for (int idx = 0; idx < 9; ++idx)
		IQLABELS[idx] = readString(s);

	CANT_GET_THERE = readString(s);

	// Get the offset of the general shared data for the game
	uint entryOffset = findEntry(_vm->getGameID(), 2, 0, (Common::Language)0);
	s.seek(entryOffset);

	// Read in the cursor list
	count = s.readUint16LE();
	CURSORS.resize(count);
	for (uint idx = 0; idx < count; ++idx) {
		uint count2 = s.readUint16LE();
		CURSORS[idx].resize(count2);
		s.read(&CURSORS[idx][0], count2);
	}

	// Load font data
	count = s.readUint16LE();
	Common::Array<int> index;
	Common::Array<byte> data;

	index.resize(count);
	for (uint idx = 0; idx < count; ++idx)
		index[idx] = s.readSint16LE();

	count = s.readUint16LE();
	data.resize(count);
	for (uint idx = 0; idx < count; ++idx)
		data[idx] = s.readByte();
	_font3x5 = new AmazonFont(&index[0], &data[0]);

	count = s.readUint16LE();
	index.resize(count);
	for (uint idx = 0; idx < count; ++idx)
		index[idx] = s.readSint16LE();

	count = s.readUint16LE();
	data.resize(count);
	for (uint idx = 0; idx < count; ++idx)
		data[idx] = s.readByte();
	_font6x6 = new AmazonFont(&index[0], &data[0]);
}
Пример #5
0
void Map_v2::loadGoblinStates(Common::SeekableReadStream &data, int index) {
	Mult::Mult_GobState *statesPtr;
	Mult::Mult_GobState *gobState;
	int8 indices[102];
	uint8 statesCount;
	uint8 dataCount;
	int16 state;
	uint32 tmpPos;

	memset(indices, -1, 101);
	_vm->_mult->_objects[index].goblinStates = new Mult::Mult_GobState*[101];
	memset(_vm->_mult->_objects[index].goblinStates, 0,
			101 * sizeof(Mult::Mult_GobState *));

	data.read(indices, 100);
	tmpPos = data.pos();
	statesCount = 0;
	for (int i = 0; i < 100; i++) {
		if (indices[i] != -1) {
			statesCount++;
			data.skip(4);
			dataCount = data.readByte();
			statesCount += dataCount;
			data.skip(dataCount * 9);
		}
	}

	data.seek(tmpPos);

	statesPtr = new Mult::Mult_GobState[statesCount];
	_vm->_mult->_objects[index].goblinStates[0] = statesPtr;
	for (int i = 0; i < 100; i++) {
		state = indices[i];
		if (state != -1) {
			_vm->_mult->_objects[index].goblinStates[state] = statesPtr++;
			gobState = _vm->_mult->_objects[index].goblinStates[state];

			gobState[0].animation = data.readSint16LE();
			gobState[0].layer = data.readSint16LE();
			dataCount = data.readByte();
			gobState[0].dataCount = dataCount;
			for (uint8 j = 1; j <= dataCount; j++) {
				data.skip(1);
				gobState[j].sndItem = data.readSByte();
				data.skip(1);
				gobState[j].sndFrame = data.readByte();
				data.skip(1);
				gobState[j].freq = data.readSint16LE();
				gobState[j].repCount = data.readSByte();
				gobState[j].speaker = data.readByte();
				statesPtr++;
			}
		}
	}
}
Пример #6
0
bool StaticResource::loadCharData(Common::SeekableReadStream &stream, void *&ptr, int &size) {
	size = stream.size() / 130;
	LoLCharacter *charData = new LoLCharacter[size];

	for (int i = 0; i < size; i++) {
		LoLCharacter *t = &charData[i];

		t->flags = stream.readUint16LE();
		stream.read(t->name, 11);
		t->raceClassSex = stream.readByte();
		t->id = stream.readSint16LE();
		t->curFaceFrame = stream.readByte();
		t->tempFaceFrame = stream.readByte();
		t->screamSfx = stream.readByte();
		stream.readUint32LE();
		for (int ii = 0; ii < 8; ii++)
			t->itemsMight[ii] = stream.readUint16LE();
		for (int ii = 0; ii < 8; ii++)
			t->protectionAgainstItems[ii] = stream.readUint16LE();
		t->itemProtection = stream.readUint16LE();
		t->hitPointsCur = stream.readSint16LE();
		t->hitPointsMax = stream.readUint16LE();
		t->magicPointsCur = stream.readSint16LE();
		t->magicPointsMax = stream.readUint16LE();
		t->field_41 = stream.readByte();
		t->damageSuffered = stream.readUint16LE();
		t->weaponHit = stream.readUint16LE();
		t->totalMightModifier = stream.readUint16LE();
		t->totalProtectionModifier = stream.readUint16LE();
		t->might = stream.readUint16LE();
		t->protection = stream.readUint16LE();
		t->nextAnimUpdateCountdown = stream.readSint16LE();
		for (int ii = 0; ii < 11; ii++)
			t->items[ii] = stream.readUint16LE();
		for (int ii = 0; ii < 3; ii++)
			t->skillLevels[ii] = stream.readByte();
		for (int ii = 0; ii < 3; ii++)
			t->skillModifiers[ii] = stream.readByte();
		for (int ii = 0; ii < 3; ii++)
			t->experiencePts[ii] = stream.readUint32LE();
		for (int ii = 0; ii < 5; ii++)
			t->characterUpdateEvents[ii] = stream.readByte();
		for (int ii = 0; ii < 5; ii++)
			t->characterUpdateDelay[ii] = stream.readByte();
	};

	ptr = charData;
	return true;
}
Пример #7
0
int64 GFF4Struct::getSint(Common::SeekableReadStream &data, IFieldType type) const {
	switch (type) {
		case kIFieldTypeUint8:
			return (int64) ((uint64) data.readByte());

		case kIFieldTypeSint8:
			return (int64) data.readSByte();

		case kIFieldTypeUint16:
			return (int64) ((uint64) data.readUint16LE());

		case kIFieldTypeSint16:
			return (int64) data.readSint16LE();

		case kIFieldTypeUint32:
			return (int64) ((uint64) data.readUint32LE());

		case kIFieldTypeSint32:
			return (int64) data.readSint32LE();

		case kIFieldTypeUint64:
			return (int64) ((uint64) data.readUint64LE());

		case kIFieldTypeSint64:
			return (int64) data.readSint64LE();

		default:
			break;
	}

	throw Common::Exception("GFF4: Field is not an int type");
}
Пример #8
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;
}
Пример #9
0
Hotspot::Hotspot(Common::SeekableReadStream &f, bool isV2) {
	_bounds.left = f.readSint16LE();
	_bounds.top = f.readSint16LE();
	_bounds.right = f.readSint16LE();
	_bounds.bottom = f.readSint16LE();
	_feetPos.x = f.readSint16LE();
	_feetPos.y = f.readSint16LE();
	_facing = (Facing)f.readByte();
	_articleNumber = f.readByte();
	_active = f.readByte() != 0;
	_cursor = (CursorType)f.readByte();
	if (isV2) {
		f.skip(1);		// cursor
		f.skip(1);		// syntax
	}
	_vocabId = f.readUint16LE();
	_verbId = f.readUint16LE();
}
Пример #10
0
void ScriptEntry::Conditional::load(Common::SeekableReadStream &s) {
	_operation = (ConditionalOperation)s.readUint16LE();

	if (_operation == CONDOP_ABORT) {
		_param1._isVariable = false;
		_param1._val = 0;
	} else {
		_param1._isVariable = s.readByte() != 0;
		_param1._val = s.readSint16LE();
	}

	if (_operation == CONDOP_ABORT || _operation == CONDOP_VALUE) {
		_param2._isVariable = false;
		_param2._val = 0;
	} else {
		_param2._isVariable = s.readByte() != 0;
		_param2._val = s.readSint16LE();
	}
}
Пример #11
0
void SoundTowns_Darkmoon::loadSoundFile(Common::String name) {
	Common::SeekableReadStream *s = _vm->resource()->createReadStream(Common::String::format("%s.SDT", name.c_str()));
	if (!s)
		error("Failed to load sound file '%s.SDT'", name.c_str());

	for (int i = 0; i < 120; i++) {
		_soundTable[i].type = s->readSByte();
		_soundTable[i].para1 = s->readSint32LE();
		_soundTable[i].para2 = s->readSint16LE();
	}

	delete s;

	uint32 bytesLeft;
	uint8 *pmb = _vm->resource()->fileData(Common::String::format("%s.PMB", name.c_str()).c_str(), &bytesLeft);

	_vm->delay(300);

	if (pmb) {
		uint8 *src = pmb + 8;
		for (int i = 0; i < 32; i++)
			_intf->callback(5, 0x40, i, &src[i << 7]);
		
		_intf->callback(35, -1);
		src += 0x1000;
		bytesLeft -= 0x1008;

		while (bytesLeft) {
			_intf->callback(34, src);
			uint32 len = READ_LE_UINT16(&src[12]) + 32;
			src = src + len;
			bytesLeft -= len;
		}

		delete[] pmb;
	} else {
		warning("Sound file '%s.PMB' not found.", name.c_str());
		// TODO
	}
}
Пример #12
0
void loadPoint(Common::SeekableReadStream &stream, Common::Point &pt) {
	pt.x = stream.readSint16LE();
	pt.y = stream.readSint16LE();
	debug(0, "loadPoint() x: %d; y: %d", pt.x, pt.y);
}
Пример #13
0
void SEQFile::load(Common::SeekableReadStream &seq) {
	const uint16 decCount = (uint16)seq.readByte() + 1;
	const uint16 aniCount = (uint16)seq.readByte() + 1;

	// Load backgrounds
	_backgrounds.reserve(decCount);
	for (uint i = 0; i < decCount; i++) {
		const Common::String dec = Util::readString(seq, 13);

		if (!_vm->_dataIO->hasFile(dec)) {
			warning("SEQFile::load(): No such background \"%s\"", dec.c_str());
			return;
		}

		_backgrounds.push_back(new DECFile(_vm, dec, 320, 200));
	}

	// Load animations
	_animations.reserve(aniCount);
	for (uint i = 0; i < aniCount; i++) {
		const Common::String ani = Util::readString(seq, 13);

		if (!_vm->_dataIO->hasFile(ani)) {
			warning("SEQFile::load(): No such animation \"%s\"", ani.c_str());
			return;
		}

		_animations.push_back(new ANIFile(_vm, ani));
	}

	_frameRate = seq.readUint16LE();

	// Load background change keys

	const uint16 bgKeyCount = seq.readUint16LE();
	_bgKeys.resize(bgKeyCount);

	for (uint16 i = 0; i < bgKeyCount; i++) {
		const uint16 frame = seq.readUint16LE();
		const uint16 index = seq.readUint16LE();

		_bgKeys[i].frame      = frame;
		_bgKeys[i].background = index < _backgrounds.size() ? _backgrounds[index] : 0;
	}

	// Load animation keys for all 4 objects

	for (uint i = 0; i < kObjectCount; i++) {
		const uint16 animKeyCount = seq.readUint16LE();
		_animKeys.reserve(_animKeys.size() + animKeyCount);

		for (uint16 j = 0; j < animKeyCount; j++) {
			_animKeys.push_back(AnimationKey());

			const uint16 frame = seq.readUint16LE();
			const uint16 index = seq.readUint16LE();

			uint16 animation;
			const ANIFile *ani = findANI(index, animation);

			_animKeys.back().object    = i;
			_animKeys.back().frame     = frame;
			_animKeys.back().ani       = ani;
			_animKeys.back().animation = animation;
			_animKeys.back().x         = seq.readSint16LE();
			_animKeys.back().y         = seq.readSint16LE();
			_animKeys.back().order     = seq.readSint16LE();
		}
	}

}
Пример #14
0
void SmushPlayer::handleIACT(int32 subSize, Common::SeekableReadStream &b) {
	debugC(DEBUG_SMUSH, "SmushPlayer::IACT()");
	assert(subSize >= 8);

	int code = b.readUint16LE();
	int flags = b.readUint16LE();
	int unknown = b.readSint16LE();
	int track_flags = b.readUint16LE();

	if ((code != 8) && (flags != 46)) {
		_vm->_insane->procIACT(_dst, 0, 0, 0, b, 0, 0, code, flags, unknown, track_flags);
		return;
	}

	if (_compressedFileMode) {
		return;
	}

	assert(flags == 46 && unknown == 0);
	int track_id = b.readUint16LE();
	int index = b.readUint16LE();
	int nbframes = b.readUint16LE();
	int32 size = b.readUint32LE();
	int32 bsize = subSize - 18;

	if (_vm->_game.id != GID_CMI) {
		int32 track = track_id;
		if (track_flags == 1) {
			track = track_id + 100;
		} else if (track_flags == 2) {
			track = track_id + 200;
		} else if (track_flags == 3) {
			track = track_id + 300;
		} else if ((track_flags >= 100) && (track_flags <= 163)) {
			track = track_id + 400;
		} else if ((track_flags >= 200) && (track_flags <= 263)) {
			track = track_id + 500;
		} else if ((track_flags >= 300) && (track_flags <= 363)) {
			track = track_id + 600;
		} else {
			error("SmushPlayer::handleIACT(): bad track_flags: %d", track_flags);
		}
		debugC(DEBUG_SMUSH, "SmushPlayer::handleIACT(): %d, %d, %d", track, index, track_flags);

		SmushChannel *c = _smixer->findChannel(track);
		if (c == 0) {
			c = new ImuseChannel(track);
			_smixer->addChannel(c);
		}
		if (index == 0)
			c->setParameters(nbframes, size, track_flags, unknown, 0);
		else
			c->checkParameters(index, nbframes, size, track_flags, unknown);
		c->appendData(b, bsize);
	} else {
		// TODO: Move this code into another SmushChannel subclass?
		byte *src = (byte *)malloc(bsize);
		b.read(src, bsize);
		byte *d_src = src;
		byte value;

		while (bsize > 0) {
			if (_IACTpos >= 2) {
				int32 len = READ_BE_UINT16(_IACToutput) + 2;
				len -= _IACTpos;
				if (len > bsize) {
					memcpy(_IACToutput + _IACTpos, d_src, bsize);
					_IACTpos += bsize;
					bsize = 0;
				} else {
					byte *output_data = (byte *)malloc(4096);

					memcpy(_IACToutput + _IACTpos, d_src, len);
					byte *dst = output_data;
					byte *d_src2 = _IACToutput;
					d_src2 += 2;
					int32 count = 1024;
					byte variable1 = *d_src2++;
					byte variable2 = variable1 / 16;
					variable1 &= 0x0f;
					do {
						value = *(d_src2++);
						if (value == 0x80) {
							*dst++ = *d_src2++;
							*dst++ = *d_src2++;
						} else {
							int16 val = (int8)value << variable2;
							*dst++ = val >> 8;
							*dst++ = (byte)(val);
						}
						value = *(d_src2++);
						if (value == 0x80) {
							*dst++ = *d_src2++;
							*dst++ = *d_src2++;
						} else {
							int16 val = (int8)value << variable1;
							*dst++ = val >> 8;
							*dst++ = (byte)(val);
						}
					} while (--count);

					if (!_IACTstream) {
						_IACTstream = Audio::makeQueuingAudioStream(22050, true);
						_vm->_mixer->playStream(Audio::Mixer::kSFXSoundType, &_IACTchannel, _IACTstream);
					}
					_IACTstream->queueBuffer(output_data, 0x1000, DisposeAfterUse::YES, Audio::FLAG_STEREO | Audio::FLAG_16BITS);

					bsize -= len;
					d_src += len;
					_IACTpos = 0;
				}
			} else {
				if (bsize > 1 && _IACTpos == 0) {
					*(_IACToutput + 0) = *d_src++;
					_IACTpos = 1;
					bsize--;
				}
				*(_IACToutput + _IACTpos) = *d_src++;
				_IACTpos++;
				bsize--;
			}
		}
Пример #15
0
void KyraEngine_MR::initSceneScript(int unk1) {
	const SceneDesc &scene = _sceneList[_mainCharacter.sceneId];
	musicUpdate(0);

	char filename[16];
	strcpy(filename, scene.filename1);
	strcat(filename, ".DAT");

	_res->exists(filename, true);
	Common::SeekableReadStream *stream = _res->createReadStream(filename);
	assert(stream);
	stream->seek(2, SEEK_CUR);

	byte scaleTable[15];
	stream->read(scaleTable, 15);
	stream->read(_sceneDatPalette, 45);
	stream->read(_sceneDatLayerTable, 15);
	int16 shapesCount = stream->readSint16LE();

	for (int i = 0; i < 15; ++i)
		_scaleTable[i] = (uint16(scaleTable[i]) << 8) / 100;

	if (shapesCount > 0) {
		strcpy(filename, scene.filename1);
		strcat(filename, "9.CPS");
		musicUpdate(0);
		_screen->loadBitmap(filename, 3, 3, 0);
		int pageBackUp = _screen->_curPage;
		_screen->_curPage = 2;
		for (int i = 0; i < shapesCount; ++i) {
			int16 x = stream->readSint16LE();
			int16 y = stream->readSint16LE();
			int16 w = stream->readSint16LE();
			int16 h = stream->readSint16LE();
			_sceneShapeDescs[i].drawX = stream->readSint16LE();
			_sceneShapeDescs[i].drawY = stream->readSint16LE();
			_sceneShapes[i] = _screen->encodeShape(x, y, w, h, 0);
			assert(_sceneShapes[i]);
			musicUpdate(0);
		}
		_screen->_curPage = pageBackUp;
		musicUpdate(0);
	}
	delete stream;
	stream = 0;
	musicUpdate(0);

	strcpy(filename, scene.filename1);
	strcat(filename, ".CPS");
	_screen->loadBitmap(filename, 3, 3, 0);
	musicUpdate(0);

	Common::set_to(_specialSceneScriptState, _specialSceneScriptState+ARRAYSIZE(_specialSceneScriptState), false);
	_sceneEnterX1 = 160;
	_sceneEnterY1 = 0;
	_sceneEnterX2 = 296;
	_sceneEnterY2 = 93;
	_sceneEnterX3 = 160;
	_sceneEnterY3 = 171;
	_sceneEnterX4 = 24;
	_sceneEnterY4 = 93;
	_sceneMinX = 0;
	_sceneMaxX = 319;

	_emc->init(&_sceneScriptState, &_sceneScriptData);
	strcpy(filename, scene.filename2);
	strcat(filename, ".EMC");
	musicUpdate(0);
	_res->exists(filename, true);
	_emc->load(filename, &_sceneScriptData, &_opcodes);

	strcpy(filename, scene.filename2);
	strcat(filename, ".");
	loadLanguageFile(filename, _sceneStrings);
	musicUpdate(0);

	runSceneScript8();
	_emc->start(&_sceneScriptState, 0);
	_sceneScriptState.regs[0] = _mainCharacter.sceneId;
	_sceneScriptState.regs[5] = unk1;
	while (_emc->isValid(&_sceneScriptState))
		_emc->run(&_sceneScriptState);

	_screen->copyRegionToBuffer(3, 0, 0, 320, 200, _gamePlayBuffer);
	musicUpdate(0);

	for (int i = 0; i < 10; ++i) {
		_emc->init(&_sceneSpecialScripts[i], &_sceneScriptData);
		_emc->start(&_sceneSpecialScripts[i], i+9);
		musicUpdate(0);
		_sceneSpecialScriptsTimer[i] = 0;
	}

	_sceneEnterX1 &= ~3;
	_sceneEnterY1 &= ~1;
	_sceneEnterX2 &= ~3;
	_sceneEnterY2 &= ~1;
	_sceneEnterX3 &= ~3;
	_sceneEnterY3 &= ~1;
	_sceneEnterX4 &= ~3;
	_sceneEnterY4 &= ~1;
	musicUpdate(0);
}
Пример #16
0
void ConversationConditionals::load(const Common::String &filename) {
	Common::File inFile;
	Common::SeekableReadStream *convFile;

	// Open up the file for access
	inFile.open(filename);
	MadsPack convFileUnpacked(&inFile);

	// **** Section 0: Header *************************************************
	convFile = convFileUnpacked.getItemStream(0);

	_currentNode = convFile->readUint16LE();
	int entryFlagsCount = convFile->readUint16LE();
	int varsCount = convFile->readUint16LE();
	int importsCount = convFile->readUint16LE();

	convFile->skip(4);

	_messageList1.resize(convFile->readUint16LE());
	_messageList2.resize(convFile->readUint16LE());
	_messageList3.resize(convFile->readUint16LE());
	_messageList4.resize(convFile->readUint16LE());
	convFile->skip(20);

	for (uint idx = 0; idx < 10; ++idx) {
		int v = convFile->readUint16LE();
		if (idx < _messageList1.size())
			_messageList1[idx] = v;
	}
	for (uint idx = 0; idx < 10; ++idx) {
		int v = convFile->readUint16LE();
		if (idx < _messageList2.size())
			_messageList2[idx] = v;
	}
	for (uint idx = 0; idx < 10; ++idx) {
		int v = convFile->readUint16LE();
		if (idx < _messageList3.size())
			_messageList3[idx] = v;
	}
	for (uint idx = 0; idx < 10; ++idx) {
		int v = convFile->readUint16LE();
		if (idx < _messageList4.size())
			_messageList4[idx] = v;
	}

	delete convFile;

	// **** Section: Imports *************************************************
	int streamNum = 1;
	
	_importVariables.resize(importsCount);
	if (importsCount > 0) {
		convFile = convFileUnpacked.getItemStream(streamNum++);

		// Read in the variable indexes that each import value will be stored in
		for (int idx = 0; idx < importsCount; ++idx)
			_importVariables[idx] = convFile->readUint16LE();

		delete convFile;
	}

	// **** Section: Entry Flags *********************************************
	convFile = convFileUnpacked.getItemStream(streamNum++);
	assert(convFile->size() == (entryFlagsCount * 2));

	_entryFlags.resize(entryFlagsCount);
	for (int idx = 0; idx < entryFlagsCount; ++idx)
		_entryFlags[idx] = convFile->readUint16LE();

	delete convFile;

	// **** Section: Variables ***********************************************
	convFile = convFileUnpacked.getItemStream(streamNum);
	assert(convFile->size() == (varsCount * 6));

	_vars.resize(varsCount);
	for (int idx = 0; idx < varsCount; ++idx) {
		convFile->skip(2);	// Loaded values are never pointers, so don't need this
		_vars[idx]._isPtr = false;
		_vars[idx]._val = convFile->readSint16LE();
		convFile->skip(2);	// Unused segment selector for pointer values
	}

	delete convFile;
}
Пример #17
0
void ScriptEntry::load(Common::SeekableReadStream &s) {
	// Get the command byte
	_command = (DialogCommand)s.readByte();

	if (!(_command == CMD_DIALOG_END || (_command >= CMD_END && _command <= CMD_ASSIGN))) {
		warning("unknown opcode - %d", _command);
		s.seek(0, SEEK_END);
		return;
	}

	// Get in the conditional values
	int numConditionals = 1;
	if (_command == CMD_NODE)
		numConditionals = 3;
	else if (_command == CMD_ASSIGN)
		numConditionals = 2;
	else if (_command == CMD_ERROR)
		numConditionals = 0;

	for (int idx = 0; idx < numConditionals; ++idx)
		_conditionals[idx].load(s);

	// Get further parameters
	switch (_command) {
	case CMD_1:
	case CMD_HIDE:
	case CMD_UNHIDE: {
		// Read in the list of entries whose flags are to be updated
		int count = s.readByte();
		for (int idx = 0; idx < count; ++idx)
			_entries.push_back(s.readSint16LE());
		break;
	}

	case CMD_MESSAGE1:
	case CMD_MESSAGE2: {
		int count2 = s.readByte();
		int count1 = s.readByte();
		_entries2.resize(count2);
		_entries.resize(count1);

		for (uint idx = 0; idx < _entries2.size(); ++idx) {
			int v = s.readByte();
			if (idx < 10)
				_entries2[idx]._size = v;
		}
		for (uint idx = 0; idx < _entries2.size(); ++idx) {
			int v = s.readUint16LE();
			if (idx < 10)
				_entries2[idx]._v2 = v;
		}
		for (uint idx = 0; idx < _entries.size(); ++idx) {
			int v = s.readUint16LE();
			if (idx < 10)
				_entries[idx] = v;
		}
		break;
	}

	case CMD_ERROR:
	case CMD_NODE:
		// These opcodes have no extra parameters
		break;

	case CMD_GOTO:
	case CMD_ASSIGN:
		// Goto has a single extra parameter for the destination
		// Assign has a single extra parameter for the variable index
		//		that the value resulting from the condition will be set to
		_index = s.readUint16LE();
		break;

	default:
		break;
	}
}
Пример #18
0
void MadsSceneResources::load(int sceneNumber, const char *resName, int v0, M4Surface *depthSurface, M4Surface *surface) {
	char buffer1[80];
	const char *sceneName;

	// TODO: Initialise spriteSet / xp_list

	if (sceneNumber > 0) {
		sceneName = MADSResourceManager::getResourceName(RESPREFIX_RM, sceneNumber, ".DAT");
	} else {
		strcpy(buffer1, "*");
		strcat(buffer1, resName);
		sceneName = buffer1; // TODO: Check whether this needs to be converted to 'HAG form'
	}

	Common::SeekableReadStream *rawStream = _vm->_resourceManager->get(sceneName);
	MadsPack sceneInfo(rawStream);

	// Chunk 0:
	// Basic scene info
	Common::SeekableReadStream *stream = sceneInfo.getItemStream(0);

	if (_vm->getGameType() == GType_RexNebular) {
		int resSceneId = stream->readUint16LE();
		assert(resSceneId == sceneNumber);
	} else {
		char roomFilename[10];
		char roomFilenameExpected[10];
		sprintf(roomFilenameExpected, "*RM%d", sceneNumber);

		stream->read(roomFilename, 6);
		roomFilename[6] = 0;
		assert(!strcmp(roomFilename, roomFilenameExpected));
	}

	// TODO: The following is wrong for Phantom/Dragon
	_artFileNum = stream->readUint16LE();
	_depthStyle = stream->readUint16LE();
	_width = stream->readUint16LE();
	_height = stream->readUint16LE();
	
	stream->skip(24);

	int nodeCount = stream->readUint16LE();
	_yBandsEnd = stream->readUint16LE();
	_yBandsStart = stream->readUint16LE();
	_maxScale = stream->readSint16LE();
	_minScale = stream->readSint16LE();
	for (int i = 0; i < DEPTH_BANDS_SIZE; ++i)
		_depthBands[i] = stream->readUint16LE();
	stream->skip(2);

	// Load in any scene objects
	for (int i = 0; i < nodeCount; ++i) {
		SceneNode rec;
		rec.load(stream);
		_nodes.push_back(rec);
	}
	for (int i = 0; i < 20 - nodeCount; ++i)
		stream->skip(48);

	// Add two extra nodes in that will be used for player movement
	for (int i = 0; i < 2; ++i) {
		SceneNode rec;
		_nodes.push_back(rec);
	}

	int setCount = stream->readUint16LE();
	stream->readUint16LE();
	for (int i = 0; i < setCount; ++i) {
		char buffer2[64];
		Common::String s(buffer2, 64);
		_setNames.push_back(s);
	}

	delete stream;

	// Initialise a copy of the surfaces if they weren't provided
	bool dsFlag = false, ssFlag = false;
	if (!surface) {
		surface = new M4Surface(_width, _height);
		ssFlag = true;
	} else if ((_width != surface->width()) || (_height != surface->height()))
		surface->setSize(_width, _height);

	if (!depthSurface) {
		depthSurface = new M4Surface(_width, _height);
		dsFlag = true;
	} else if ((_width != depthSurface->width()) || (_height != depthSurface->height()))
		depthSurface->setSize(_width, _height);


	// For Rex Nebular, read in the scene's compressed walk surface information
	if (_vm->getGameType() == GType_RexNebular) {
		assert(depthSurface);
		stream = sceneInfo.getItemStream(1);
		byte *walkData = (byte *)malloc(stream->size());
		stream->read(walkData, stream->size());

		// For Rex Nebular, the walk areas are part of the scene info
		byte *destP = depthSurface->getBasePtr(0, 0);
		const byte *srcP = walkData;
		byte runLength;

		// Run length encoded depth data
		while ((runLength = *srcP++) != 0) {
			if (_depthStyle == 2) {
				// 2-bit depth pixels
				byte byteVal = *srcP++;
				for (int byteCtr = 0; byteCtr < runLength; ++byteCtr) {
					byte v = byteVal;
					for (int bitCtr = 0; bitCtr < 4; ++bitCtr, v >>= 2)
						*destP++ = (((v & 1) + 1) << 3) - 1;
				}
			} else {
Пример #19
0
void ConversationData::load(const Common::String &filename) {
	Common::File inFile;
	char buffer[16];

	inFile.open(filename);
	MadsPack convFileUnpacked(&inFile);

	// **** Section 0: Header *************************************************
	Common::SeekableReadStream *convFile = convFileUnpacked.getItemStream(0);

	_nodeCount = convFile->readUint16LE();
	_dialogCount = convFile->readUint16LE();
	_messageCount = convFile->readUint16LE();
	_textLineCount = convFile->readUint16LE();
	_unk2 = convFile->readUint16LE();
	_maxImports = convFile->readUint16LE();
	_speakerCount = convFile->readUint16LE();

	for (uint idx = 0; idx < MAX_SPEAKERS; ++idx) {
		convFile->read(buffer, 16);
		_portraits[idx] = buffer;
	}

	for (uint idx = 0; idx < MAX_SPEAKERS; ++idx) {
		_speakerFrame[idx] = convFile->readUint16LE();
	}

	convFile->read(buffer, 14);
	_speechFile = Common::String(buffer);

	// Total text length in section 5
	_textSize = convFile->readUint32LE();
	_commandsSize = convFile->readUint32LE();

	// The rest of the section 0 is padding to allow room for a set of pointers
	// to the contents of the remaining sections loaded into memory as a
	// continuous data block containing both the header and the sections
	delete convFile;

	// **** Section 1: Nodes **************************************************
	convFile = convFileUnpacked.getItemStream(1);

	_nodes.clear();
	for (uint i = 0; i < _nodeCount; i++) {
		ConvNode node;
		node._index = convFile->readUint16LE();
		node._dialogCount = convFile->readUint16LE();
		node._unk1 = convFile->readSint16LE();	// TODO
		node._active = convFile->readSint16LE() != 0;
		node._unk3 = convFile->readSint16LE();	// TODO
		_nodes.push_back(node);
	}

	delete convFile;

	// **** Section 2: Dialogs ************************************************
	convFile = convFileUnpacked.getItemStream(2);
	assert(convFile->size() == _dialogCount * 8);

	_dialogs.resize(_dialogCount);
	for (uint idx = 0; idx < _dialogCount; ++idx) {
		_dialogs[idx]._textLineIndex = convFile->readSint16LE();
		_dialogs[idx]._speechIndex = convFile->readSint16LE();
		_dialogs[idx]._scriptOffset = convFile->readUint16LE();
		_dialogs[idx]._scriptSize = convFile->readUint16LE();
	}

	delete convFile;

	// **** Section 3: Messages ***********************************************
	convFile = convFileUnpacked.getItemStream(3);
	assert(convFile->size() == _messageCount * 4);

	_messages.resize(_messageCount);
	for (uint idx = 0; idx < _messageCount; ++idx) {
		_messages[idx]._stringIndex = convFile->readUint16LE();
		_messages[idx]._count = convFile->readUint16LE();
	}

	delete convFile;

	// **** Section 4: Text line offsets **************************************
	convFile = convFileUnpacked.getItemStream(4);
	assert(convFile->size() == _textLineCount * 2);

	uint16 *textLineOffsets = new uint16[_textLineCount];	// deleted below in section 5
	for (uint16 i = 0; i < _textLineCount; i++)
		textLineOffsets[i] = convFile->readUint16LE();

	delete convFile;

	// **** Section 5: Text lines *********************************************
	convFile = convFileUnpacked.getItemStream(5);
	assert(convFile->size() == _textSize);

	Common::String textLine;
	_textLines.resize(_textLineCount);
	char textLineBuffer[256];
	uint16 nextOffset;
	for (uint16 i = 0; i < _textLineCount; i++) {
		nextOffset = (i != _textLineCount - 1) ? textLineOffsets[i + 1] : convFile->size();
		convFile->read(textLineBuffer, nextOffset - textLineOffsets[i]);
		_textLines[i] = Common::String(textLineBuffer);
	}

	delete[] textLineOffsets;
	delete convFile;

	// **** Section 6: Scripts ************************************************
	convFile = convFileUnpacked.getItemStream(6);
	assert(convFile->size() == _commandsSize);

	for (uint idx = 0; idx < _dialogs.size(); ++idx) {
		// Move to the correct position for the dialog's script, and create
		// a memory stream to represent the data for just that script
		convFile->seek(_dialogs[idx]._scriptOffset);
		Common::SeekableReadStream *scriptStream = convFile->readStream(_dialogs[idx]._scriptSize);

		// Pass it to the dialog's script set class to parse into commands
		_dialogs[idx]._script.load(*scriptStream, _dialogs[idx]._scriptOffset);
		delete scriptStream;
	}

	delete convFile;
	inFile.close();
}
Пример #20
0
void ConversationData::load(const Common::String &filename) {
	Common::File inFile;
	char buffer[16];

	inFile.open(filename);
	MadsPack convFileUnpacked(&inFile);
	Common::SeekableReadStream *convFile = convFileUnpacked.getItemStream(0);

	// **** Section 0: Header *************************************************
	_nodeCount = convFile->readUint16LE();
	_dialogCount = convFile->readUint16LE();
	_messageCount = convFile->readUint16LE();
	_textLineCount = convFile->readUint16LE();
	_unk2 = convFile->readUint16LE();
	_importCount = convFile->readUint16LE();
	_speakerCount = convFile->readUint16LE();

	for (uint idx = 0; idx < MAX_SPEAKERS; ++idx) {
		convFile->read(buffer, 16);
		_portraits[idx] = buffer;
	}

	for (uint idx = 0; idx < MAX_SPEAKERS; ++idx) {
		_speakerExists[idx] = convFile->readUint16LE();
	}

	convFile->read(buffer, 14);
	_speechFile = Common::String(buffer);

	// Total text length in section 5
	_textSize = convFile->readUint32LE();
	_commandsSize = convFile->readUint32LE();

	// The rest of the section 0 is padding to allow room for a set of pointers
	// to the contents of the remaining sections loaded into memory as a
	// continuous data block containing both the header and the sections
	delete convFile;

	// **** Section 1: Nodes **************************************************
	convFile = convFileUnpacked.getItemStream(1);

	_convNodes.clear();
	for (uint i = 0; i < _nodeCount; i++) {
		ConvNode node;
		node._index = convFile->readUint16LE();
		node._dialogCount = convFile->readUint16LE();
		node._unk1 = convFile->readSint16LE();	// TODO
		node._unk2 = convFile->readSint16LE();	// TODO
		node._unk3 = convFile->readSint16LE();	// TODO
		_convNodes.push_back(node);
		//debug("Node %d, index %d, entries %d - %d, %d, %d", i, node.index, node.dialogCount, node.unk1, node.unk2, node.unk3);
	}
	delete convFile;

	// **** Section 2: Dialogs ************************************************
	convFile = convFileUnpacked.getItemStream(2);
	assert(convFile->size() == _dialogCount * 8);

	for (uint idx = 0; idx < _nodeCount; ++idx) {
		uint dialogCount = _convNodes[idx]._dialogCount;

		for (uint j = 0; j < dialogCount; ++j) {
			ConvDialog dialog;
			dialog._textLineIndex = convFile->readSint16LE();
			dialog._speechIndex = convFile->readSint16LE();
			dialog._nodeOffset = convFile->readUint16LE();
			dialog._nodeSize = convFile->readUint16LE();
			_convNodes[idx]._dialogs.push_back(dialog);
		}
	}
	delete convFile;

	// **** Section 3: Messages ***********************************************
	convFile = convFileUnpacked.getItemStream(3);
	assert(convFile->size() == _messageCount * 8);

	_messages.resize(_messageCount);
	for (uint idx = 0; idx < _messageCount; ++idx)
		_messages[idx] = convFile->readUint32LE();

	delete convFile;

	// **** Section 4: Text line offsets **************************************
	convFile = convFileUnpacked.getItemStream(4);
	assert(convFile->size() == _textLineCount * 2);

	uint16 *textLineOffsets = new uint16[_textLineCount];	// deleted below in section 5
	for (uint16 i = 0; i < _textLineCount; i++)
		textLineOffsets[i] = convFile->readUint16LE();

	delete convFile;

	// **** Section 5: Text lines *********************************************
	convFile = convFileUnpacked.getItemStream(5);
	assert(convFile->size() == _textSize);

	Common::String textLine;
	_textLines.resize(_textLineCount);
	char textLineBuffer[256];
	uint16 nextOffset;
	for (uint16 i = 0; i < _textLineCount; i++) {
		nextOffset = (i != _textLineCount - 1) ? textLineOffsets[i + 1] : convFile->size();
		convFile->read(textLineBuffer, nextOffset - textLineOffsets[i]);
		_textLines[i] = Common::String(textLineBuffer);
	}

	delete[] textLineOffsets;
	delete convFile;

	// **** Section 6: Node entry commands ************************************
	convFile = convFileUnpacked.getItemStream(6);
	assert(convFile->size() == _commandsSize);

	for (uint16 i = 0; i < _nodeCount; i++) {
		uint16 dialogCount = _convNodes[i]._dialogCount;

		for (uint16 j = 0; j < dialogCount; j++) {
			//ConvDialog dialog = _convNodes[i].dialogs[j];
			byte command;
			uint16 chk;

			do {
				command = convFile->readByte();
				chk = convFile->readUint16BE();
				if (chk != 0xFF00 && chk != 0x0000) {
					warning("Error while reading conversation node entries - bailing out");
					break;
				}

				switch (command) {
				case cmdNodeEnd:
					//debug("Node end");
					break;
				case cmdDialogEnd:
					//debug("Dialog end");
					break;
				case cmdHide: {
					byte count = convFile->readByte();
					for (byte k = 0; k < count; k++) {
						/*uint16 nodeRef = */convFile->readUint16LE();
						//debug("Hide node %d", nodeRef);
					}

				}
							  break;
				case cmdUnhide: {
					byte count = convFile->readByte();
					for (byte k = 0; k < count; k++) {
						/*uint16 nodeRef = */convFile->readUint16LE();
						//debug("Unhide node %d", nodeRef);
					}

				}
								break;
				case cmdMessage:
					//debug("Message");
					convFile->skip(7);	// TODO
					break;
				case cmdGoto: {
					convFile->skip(3);	// unused?
					/*byte nodeRef = */convFile->readByte();
					//debug("Goto %d", nodeRef);
				}
							  break;
				case cmdAssign: {
					convFile->skip(3);	// unused?
					/*uint16 value = */convFile->readUint16LE();
					/*uint16 variable = */convFile->readUint16LE();
					//debug("Variable %d = %d", variable, value);
				}
								break;
				default:
					error("Unknown conversation command %d", command);
					break;
				}
			} while (command != cmdNodeEnd && command != cmdDialogEnd);
		}
	}

	delete convFile;
	inFile.close();

	// TODO: Still stuff to do
	warning("TODO GameConversations::get");
}
Пример #21
0
void FileIdent::load(Common::SeekableReadStream &s) {
	_fileNum = s.readSint16LE();
	_subfile = s.readUint16LE();
}
Пример #22
0
/**
 * Initialises and loads the data of an animation
 */
void MadsAnimation::initialise(const Common::String &filename, uint16 flags, M4Surface *surface, M4Surface *depthSurface) {
	MadsPack anim(filename.c_str(), _vm);
	bool madsRes = filename[0] == '*';
	char buffer[20];
	int streamIndex = 1;

	// Chunk 1: header
	// header

	Common::SeekableReadStream *animStream = anim.getItemStream(0);

	int spriteListCount = animStream->readUint16LE();
	int miscEntriesCount = animStream->readUint16LE();
	int frameEntryCount = animStream->readUint16LE();
	int messagesCount = animStream->readUint16LE();
	animStream->skip(1);
	_flags = animStream->readByte();

	animStream->skip(2);
	_animMode = animStream->readUint16LE();
	_roomNumber = animStream->readUint16LE();
	animStream->skip(2);
	_field12 = animStream->readUint16LE() != 0;
	_spriteListIndex = animStream->readUint16LE();
	_scrollX = animStream->readSint16LE();
	_scrollY = animStream->readSint16LE();
	_scrollTicks = animStream->readUint16LE();
	animStream->skip(8);
	
	animStream->read(buffer, FILENAME_SIZE);
	buffer[FILENAME_SIZE] = '\0';
	_interfaceFile = Common::String(buffer);

	for (int i = 0; i < 10; ++i) {
		animStream->read(buffer, FILENAME_SIZE);
		buffer[FILENAME_SIZE] = '\0';
		_spriteSetNames[i] = Common::String(buffer);
	}

	animStream->skip(81);
	animStream->read(buffer, FILENAME_SIZE);
	buffer[FILENAME_SIZE] = '\0';
	_lbmFilename = Common::String(buffer);

	animStream->skip(365);
	animStream->read(buffer, FILENAME_SIZE);
	buffer[FILENAME_SIZE] = '\0';
	_spritesFilename = Common::String(buffer);

	animStream->skip(48);
	animStream->read(buffer, FILENAME_SIZE);
	buffer[FILENAME_SIZE] = '\0';
	_soundName = Common::String(buffer);

	animStream->skip(13);
	animStream->read(buffer, FILENAME_SIZE);
	buffer[FILENAME_SIZE] = '\0';
	_dsrName = Common::String(buffer);

	animStream->read(buffer, FILENAME_SIZE);
	buffer[FILENAME_SIZE] = '\0';
	Common::String fontResource(buffer);

	if (_animMode == 4)
		flags |= 0x4000;
	if (flags & 0x100)
		loadInterface(surface, depthSurface);

	// Initialise the reference list
	for (int i = 0; i < spriteListCount; ++i)
		_spriteListIndexes.push_back(-1);

	delete animStream;

	if (messagesCount > 0) {
		// Chunk 2
		// Following is a list of any messages for the animation

		animStream = anim.getItemStream(streamIndex++);

		for (int i = 0; i < messagesCount; ++i) {
			AnimMessage rec;
			rec.soundId = animStream->readSint16LE();
			animStream->read(rec.msg, 64);
			animStream->skip(4);
			rec.pos.x = animStream->readSint16LE();
			rec.pos.y = animStream->readSint16LE();
			rec.flags = animStream->readUint16LE();
			rec.rgb1.r = animStream->readByte() << 2;
			rec.rgb1.g = animStream->readByte() << 2;
			rec.rgb1.b = animStream->readByte() << 2;
			rec.rgb2.r = animStream->readByte() << 2;
			rec.rgb2.g = animStream->readByte() << 2;
			rec.rgb2.b = animStream->readByte() << 2;
			animStream->skip(2);	// Space for kernelMsgIndex
			rec.kernelMsgIndex = -1;
			animStream->skip(6);
			rec.startFrame = animStream->readUint16LE();
			rec.endFrame = animStream->readUint16LE();
			animStream->skip(2);

			_messages.push_back(rec);
		}

		delete animStream;
	}

	if (frameEntryCount > 0) {
		// Chunk 3: animation frame info
		animStream = anim.getItemStream(streamIndex++);

		for (int i = 0; i < frameEntryCount; i++) {
			AnimFrameEntry rec;
			rec.frameNumber = animStream->readUint16LE();
			rec.seqIndex = animStream->readByte();
			rec.spriteSlot.spriteListIndex = animStream->readByte();
			rec.spriteSlot.frameNumber = animStream->readUint16LE();
			rec.spriteSlot.xp = animStream->readSint16LE();
			rec.spriteSlot.yp = animStream->readSint16LE();
			rec.spriteSlot.depth = animStream->readSByte();
			rec.spriteSlot.scale = (int8)animStream->readByte();

			_frameEntries.push_back(rec);
		}

		delete animStream;
	}

	if (miscEntriesCount > 0) {
		// Chunk 4: Misc Data
		animStream = anim.getItemStream(streamIndex);

		for (int i = 0; i < miscEntriesCount; ++i) {
			AnimMiscEntry rec;
			rec.soundNum = animStream->readByte();
			rec.msgIndex = animStream->readSByte();
			rec.numTicks = animStream->readUint16LE();
			rec.posAdjust.x = animStream->readUint16LE();
			rec.posAdjust.y = animStream->readUint16LE();
			animStream->readUint16LE();

			_miscEntries.push_back(rec);
		}

		delete animStream;
	}

	// If the animation specifies a font, then load it for access
	if (_flags & ANIM_CUSTOM_FONT) {
		Common::String fontName;
		if (madsRes)
			fontName += "*";
		fontName += fontResource;

		if (fontName != "")
			_font = _vm->_font->getFont(fontName.c_str());
		else
			warning("Attempted to set a font with an empty name");
	}

	// If a speech file is specified, then load it
	if (!_dsrName.empty())
		_vm->_sound->loadDSRFile(_dsrName.c_str());

	// Load all the sprite sets for the animation
	for (int i = 0; i < spriteListCount; ++i) {
		if (_field12 && (i == _spriteListIndex))
			// Skip over field, since it's manually loaded		
			continue;

		_spriteListIndexes[i] = _view->_spriteSlots.addSprites(_spriteSetNames[i].c_str());
	}


	if (_field12) {
		Common::String resName;
		if (madsRes)
			resName += "*";
		resName += _spriteSetNames[_spriteListIndex];
		
		_spriteListIndexes[_spriteListIndex] = _view->_spriteSlots.addSprites(resName.c_str());
	}

	// TODO: Unknown section about handling sprite set list combined with messages size

	// TODO: The original has two separate loops for the loop below based on _animMode == 4. Is it
	// perhaps that in that mode the sprite frames has a different format..?

	// Remap the sprite list index fields from the initial value to the indexes of the loaded
	// sprite sets for the animation
	for (uint i = 0; i < _frameEntries.size(); ++i)  {
		int idx = _frameEntries[i].spriteSlot.spriteListIndex;
		_frameEntries[i].spriteSlot.spriteListIndex = _spriteListIndexes[idx];
	}

	if (hasScroll())
		_nextScrollTimer = _madsVm->_currentTimer + _scrollTicks;
}