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]); }
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); }
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; }
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]); } }
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; }