Beispiel #1
0
 def decompile_data(self, remastered=None):
     remastered = (self.remastered or self.remastered_required()
                   ) if remastered == None else remastered
     result = ''
     attrs = BINSMK.ATTR_NAMES
     longest = sorted(len(n) for n in attrs)[-1]
     for i, smk in enumerate(self.smks):
         result += 'SMK %d:\n' % i
         for attr in attrs:
             value = getattr(smk, attr)
             hint = ''
             if attr == 'overlay_smk' and value != None:
                 value = self.smks.index(value)
             elif attr == 'filename':
                 value = TBL.decompile_string(value)
             elif attr == 'flags':
                 value = flags(value, 5)
             result += '\t%s%s%s%s%s\n' % (attr, ' ' *
                                           (longest - len(attr) + 1), value,
                                           ' # ' if hint else '', hint)
         result += '\n'
     attrs = BINWidget.ATTR_NAMES_REMASTERED if remastered else BINWidget.ATTR_NAMES
     longest = sorted(len(n) for n in attrs)[-1]
     for widget in self.widgets:
         result += 'Widget:\n'
         for attr in attrs:
             value = getattr(widget, attr)
             hint = ''
             if attr == 'smk' and value != None:
                 value = self.smks.index(value)
             elif attr == 'string' and value != None:
                 value = TBL.decompile_string(value)
             elif attr == 'flags':
                 value = flags(value, 27)
             elif attr == 'type':
                 if value < len(BINWidget.TYPE_NAMES):
                     hint = BINWidget.TYPE_NAMES[value]
                 else:
                     hint = 'Unknown'
             result += '\t%s%s%s%s%s\n' % (attr, ' ' *
                                           (longest - len(attr) + 1), value,
                                           ' # ' if hint else '', hint)
         result += '\n'
     return result
Beispiel #2
0
def type_weaponid(stage, bin, data=None):
	"""WeaponID"""
	if data == None:
		return 1
	if stage == 1:
		return (str(data),'%s (%s)' % (DAT.DATA_CACHE['Weapons.txt'][data], TBL.decompile_string(bin.tbl.strings[bin.weaponsdat.get_value(data,'Label')-1][:-1])))
	try:
		v = int(data)
		if 0 > v or v > DAT.WeaponsDAT.count:
			raise
	except:
		raise PyMSError('Parameter',"Invalid WeaponID value '%s', it must be a number in the range 0 to %s" % (data,DAT.WeaponsDAT.count))
	return v
Beispiel #3
0
def type_soundid(stage, bin, data=None):
	"""SoundID"""
	if data == None:
		return 2
	if stage == 1:
		return (str(data), TBL.decompile_string(bin.sfxdatatbl.strings[bin.soundsdat.get_value(data,'SoundFile')-1][:-1]))
	try:
		v = int(data)
		if 0 > v or v > DAT.SoundsDAT.count:
			raise
	except:
		raise PyMSError('Parameter',"Invalid SoundID value '%s', it must be a number in the range 0 to %s" % (data,DAT.SoundsDAT.count))
	return v
Beispiel #4
0
def type_flingy(stage, bin, data=None):
	"""FlingyID"""
	if data == None:
		return 2
	if stage == 1:
		return (str(data),'%s (%s)' % (DAT.DATA_CACHE['Flingy.txt'][data], TBL.decompile_string(bin.imagestbl.strings[bin.imagesdat.get_value(bin.spritesdat.get_value(bin.flingydat.get_value(data,'Sprite'),'ImageFile'),'GRPFile')-1][:-1])))
	try:
		v = int(data)
		if 0 > v or v > DAT.FlingyDAT.count:
			raise
	except:
		raise PyMSError('Parameter',"Invalid FlingyID value '%s', it must be a number in the range 0 to %s" % (data,DAT.FlingyDAT.count))
	return v
Beispiel #5
0
def type_weaponid(stage, bin, data=None):
	"""WeaponID"""
	if data == None:
		return 1
	if stage == 1:
		return (str(data),'%s (%s)' % (DAT.DATA_CACHE['Weapons.txt'][data], TBL.decompile_string(bin.tbl.strings[bin.weaponsdat.get_value(data,'Label')-1][:-1])))
	try:
		v = int(data)
		if 0 > v or v > DAT.WeaponsDAT.count:
			raise
	except:
		raise PyMSError('Parameter',"Invalid WeaponID value '%s', it must be a number in the range 0 to %s" % (data,DAT.WeaponsDAT.count))
	return v
