Пример #1
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]);
}
Пример #2
0
RivenSimpleCommand *RivenSimpleCommand::createFromStream(MohawkEngine_Riven *vm, RivenCommandType type, Common::ReadStream *stream) {
	uint16 argc = stream->readUint16BE();

	Common::Array<uint16> arguments;
	arguments.resize(argc);

	for (uint16 i = 0; i < argc; i++) {
		arguments[i] = stream->readUint16BE();
	}

	return new RivenSimpleCommand(vm, type, arguments);
}
Пример #3
0
Common::Array<SaveContainer::PartInfo> *SaveContainer::getPartsInfo(Common::SeekableReadStream &stream) {
	Common::Array<PartInfo> *parts = 0;

	// Remember the stream's position to seek back to
	uint32 startPos = stream.pos();

	SaveHeader header;

	header.setType(kID);
	header.setVersion(kVersion);

	// Verify the header
	if (!header.verifyReadSize(stream)) {
		// Seek back
		stream.seek(startPos);
		return 0;
	}

	// Read the part count
	uint32 partCount = stream.readUint32LE();

	// Create a part information array
	parts = new Common::Array<PartInfo>;
	parts->resize(partCount);

	// Read all part sizes
	for (uint32 i = 0; i < partCount; i++)
		(*parts)[i].size = stream.readUint32LE();

	// Iterate over all parts
	for (uint32 i = 0; i < partCount; i++) {
		// The part's offset (from the starting point of the stream)
		(*parts)[i].offset = stream.pos() - startPos;

		SaveHeader partHeader;

		// Read the header
		if (!partHeader.read(stream)) {
			// Seek back
			stream.seek(startPos);
			delete parts;
			return 0;
		}

		// Fill in the ID
		(*parts)[i].id = partHeader.getType();

		// Skip the part's content
		stream.skip(partHeader.getSize());
	}

	if (stream.err()) {
		delete parts;
		parts = 0;
	}

	// Seek back
	stream.seek(startPos);

	return parts;
}
Пример #4
0
void SagaEngine::loadStrings(StringsTable &stringsTable, const ByteArray &stringsData) {
	uint16 stringsCount;
	size_t offset;
	size_t prevOffset = 0;
	Common::Array<size_t> tempOffsets;
	uint ui;

	if (stringsData.empty()) {
		error("SagaEngine::loadStrings() Error loading strings list resource");
	}


	ByteArrayReadStreamEndian scriptS(stringsData, isBigEndian()); //TODO: get endianess from context

	offset = scriptS.readUint16();
	stringsCount = offset / 2;
	ui = 0;
	scriptS.seek(0);
	tempOffsets.resize(stringsCount);
	while (ui < stringsCount) {
		offset = scriptS.readUint16();
		// In some rooms in IHNM, string offsets can be greater than the maximum value than a 16-bit integer can hold
		// We detect this by checking the previous offset, and if it was bigger than the current one, an overflow
		// occurred (since the string offsets are sequential), so we're adding the missing part of the number
		// Fixes bug #1895205 - "IHNM: end game text/caption error"
		if (prevOffset > offset)
			offset += 65536;
		prevOffset = offset;
		if (offset == stringsData.size()) {
			stringsCount = ui;
			tempOffsets.resize(stringsCount);
			break;
		}
		if (offset > stringsData.size()) {
			// This case should never occur, but apparently it does in the Italian fan
			// translation of IHNM
			warning("SagaEngine::loadStrings wrong strings table");
			stringsCount = ui;
			tempOffsets.resize(stringsCount);
			break;
		}
		tempOffsets[ui] = offset;
		ui++;
	}

	prevOffset = scriptS.pos();
	int32 left = scriptS.size() - prevOffset;
	if (left < 0) {
		error("SagaEngine::loadStrings() Error loading strings buffer");
	}

	stringsTable.buffer.resize(left);
	if (left > 0) {
		scriptS.read(&stringsTable.buffer.front(), left);
	}

	stringsTable.strings.resize(tempOffsets.size());
	for (ui = 0; ui < tempOffsets.size(); ui++) {
		offset = tempOffsets[ui] - prevOffset;
		if (offset >= stringsTable.buffer.size()) {
			error("SagaEngine::loadStrings() Wrong offset");
		}
		stringsTable.strings[ui] = &stringsTable.buffer[offset];

		debug(9, "string[%i]=%s", ui, stringsTable.strings[ui]);
	}
}
Пример #5
0
static uint tableRegionToRegion(lua_State *L, const char *className) {
#ifdef DEBUG
	int __startStackDepth = lua_gettop(L);
#endif

	// You can define a region in Lua in two ways:
	// 1. A table that defines a polygon (polgon = table with numbers, which define
	// two consecutive numbers per vertex)
	// 2. A table containing more polygon definitions
	// Then the first polygon is the contour of the region, and the following are holes
	// defined in the first polygon.

	// It may be passed only one parameter, and this must be a table
	if (lua_gettop(L) != 1 || !lua_istable(L, -1)) {
		luaL_error(L, "First and only parameter has to be of type \"table\".");
		return 0;
	}

	uint regionHandle = 0;
	if (!strcmp(className, REGION_CLASS_NAME)) {
		regionHandle = Region::create(Region::RT_REGION);
	} else if (!strcmp(className, WALKREGION_CLASS_NAME)) {
		regionHandle = WalkRegion::create(Region::RT_WALKREGION);
	} else {
		assert(false);
	}

	assert(regionHandle);

	// If the first element of the parameter is a number, then case 1 is accepted
	// If the first element of the parameter is a table, then case 2 is accepted
	// If the first element of the parameter has a different type, there is an error
	lua_rawgeti(L, -1, 1);
	int firstElementType = lua_type(L, -1);
	lua_pop(L, 1);

	switch (firstElementType) {
	case LUA_TNUMBER: {
		Polygon polygon;
		tablePolygonToPolygon(L, polygon);
		RegionRegistry::instance().resolveHandle(regionHandle)->init(polygon);
	}
	break;

	case LUA_TTABLE: {
		lua_rawgeti(L, -1, 1);
		Polygon polygon;
		tablePolygonToPolygon(L, polygon);
		lua_pop(L, 1);

		int polygonCount = luaL_getn(L, -1);
		if (polygonCount == 1)
			RegionRegistry::instance().resolveHandle(regionHandle)->init(polygon);
		else {
			Common::Array<Polygon> holes;
			holes.reserve(polygonCount - 1);

			for (int i = 2; i <= polygonCount; i++) {
				lua_rawgeti(L, -1, i);
				holes.resize(holes.size() + 1);
				tablePolygonToPolygon(L, holes.back());
				lua_pop(L, 1);
			}
			assert((int)holes.size() == polygonCount - 1);

			RegionRegistry::instance().resolveHandle(regionHandle)->init(polygon, &holes);
		}
	}
	break;

	default:
		luaL_error(L, "Illegal region definition.");
		return 0;
	}

#ifdef DEBUG
	assert(__startStackDepth == lua_gettop(L));
#endif

	return regionHandle;
}