Exemple #1
0
 def load(self, reader):
     Editable.load(self, reader)
     self.scrn.load(reader)
Exemple #2
0
 def load(self, reader):
     reader = BinaryIO.reader(reader)
     AtomicStruct.load(self, reader)
     self.files = {}
     self.ids = {}
     offsets = []
     sizes = []
     if self.version in game.GEN_IV:
         commented = False  # (self.seed & 0x1FF) == 0x1FF
         for i in xrange(1, self.num + 1):
             state = (((self.seed * 0x2FD) & 0xFFFF) * i) & 0xFFFF
             key = state | state << 16
             offsets.append(reader.readUInt32() ^ key)
             sizes.append(reader.readUInt32() ^ key)
         if commented:
             state = (((self.seed * 0x2FD) & 0xFFFF) * i) & 0xFFFF
             key = state | state << 16
             comment_ofs = reader.readUInt32() ^ key
             term = reader.readUInt32() ^ key
             if term != 0xFFFF:
                 raise ValueError('Expected 0xFFFF comment ofs terminator.'
                                  ' Got {0:#x}'.format(term))
         for i in xrange(self.num):
             compressed = False
             reader.seek(offsets[i])
             size = sizes[i]
             string = []
             key = (TEXT_KEY4_INIT * (i + 1)) & 0xFFFF
             for j in range(size):
                 string.append(reader.readUInt16() ^ key)
                 key = (key + TEXT_KEY4_STEP) & 0xFFFF
             if string[0] == 0xF100:
                 compressed = True
                 string = decompress(string)
             text = ''
             while string:
                 char = string.pop(0)
                 if char == 0xFFFF:
                     break
                 elif char == 0xFFFE:
                     text += 'VAR('
                     args = [string.pop(0)]
                     count = string.pop(0)
                     args += string[:count]
                     string = string[count:]
                     text += ', '.join(map(str, args))
                     text += ')'
                 elif char == 0xE000:
                     text += '\\n'
                 elif char == 0x25bc:
                     text += '\\r'
                 elif char == 0x25bd:
                     text += '\\f'
                 else:
                     try:
                         text += table[char]
                     except KeyError:
                         text += '\\?{0:04x}'.format(char)
                 name = '0_{0:05}'.format(i)
                 if compressed:
                     name += 'c'
                 self.files[name] = text
                 self.ids[i] = name
             else:
                 raise RuntimeError('Did not have a terminating character')
     else:
         commented = False
         for i in xrange(self.numblocks):
             offsets.append(reader.readUInt32())
         block = Editable()
         block.uint32('size')
         block.array('entries',
                     TableEntry(self.version).base_struct,
                     length=self.num)
         block.freeze()
         for i, block_offset in enumerate(offsets):
             reader.seek(block_offset)
             block.load(reader)
             for j, entry in enumerate(block.entries):
                 compressed = False
                 text = ''
                 reader.seek(block_offset + entry.offset)
                 encchars = [
                     reader.readUInt16() for k in xrange(entry.charcount)
                 ]
                 seed = key = encchars[-1] ^ 0xFFFF
                 string = []  # decrypted chars
                 while encchars:
                     char = encchars.pop() ^ key
                     key = ((key >> 3) | (key << 13)) & 0xFFFF
                     string.insert(0, char)
                 if string[0] == 0xF100:
                     compressed = True
                     string = decompress(string, 16)
                 while string:
                     char = string.pop(0)
                     if char == 0xFFFF:
                         break
                     elif char == 0xFFFE:
                         text += '\\n'
                     elif char < 20 or char > 0xF000:
                         text += '\\?{0:04X}'.format(char)
                     elif char == 0xF000:
                         kind = string.pop(0)
                         count = string.pop(0)
                         if kind == 0xbe00 and not count:
                             text += '\\f'
                         elif kind == 0xbe01 and not count:
                             text += '\\r'
                         else:
                             text += 'VAR('
                             args = [kind]
                             args += string[:count]
                             string = string[count:]
                             text += ', '.join(map(str, args))
                             text += ')'
                     else:
                         text += unichr(char)
                 name = '{0}_{1:05}'.format(i, j)
                 c = 65
                 for k in xrange(16):
                     if (entry.flags >> k) & 0x1:
                         name += ord(c + k)
                 if compressed:
                     name += 'c'
                 name += '[{0:04X}]'.format(seed)
                 self.files[name] = text
                 self.ids[j] = name
     if commented:
         reader.seek(comment_ofs)
         num = reader.readUInt16()
         for i in xrange(num):
             commentid = reader.readUInt16()
             text = ''
             while True:
                 char = reader.readUInt16()
                 if char == 0xFFFF:
                     break
                 text += unichr(char)
                 name = '0c_{0:05}'.format(commentid)
                 self.files[name] = text
     return self
Exemple #3
0
 def load(self, reader):
     Editable.load(self, reader)
     self.data = array.array('H', reader.read(self.datasize))
Exemple #4
0
 def load(self, reader):
     Editable.load(self, reader)
     assert self.magic == 'RLCN', 'Expected RLCN got '.format(self.magic)
     self.pltt.load(reader)