Beispiel #6
0
def type_soundid(stage, bin, data=None):
	"""SoundID"""
	if data == None:
		return 2
	if stage == 1:
		return (str(data), TBL.decompile_string(bin.sfxdatatbl.strings[bin.soundsdat.get_value(data,'SoundFile')-1][:-1]))
	try:
		v = int(data)
		if 0 > v or v > DAT.SoundsDAT.count:
			raise
	except:
		raise PyMSError('Parameter',"Invalid SoundID value '%s', it must be a number in the range 0 to %s" % (data,DAT.SoundsDAT.count))
	return v
Beispiel #7
0
def type_flingy(stage, bin, data=None):
	"""FlingyID"""
	if data == None:
		return 2
	if stage == 1:
		return (str(data),'%s (%s)' % (DAT.DATA_CACHE['Flingy.txt'][data], TBL.decompile_string(bin.imagestbl.strings[bin.imagesdat.get_value(bin.spritesdat.get_value(bin.flingydat.get_value(data,'Sprite'),'ImageFile'),'GRPFile')-1][:-1])))
	try:
		v = int(data)
		if 0 > v or v > DAT.FlingyDAT.count:
			raise
	except:
		raise PyMSError('Parameter',"Invalid FlingyID value '%s', it must be a number in the range 0 to %s" % (data,DAT.FlingyDAT.count))
	return v
Beispiel #8
0
	def decompile_data(self):
		result = ''
		attrs = BINSMK.ATTR_NAMES
		longest = sorted(len(n) for n in attrs)[-1]
		for i,smk in enumerate(self.smks):
			result += 'SMK %d:\n' % i
			for attr in attrs:
				value = getattr(smk, attr)
				hint = ''
				if attr == 'overlay_smk' and value != None:
					value = self.smks.index(value)
				elif attr == 'filename':
					value = TBL.decompile_string(value)
				elif attr == 'flags':
					value = flags(value, 5)
				result += '\t%s%s%s%s%s\n' % (attr,' ' * (longest - len(attr) + 1),value,' # ' if hint else '',hint)
			result += '\n'
		attrs = BINWidget.ATTR_NAMES
		longest = sorted(len(n) for n in attrs)[-1]
		for widget in self.widgets:
			result += 'Widget:\n'
			for attr in attrs:
				value = getattr(widget, attr)
				hint = ''
				if attr == 'smk' and value != None:
					value = self.smks.index(value)
				elif attr == 'string' and value != None:
					value = TBL.decompile_string(value)
				elif attr == 'flags':
					value = flags(value, 27)
				elif attr == 'type':
					if value < len(BINWidget.TYPE_NAMES):
						hint = BINWidget.TYPE_NAMES[value]
					else:
						hint = 'Unknown'
				result += '\t%s%s%s%s%s\n' % (attr,' ' * (longest - len(attr) + 1),value,' # ' if hint else '',hint)
			result += '\n'
		return result
Beispiel #9
0
	def stattxt_value(self, type, value):
		if value == 65:
			return '%s in mapdata.tbl, item %s: None' % (type, value)
		return '%s in mapdata.tbl, item %s: %s' % (type, value, TBL.decompile_string(self.tbl.strings[value]))
Beispiel #10
0
	def stattxt_value(self, type, value):
		if value == 0:
			return '%s: None' % type
		return '%s in portdata.tbl, item %s: %s' % (type, value - 1, TBL.decompile_string(self.tbl.strings[value - 1]))
Beispiel #11
0
	def stattxt_value(self, type, value):
		if type == 'Sublabel':
			value += 1301
		return '%s in stat_txt.tbl, item %s: %s' % (type, value, TBL.decompile_string(self.tbl.strings[value]))
