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
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
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
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
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
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]))
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]))
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]))
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()
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]))
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]))
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]))
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()