Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #1.1 Changed dump format- added delay into the flag box
- #1 Initial release
- import os
- import struct
- import sys
- asciichar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ()0123456789 :!'
- #Gets data
- def get_data(filename):
- totalbytes = os.path.getsize(filename)
- infile = open(filename, 'rb')
- totalfiledata = infile.read(totalbytes)
- infile.close()
- return totalfiledata
- #Tells if the string s is a SHIFT-JIS character or not
- def is_jis_char(s):
- if len(s) != 2: #If it's not a string of length 2, then...
- return False
- try: #Python error handling
- if len(s.decode('cp932')) != 1: #For example, 2 ascii characters will be length 2
- return False #Two bytes that decode to a SHIFT-JIS character will be length 1
- except UnicodeDecodeError: #The string couldn't be decoded
- return False #Not a SHIFT-JIS character
- return True #It is a SHIFT-JIS character
- def script_dump(filename):
- filedata = get_data(filename + '.orig') #Get data
- ptr = 0 #Initialize variables
- end_of_ptr_table = struct.unpack('<I',filedata[0:4])[0]
- ptr_table = []
- while ptr < end_of_ptr_table: #Load pointers
- ptr_table.append(struct.unpack('<I',filedata[ptr:ptr+4])[0])
- ptr += 4
- flag = True
- chunks = [] #Load chunks
- for ptr in ptr_table:
- if flag == True:
- flag = False
- else:
- chunks.append([prev_ptr,filedata[prev_ptr:ptr]])
- prev_ptr = ptr
- chunks.append([ptr,filedata[ptr:]])
- #Find open dialog chunk and delay chunk by searching
- for i, (ptr, chunk) in enumerate(chunks):
- if chunk == '400B0000400600004001000040090100400C0000000000004002010040160000'.decode('hex'):
- print 'Open dialog box chunk is 0x{:2x} at address {}.'.format(i,hex(ptr))
- opendialog_chunk = i
- elif chunk == '4002000040033C804002010040160000'.decode('hex'):
- print 'Delay chunk is 0x{:2x} at address {}.'.format(i,hex(ptr))
- delay_chunk = i
- script_chunks = []
- name_chunks = []
- for i, (ptr, chunk) in enumerate(chunks): #Loop through chunks
- #Finds open dialog and delay chunks
- if chunk[:4] == '\x40\x14' + struct.pack('<H',opendialog_chunk):
- script_chunks.append(i)
- elif chunk[:4] == '\x40\x02\x00\x00' and chunk.find('400500004002010040160000'.decode('hex')) > 0:
- name_chunks.append(i)
- print 'Script Chunks: {}'.format(', '.join([hex(x) for x in script_chunks]))
- print 'Name Chunks: {}'.format(', '.join([hex(x) for x in name_chunks]))
- output = [] #Initialize variables
- namelist = []
- for j in name_chunks: #Loop through name chunks
- i, chunk = chunks[j] #Assign chunk to local variable
- pos = 4 #Name starts at position 4 within chunk
- while is_jis_char(chunk[pos:pos+2]):
- pos += 2 #Find end of name
- name = chunk[4:pos]
- namelist.append([j, name]) #Add chunk number and name to name list
- output.append(hex(j) + ';') #Add name to output
- output.append(name + ';;' + 'name' + '\r\n')
- firstpass = True
- for chunk in script_chunks: #Loop through script chunks
- if firstpass == True:
- firstpass = False
- else:
- del output[-1] #Delete ';' entry if 1st line in opcode
- output.append(hex(chunk) + ';') #Add chunk # to output
- chunkaddr = chunks[chunk][0] #Get chunk addr and text
- chunk = chunks[chunk][1]
- pos = 0 #Init variable
- while pos < len(chunk):
- if ord(chunk[pos]) == 0: #For byte 0x00, advance to next byte
- pos += 1
- continue
- elif ord(chunk[pos]) == 0x40: #For byte 0x40, it's an opcode
- if ord(chunk[pos+1]) == 0x17:
- output.append('0x' + chunk[pos:pos+8].encode('hex') + ';' +
- '0x' + chunk[pos:pos+8].encode('hex') + ';' + 'unknown' + '\r\n')
- output.append(';')
- pos += 8
- continue
- output.append('0x' + chunk[pos:pos+4].encode('hex') + ';' + '0x' +
- chunk[pos:pos+4].encode('hex') + ';')
- if ord(chunk[pos+1]) == 0x14:
- f_number = struct.unpack('<H',chunk[pos+2:pos+4])[0]
- if f_number == opendialog_chunk:
- output.append('open dialog')
- elif f_number == delay_chunk:
- output.append('delay')
- elif f_number in [x[0] for x in namelist]:
- for i, name in namelist:
- if f_number == i:
- break
- output.append('name: {}'.format(name))
- else:
- output.append('function {}'.format(hex(f_number)))
- elif ord(chunk[pos+1]) == 0x00:
- output.append('end chunk')
- elif ord(chunk[pos+1]) == 0x02:
- output.append('unknown')
- elif ord(chunk[pos+1]) == 0x05:
- output.append('linebreak')
- elif ord(chunk[pos+1]) == 0x06:
- output.append('closebox')
- else:
- output.append('unknown opcode')
- pos += 4
- ## elif ord(chunk[pos]) == 0x80:
- ## output.append(chunk[pos:pos+4].encode('hex') + ';' + chunk[pos:pos+4].encode('hex') + ';')
- ## output.append('unknown opcode')
- ## pos += 4
- elif is_jis_char(chunk[pos:pos+2]) or chunk[pos] in asciichar: #It's text
- start = pos
- while is_jis_char(chunk[pos:pos+2]) or chunk[pos] in asciichar:
- if chunk[pos] in asciichar: #If ascii, advance by 1
- pos += 1
- elif is_jis_char(chunk[pos:pos+2]): #If S-JIS, advance by 2
- pos += 2
- output.append(chunk[start:pos] + ';') #Output text
- if chunk[pos:pos+2] == '\x40\x05':
- output.append(';linebreak')
- pos += 4
- elif chunk[pos:pos+4] == '\x00\x00\x40\x05':
- output.append(';linebreak')
- pos += 6
- if chunk[pos:pos+4] == '\x40\x14' + struct.pack('<H',delay_chunk):
- if 'linebreak' in output[-1]:
- output[-1] += '+delay'
- else:
- output.append(';delay')
- pos += 4
- else: #Not byte 0x00, byte 0x40, or text
- print 'Unknown character'
- print hex(chunkaddr) #Start of chunk
- print hex(chunkaddr+pos) #Postion of miss
- quit()
- output.append('\r\n') #Output linebreak and indent
- output.append(';') #for next opcode within chunk
- with open(filename + '.csv','wb') as f: #Write output to file
- f.write(''.join(output))
- scripts = ['apend00','bird01','bird02','bird03','bird04','bird05','bird06','birddemo','boss01','boss02','boss2',
- 'boss03','boss3','catedral','church01','church02','church03','churdemo','cnt01','coloseum',
- 'eddemo01','eddemo02','eddemo03','exdemo01','extra01','extra02','extra03','fir01','fir02','fir03',
- 'grave01','grave02','grave03','house','ice01','ice02','ice03','inn01','inn02','inn03','ise01','ise02',
- 'ise03','knondemo','last01','last02_0','last02_1','last02_2','last02_3','last03','last04','lastdemo',
- 'mnt00','mnt01','mnt02','mnt03','mnt04','mnt05','museum','nxdemo01','nxdemo02','nxdemo03','opdemo00',
- 'opdemo01','opdemo02','opdemo03','plane01','plane02','plane03','random','sai01','sai02','sai03',
- 'sai04','sand01','sand02','shops','soldier','subgame','thu01','thu02','thu03','tiademo','tower00',
- 'tower01','tower02','tower03','tower04','tower05','tower06','tower07','tower08','tower09','town01',
- 'town02','town2','town03','tree00','tree01','tree02','tree03','tree04','tutori01','tutori02','tutori03',
- 'twdemo01','twdemo02','wind00','wind01','wind02','wood01','wood02','wpshop01','wpshop02','wpshop03']
- for script in scripts: #Dump each script
- print 'Dumping: {}'.format(script)
- script_dump(script)
- print ''
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement