Beispiel #1
0
	def __init__(self, fname):
		self.files = {}   #(extension, id): (data offset, size)

		self.fname = fname
		fname = file_get_path(fname, write = False)
		f = file_open(fname, binary = True, write = False)

		#read header
		buf = f.read(DRS.drs_header.size)
		self.header = DRS.drs_header.unpack(buf)

		dbg("DRS header [" + fname + "]", 1, push = "drs")
		dbg("copyright:          " + self.header[0].decode('latin-1'))
		dbg("version:            " + self.header[1].decode('latin-1'))
		dbg("ftype:              " + self.header[2].decode('latin-1'))
		dbg("table count:        " + str(self.header[3]))
		dbg("file offset:        " + str(self.header[4]))
		dbg("")

		#read table info
		table_count = self.header[3]

		table_header_buf = f.read(table_count * DRS.drs_table_info.size)
		for i in range(table_count):
			table_header = DRS.drs_table_info.unpack_from(table_header_buf, i * DRS.drs_table_info.size)
			file_type, file_extension, file_info_offset, num_files = table_header

			#flip the extension... it's stored that way...
			file_extension = file_extension.decode('latin-1').lower()[::-1]

			dbg("Table header [" + str(i) + "]", 2, push = "table")
			dbg("file type:        0x" + hexlify(file_type).decode('utf-8'))
			dbg("file extension:   " + file_extension)
			dbg("file_info_offset: " + str(file_info_offset))
			dbg("num_files:        " + str(num_files))
			dbg("")

			f.seek(file_info_offset)
			file_info_buf = f.read(num_files * DRS.drs_file_info.size)

			for j in range(num_files):
				file_header = DRS.drs_file_info.unpack_from(file_info_buf, j * DRS.drs_file_info.size)
				file_id, file_data_offset, file_size = file_header

				dbg("File info header [" + str(j) + "]", 3, push = "fileinfo")
				dbg("file id:        " + str(file_id))
				dbg("data offset:    " + str(file_data_offset))
				dbg("file size:      " + str(file_size))
				dbg("")

				self.files[(file_extension, file_id)] = file_data_offset, file_size
				dbg(pop = "fileinfo")

			dbg(pop = "table")

		self.f = f

		dbg(pop = "drs")
Beispiel #2
0
    def __init__(self, fname):
        self.fname = fname
        dbg("reading empires2_x1_p1 from %s..." % fname, 1)

        fname = file_get_path(fname, write=False)
        f = file_open(fname, binary=True, write=False)

        dbg("decompressing data from %s" % fname, 1)

        compressed_data = f.read()
        # decompress content with zlib (note the magic -15)
        # -15: - -> there is no header, 15 is the max windowsize
        self.content = zlib.decompress(compressed_data, -15)
        f.close()

        compressed_size = len(compressed_data)
        decompressed_size = len(self.content)

        del compressed_data

        dbg("length of compressed data: %d = %d kB" % (compressed_size, compressed_size / 1024), 1)
        dbg("length of decompressed data: %d = %d kB" % (decompressed_size, decompressed_size / 1024), 1)

        from util import file_write

        print("saving uncompressed dat file...")
        file_write(file_get_path("info/empires2x1p1.raw", write=True), self.content)

        # the main data storage
        self.data = dict()

        offset = 0
        offset = self.read(self.content, offset)

        dbg(
            "finished reading empires*.dat at %d of %d bytes (%f%%)."
            % (offset, decompressed_size, 100 * (offset / decompressed_size)),
            1,
        )
Beispiel #3
0
	def __init__(self, fname):
		self.fname = fname
		dbg("reading blendomatic data from %s" % fname, 1, push="blendomatic")

		fname = file_get_path(fname, write = False)
		f = file_open(fname, binary = True, write = False)

		buf = f.read(Blendomatic.blendomatic_header.size)
		self.header = Blendomatic.blendomatic_header.unpack_from(buf)

		blending_mode_count, tile_count = self.header

		dbg("%d blending modes, each %d tiles" % (blending_mode_count, tile_count), 2)

		self.blending_modes = []

		for i in range(blending_mode_count):

			blending_mode = Struct(endianness + "I %dB" % (tile_count))
			blending_mode_buf = f.read(blending_mode.size)
			bmode_header = blending_mode.unpack_from(blending_mode_buf)

			#should be 2353 -> number of pixels (single alpha byte values)
			tile_size = bmode_header[0]

			#tile_flags = bmode_header[1:]  #TODO

			dbg("tile in this blending mode %d has %d pixels" % (i, tile_size), 2)

			#as we draw in isometric tile format, this is the row count
			row_count = int(math.sqrt(tile_size)) + 1  #49


			#alpha_masks_raw is an array of bytes that will draw 32 images,
			#which are bit masks.
			#
			#one of these masks also has 2353 pixels (like terraintile or alpha mask)
			#the storage of the bit masks is 4*tilesize, here's why:
			#
			#4 * 8bit * 2353 pixels = 75296 bitpixels
			#==> 75296/(32 images) = 2353 bitpixel/image
			#
			#this means if we interprete the 75296 bitpixels as 32 images,
			#each of these images gets 2353 bit as data.
			#TODO: why 32 images? isn't that depending on tile_count?

			bitmask_buf_size = tile_size * 4
			dbg("reading 1bit masks -> %d bytes" % (bitmask_buf_size), 2)
			alpha_masks_buf = f.read(bitmask_buf_size)
			alpha_masks_raw = unpack_from("%dB" % (bitmask_buf_size), alpha_masks_buf)


			#list of alpha-mask tiles
			bmode_tiles = []

			dbg("reading 8bit masks for %d tiles -> %d bytes" % (tile_count, tile_size * tile_count), 2)

			#draw mask tiles for this blending mode
			for j in range(tile_count):
				tile_buf = f.read(tile_size)
				pixels = unpack_from("%dB" % tile_size, tile_buf)

				tile = self.get_tile_from_data(row_count, pixels)

				bmode_tiles.append(tile)


			bitvalues = []
			for i in alpha_masks_raw:
				for b_id in range(7, -1, -1):
					#bitmask from 0b00000001 to 0b10000000
					bit_mask = 2 ** b_id
					bit = i & bit_mask
					bitvalues.append(bit)

			#list of bit-mask tiles
			bmode_bittiles = []

			#TODO: again, is 32 really hardcoded?
			for i in range(32):
				data_begin =  i    * tile_size
				data_end   = (i+1) * tile_size
				pixels = bitvalues[ data_begin : data_end ]

				tile = self.get_tile_from_data(row_count, pixels)

				bmode_bittiles.append(tile)


			bmode_data = dict()
			bmode_data["pxcount"] = tile_size
			bmode_data["alphamasks"] = bmode_tiles
			bmode_data["bitmasks"] = bmode_bittiles

			self.blending_modes.append(bmode_data)

		dbg(pop = "blendomatic")