def write_bva(self, f): f.write(BVAFILEMAGIC) filesize_offset = f.tell() f.write(b"ABCD") # Placeholder for file size write_uint32(f, 1) # Always a section count of 1 f.write(b"\xFF" * 16) vaf1_start = f.tell() f.write(b"VAF1") vaf1_size_offset = f.tell() f.write(b"EFGH") # Placeholder for vaf1 size write_uint8(f, self.loop_mode) write_uint8(f, 0xFF) write_uint16(f, self.duration) write_uint16(f, len(self.animations)) count_offset = f.tell() f.write(b"AB" * 1) # Placeholder for table count data_offsets = f.tell() f.write(b"ABCD" * 2) # Placeholder for data offsets write_padding(f, multiple=32) assert f.tell() == 0x40 # now, time for the visiblity animations to be written as placeholders anim_start = f.tell() f.write(b"\x00" * (0x4 * len(self.animations))) write_padding(f, multiple=4) table_offset = f.tell() # write the table all_frames = [] for anim in self.animations: print(anim.frames) offset = j3d.find_sequence(all_frames, anim.frames) if offset == -1: offset = len(all_frames) all_frames.extend(anim.frames) anim._set_offset(offset) for val in all_frames: j3d.write_uint8(f, int(val)) j3d.write_padding(f, 4) write_padding(f, multiple=32) total_size = f.tell() f.seek(anim_start) for anim in self.animations: write_uint16(f, len(anim.frames)) write_uint16(f, anim._offset) # Fill in all the placeholder values f.seek(count_offset) write_uint16(f, len(all_frames)) f.seek(filesize_offset) write_uint32(f, total_size) f.seek(vaf1_size_offset) write_uint32(f, total_size - vaf1_start) f.seek(data_offsets) write_uint32(f, anim_start - vaf1_start) write_uint32(f, table_offset - vaf1_start)
def write_bla(self, f): f.write(BLAFILEMAGIC) filesize_offset = f.tell() f.write(b"ABCD") # Placeholder for file size j3d.write_uint32(f, 1) # Always a section count of 1 f.write(b"\xFF" * 16) clf1_start = f.tell() f.write(b"CLF1") clf1_size_offset = f.tell() f.write(b"EFGH") # Placeholder for clf1 size j3d.write_uint8(f, self.loop_mode) j3d.write_sint8(f, self.anglescale) j3d.write_uint16(f, self.duration) #0x30 count_offset = f.tell() f.write(b"toad") # Placeholder for cluster and scale counts data_offsets = f.tell() f.write(b"toadette") #placeholder for offsets write_padding(f, multiple=32) cluster_anim_start = f.tell() f.write(b"\x00" * (0x4 * len(self.animations))) #placeholder for stuff write_padding(f, multiple=32) all_scales = [] for anim in self.animations: if len(anim.seq) == 1: sequence = [anim.seq[0].value] else: sequence = [] for comp in anim.seq: sequence.append(comp.value) offset = j3d.find_sequence(all_scales, sequence) if offset == -1: offset = len(all_scales) all_scales.extend(sequence) anim.scale_offset = offset scale_start = f.tell() for val in all_scales: write_float(f, val) j3d.write_padding(f, 32) total_size = f.tell() f.seek(cluster_anim_start) for anim in self.animations: j3d.write_uint16(f, len(anim.seq)) # Scale count for this animation j3d.write_uint16(f, anim.scale_offset) # Fill in all the placeholder values f.seek(filesize_offset) j3d.write_uint32(f, total_size) f.seek(clf1_size_offset) j3d.write_uint32(f, total_size - clf1_start) f.seek(count_offset) j3d.write_uint16(f, 1) j3d.write_uint16(f, len(all_scales)) # Next come the section offsets j3d.write_uint32(f, cluster_anim_start - clf1_start) j3d.write_uint32(f, scale_start - clf1_start)
def write_btk(self, f): f.write(BTKFILEMAGIC) filesize_offset = f.tell() f.write(b"ABCD") # Placeholder for file size j3d.write_uint32(f, 1) # Always a section count of 1 f.write(b"SVR1" + b"\xFF" * 12) ttk1_start = f.tell() f.write(b"TTK1") ttk1_size_offset = f.tell() f.write(b"EFGH") # Placeholder for ttk1 size j3d.write_uint8(f, self.loop_mode) j3d.write_sint8(f, self.anglescale) rotscale = (2.0**self.anglescale) * (180.0 / 32768.0) j3d.write_uint16(f, self.duration) j3d.write_uint16(f, len(self.animations) * 3) # Three times the matrix animations count_offset = f.tell() f.write( b"1+1=11") # Placeholder for scale, rotation and translation count data_offsets = f.tell() f.write(b"--OnceUponATimeInALandFarAway---") f.write(b"\x00" * (0x7C - f.tell())) j3d.write_uint32(f, self.unknown_address) matrix_anim_start = f.tell() f.write(b"\x00" * (0x36 * len(self.animations))) write_padding(f, multiple=4) index_start = f.tell() for i in range(len(self.animations)): j3d.write_uint16(f, i) j3d.write_padding(f, multiple=4) stringtable = j3d.StringTable() for anim in self.animations: stringtable.strings.append(anim.name) stringtable_start = f.tell() stringtable.write(f, stringtable.strings) j3d.write_padding(f, multiple=4) matindex_start = f.tell() for anim in self.animations: j3d.write_uint8(f, anim.matindex) j3d.write_padding(f, multiple=4) center_start = f.tell() for anim in self.animations: for val in anim.center: write_float(f, val) j3d.write_padding(f, multiple=4) all_scales = [] all_rotations = [] all_translations = [] for anim in self.animations: for axis in "UVW": # Set up offset for scale if len(anim.scale[axis]) == 1: sequence = [anim.scale[axis][0].value] else: sequence = [] for comp in anim.scale[axis]: sequence.append(comp.time) sequence.append(comp.value) sequence.append(comp.tangentIn) if self.tan_type == 1: sequence.append(comp.tangentOut) offset = j3d.find_sequence(all_scales, sequence) if offset == -1: offset = len(all_scales) all_scales.extend(sequence) anim._set_scale_offsets(axis, offset) # Set up offset for rotation if len(anim.rotation[axis]) == 1: comp = anim.rotation[axis][0] #angle = ((comp.value+180) % 360) - 180 sequence = [comp.value / rotscale] #print("seq", sequence) else: sequence = [] for comp in anim.rotation[axis]: #angle = ((comp.value+180) % 360) - 180 sequence.append(comp.time) sequence.append(comp.value / rotscale) sequence.append(comp.tangentIn / rotscale) if self.tan_type == 1: sequence.append(comp.tangentOut / rotscale) #print("seq", sequence) offset = j3d.find_sequence(all_rotations, sequence) if offset == -1: offset = len(all_rotations) all_rotations.extend(sequence) anim._set_rot_offsets(axis, offset) """for comp in anim.rotation[axis]: all_rotations.append(comp.frame) all_rotations.append(comp.value/rotscale) all_rotations.append(comp.tangentIn/rotscale) all_rotations.append(comp.tangentOut/rotscale) """ # Set up offset for translation if len(anim.translation[axis]) == 1: sequence = [anim.translation[axis][0].value] else: sequence = [] for comp in anim.translation[axis]: sequence.append(comp.time) sequence.append(comp.value) sequence.append(comp.tangentIn) if self.tan_type == 1: sequence.append(comp.tangentOut) offset = j3d.find_sequence(all_translations, sequence) if offset == -1: offset = len(all_translations) all_translations.extend(sequence) anim._set_translation_offsets(axis, offset) """offset = len(all_translations) for comp in anim.translation[axis]: all_translations.append(comp.frame) all_translations.append(comp.value) all_translations.append(comp.tangentIn) all_translations.append(comp.tangentOut)""" scale_start = f.tell() for val in all_scales: write_float(f, val) j3d.write_padding(f, 4) rotations_start = f.tell() for val in all_rotations: val = int(val) if val <= -32767: val = -32767 elif val > 32767: val = 32767 """angle = ((val+180) % 360) - 180 # Force the angle between -180 and 180 degrees print(val, "becomes", angle) if angle >= 0: angle = (angle/180.0)*(2**15-1) else: angle = (angle/180.0)*(2**15)""" j3d.write_sint16(f, int(val)) j3d.write_padding(f, 4) translations_start = f.tell() for val in all_translations: #print(val) write_float(f, val) j3d.write_padding(f, 32) total_size = f.tell() f.seek(matrix_anim_start) for anim in self.animations: for axis in "UVW": j3d.write_uint16(f, len( anim.scale[axis])) # Scale count for this animation j3d.write_uint16( f, anim._scale_offsets[axis]) # Offset into scales j3d.write_uint16( f, self.tan_type ) # Tangent type, 0 = only TangentIn; 1 = TangentIn and TangentOut j3d.write_uint16(f, len( anim.rotation[axis])) # Rotation count for this animation j3d.write_uint16( f, anim._rot_offsets[axis]) # Offset into rotations j3d.write_uint16( f, self.tan_type ) # Tangent type, 0 = only TangentIn; 1 = TangentIn and TangentOut j3d.write_uint16(f, len(anim.translation[axis]) ) # Translation count for this animation j3d.write_uint16(f, anim._translation_offsets[axis] ) # offset into translations j3d.write_uint16( f, self.tan_type ) # Tangent type, 0 = only TangentIn; 1 = TangentIn and TangentOut # Fill in all the placeholder values f.seek(filesize_offset) j3d.write_uint32(f, total_size) f.seek(ttk1_size_offset) j3d.write_uint32(f, total_size - ttk1_start) f.seek(count_offset) j3d.write_uint16(f, len(all_scales)) j3d.write_uint16(f, len(all_rotations)) j3d.write_uint16(f, len(all_translations)) # Next come the section offsets j3d.write_uint32(f, matrix_anim_start - ttk1_start) j3d.write_uint32(f, index_start - ttk1_start) j3d.write_uint32(f, stringtable_start - ttk1_start) j3d.write_uint32(f, matindex_start - ttk1_start) j3d.write_uint32(f, center_start - ttk1_start) j3d.write_uint32(f, scale_start - ttk1_start) j3d.write_uint32(f, rotations_start - ttk1_start) j3d.write_uint32(f, translations_start - ttk1_start)
def write_bck(self, f): f.write(BCKFILEMAGIC) filesize_offset = f.tell() f.write(b"ABCD") # Placeholder for file size j3d.write_uint32(f, 1) # Always a section count of 1 f.write(b"\xFF"*16) ank1_start = f.tell() f.write(b"ANK1") ttk1_size_offset = f.tell() f.write(b"EFGH") # Placeholder for ttk1 size j3d.write_uint8(f, self.loop_mode) j3d.write_sint8(f, self.anglescale) rotscale = (2.0**self.anglescale)*(180.0 / 32768.0) j3d.write_uint16(f, self.duration) j3d.write_uint16(f, len( self.animations )) #0x30 count_offset = f.tell() f.write(b"1+1=11") # Placeholder for scale, rotation and translation count data_offsets = f.tell() f.write(b"toadettebestgirl") #placeholder for offsets write_padding(f, multiple=32) bone_anim_start = f.tell() f.write(b"\x00"*(0x36*len(self.animations))) #placeholder for stuff write_padding(f, multiple=32) all_scales = [] all_rotations = [] all_translations = [] for anim in self.animations: for axis in "XYZ": # Set up offset for scale if len(anim.scale[axis]) == 1: sequence = [anim.scale[axis][0].value] else: sequence = [] for comp in anim.scale[axis]: sequence.append(comp.time) sequence.append(comp.value) sequence.append(comp.tangentIn) if self.tan_type == 1 : sequence.append(comp.tangentOut) offset = j3d.find_sequence(all_scales,sequence) if offset == -1: offset = len(all_scales) all_scales.extend(sequence) anim._set_scale_offsets(axis, offset) # Set up offset for rotation if len(anim.rotation[axis]) == 1: comp = anim.rotation[axis][0] #angle = ((comp.value+180) % 360) - 180 sequence = [comp.value/rotscale] #print("seq", sequence) else: sequence = [] for comp in anim.rotation[axis]: #angle = ((comp.value+180) % 360) - 180 sequence.append(comp.time) sequence.append(comp.value/rotscale) sequence.append(comp.tangentIn/rotscale) if self.tan_type == 1 : sequence.append(comp.tangentOut/rotscale) #print("seq", sequence) offset = j3d.find_sequence(all_rotations, sequence) if offset == -1: offset = len(all_rotations) all_rotations.extend(sequence) anim._set_rot_offsets(axis, offset) # Set up offset for translation if len(anim.translation[axis]) == 1: sequence = [anim.translation[axis][0].value] else: sequence = [] for comp in anim.translation[axis]: sequence.append(comp.time) sequence.append(comp.value) sequence.append(comp.tangentIn) if self.tan_type == 1 : sequence.append(comp.tangentOut) offset = j3d.find_sequence(all_translations, sequence) if offset == -1: offset = len(all_translations) all_translations.extend(sequence) anim._set_translation_offsets(axis, offset) scale_start = f.tell() for val in all_scales: write_float(f, val) j3d.write_padding(f, 32) rotations_start = f.tell() for val in all_rotations: val = int(val) if val <= -32767: val = -32767 elif val > 32767: val = 32767 #try: j3d.write_sint16(f, val ) """except: print(val)""" j3d.write_padding(f, 32) translations_start = f.tell() for val in all_translations: #print(val) write_float(f, val) j3d.write_padding(f, 32) total_size = f.tell() f.seek(bone_anim_start) for anim in self.animations: for axis in "XYZ": j3d.write_uint16(f, len(anim.scale[axis])) # Scale count for this animation j3d.write_uint16(f, anim._scale_offsets[axis]) # Offset into scales j3d.write_uint16(f, self.tan_type) # Tangent type, 0 = only TangentIn; 1 = TangentIn and TangentOut j3d.write_uint16(f, len(anim.rotation[axis])) # Rotation count for this animation j3d.write_uint16(f, anim._rot_offsets[axis]) # Offset into rotations j3d.write_uint16(f, self.tan_type) # Tangent type, 0 = only TangentIn; 1 = TangentIn and TangentOut j3d.write_uint16(f, len(anim.translation[axis])) # Translation count for this animation j3d.write_uint16(f, anim._translation_offsets[axis])# offset into translations j3d.write_uint16(f, self.tan_type) # Tangent type, 0 = only TangentIn; 1 = TangentIn and TangentOut # Fill in all the placeholder values f.seek(filesize_offset) j3d.write_uint32(f, total_size) f.seek(ttk1_size_offset) j3d.write_uint32(f, total_size - ank1_start) f.seek(count_offset) j3d.write_uint16(f, len(all_scales)) j3d.write_uint16(f, len(all_rotations)) j3d.write_uint16(f, len(all_translations)) # Next come the section offsets j3d.write_uint32(f, bone_anim_start - ank1_start) j3d.write_uint32(f, scale_start - ank1_start) j3d.write_uint32(f, rotations_start - ank1_start) j3d.write_uint32(f, translations_start - ank1_start)
def write_btp(self, f): #header info f.write(j3d.BTPFILEMAGIC) filesize_offset = f.tell() f.write(b"ABCD") # Placeholder for file size j3d.write_uint32(f, 1) # Always a section count of 1 f.write(b"\xFF"*16) tpt1_start = f.tell() f.write(b"TPT1") tpt1_size_offset = f.tell() f.write(b"EFGH") # Placeholder for tpt1 size j3d.write_uint8(f, self.flag) j3d.write_uint8(f, self.anglescale) j3d.write_uint16(f, self.largest_duration) j3d.write_uint16(f, len(self.animations) ) j3d.write_uint16(f, self.unknown_address) tables_offset = f.tell(); f.write(b"toadettebestgril") facial_animation_entries_os = f.tell() f.write(b"\x00"*(0x8*len(self.animations))) #placeholder for stuff """ total_frames = 0; for i in range( len (btp.animations) ): j3d.write_uint16(f, len ( btp.animations[i].frames )) j3d.write_uint16(f, total_frames) total_frames += len (btp.animations[i].frames ) j3d.write_uint16(f, 0x00FF) j3d.write_uint16(f, 0xFFFF) """ j3d.write_padding(f, 4) texture_index_bank_os = f.tell() all_frames = [] for anim in self.animations: offset = j3d.find_sequence( all_frames, anim.frames ) if offset == -1: offset = len(all_frames) all_frames.extend(anim.frames) anim._set_offset(offset) for val in all_frames: j3d.write_uint16(f, int(val) ) j3d.write_padding(f, 4) """ for i in range( len (btp.animations) ): for j in btp.animations[i].frames: j = int(j) j3d.write_uint16(f, j) """ remap_table_os = f.tell() j3d.write_uint32(f, 0x00000001) stringtable_os = f.tell() strings = self.get_children_names() j3d.StringTable.write(f, strings) j3d.write_padding(f, 32) total_size = f.tell() f.seek(filesize_offset) j3d.write_uint32(f, total_size) f.seek(tpt1_size_offset) j3d.write_uint32(f, total_size - tpt1_start) f.seek(facial_animation_entries_os); for anim in self.animations: j3d.write_uint16(f, len ( anim.frames )) j3d.write_uint16(f, anim._offset) j3d.write_uint16(f, 0x00FF) j3d.write_uint16(f, 0xFFFF) f.seek(tables_offset) j3d.write_uint32(f, facial_animation_entries_os - tpt1_start) j3d.write_uint32(f, texture_index_bank_os - tpt1_start) j3d.write_uint32(f, remap_table_os - tpt1_start) j3d.write_uint32(f, stringtable_os - tpt1_start)