Esempio n. 1
0
    def __init__(self, frame_info, data):
        self.info = frame_info

        self.boundaries = []  # for each row, contains the (left, right) number of boundary pixels
        self.cmd_offsets = []  # for each row, store the file offset to the first drawing command

        self.pcolor = []  # matrix that contains all the palette indices drawn by commands, key: rowid

        dbg(push="frame", lvl=3)

        # process bondary table
        for i in range(self.info.size[1]):
            outline_entry_position = self.info.outline_table_offset + i * SLPFrame.slp_frame_row_edge.size

            left, right = SLPFrame.slp_frame_row_edge.unpack_from(data, outline_entry_position)

            # is this row completely transparent?
            if left == 0x8000 or right == 0x8000:
                self.boundaries.append(self.transparent)  # TODO: -1 or like should be enough
            else:
                self.boundaries.append((left, right))

        dbg("boundary values: " + str(self.boundaries))

        # process cmd table
        for i in range(self.info.size[1]):
            cmd_table_position = self.info.qdl_table_offset + i * SLPFrame.slp_command_offset.size

            cmd_offset, = SLPFrame.slp_command_offset.unpack_from(data, cmd_table_position)

            self.cmd_offsets.append(cmd_offset)

        dbg("cmd_offsets:     " + str(self.cmd_offsets))

        self.pcolor = []
        for i in range(self.info.size[1]):
            palette_color_row = self.create_palette_color_row(data, i)

            self.pcolor.append(palette_color_row)

        if ifdbg(4):
            dbg("frame color index data:\n" + str(self.pcolor), 4)

        dbg(pop="frame")
Esempio n. 2
0
def main():

	args = parse_args()

	#set verbose value in util
	set_verbosity(args.verbose)

	#assume to extract all files when nothing specified.
	if args.extract == []:
		args.extract.append('*:*.*')

	extraction_rules = [ ExtractionRule(e) for e in args.extract ]

	merge_images = not args.nomerge
	exec_dev = args.development

	#set path in utility class
	dbg("setting age2 input directory to " + args.srcdir, 1)
	set_read_dir(args.srcdir)

	#write mode is disabled by default, unless destdir is set
	if args.destdir != '/dev/null' and not args.listfiles and not args.dumpfilelist:
		dbg("setting write dir to " + args.destdir, 1)
		set_write_dir(args.destdir)
		write_enabled = True
	else:
		write_enabled = False


	drsfiles = {
		"graphics":  DRS("Data/graphics.drs"),
		"interface": DRS("Data/interfac.drs"),
		"sounds0":   DRS("Data/sounds.drs"),
		"sounds1":   DRS("Data/sounds_x1.drs"),
		"gamedata0": DRS("Data/gamedata.drs"),
		"gamedata1": DRS("Data/gamedata_x1.drs"),
		"gamedata2": DRS("Data/gamedata_x1_p1.drs"),
		"terrain":   DRS("Data/terrain.drs")
	}

	palette = ColorTable(drsfiles["interface"].get_file_data('bin', 50500))

	if exec_dev:
		if write_enabled:
			print("no indev function available at the moment.")
			return
		else:
			raise Exception("development mode requires write access")

	if write_enabled:
		file_write(file_get_path('processed/player_color_palette.pal', write=True), palette.gen_player_color_palette())

		import blendomatic
		blend_data = blendomatic.Blendomatic("Data/blendomatic.dat")

		for (modeidx, png, size, metadata) in blend_data.draw_alpha_frames_merged():
			fname = 'alphamask/mode%02d' % (modeidx)
			filename = file_get_path(fname, write=True)
			file_write(filename + ".png", png)
			file_write(filename + ".docx", metadata)
			dbg("blending mode%02d -> saved packed atlas" % (modeidx), 1)

		import gamedata.empiresdat
		datfile = gamedata.empiresdat.Empires2X1P1("Data/empires2_x1_p1.dat")
		filename = file_get_path("processed/terrain_meta.docx", write=True)

		tmeta = "#terrain specification\n"
		tmeta += "#idx=terrain_id, slp_id, sound_id, blend_mode, blend_priority, angle_count, frame_count, terrain_dimensions0, terrain_dimensions1, terrain_replacement_id, name0, name1\n"

		tmeta += "n=%d\n" % len(datfile.data["terrain"]["terrain"])

		i = 0
		blending_modes = set()
		for tk in datfile.data["terrain"]["terrain"]:
			if tk["slp_id"] < 0:
				continue

			blending_modes.add(tk["blend_mode"])

			wanted = ["terrain_id", "slp_id", "sound_id", "blend_mode", "blend_priority", "angle_count", "frame_count", "terrain_dimensions0", "terrain_dimensions1", "terrain_replacement_id", "name0", "name1"]

			line = [tk[w] for w in wanted]

			#as blending mode 0==1 and 7==8, and ice is 5 for sure,
			#we subtract one from the ids, and can map -1 to 0, as mode (0-1) == (1-1)
			#TODO: this can't be correct...
			line[3] -= 1
			if line[3] < 0:
				line[3] = 0

			line = map(str, line)
			tmeta += ("%d=" % i) + ",".join(line) + "\n"
			i += 1

		file_write(filename, tmeta)


		filename = file_get_path("processed/blending_meta.docx", write=True)

		bmeta = "#blending mode specification\n"
		bmeta += "#yeah, i know that this content is totally stupid, but that's how the data can be injected later\n"
		bmeta += "#idx=mode_id\n"

		bmeta += "n=%d\n" % len(blending_modes)

		i = 0
		for m in blending_modes:
			bmeta += "%d=%d\n" % (i, m)
			i += 1

		file_write(filename, bmeta)


		if args.extrafiles:
			file_write(file_get_path('info/colortable.pal.png', write=True), palette.gen_image())


	file_list = dict()
	files_extracted = 0

	for drsname, drsfile in drsfiles.items():
		for file_extension, file_id in drsfile.files:
			if not any((er.matches(drsname, file_id, file_extension) for er in extraction_rules)):
				continue

			if args.listfiles or args.dumpfilelist:
				fid = int(file_id)
				if fid not in file_list:
					file_list[fid] = list()

				file_list[fid] += [(drsfile.fname, file_extension)]
				continue

			if write_enabled:
				fbase = file_get_path('raw/' + drsfile.fname + '/' + str(file_id), write=True)
				fname = fbase + '.' + file_extension

				dbg("Extracting to " + fname + "...", 2)

				file_data = drsfile.get_file_data(file_extension, file_id)

			if file_extension == 'slp':

				if write_enabled:

					s = SLP(file_data)
					out_file_tmp = drsname + ": " + str(file_id) + "." + file_extension

					if merge_images:
						png, (width, height), metadata = s.draw_frames_merged(palette)
						file_write(fname + ".png", png)
						file_write(fname + '.docx', metadata)
						dbg(out_file_tmp + " -> saved packed atlas", 1)

					else:
						for idx, (png, metadata) in enumerate(s.draw_frames(palette)):
							filename = fname + '.' + str(idx)
							file_write(filename + '.png', png.image)
							file_write(filename + '.docx', metadata)

							dbg(out_file_tmp + " -> extracting frame %3d...\r" % (idx), 1, end="")
						dbg(out_file_tmp + " -> saved single frame(s)", 1)

			elif file_extension == 'wav':

				if write_enabled:

					file_write(fname, file_data)

					use_opus = True

					if use_opus:
					#opusenc invokation (TODO: ffmpeg?)
						opus_convert_call = ['opusenc', fname, fbase + '.opus']
						dbg("converting... : " + fname + " to opus.", 1)

						oc = subprocess.Popen(opus_convert_call, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
						oc_out, oc_err = oc.communicate()

						if ifdbg(2):
							oc_out = oc_out.decode("utf-8")
							oc_err = oc_err.decode("utf-8")

							dbg(oc_out + "\n" + oc_err, 2)

						#remove original wave file
						remove(fname)


			else:
				#this type is unknown or does not require conversion

				if write_enabled:
					file_write(fname, file_data)

			files_extracted += 1

	if write_enabled:
		dbg(str(files_extracted) + " files extracted", 0)

	if args.listfiles or args.dumpfilelist:
		#file_list = sorted(file_list)
		if not args.dumpfilelist:
			for idx, f in file_list.items():
				ret = "%d = [ " % idx
				for file_name, file_extension in f:
					ret += "%s/%d.%s, " % (file_name, idx, file_extension)
				ret += "]"
				print(ret)
		else:
			ret = "#!/usr/bin/python\n\n#auto generated age2tc file list\n\n"
			import pprint
			ret += "avail_files = "
			ret += pprint.pformat(file_list)
			print(ret)