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")
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, )
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")