SHARE
TWEET

Wander Wonder Script Dump v1.1

a guest Apr 30th, 2015 12 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #1.1    Changed dump format- added delay into the flag box
  2. #1      Initial release
  3. import os
  4. import struct
  5. import sys
  6. asciichar = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ()0123456789 :!'
  7.  
  8. #Gets data
  9. def get_data(filename):
  10.     totalbytes = os.path.getsize(filename)
  11.     infile = open(filename, 'rb')
  12.     totalfiledata = infile.read(totalbytes)
  13.     infile.close()
  14.     return totalfiledata
  15.  
  16. #Tells if the string s is a SHIFT-JIS character or not
  17. def is_jis_char(s):
  18.     if len(s) != 2: #If it's not a string of length 2, then...
  19.         return False
  20.     try:            #Python error handling
  21.         if len(s.decode('cp932')) != 1: #For example, 2 ascii characters will be length 2
  22.             return False                #Two bytes that decode to a SHIFT-JIS character will be length 1
  23.     except UnicodeDecodeError:  #The string couldn't be decoded
  24.         return False            #Not a SHIFT-JIS character
  25.     return True                 #It is a SHIFT-JIS character
  26.  
  27. def script_dump(filename):
  28.     filedata = get_data(filename + '.orig')  #Get data
  29.     ptr = 0                         #Initialize variables
  30.     end_of_ptr_table = struct.unpack('<I',filedata[0:4])[0]    
  31.     ptr_table = []
  32.     while ptr < end_of_ptr_table:   #Load pointers
  33.         ptr_table.append(struct.unpack('<I',filedata[ptr:ptr+4])[0])
  34.         ptr += 4
  35.     flag = True
  36.     chunks = []                     #Load chunks
  37.     for ptr in ptr_table:
  38.         if flag == True:
  39.             flag = False
  40.         else:
  41.             chunks.append([prev_ptr,filedata[prev_ptr:ptr]])
  42.         prev_ptr = ptr
  43.     chunks.append([ptr,filedata[ptr:]])
  44.  
  45.     #Find open dialog chunk and delay chunk by searching
  46.     for i, (ptr, chunk) in enumerate(chunks):
  47.         if chunk == '400B0000400600004001000040090100400C0000000000004002010040160000'.decode('hex'):
  48.             print 'Open dialog box chunk is 0x{:2x} at address {}.'.format(i,hex(ptr))
  49.             opendialog_chunk = i
  50.         elif chunk == '4002000040033C804002010040160000'.decode('hex'):
  51.             print 'Delay chunk is 0x{:2x} at address {}.'.format(i,hex(ptr))
  52.             delay_chunk = i
  53.  
  54.     script_chunks = []
  55.     name_chunks = []
  56.     for i, (ptr, chunk) in enumerate(chunks):   #Loop through chunks
  57.         #Finds open dialog and delay chunks
  58.         if chunk[:4] == '\x40\x14' + struct.pack('<H',opendialog_chunk):    
  59.             script_chunks.append(i)
  60.         elif chunk[:4] == '\x40\x02\x00\x00' and chunk.find('400500004002010040160000'.decode('hex')) > 0:
  61.             name_chunks.append(i)
  62.     print 'Script Chunks: {}'.format(', '.join([hex(x) for x in script_chunks]))
  63.     print 'Name Chunks: {}'.format(', '.join([hex(x) for x in name_chunks]))
  64.  
  65.     output = []                 #Initialize variables  
  66.     namelist = []
  67.     for j in name_chunks:       #Loop through name chunks
  68.         i, chunk = chunks[j]    #Assign chunk to local variable
  69.         pos = 4                 #Name starts at position 4 within chunk
  70.         while is_jis_char(chunk[pos:pos+2]):
  71.             pos += 2            #Find end of name
  72.         name = chunk[4:pos]
  73.         namelist.append([j, name])  #Add chunk number and name to name list
  74.         output.append(hex(j) + ';')         #Add name to output
  75.         output.append(name + ';;' + 'name' + '\r\n')
  76.  
  77.     firstpass = True
  78.     for chunk in script_chunks: #Loop through script chunks
  79.         if firstpass == True:
  80.             firstpass = False
  81.         else:
  82.             del output[-1]      #Delete ';' entry if 1st line in opcode
  83.         output.append(hex(chunk) + ';')     #Add chunk # to output
  84.         chunkaddr = chunks[chunk][0]        #Get chunk addr and text
  85.         chunk = chunks[chunk][1]
  86.         pos = 0                             #Init variable
  87.         while pos < len(chunk):            
  88.             if ord(chunk[pos]) == 0:        #For byte 0x00, advance to next byte
  89.                 pos += 1
  90.                 continue
  91.             elif ord(chunk[pos]) == 0x40:   #For byte 0x40, it's an opcode
  92.                 if ord(chunk[pos+1]) == 0x17:
  93.                     output.append('0x' + chunk[pos:pos+8].encode('hex') + ';' +
  94.                                   '0x' + chunk[pos:pos+8].encode('hex') + ';' + 'unknown' + '\r\n')
  95.                     output.append(';')
  96.                     pos += 8
  97.                     continue
  98.                 output.append('0x' + chunk[pos:pos+4].encode('hex') + ';' + '0x' +
  99.                               chunk[pos:pos+4].encode('hex') + ';')
  100.                 if ord(chunk[pos+1]) == 0x14:
  101.                     f_number = struct.unpack('<H',chunk[pos+2:pos+4])[0]
  102.                     if f_number == opendialog_chunk:
  103.                         output.append('open dialog')
  104.                     elif f_number == delay_chunk:
  105.                         output.append('delay')
  106.                     elif f_number in [x[0] for x in namelist]:
  107.                         for i, name in namelist:
  108.                             if f_number == i:
  109.                                 break
  110.                         output.append('name: {}'.format(name))
  111.                     else:
  112.                         output.append('function {}'.format(hex(f_number)))
  113.                 elif ord(chunk[pos+1]) == 0x00:
  114.                     output.append('end chunk')
  115.                 elif ord(chunk[pos+1]) == 0x02:
  116.                     output.append('unknown')
  117.                 elif ord(chunk[pos+1]) == 0x05:
  118.                     output.append('linebreak')
  119.                 elif ord(chunk[pos+1]) == 0x06:
  120.                     output.append('closebox')
  121.                 else:
  122.                     output.append('unknown opcode')
  123.                 pos += 4
  124.     ##            elif ord(chunk[pos]) == 0x80:
  125.     ##                output.append(chunk[pos:pos+4].encode('hex') + ';' + chunk[pos:pos+4].encode('hex') + ';')
  126.     ##                output.append('unknown opcode')
  127.     ##                pos += 4
  128.             elif is_jis_char(chunk[pos:pos+2]) or chunk[pos] in asciichar:  #It's text
  129.                 start = pos
  130.                 while is_jis_char(chunk[pos:pos+2]) or chunk[pos] in asciichar:
  131.                     if chunk[pos] in asciichar:         #If ascii, advance by 1
  132.                         pos += 1
  133.                     elif is_jis_char(chunk[pos:pos+2]): #If S-JIS, advance by 2
  134.                         pos += 2
  135.                 output.append(chunk[start:pos] + ';')   #Output text
  136.                 if chunk[pos:pos+2] == '\x40\x05':
  137.                     output.append(';linebreak')
  138.                     pos += 4
  139.                 elif chunk[pos:pos+4] == '\x00\x00\x40\x05':
  140.                     output.append(';linebreak')
  141.                     pos += 6
  142.                 if chunk[pos:pos+4] == '\x40\x14' + struct.pack('<H',delay_chunk):
  143.                     if 'linebreak' in output[-1]:
  144.                         output[-1] += '+delay'
  145.                     else:
  146.                         output.append(';delay')
  147.                     pos += 4
  148.             else:   #Not byte 0x00, byte 0x40, or text
  149.                 print 'Unknown character'
  150.                 print hex(chunkaddr)        #Start of chunk
  151.                 print hex(chunkaddr+pos)    #Postion of miss
  152.                 quit()
  153.             output.append('\r\n')           #Output linebreak and indent
  154.             output.append(';')              #for next opcode within chunk
  155.     with open(filename + '.csv','wb') as f: #Write output to file
  156.         f.write(''.join(output))
  157.  
  158. scripts = ['apend00','bird01','bird02','bird03','bird04','bird05','bird06','birddemo','boss01','boss02','boss2',
  159.            'boss03','boss3','catedral','church01','church02','church03','churdemo','cnt01','coloseum',
  160.            'eddemo01','eddemo02','eddemo03','exdemo01','extra01','extra02','extra03','fir01','fir02','fir03',
  161.            'grave01','grave02','grave03','house','ice01','ice02','ice03','inn01','inn02','inn03','ise01','ise02',
  162.            'ise03','knondemo','last01','last02_0','last02_1','last02_2','last02_3','last03','last04','lastdemo',
  163.            'mnt00','mnt01','mnt02','mnt03','mnt04','mnt05','museum','nxdemo01','nxdemo02','nxdemo03','opdemo00',
  164.            'opdemo01','opdemo02','opdemo03','plane01','plane02','plane03','random','sai01','sai02','sai03',
  165.            'sai04','sand01','sand02','shops','soldier','subgame','thu01','thu02','thu03','tiademo','tower00',
  166.            'tower01','tower02','tower03','tower04','tower05','tower06','tower07','tower08','tower09','town01',
  167.            'town02','town2','town03','tree00','tree01','tree02','tree03','tree04','tutori01','tutori02','tutori03',
  168.            'twdemo01','twdemo02','wind00','wind01','wind02','wood01','wood02','wpshop01','wpshop02','wpshop03']
  169. for script in scripts:                      #Dump each script
  170.     print 'Dumping: {}'.format(script)
  171.     script_dump(script)
  172.     print ''
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top