Advertisement
Guest User

Taiko Wii 4+ Fumen Endianness Converter

a guest
Jul 13th, 2017
2,139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.14 KB | None | 0 0
  1. '''
  2. TAIKO WII 4 FUMEN FORMAT (seems like games as recent as 3ds 3 still use this format)
  3. (found by decompiling FumenViewer @ http://web.archive.org/web/20130718194918/http://forum.owataiko.com/viewtopic.php?f=4&t=356)
  4.  
  5. 0x0: 36 "hantei notes". each one is 3 float32's.
  6. 0x200: int32 num_section, int32 unknown
  7.  
  8. 0x208: num_section sections follow
  9.     float32 bpm, float32 start_time, int8 gogo, int8 section_line, int16 unknown
  10.     6 "bunkis". each one is 1 int32
  11.     int32 unknown
  12.     3 routes follow
  13.         int16 num_notes, int16 unknown, float32 scroll
  14.         num_notes notes follow
  15.             int32 note_type
  16.             float32 headerI1 (note_time = bpm * headerI1 / 5000)
  17.             int32 item, float32 unknown1, int16 hit, int16 score_inc, float32 length
  18.             if note_type is 6, 9 or 98:
  19.                 int32 unknown, int32 unknown
  20. '''
  21.  
  22. import struct
  23. import sys
  24. import shutil
  25. import argparse
  26.  
  27. parser = argparse.ArgumentParser(description='Taiko Wii 4+ Fumen Endianness Converter')
  28. parser.add_argument('direction', help='set to bl to convert from big to little endian, or lb to convert from little to big endian')
  29. parser.add_argument('in.bin')
  30. parser.add_argument('out.bin')
  31. if len(sys.argv) == 1:
  32.     parser.print_help()
  33.     sys.exit()
  34. args = parser.parse_args()
  35.  
  36. ibo = obo = None # in byte order, out byte order
  37. try:
  38.     ibo = {'lb': '<', 'bl': '>'}[args.direction.lower()]
  39. except KeyError:
  40.     sys.exit('error: invalid direction "%s"!' % args.direction.lower())
  41. obo = '>' if ibo == '<' else '<'
  42.  
  43. in_path = getattr(args, 'in.bin')
  44. out_path = getattr(args, 'out.bin')
  45.  
  46. same_file = out_path == in_path
  47.  
  48. if same_file:
  49.     out_path += '.r'
  50.  
  51. with open(in_path, 'rb') as fin:
  52.     with open(out_path, 'wb') as fout:
  53.         for hanteiI in range(36 * 3):
  54.             fout.write(struct.pack(obo + 'f', struct.unpack(ibo + 'f', fin.read(4))[0])) # hantei notes
  55.        
  56.         while fin.tell() != 0x200:
  57.             fout.write(struct.pack(obo + 'I', struct.unpack(ibo + 'I', fin.read(4))[0])) # header stuff like tamashii rate
  58.        
  59.         num_section = struct.unpack(ibo + 'I', fin.read(4))[0]
  60.         fout.write(struct.pack(obo + 'I', num_section)) # num_section
  61.         fout.write(struct.pack(obo + 'I', struct.unpack(ibo + 'I', fin.read(4))[0])) # unknown
  62.        
  63.         for sectionI in range(num_section):
  64.             fout.write(struct.pack(obo + 'f', struct.unpack(ibo + 'f', fin.read(4))[0])) # bpm
  65.             fout.write(struct.pack(obo + 'f', struct.unpack(ibo + 'f', fin.read(4))[0])) # start_time
  66.             fout.write(struct.pack(obo + 'B', struct.unpack(ibo + 'B', fin.read(1))[0])) # gogo
  67.             fout.write(struct.pack(obo + 'B', struct.unpack(ibo + 'B', fin.read(1))[0])) # section_line
  68.             fout.write(struct.pack(obo + 'H', struct.unpack(ibo + 'H', fin.read(2))[0])) # unknown
  69.            
  70.             for bunkiI in range(6):
  71.                 fout.write(struct.pack(obo + 'I', struct.unpack(ibo + 'I', fin.read(4))[0])) # bunkis
  72.            
  73.             fout.write(struct.pack(obo + 'I', struct.unpack(ibo + 'I', fin.read(4))[0])) # unknown
  74.            
  75.             for routeI in range(3):
  76.                 num_notes = struct.unpack(ibo + 'H', fin.read(2))[0]
  77.                 fout.write(struct.pack(obo + 'H', num_notes)) # num_notes
  78.                 fout.write(struct.pack(obo + 'H', struct.unpack(ibo + 'H', fin.read(2))[0])) # unknown
  79.                 fout.write(struct.pack(obo + 'f', struct.unpack(ibo + 'f', fin.read(4))[0])) # scroll
  80.                
  81.                 for noteI in range(num_notes):
  82.                     note_type = struct.unpack(ibo + 'I', fin.read(4))[0]
  83.                     fout.write(struct.pack(obo + 'I', note_type)) # note_type
  84.                     fout.write(struct.pack(obo + 'f', struct.unpack(ibo + 'f', fin.read(4))[0])) # headerI1
  85.                     fout.write(struct.pack(obo + 'I', struct.unpack(ibo + 'I', fin.read(4))[0])) # item
  86.                     fout.write(struct.pack(obo + 'f', struct.unpack(ibo + 'f', fin.read(4))[0])) # unknown1
  87.                     fout.write(struct.pack(obo + 'H', struct.unpack(ibo + 'H', fin.read(2))[0])) # hit
  88.                     fout.write(struct.pack(obo + 'H', struct.unpack(ibo + 'H', fin.read(2))[0])) # score_inc
  89.                     fout.write(struct.pack(obo + 'f', struct.unpack(ibo + 'f', fin.read(4))[0])) # length
  90.                    
  91.                     if note_type in [6, 9, 98]:
  92.                         fout.write(struct.pack(obo + 'I', struct.unpack(ibo + 'I', fin.read(4))[0])) # unknown
  93.                         fout.write(struct.pack(obo + 'I', struct.unpack(ibo + 'I', fin.read(4))[0])) # unknown
  94.  
  95. if same_file:
  96.     shutil.move(out_path, in_path)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement