Skip to content

Instantly share code, notes, and snippets.

@lardratboy
Last active May 29, 2024 20:32
Show Gist options
  • Save lardratboy/d285db4c6a01ceaa9f1549634aaf15e2 to your computer and use it in GitHub Desktop.
Save lardratboy/d285db4c6a01ceaa9f1549634aaf15e2 to your computer and use it in GitHub Desktop.
quick and dirty tool to display the chunk structure of a .bpt file
import io, struct, argparse
class Chunk:
def __init__(self, id):
self.id = id
self.children = []
def process_chunk( input, size_encoding, parent_chunk, remaining_data, depth = 0 ):
if None != parent_chunk.id and not parent_chunk.id in [ 'aBPT', 'aLII', 'aFRM', 'aLYR', 'aVEL', 'nPAL', 'nAMS', 'aANM', 'nFMS', 'nVLS', 'nLIS', 'nLRS' ]:
input.seek( input.tell() + remaining_data )
print( ' ' * depth + f'{parent_chunk.id} size={remaining_data}' )
if remaining_data % 2 != 0: input.seek( input.tell() + 1 )
return
print( ' ' * depth + f'processing {parent_chunk.id}' )
while 7 < remaining_data:
id = input.read( 4 ).decode( 'ascii' )
size = struct.unpack( size_encoding, input.read( 4 ))[0]
chunk = Chunk( id )
parent_chunk.children.append( chunk )
process_chunk( input, size_encoding, chunk, size, depth + 1 )
remaining_data -= size + 8
def parse_chunks_for_file( filename, size_encoding ):
with open(filename,'rb') as f: raw_data = f.read()
input = io.BytesIO( raw_data )
root_chunk = Chunk( None )
process_chunk( input, size_encoding, root_chunk, len( raw_data ) )
return root_chunk
def main():
parser = argparse.ArgumentParser( description='puke up some BPT file chunks' )
parser.add_argument( 'filename', help='filename' )
parser.add_argument( '-s', '--size', default='<I', help='size encoding (use <I)')
args = parser.parse_args()
file_chunks = parse_chunks_for_file( args.filename, args.size )
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment