예제 #1
0
def read(pac_path, read_inner=False):
  f = open(pac_path, 'rb')
  assert f.read(4) == b'KCAP'
  util.log('\nReading PAC', pac_path, level=util.LOG_INFO)

  files = OrderedDict()

  f.seek(0x04, 1)
  file_count = util.readlong(f)
  util.log('{:d} files in archive'.format(file_count), level=util.LOG_INFO)
  
  if read_inner:
    import fmt_omo

  for i in range(0, file_count):
    f.seek(0x10 + i*4)
    f.seek(util.readlong(f))
    file_name = util.readstring(f)

    m = re.match('(.*)([A-Z])([0-9][0-9])(.*)\.([a-z]{3})', file_name)
    if not m:
      util.log('Unmatched file skipped', file_name, level=util.LOG_ERROR)
      continue

    bodygroup = m.group(1)
    motion_name = m.group(4)
    ext = m.group(5)

    f.seek(0x10 + (file_count * 4) + (i * 4))
    file_offset = util.readlong(f)
    f.seek(0x10 + (file_count * 8) + (i * 4))
    file_len = util.readlong(f)

    f.seek(file_offset)
    file_contents = f.read(file_len)
    assert(len(file_contents) == file_len)

    if read_inner and m.group(5) == 'omo':
      util.log('\nReading OMO', file_name, level=util.LOG_INFO)
      files[file_name] = fmt_omo.read(file_contents)
    else:
      files[file_name] = file_contents

  return files
예제 #2
0
def read(pac_path, read_inner=False):
    f = open(pac_path, 'rb')
    assert f.read(4) == b'KCAP'
    util.log('\nReading PAC', pac_path, level=util.LOG_INFO)

    files = OrderedDict()

    f.seek(0x04, 1)
    file_count = util.readlong(f)
    util.log('{:d} files in archive'.format(file_count), level=util.LOG_INFO)

    if read_inner:
        import fmt_omo

    for i in range(0, file_count):
        f.seek(0x10 + i * 4)
        f.seek(util.readlong(f))
        file_name = util.readstring(f)

        m = re.match('(.*)([A-Z])([0-9][0-9])(.*)\.([a-z]{3})', file_name)
        if not m:
            util.log('Unmatched file skipped', file_name, level=util.LOG_ERROR)
            continue

        bodygroup = m.group(1)
        motion_name = m.group(4)
        ext = m.group(5)

        f.seek(0x10 + (file_count * 4) + (i * 4))
        file_offset = util.readlong(f)
        f.seek(0x10 + (file_count * 8) + (i * 4))
        file_len = util.readlong(f)

        f.seek(file_offset)
        file_contents = f.read(file_len)
        assert (len(file_contents) == file_len)

        if read_inner and m.group(5) == 'omo':
            util.log('\nReading OMO', file_name, level=util.LOG_INFO)
            files[file_name] = fmt_omo.read(file_contents)
        else:
            files[file_name] = file_contents

    return files
예제 #3
0

if __name__ == '__main__':
    util.log_level = util.LOG_INFO
    paths = get_fighter_paths('S:\\SSB4\\extracted_content', 'yoshi')
    bones, bone_uids = fmt_vbn.read(paths['vbn'])
    archive = fmt_pac.read(paths['pac'])

    # convert OMOs into JSON animation format
    animations = []
    for f, f_data in archive.items():
        m = re.match('.+([A-Z])\d{2}(.+)\.([a-z]{3})', f)
        if m.group(3) == 'omo' and (m.group(1) == 'A'):
            util.log('\nReading OMO', f, level=util.LOG_INFO)
            motion = fmt_omo.read(f_data,
                                  debug_bones=bones,
                                  debug_bone_ids=bone_uids)
            animation = {
                'name': m.group(2),
                'fps': 30,
                'length': motion['frame_count'] / 30,
                'hierarchy': [{
                    'parent': b['parent'],
                    'keys': []
                } for b in bones]
            }
            if motion['unknown']:
                animation['name'] += '_INCOMPLETE'

            for channel in motion['channels']:
                bone_index = bone_uids[channel['bone']]
예제 #4
0
    'pac': os.path.join(base, 'fighter', name, 'motion', 'body', 'main.pac')
  }

if __name__ == '__main__':
  util.log_level = util.LOG_INFO
  paths = get_fighter_paths('S:\\SSB4\\extracted_content', 'yoshi')
  bones, bone_uids = fmt_vbn.read(paths['vbn'])
  archive = fmt_pac.read(paths['pac'])

  # convert OMOs into JSON animation format
  animations = []
  for f, f_data in archive.items():
    m = re.match('.+([A-Z])\d{2}(.+)\.([a-z]{3})', f)
    if m.group(3) == 'omo' and (m.group(1) == 'A'):
      util.log('\nReading OMO', f, level=util.LOG_INFO)
      motion = fmt_omo.read(f_data, debug_bones=bones, debug_bone_ids=bone_uids)
      animation = {
        'name': m.group(2),
        'fps': 30,
        'length': motion['frame_count'] / 30,
        'hierarchy': [{ 'parent': b['parent'], 'keys': []} for b in bones]
      }
      if motion['unknown']:
        animation['name'] += '_INCOMPLETE'

      for channel in motion['channels']:
        bone_index = bone_uids[channel['bone']]
        for i, frame in enumerate(channel['frames']):
          frame['time'] = i / 30
          if 'pos' in frame:
            frame['pos'] = list(np.add(bones[bone_index]['pos'], frame['pos']))