qazmlpok

東方神医伝 extract

May 15th, 2012
179
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.35 KB | None | 0 0
  1. import os
  2. import sys
  3.  
  4. #Constants taken from insani tools.
  5. LITTLE_ENDIAN = 1
  6. BIG_ENDIAN = -1
  7.  
  8. BYTE_LENGTH = 1
  9. SHORT_LENGTH = 2
  10. INT_LENGTH = 4
  11. LONG_LENGTH = 8
  12.  
  13. ERROR_NONE = 0
  14. ERROR_WARNING = 1
  15. ERROR_ABORT = 2
  16.  
  17. def readbytes(infile, bytecount, key=-1):
  18.     ret = infile.read(bytecount)
  19.  
  20.     return ret
  21.  
  22. def converttoint(bytes, size=INT_LENGTH, endian=LITTLE_ENDIAN):
  23.     result = 0
  24.     for i in xrange(size):
  25.         temp=long(ord(bytes[i]))
  26.         if endian == LITTLE_ENDIAN :
  27.             result |= (temp << (8*i))
  28.         elif endian == BIG_ENDIAN :
  29.             result = (result << 8) | temp
  30.         else :
  31.                 raise Exception('converttoint: Unknown endian specification')
  32.  
  33.         return result
  34.  
  35. def convertfromint(value, size=INT_LENGTH, endian=LITTLE_ENDIAN):
  36.     result = ""
  37.     for i in xrange(size):
  38.         if endian == LITTLE_ENDIAN :
  39.             #result |= (temp << (8*i))
  40.             temp = (value >> (8*i)) & 0x00FF
  41.         elif endian == BIG_ENDIAN :
  42.             #result = (result << 8) | temp
  43.             temp = (value >> (8*(size-i-1))) & 0x00FF
  44.         else :
  45.                 raise Exception('convertfromint: Unknown endian specification')
  46.             result += chr(temp)
  47.  
  48.         return result
  49.  
  50. #program
  51.  
  52. files = sys.argv[1:]
  53. for filename in files:
  54.     infile = open(filename, 'rb')
  55.  
  56.     print "Reading file", filename
  57.  
  58.     #Header:
  59.     #4 bytes for the total size of the index, not counting this header.
  60.  
  61.     filecount = converttoint(readbytes(infile, 4, 0)) / 0x10C
  62.     print "Expecting", filecount, "files."
  63.  
  64.     #Each file entry is
  65.     #4 bytes    4 bytes     104 bytes
  66.     #File start Filesize    Filename
  67.  
  68.     #Total of x10C bytes per entry.
  69.     #The unusual length of the filename makes me think the last 4 bytes might be a useful int
  70.     #I think the filename is just a filename. It isn't all zeroes, but the data does appear to be junk
  71.     #(One filename included "png" several times). On rebuild it is probably safe to just zero fill the filename.
  72.  
  73.     entries = []
  74.  
  75.     for i in xrange(filecount):
  76.         entry = {}
  77.         entry['filestart'] = converttoint(readbytes(infile, 4))
  78.         entry['filesize'] = converttoint(readbytes(infile, 4))
  79.         nameraw = readbytes(infile, 0x100)
  80.         #nameraw = readbytes(infile, 0x104)
  81.         entry['name'] = nameraw[0:nameraw.find("\x00")]     #Truncate to the first \0.
  82.         entry['unk'] = converttoint(readbytes(infile, 4))   #Maybe the filename is exactly x100?
  83.  
  84.         entries.append(entry)
  85.  
  86.  
  87.     #print "Current position is now %d / %X" % (infile.tell(), infile.tell())
  88.  
  89.     #for entry in entries:
  90.     #   for i in entry:
  91.     #       print i + ":", entry[i]
  92.     #   print ""
  93.  
  94.     #sys.exit(0)
  95.  
  96.     dirname = filename[0:filename.find(".")]
  97.     if not os.path.isdir(dirname):
  98.         os.mkdir(dirname)
  99.  
  100.     i = 0
  101.     for entry in entries:
  102.         filename = entry['name'].strip(" \n\t\x00")
  103.  
  104.         dirsegment, filesegment = os.path.split(filename)
  105.         #filename = os.path.join(dirsegment, ("%03d_" % i) + filesegment)       #Can be done to enforce correct order on repacking
  106.         if (not os.path.isdir(os.path.join(dirname, dirsegment))):
  107.             os.makedirs(os.path.join(dirname, dirsegment))
  108.  
  109.         infile.seek(entry['filestart'])
  110.         data = readbytes(infile, entry['filesize'])
  111.         outfile = open(os.path.join(dirname, filename), 'wb')
  112.         outfile.write(data)
  113.         outfile.close()
  114.  
  115.         print "Created file %s of size %08X from position %08X" % (filename, entry['filesize'], entry['filestart'])
  116.         #print "Unk is %08X " % entry['unk']    #It's mostly 0012F79C, also a few 0012FAC4. No idea what it would be used for.
  117.  
  118.         i += 1
  119.  
  120.     infile.close()
Advertisement
Add Comment
Please, Sign In to add comment