def load(self, filename, data): self._filename = filename self._world_index = int(os.path.basename(filename)[1]) - 1 stream = StreamRead.from_file(filename, Endianness.BIG) self._offset_tile_gfx = stream.read_uint() - WORLD_BASE_OFFSET self._offset_tile_collision = stream.read_uint() - WORLD_BASE_OFFSET self._offset_palette = stream.read_uint() - WORLD_BASE_OFFSET self._offset_u1 = stream.read_uint() - WORLD_BASE_OFFSET self._offset_u2 = stream.read_uint() - WORLD_BASE_OFFSET if self._offset_tile_gfx > stream.size or self._offset_tile_collision > stream.size or self._offset_palette > stream.size: raise Exception('"{}" is not a valid world file.'.format(filename)) # Read level header offsets. level_count = stream.read_ushort() self._level_offsets = [] for _ in range(0, level_count): self._level_offsets.append(stream.read_uint() - WORLD_BASE_OFFSET) # Read level headers. self._levels = [] for level_index, offset in enumerate(self._level_offsets): stream.seek(offset) level = Level(self._world_index, level_index) level.name = '{}-{}: {}'.format(self._world_index + 1, level_index + 1, data[level_index]['name']) level.maximum_blockmap_size = data[level_index]['blockmap_size'] level.load_header(stream) self._levels.append(level) # Read the world palette. stream.seek(self._offset_palette) self._palette = Palette.from_stream(stream, 16, 4) # Read tileset. self._tileset = TileSet.from_stream(stream, self._offset_tile_gfx, self._offset_tile_collision, self._palette) # Read level data. for level_index, level in enumerate(self._levels): if level_index > 0: game_dir = os.path.dirname(filename) level_file = 'L{}-{}'.format(self._world_index + 1, level_index + 1) level_file = os.path.join(game_dir, level_file) stream.insert(level_file, level.data_offset) if self._world_index == 2 and level_index == 1: offset = 19620 else: offset = 0 level.load(stream, offset)