Beispiel #12
0
	def decompile(self, file, reference=False, ids=None):
		if isstr(file):
			try:
				f = open(file, 'w')
			except:
				raise PyMSError('Decompile',"Could not load file '%s'" % file, warnings=warnings)
		else:
			f = file
		if ids == None:
			ids = self.header.keys()
		longheader = max([len(h[0]) for h in HEADER] + [13]) + 1
		longopcode = max([len(o[0][0]) for o in OPCODES] + [13]) + 1
		warnings = []
		labels = {}
		completed = []
		def setlabel(o,local,entry):
			entry = re.sub('[\\/\\(\\)-]','_',entry.replace(' ','').replace("'",''))
			f = []
			for i in self.offsets[o]:
				if isinstance(i,list) and i[0] == id:
					f.append(i[1])
			if f:
				f.sort()
				labels[o] = entry + HEADER[f[0]][0]
				return 0
			labels[o] = entry + 'Local' + str(local).zfill(2)
			return 1
		def decompile_offset(o,code,local,id):
			if id in self.extrainfo:
				entry = self.extrainfo[id].replace(' ','_')
			elif id < len(DAT.DATA_CACHE['IscriptIDList.txt']):
				entry = DAT.DATA_CACHE['IscriptIDList.txt'][id]
			else:
				entry = 'Unnamed Custom Entry'
			if not o in completed:
				completed.append(o)
				if not o in labels:
					labels[o] = re.sub('[\\/\\(\\)-]','_',entry.replace(' ','').replace("'",'')) + 'Local%s' % local
					local += 1
				code += labels[o] + ':\n'
				curcmd = self.code.index(o)
				# print '\t%s' % o
				donext = []
				while True:
					# print curcmd
					co = self.code.getkey(curcmd)
					# print co
					if co in self.offsets and not co in labels:
						local += setlabel(co,local,entry)
						completed.append(co)
						code += '%s:\n' % labels[co]
					cmd = self.code.getitem(curcmd)
					c = OPCODES[cmd[0]][0][0]
					if cmd[0] == 7:
						if not cmd[1] in labels:
							local += setlabel(cmd[1],local,entry)
						code += '	%s%s	%s\n\n' % (c,' ' * (longopcode-len(c)),labels[cmd[1]])
						code,local,curcmd = decompile_offset(cmd[1],code,local,id)
						break
					elif cmd[0] in [22,54]: #end,return
						code += '	%s\n\n' % c
						break
					elif cmd[0] in [30,53,57,58,59,60,63]: #randcondjump,call,pwrupcondjmp,trgtrangecondjmp,trgtarccondjmp,curdirectcondjmp,liftoffcondjump
						if cmd[-1] not in labels:
							local += setlabel(cmd[-1],local,entry)
						if not cmd[-1] in donext:
							donext.append(cmd[-1])
						extra = []
						code += '	%s%s	' % (c,' ' * (longopcode-len(c)))
						for v,t in zip(cmd[1:-1],OPCODES[cmd[0]][1][:-1]):
							p,e = t(1,self,v)
							if e:
								extra.append(e)
							code += p + ' '
						code += labels[cmd[-1]]
						if extra:
							code = code[:-1] + '\t# ' + ' | '.join(extra)
						code += '\n'
						curcmd += 1
					else:
						extra = []
						code += '	' + c
						if OPCODES[cmd[0]][1]:
							code += ' ' * (longopcode-len(c)) + '\t'
							d,o = cmd[1:],OPCODES[cmd[0]][1]
							if OPCODES[cmd[0]][1][0](0,self) == -1:
								n = OPCODES[cmd[0]][1][0](1,self,d[0])[0]
								code += n + ' '
								o = [OPCODES[cmd[0]][1][1]] * int(n)
								del d[0]
							for v,t in zip(d,o):
								p,e = t(1,self,v)
								if e:
									extra.append(e)
								code += p + ' '
							if extra:
								code = code[:-1] + '\t# ' + ' | '.join(extra)
						code += '\n'
						curcmd += 1
				if donext:
					for d in donext:
						code,local,curcmd = decompile_offset(d,code,local,id)
				return (code,local,curcmd)
			return (code,local,-1)
		usedby = {}
		for i in range(DAT.ImagesDAT.count):
			id = self.imagesdat.get_value(i, 'IscriptID')
			if id in ids:
				if not id in usedby:
					usedby[id] = '# This header is used by images.dat entries:\n'
				usedby[id] += '# %s %s (%s)\n' % (str(i).zfill(3), DAT.DATA_CACHE['Images.txt'][i], TBL.decompile_string(self.imagestbl.strings[self.imagesdat.get_value(i,'GRPFile')-1][:-1]))
		invalid = []
		unknownid = 0
		for id in ids:
			code = ''
			local = 0
			if not id in self.headers:
				invalid.append(id)
				continue
			type, offset, header = self.headers[id]
			u = ''
			if id in usedby:
				u = usedby[id]
			f.write('# ----------------------------------------------------------------------------- #\n%s.headerstart\nIsId          	%s\nType          	%s\n' % (u, id, type))
			for o,l in zip(header,HEADER[:ENTRY_TYPES[type]]):
				if o == None:
					label = '[NONE]'
				elif o in labels:
					label = labels[o]
				else:
					if id in self.extrainfo:
						entry = self.extrainfo[id].replace(' ','_')
					elif id < len(DAT.DATA_CACHE['IscriptIDList.txt']):
						entry = DAT.DATA_CACHE['IscriptIDList.txt'][id]
					else:
						entry = 'Unnamed Custom Entry'
					local += setlabel(o,local,entry)
					label = labels[o]#'%s%s' % (DAT.DATA_CACHE['IscriptIDList.txt'][id],l[0])
				f.write('%s%s	%s\n' % (l[0],' ' * (longheader-len(l[0])),label))
				if o != None:
					code,local,curcmd = decompile_offset(o,code,local,id)
			if id in self.extrainfo:
				f.write('##Name: %s\n' % self.extrainfo[id])
			f.write('.headerend\n# ----------------------------------------------------------------------------- #\n\n' + code)
		f.close()
Beispiel #13
0
 def stattxt_value(self, type, value):
     if value == 65:
         return '%s in mapdata.tbl, item %s: None' % (type, value)
     return '%s in mapdata.tbl, item %s: %s' % (
         type, value, TBL.decompile_string(self.tbl.strings[value]))
Beispiel #14
0
 def stattxt_value(self, type, value):
     if value == 0:
         return '%s: None' % type
     return '%s in portdata.tbl, item %s: %s' % (
         type, value - 1, TBL.decompile_string(self.tbl.strings[value - 1]))
Beispiel #15
0
 def stattxt_value(self, type, value):
     if type == 'Sublabel':
         value += 1301
     return '%s in stat_txt.tbl, item %s: %s' % (
         type, value, TBL.decompile_string(self.tbl.strings[value]))
Beispiel #16
0
	def decompile(self, file, reference=False, ids=None):
		if isstr(file):
			try:
				f = AtomicWriter(file, 'w')
			except:
				raise PyMSError('Decompile',"Could not load file '%s'" % file, warnings=warnings)
		else:
			f = file
		if ids == None:
			ids = self.headers.keys()
		longheader = max([len(h[0]) for h in HEADER] + [13]) + 1
		longopcode = max([len(o[0][0]) for o in OPCODES] + [13]) + 1
		warnings = []
		labels = {}
		completed = []
		def setlabel(o,local,entry):
			entry = re.sub('[\\/\\(\\)-]','_',entry.replace(' ','').replace("'",''))
			f = []
			for i in self.offsets[o]:
				if isinstance(i,list) and i[0] == id:
					f.append(i[1])
			if f:
				f.sort()
				labels[o] = entry + HEADER[f[0]][0]
				return 0
			labels[o] = entry + 'Local' + str(local).zfill(2)
			return 1
		def decompile_offset(o,code,local,id):
			if id in self.extrainfo:
				entry = self.extrainfo[id].replace(' ','_')
			elif id < len(DAT.DATA_CACHE['IscriptIDList.txt']):
				entry = DAT.DATA_CACHE['IscriptIDList.txt'][id]
			else:
				entry = 'Unnamed Custom Entry'
			if not o in completed:
				completed.append(o)
				if not o in labels:
					labels[o] = re.sub('[\\/\\(\\)-]','_',entry.replace(' ','').replace("'",'')) + 'Local%s' % local
					local += 1
				code += labels[o] + ':\n'
				curcmd = self.code.index(o)
				# print '\t%s' % o
				donext = []
				while True:
					# print curcmd
					co = self.code.getkey(curcmd)
					# print co
					if co in self.offsets and not co in labels:
						local += setlabel(co,local,entry)
						completed.append(co)
						code += '%s:\n' % labels[co]
					cmd = self.code.getitem(curcmd)
					c = OPCODES[cmd[0]][0][0]
					if cmd[0] == 7:
						if not cmd[1] in labels:
							local += setlabel(cmd[1],local,entry)
						code += '	%s%s	%s\n\n' % (c,' ' * (longopcode-len(c)),labels[cmd[1]])
						code,local,curcmd = decompile_offset(cmd[1],code,local,id)
						break
					elif cmd[0] in [22,54]: #end,return
						code += '	%s\n\n' % c
						break
					elif cmd[0] in [30,53,57,58,59,60,63]: #randcondjump,call,pwrupcondjmp,trgtrangecondjmp,trgtarccondjmp,curdirectcondjmp,liftoffcondjump
						if cmd[-1] not in labels:
							local += setlabel(cmd[-1],local,entry)
						if not cmd[-1] in donext:
							donext.append(cmd[-1])
						extra = []
						code += '	%s%s	' % (c,' ' * (longopcode-len(c)))
						for v,t in zip(cmd[1:-1],OPCODES[cmd[0]][1][:-1]):
							p,e = t(1,self,v)
							if e:
								extra.append(e)
							code += p + ' '
						code += labels[cmd[-1]]
						if extra:
							code = code[:-1] + '\t# ' + ' | '.join(extra)
						code += '\n'
						curcmd += 1
					else:
						extra = []
						code += '	' + c
						if OPCODES[cmd[0]][1]:
							code += ' ' * (longopcode-len(c)) + '\t'
							d,o = cmd[1:],OPCODES[cmd[0]][1]
							if OPCODES[cmd[0]][1][0](0,self) == -1:
								n = OPCODES[cmd[0]][1][0](1,self,d[0])[0]
								code += n + ' '
								o = [OPCODES[cmd[0]][1][1]] * int(n)
								del d[0]
							for v,t in zip(d,o):
								p,e = t(1,self,v)
								if e:
									extra.append(e)
								code += p + ' '
							if extra:
								code = code[:-1] + '\t# ' + ' | '.join(extra)
						code += '\n'
						curcmd += 1
				if donext:
					for d in donext:
						code,local,curcmd = decompile_offset(d,code,local,id)
				return (code,local,curcmd)
			return (code,local,-1)
		usedby = {}
		for i in range(DAT.ImagesDAT.count):
			id = self.imagesdat.get_value(i, 'IscriptID')
			if id in ids:
				if not id in usedby:
					usedby[id] = '# This header is used by images.dat entries:\n'
				usedby[id] += '# %s %s (%s)\n' % (str(i).zfill(3), DAT.DATA_CACHE['Images.txt'][i], TBL.decompile_string(self.imagestbl.strings[self.imagesdat.get_value(i,'GRPFile')-1][:-1]))
		invalid = []
		unknownid = 0
		for id in ids:
			code = ''
			local = 0
			if not id in self.headers:
				invalid.append(id)
				continue
			type, offset, header = self.headers[id]
			u = ''
			if id in usedby:
				u = usedby[id]
			f.write('# ----------------------------------------------------------------------------- #\n%s.headerstart\nIsId          	%s\nType          	%s\n' % (u, id, type))
			for o,l in zip(header,HEADER[:ENTRY_TYPES[type]]):
				if o == None:
					label = '[NONE]'
				elif o in labels:
					label = labels[o]
				else:
					if id in self.extrainfo:
						entry = self.extrainfo[id].replace(' ','_')
					elif id < len(DAT.DATA_CACHE['IscriptIDList.txt']):
						entry = DAT.DATA_CACHE['IscriptIDList.txt'][id]
					else:
						entry = 'Unnamed Custom Entry'
					local += setlabel(o,local,entry)
					label = labels[o]#'%s%s' % (DAT.DATA_CACHE['IscriptIDList.txt'][id],l[0])
				f.write('%s%s	%s\n' % (l[0],' ' * (longheader-len(l[0])),label))
				if o != None:
					code,local,curcmd = decompile_offset(o,code,local,id)
			if id in self.extrainfo:
				f.write('##Name: %s\n' % self.extrainfo[id])
			f.write('.headerend\n# ----------------------------------------------------------------------------- #\n\n' + code)
		f.close()