class Dxt10Header: context = ContextReference() def __init__(self, context, arg=None, template=None): self.name = '' self._context = context self.arg = arg self.template = template self.io_size = 0 self.io_start = 0 self.dxgi_format = DxgiFormat() self.resource_dimension = D3D10ResourceDimension() self.misc_flag = 0 self.array_size = 0 self.misc_flag_2 = 0 self.set_defaults() def set_defaults(self): self.dxgi_format = DxgiFormat() self.resource_dimension = D3D10ResourceDimension() self.misc_flag = 0 self.array_size = 0 self.misc_flag_2 = 0 def read(self, stream): self.io_start = stream.tell() self.dxgi_format = DxgiFormat(stream.read_uint()) self.resource_dimension = D3D10ResourceDimension(stream.read_uint()) self.misc_flag = stream.read_uint() self.array_size = stream.read_uint() self.misc_flag_2 = stream.read_uint() self.io_size = stream.tell() - self.io_start def write(self, stream): self.io_start = stream.tell() stream.write_uint(self.dxgi_format.value) stream.write_uint(self.resource_dimension.value) stream.write_uint(self.misc_flag) stream.write_uint(self.array_size) stream.write_uint(self.misc_flag_2) self.io_size = stream.tell() - self.io_start def get_info_str(self): return f'Dxt10Header [Size: {self.io_size}, Address: {self.io_start}] {self.name}' def get_fields_str(self): s = '' s += f'\n * dxgi_format = {self.dxgi_format.__repr__()}' s += f'\n * resource_dimension = {self.resource_dimension.__repr__()}' s += f'\n * misc_flag = {self.misc_flag.__repr__()}' s += f'\n * array_size = {self.array_size.__repr__()}' s += f'\n * misc_flag_2 = {self.misc_flag_2.__repr__()}' return s def __repr__(self): s = self.get_info_str() s += self.get_fields_str() s += '\n' return s
class PixelFormat: context = ContextReference() def __init__(self, context, arg=None, template=None): self.name = '' self._context = context self.arg = arg self.template = template self.io_size = 0 self.io_start = 0 # Always 32. self.size = 32 # Non-zero for DX9, zero for DX10. self.flags = PixelFormatFlags() # Determines compression type. Zero means no compression. self.four_c_c = FourCC() # For non-compressed types, this is either 24 or 32 depending on whether there is an alpha channel. For compressed types, this describes the number of bits per block, which can be either 256 or 512. self.bit_count = 0 # For non-compressed types, this determines the red mask. Usually 0x00FF0000. Is zero for compressed textures. self.r_mask = 0 # For non-compressed types, this determines # the green mask. Usually 0x0000FF00. Is zero for compressed textures. self.g_mask = 0 # For non-compressed types, this determines # the blue mask. Usually 0x00FF0000. Is zero for compressed textures. self.b_mask = 0 # For non-compressed types, this determines # the alpha mask. Usually 0x00000000 if there is no alpha channel and 0xFF000000 if there is an alpha channel. Is zero for compressed textures. self.a_mask = 0 self.set_defaults() def set_defaults(self): self.size = 32 self.flags = PixelFormatFlags() self.four_c_c = FourCC() self.bit_count = 0 self.r_mask = 0 self.g_mask = 0 self.b_mask = 0 self.a_mask = 0 def read(self, stream): self.io_start = stream.tell() self.size = stream.read_uint() self.flags = stream.read_type(PixelFormatFlags) self.four_c_c = FourCC(stream.read_uint()) self.bit_count = stream.read_uint() self.r_mask = stream.read_uint() self.g_mask = stream.read_uint() self.b_mask = stream.read_uint() self.a_mask = stream.read_uint() self.io_size = stream.tell() - self.io_start def write(self, stream): self.io_start = stream.tell() stream.write_uint(self.size) stream.write_type(self.flags) stream.write_uint(self.four_c_c.value) stream.write_uint(self.bit_count) stream.write_uint(self.r_mask) stream.write_uint(self.g_mask) stream.write_uint(self.b_mask) stream.write_uint(self.a_mask) self.io_size = stream.tell() - self.io_start def get_info_str(self): return f'PixelFormat [Size: {self.io_size}, Address: {self.io_start}] {self.name}' def get_fields_str(self): s = '' s += f'\n * size = {self.size.__repr__()}' s += f'\n * flags = {self.flags.__repr__()}' s += f'\n * four_c_c = {self.four_c_c.__repr__()}' s += f'\n * bit_count = {self.bit_count.__repr__()}' s += f'\n * r_mask = {self.r_mask.__repr__()}' s += f'\n * g_mask = {self.g_mask.__repr__()}' s += f'\n * b_mask = {self.b_mask.__repr__()}' s += f'\n * a_mask = {self.a_mask.__repr__()}' return s def __repr__(self): s = self.get_info_str() s += self.get_fields_str() s += '\n' return s
class LayerFrag: """ name_ptr, u0, u1, info_ptr, info_count, u2, u3, attrib_ptr, attrib_count """ context = ContextReference() def __init__(self, context, arg=None, template=None): self.name = '' self._context = context self.arg = arg self.template = template self.io_size = 0 self.io_start = 0 self.name_ptr = 0 self.u_0 = 0 self.u_1 = 0 self.info_ptr = 0 self.info_count = 0 self.u_2 = 0 self.u_3 = 0 self.attrib_ptr = 0 self.attrib_count = 0 self.set_defaults() def set_defaults(self): self.name_ptr = 0 self.u_0 = 0 self.u_1 = 0 self.info_ptr = 0 self.info_count = 0 self.u_2 = 0 self.u_3 = 0 self.attrib_ptr = 0 self.attrib_count = 0 def read(self, stream): self.io_start = stream.tell() self.name_ptr = stream.read_uint64() self.u_0 = stream.read_uint64() self.u_1 = stream.read_uint64() self.info_ptr = stream.read_uint64() self.info_count = stream.read_uint64() self.u_2 = stream.read_uint64() self.u_3 = stream.read_uint64() self.attrib_ptr = stream.read_uint64() self.attrib_count = stream.read_uint64() self.io_size = stream.tell() - self.io_start def write(self, stream): self.io_start = stream.tell() stream.write_uint64(self.name_ptr) stream.write_uint64(self.u_0) stream.write_uint64(self.u_1) stream.write_uint64(self.info_ptr) stream.write_uint64(self.info_count) stream.write_uint64(self.u_2) stream.write_uint64(self.u_3) stream.write_uint64(self.attrib_ptr) stream.write_uint64(self.attrib_count) self.io_size = stream.tell() - self.io_start def get_info_str(self): return f'LayerFrag [Size: {self.io_size}, Address: {self.io_start}] {self.name}' def get_fields_str(self): s = '' s += f'\n * name_ptr = {self.name_ptr.__repr__()}' s += f'\n * u_0 = {self.u_0.__repr__()}' s += f'\n * u_1 = {self.u_1.__repr__()}' s += f'\n * info_ptr = {self.info_ptr.__repr__()}' s += f'\n * info_count = {self.info_count.__repr__()}' s += f'\n * u_2 = {self.u_2.__repr__()}' s += f'\n * u_3 = {self.u_3.__repr__()}' s += f'\n * attrib_ptr = {self.attrib_ptr.__repr__()}' s += f'\n * attrib_count = {self.attrib_count.__repr__()}' return s def __repr__(self): s = self.get_info_str() s += self.get_fields_str() s += '\n' return s
class ManiBlock: context = ContextReference() def __init__(self, context, arg=None, template=None): self.name = '' self._context = context self.arg = arg self.template = template self.io_size = 0 self.io_start = 0 self.ref = Empty(self.context, None, None) self.indices_c_0 = numpy.zeros((), dtype='ushort') self.indices_c_0 = numpy.zeros((), dtype='uint') self.indices_c_1 = numpy.zeros((), dtype='ushort') self.indices_c_1 = numpy.zeros((), dtype='uint') self.indices_1 = numpy.zeros((), dtype='ushort') self.indices_1 = numpy.zeros((), dtype='uint') self.indices_e_2 = numpy.zeros((), dtype='ushort') self.indices_e_2 = numpy.zeros((), dtype='uint') self.p_indices_c_0 = numpy.zeros((), dtype='ubyte') self.p_indices_c_0 = numpy.zeros((), dtype='ubyte') self.p_indices_c_1 = numpy.zeros((), dtype='ubyte') self.p_indices_c_1 = numpy.zeros((), dtype='ubyte') self.p_indices_0_b = numpy.zeros((), dtype='ubyte') self.p_indices_0_c = numpy.zeros((), dtype='ubyte') # ? self.pad = PadAlign(self.context, self.ref, 4) # these are likely a scale reference or factor self.floatsa = numpy.zeros((), dtype='float') # ? self.pad_2 = SmartPadding(self.context, None, None) # likely self.frame_count = 0 self.c_1 = 0 self.e = 0 # fixed self.zeros_19 = numpy.zeros((19), dtype='uint') self.count = 0 # usually / always 420 self.four_and_twenty = 0 self.ref_2 = Empty(self.context, None, None) self.zeros = numpy.zeros((self.c_1), dtype='ubyte') # ? self.anoth_pad = SmartPadding(self.context, None, None) # these are likely a scale reference or factor self.floatsb = numpy.zeros((6), dtype='float') # ? self.unk = 0 # this seems to be vaguely related, but not always there? self.unk_for_e_2 = 0 self.repeats = Array(self.context) self.set_defaults() def set_defaults(self): self.ref = Empty(self.context, None, None) if self.context.version == 18: self.indices_c_0 = numpy.zeros((), dtype='ushort') if not (self.context.version == 18): self.indices_c_0 = numpy.zeros((), dtype='uint') if self.context.version == 18: self.indices_c_1 = numpy.zeros((), dtype='ushort') if not (self.context.version == 18): self.indices_c_1 = numpy.zeros((), dtype='uint') if self.context.version == 18: self.indices_1 = numpy.zeros((), dtype='ushort') if not (self.context.version == 18): self.indices_1 = numpy.zeros((), dtype='uint') if self.context.version == 18: self.indices_e_2 = numpy.zeros((), dtype='ushort') if not (self.context.version == 18): self.indices_e_2 = numpy.zeros((), dtype='uint') self.p_indices_c_0 = numpy.zeros((), dtype='ubyte') if self.context.version == 18: self.p_indices_c_0 = numpy.zeros((), dtype='ubyte') self.p_indices_c_1 = numpy.zeros((), dtype='ubyte') if self.context.version == 18: self.p_indices_c_1 = numpy.zeros((), dtype='ubyte') self.p_indices_0_b = numpy.zeros((), dtype='ubyte') self.p_indices_0_c = numpy.zeros((), dtype='ubyte') self.pad = PadAlign(self.context, self.ref, 4) self.floatsa = numpy.zeros((), dtype='float') self.pad_2 = SmartPadding(self.context, None, None) self.frame_count = 0 self.c_1 = 0 self.e = 0 self.zeros_19 = numpy.zeros((19), dtype='uint') self.count = 0 self.four_and_twenty = 0 self.ref_2 = Empty(self.context, None, None) self.zeros = numpy.zeros((self.c_1), dtype='ubyte') self.anoth_pad = SmartPadding(self.context, None, None) self.floatsb = numpy.zeros((6), dtype='float') self.unk = 0 if self.arg.e_2: self.unk_for_e_2 = 0 self.repeats = Array(self.context) def read(self, stream): self.io_start = stream.tell() self.ref = stream.read_type(Empty, (self.context, None, None)) if self.context.version == 18: self.indices_c_0 = stream.read_ushorts((self.arg.c_0)) if not (self.context.version == 18): self.indices_c_0 = stream.read_uints((self.arg.c_0)) if self.context.version == 18: self.indices_c_1 = stream.read_ushorts((self.arg.c_1)) if not (self.context.version == 18): self.indices_c_1 = stream.read_uints((self.arg.c_1)) if self.context.version == 18: self.indices_1 = stream.read_ushorts((self.arg.name_count)) if not (self.context.version == 18): self.indices_1 = stream.read_uints((self.arg.name_count)) if self.context.version == 18: self.indices_e_2 = stream.read_ushorts((self.arg.e_2)) if not (self.context.version == 18): self.indices_e_2 = stream.read_uints((self.arg.e_2)) self.p_indices_c_0 = stream.read_ubytes((self.arg.c_0)) if self.context.version == 18: self.p_indices_c_0 = stream.read_ubytes((self.arg.c_0)) self.p_indices_c_1 = stream.read_ubytes((self.arg.c_1)) if self.context.version == 18: self.p_indices_c_1 = stream.read_ubytes((self.arg.c_1)) self.p_indices_0_b = stream.read_ubytes( ((self.arg.p_indices_c_0_max - self.arg.p_indices_c_0_min) + 1)) self.p_indices_0_c = stream.read_ubytes( ((self.arg.p_indices_c_1_max - self.arg.p_indices_c_1_min) + 1)) self.pad = stream.read_type(PadAlign, (self.context, self.ref, 4)) self.floatsa = stream.read_floats((self.arg.frame_count, self.arg.e_2)) self.pad_2 = stream.read_type(SmartPadding, (self.context, None, None)) self.frame_count = stream.read_uint() self.c_1 = stream.read_uint() self.e = stream.read_uint() self.zeros_19 = stream.read_uints((19)) self.count = stream.read_ushort() self.four_and_twenty = stream.read_ushort() self.ref_2 = stream.read_type(Empty, (self.context, None, None)) self.zeros = stream.read_ubytes((self.c_1)) self.anoth_pad = stream.read_type(SmartPadding, (self.context, None, None)) self.floatsb = stream.read_floats((6)) self.unk = stream.read_uint() if self.arg.e_2: self.unk_for_e_2 = stream.read_uint64() self.repeats.read(stream, Repeat, self.count, None) self.io_size = stream.tell() - self.io_start def write(self, stream): self.io_start = stream.tell() stream.write_type(self.ref) if self.context.version == 18: stream.write_ushorts(self.indices_c_0) if not (self.context.version == 18): stream.write_uints(self.indices_c_0) if self.context.version == 18: stream.write_ushorts(self.indices_c_1) if not (self.context.version == 18): stream.write_uints(self.indices_c_1) if self.context.version == 18: stream.write_ushorts(self.indices_1) if not (self.context.version == 18): stream.write_uints(self.indices_1) if self.context.version == 18: stream.write_ushorts(self.indices_e_2) if not (self.context.version == 18): stream.write_uints(self.indices_e_2) stream.write_ubytes(self.p_indices_c_0) if self.context.version == 18: stream.write_ubytes(self.p_indices_c_0) stream.write_ubytes(self.p_indices_c_1) if self.context.version == 18: stream.write_ubytes(self.p_indices_c_1) stream.write_ubytes(self.p_indices_0_b) stream.write_ubytes(self.p_indices_0_c) stream.write_type(self.pad) stream.write_floats(self.floatsa) stream.write_type(self.pad_2) stream.write_uint(self.frame_count) stream.write_uint(self.c_1) stream.write_uint(self.e) stream.write_uints(self.zeros_19) stream.write_ushort(self.count) stream.write_ushort(self.four_and_twenty) stream.write_type(self.ref_2) stream.write_ubytes(self.zeros) stream.write_type(self.anoth_pad) stream.write_floats(self.floatsb) stream.write_uint(self.unk) if self.arg.e_2: stream.write_uint64(self.unk_for_e_2) self.repeats.write(stream, Repeat, self.count, None) self.io_size = stream.tell() - self.io_start def get_info_str(self): return f'ManiBlock [Size: {self.io_size}, Address: {self.io_start}] {self.name}' def get_fields_str(self): s = '' s += f'\n * ref = {self.ref.__repr__()}' s += f'\n * indices_c_0 = {self.indices_c_0.__repr__()}' s += f'\n * indices_c_1 = {self.indices_c_1.__repr__()}' s += f'\n * indices_1 = {self.indices_1.__repr__()}' s += f'\n * indices_e_2 = {self.indices_e_2.__repr__()}' s += f'\n * p_indices_c_0 = {self.p_indices_c_0.__repr__()}' s += f'\n * p_indices_c_1 = {self.p_indices_c_1.__repr__()}' s += f'\n * p_indices_0_b = {self.p_indices_0_b.__repr__()}' s += f'\n * p_indices_0_c = {self.p_indices_0_c.__repr__()}' s += f'\n * pad = {self.pad.__repr__()}' s += f'\n * floatsa = {self.floatsa.__repr__()}' s += f'\n * pad_2 = {self.pad_2.__repr__()}' s += f'\n * frame_count = {self.frame_count.__repr__()}' s += f'\n * c_1 = {self.c_1.__repr__()}' s += f'\n * e = {self.e.__repr__()}' s += f'\n * zeros_19 = {self.zeros_19.__repr__()}' s += f'\n * count = {self.count.__repr__()}' s += f'\n * four_and_twenty = {self.four_and_twenty.__repr__()}' s += f'\n * ref_2 = {self.ref_2.__repr__()}' s += f'\n * zeros = {self.zeros.__repr__()}' s += f'\n * anoth_pad = {self.anoth_pad.__repr__()}' s += f'\n * floatsb = {self.floatsb.__repr__()}' s += f'\n * unk = {self.unk.__repr__()}' s += f'\n * unk_for_e_2 = {self.unk_for_e_2.__repr__()}' s += f'\n * repeats = {self.repeats.__repr__()}' return s def __repr__(self): s = self.get_info_str() s += self.get_fields_str() s += '\n' return s
class MeshCollision: context = ContextReference() def __init__(self, context, arg=None, template=None): self.name = '' self._context = context self.arg = arg self.template = template self.io_size = 0 self.io_start = 0 self.rotation = Matrix33(self.context, None, None) # offset of mesh self.offset = Vector3(self.context, None, None) # not floats, maybe 6 ushorts, shared among (all?) redwoods self.unk_1 = numpy.zeros((3, 2), dtype='ushort') # vertices (3 float) self.vertex_count = 0 # tris?, counts the 25s at the end self.tri_count = 0 # the smallest coordinates across all axes self.bounds_min = Vector3(self.context, None, None) # the biggest coordinates across all axes self.bounds_max = Vector3(self.context, None, None) # seemingly fixed self.ones_or_zeros = numpy.zeros((7), dtype='uint64') # seemingly fixed self.ff_or_zero = numpy.zeros((10), dtype='int') # seemingly fixed self.ff_or_zero = numpy.zeros((8), dtype='int') # verbatim self.bounds_min_repeat = Vector3(self.context, None, None) # verbatim self.bounds_max_repeat = Vector3(self.context, None, None) # seems to repeat tri_count self.tri_flags_count = 0 # counts MeshCollisionBit self.count_bits = 0 # ? self.stuff = numpy.zeros((9), dtype='ushort') # ? self.collision_bits = Array(self.context) # always 25 self.zeros = numpy.zeros((4), dtype='uint') # array of vertices self.vertices = numpy.zeros((self.vertex_count, 3), dtype='float') # triangle indices into vertex list self.triangles = numpy.zeros((self.tri_count, 3), dtype='ushort') # ? self.const = 0 # always 25 self.triangle_flags = numpy.zeros((self.tri_flags_count), dtype='uint') # might be padding! self.zero_end = 0 self.set_defaults() def set_defaults(self): self.rotation = Matrix33(self.context, None, None) self.offset = Vector3(self.context, None, None) self.unk_1 = numpy.zeros((3, 2), dtype='ushort') self.vertex_count = 0 self.tri_count = 0 self.bounds_min = Vector3(self.context, None, None) self.bounds_max = Vector3(self.context, None, None) self.ones_or_zeros = numpy.zeros((7), dtype='uint64') if self.context.version <= 32: self.ff_or_zero = numpy.zeros((10), dtype='int') if self.context.version >= 47: self.ff_or_zero = numpy.zeros((8), dtype='int') if self.context.version <= 32: self.bounds_min_repeat = Vector3(self.context, None, None) if self.context.version <= 32: self.bounds_max_repeat = Vector3(self.context, None, None) if self.context.version <= 32: self.tri_flags_count = 0 if self.context.version <= 32: self.count_bits = 0 if self.context.version <= 32: self.stuff = numpy.zeros((9), dtype='ushort') if self.context.version <= 32: self.collision_bits = Array(self.context) if self.context.version <= 32: self.zeros = numpy.zeros((4), dtype='uint') self.vertices = numpy.zeros((self.vertex_count, 3), dtype='float') self.triangles = numpy.zeros((self.tri_count, 3), dtype='ushort') if self.context.version <= 32: self.const = 0 if self.context.version <= 32 and self.const: self.triangle_flags = numpy.zeros((self.tri_flags_count), dtype='uint') self.zero_end = 0 def read(self, stream): self.io_start = stream.tell() self.rotation = stream.read_type(Matrix33, (self.context, None, None)) self.offset = stream.read_type(Vector3, (self.context, None, None)) self.unk_1 = stream.read_ushorts((3, 2)) self.vertex_count = stream.read_uint64() self.tri_count = stream.read_uint64() self.bounds_min = stream.read_type(Vector3, (self.context, None, None)) self.bounds_max = stream.read_type(Vector3, (self.context, None, None)) self.ones_or_zeros = stream.read_uint64s((7)) if self.context.version <= 32: self.ff_or_zero = stream.read_ints((10)) if self.context.version >= 47: self.ff_or_zero = stream.read_ints((8)) if self.context.version <= 32: self.bounds_min_repeat = stream.read_type( Vector3, (self.context, None, None)) self.bounds_max_repeat = stream.read_type( Vector3, (self.context, None, None)) if self.context.version <= 32: self.tri_flags_count = stream.read_uint() self.count_bits = stream.read_ushort() if self.context.version <= 32: self.stuff = stream.read_ushorts((9)) self.collision_bits.read(stream, MeshCollisionBit, self.count_bits, None) if self.context.version <= 32: self.zeros = stream.read_uints((4)) self.vertices = stream.read_floats((self.vertex_count, 3)) self.triangles = stream.read_ushorts((self.tri_count, 3)) if self.context.version <= 32: self.const = stream.read_uint() if self.context.version <= 32 and self.const: self.triangle_flags = stream.read_uints((self.tri_flags_count)) self.zero_end = stream.read_uint() self.io_size = stream.tell() - self.io_start def write(self, stream): self.io_start = stream.tell() stream.write_type(self.rotation) stream.write_type(self.offset) stream.write_ushorts(self.unk_1) stream.write_uint64(self.vertex_count) stream.write_uint64(self.tri_count) stream.write_type(self.bounds_min) stream.write_type(self.bounds_max) stream.write_uint64s(self.ones_or_zeros) if self.context.version <= 32: stream.write_ints(self.ff_or_zero) if self.context.version >= 47: stream.write_ints(self.ff_or_zero) if self.context.version <= 32: stream.write_type(self.bounds_min_repeat) stream.write_type(self.bounds_max_repeat) if self.context.version <= 32: stream.write_uint(self.tri_flags_count) stream.write_ushort(self.count_bits) if self.context.version <= 32: stream.write_ushorts(self.stuff) self.collision_bits.write(stream, MeshCollisionBit, self.count_bits, None) if self.context.version <= 32: stream.write_uints(self.zeros) stream.write_floats(self.vertices) stream.write_ushorts(self.triangles) if self.context.version <= 32: stream.write_uint(self.const) if self.context.version <= 32 and self.const: stream.write_uints(self.triangle_flags) stream.write_uint(self.zero_end) self.io_size = stream.tell() - self.io_start def get_info_str(self): return f'MeshCollision [Size: {self.io_size}, Address: {self.io_start}] {self.name}' def get_fields_str(self): s = '' s += f'\n * rotation = {self.rotation.__repr__()}' s += f'\n * offset = {self.offset.__repr__()}' s += f'\n * unk_1 = {self.unk_1.__repr__()}' s += f'\n * vertex_count = {self.vertex_count.__repr__()}' s += f'\n * tri_count = {self.tri_count.__repr__()}' s += f'\n * bounds_min = {self.bounds_min.__repr__()}' s += f'\n * bounds_max = {self.bounds_max.__repr__()}' s += f'\n * ones_or_zeros = {self.ones_or_zeros.__repr__()}' s += f'\n * ff_or_zero = {self.ff_or_zero.__repr__()}' s += f'\n * bounds_min_repeat = {self.bounds_min_repeat.__repr__()}' s += f'\n * bounds_max_repeat = {self.bounds_max_repeat.__repr__()}' s += f'\n * tri_flags_count = {self.tri_flags_count.__repr__()}' s += f'\n * count_bits = {self.count_bits.__repr__()}' s += f'\n * stuff = {self.stuff.__repr__()}' s += f'\n * collision_bits = {self.collision_bits.__repr__()}' s += f'\n * zeros = {self.zeros.__repr__()}' s += f'\n * vertices = {self.vertices.__repr__()}' s += f'\n * triangles = {self.triangles.__repr__()}' s += f'\n * const = {self.const.__repr__()}' s += f'\n * triangle_flags = {self.triangle_flags.__repr__()}' s += f'\n * zero_end = {self.zero_end.__repr__()}' return s def __repr__(self): s = self.get_info_str() s += self.get_fields_str() s += '\n' return s
class CommonJointInfo: context = ContextReference() def __init__(self, context, arg=None, template=None): self.name = '' self._context = context self.arg = arg self.template = template self.io_size = 0 self.io_start = 0 # must be 11 self.eleven = 0 # bunch of -1's self.f_fs = numpy.zeros((3), dtype='int') self.name_offset = 0 self.hitcheck_count = 0 self.set_defaults() def set_defaults(self): self.eleven = 0 self.f_fs = numpy.zeros((3), dtype='int') self.name_offset = 0 self.hitcheck_count = 0 def read(self, stream): self.io_start = stream.tell() self.eleven = stream.read_uint() self.f_fs = stream.read_ints((3)) self.name_offset = stream.read_uint() self.hitcheck_count = stream.read_uint() self.io_size = stream.tell() - self.io_start def write(self, stream): self.io_start = stream.tell() stream.write_uint(self.eleven) stream.write_ints(self.f_fs) stream.write_uint(self.name_offset) stream.write_uint(self.hitcheck_count) self.io_size = stream.tell() - self.io_start def get_info_str(self): return f'CommonJointInfo [Size: {self.io_size}, Address: {self.io_start}] {self.name}' def get_fields_str(self): s = '' s += f'\n * eleven = {self.eleven.__repr__()}' s += f'\n * f_fs = {self.f_fs.__repr__()}' s += f'\n * name_offset = {self.name_offset.__repr__()}' s += f'\n * hitcheck_count = {self.hitcheck_count.__repr__()}' return s def __repr__(self): s = self.get_info_str() s += self.get_fields_str() s += '\n' return s
class ManiInfo: """ 288 bytes for JWE / PZ 312 bytes for PC """ context = ContextReference() def __init__(self, context, arg=None, template=None): self.name = '' self._context = context self.arg = arg self.template = template self.io_size = 0 self.io_start = 0 self.duration = 0 # likely self.frame_count = 0 self.b = 0 # rest self.zeros_0 = numpy.zeros((6), dtype='ushort') self.c_0 = 0 self.c_1 = 0 self.name_count = 0 # rest self.zeros_1 = numpy.zeros((3), dtype='ushort') self.e_2 = 0 # always FF FF self.minus_1_a = 0 self.e = 0 self.extra_pc = numpy.zeros((5), dtype='ushort') self.g = 0 # rest 228 bytes self.zeros_2 = numpy.zeros((57), dtype='uint') # rest 14 bytes self.extra_zeros_pc = numpy.zeros((7), dtype='ushort') self.p_indices_c_0_min = 0 self.p_indices_c_0_max = 0 self.p_indices_c_1_min = 0 self.p_indices_c_1_max = 0 # always FF self.minus_1_b = 0 # always 00 self.zero = 0 self.c_2 = 0 self.c_3 = 0 self.c_4 = 0 self.c_5 = 0 self.zeros_end = numpy.zeros((3), dtype='ushort') self.set_defaults() def set_defaults(self): self.duration = 0 self.frame_count = 0 self.b = 0 self.zeros_0 = numpy.zeros((6), dtype='ushort') self.c_0 = 0 self.c_1 = 0 self.name_count = 0 self.zeros_1 = numpy.zeros((3), dtype='ushort') self.e_2 = 0 self.minus_1_a = 0 self.e = 0 if self.context.version == 18: self.extra_pc = numpy.zeros((5), dtype='ushort') self.g = 0 self.zeros_2 = numpy.zeros((57), dtype='uint') if self.context.version == 18: self.extra_zeros_pc = numpy.zeros((7), dtype='ushort') self.p_indices_c_0_min = 0 self.p_indices_c_0_max = 0 self.p_indices_c_1_min = 0 self.p_indices_c_1_max = 0 self.minus_1_b = 0 self.zero = 0 self.c_2 = 0 self.c_3 = 0 self.c_4 = 0 self.c_5 = 0 self.zeros_end = numpy.zeros((3), dtype='ushort') def read(self, stream): self.io_start = stream.tell() self.duration = stream.read_float() self.frame_count = stream.read_uint() self.b = stream.read_uint() self.zeros_0 = stream.read_ushorts((6)) self.c_0 = stream.read_ushort() self.c_1 = stream.read_ushort() self.name_count = stream.read_ushort() self.zeros_1 = stream.read_ushorts((3)) self.e_2 = stream.read_ushort() self.minus_1_a = stream.read_short() self.e = stream.read_ushort() if self.context.version == 18: self.extra_pc = stream.read_ushorts((5)) self.g = stream.read_ushort() self.zeros_2 = stream.read_uints((57)) if self.context.version == 18: self.extra_zeros_pc = stream.read_ushorts((7)) self.p_indices_c_0_min = stream.read_ubyte() self.p_indices_c_0_max = stream.read_ubyte() self.p_indices_c_1_min = stream.read_ubyte() self.p_indices_c_1_max = stream.read_ubyte() self.minus_1_b = stream.read_byte() self.zero = stream.read_byte() self.c_2 = stream.read_ubyte() self.c_3 = stream.read_ubyte() self.c_4 = stream.read_ubyte() self.c_5 = stream.read_ubyte() self.zeros_end = stream.read_ushorts((3)) self.io_size = stream.tell() - self.io_start def write(self, stream): self.io_start = stream.tell() stream.write_float(self.duration) stream.write_uint(self.frame_count) stream.write_uint(self.b) stream.write_ushorts(self.zeros_0) stream.write_ushort(self.c_0) stream.write_ushort(self.c_1) stream.write_ushort(self.name_count) stream.write_ushorts(self.zeros_1) stream.write_ushort(self.e_2) stream.write_short(self.minus_1_a) stream.write_ushort(self.e) if self.context.version == 18: stream.write_ushorts(self.extra_pc) stream.write_ushort(self.g) stream.write_uints(self.zeros_2) if self.context.version == 18: stream.write_ushorts(self.extra_zeros_pc) stream.write_ubyte(self.p_indices_c_0_min) stream.write_ubyte(self.p_indices_c_0_max) stream.write_ubyte(self.p_indices_c_1_min) stream.write_ubyte(self.p_indices_c_1_max) stream.write_byte(self.minus_1_b) stream.write_byte(self.zero) stream.write_ubyte(self.c_2) stream.write_ubyte(self.c_3) stream.write_ubyte(self.c_4) stream.write_ubyte(self.c_5) stream.write_ushorts(self.zeros_end) self.io_size = stream.tell() - self.io_start def get_info_str(self): return f'ManiInfo [Size: {self.io_size}, Address: {self.io_start}] {self.name}' def get_fields_str(self): s = '' s += f'\n * duration = {self.duration.__repr__()}' s += f'\n * frame_count = {self.frame_count.__repr__()}' s += f'\n * b = {self.b.__repr__()}' s += f'\n * zeros_0 = {self.zeros_0.__repr__()}' s += f'\n * c_0 = {self.c_0.__repr__()}' s += f'\n * c_1 = {self.c_1.__repr__()}' s += f'\n * name_count = {self.name_count.__repr__()}' s += f'\n * zeros_1 = {self.zeros_1.__repr__()}' s += f'\n * e_2 = {self.e_2.__repr__()}' s += f'\n * minus_1_a = {self.minus_1_a.__repr__()}' s += f'\n * e = {self.e.__repr__()}' s += f'\n * extra_pc = {self.extra_pc.__repr__()}' s += f'\n * g = {self.g.__repr__()}' s += f'\n * zeros_2 = {self.zeros_2.__repr__()}' s += f'\n * extra_zeros_pc = {self.extra_zeros_pc.__repr__()}' s += f'\n * p_indices_c_0_min = {self.p_indices_c_0_min.__repr__()}' s += f'\n * p_indices_c_0_max = {self.p_indices_c_0_max.__repr__()}' s += f'\n * p_indices_c_1_min = {self.p_indices_c_1_min.__repr__()}' s += f'\n * p_indices_c_1_max = {self.p_indices_c_1_max.__repr__()}' s += f'\n * minus_1_b = {self.minus_1_b.__repr__()}' s += f'\n * zero = {self.zero.__repr__()}' s += f'\n * c_2 = {self.c_2.__repr__()}' s += f'\n * c_3 = {self.c_3.__repr__()}' s += f'\n * c_4 = {self.c_4.__repr__()}' s += f'\n * c_5 = {self.c_5.__repr__()}' s += f'\n * zeros_end = {self.zeros_end.__repr__()}' return s def __repr__(self): s = self.get_info_str() s += self.get_fields_str() s += '\n' return s
class BnkFileContainer: """ Buffer data of bnk files """ context = ContextReference() def __init__(self, context, arg=None, template=None): self.name = '' self._context = context self.arg = arg self.template = template self.io_size = 0 self.io_start = 0 # data size of aux file of type b self.size_b = 0 # 1, guess self.name_count = 0 # 2 for PZ, 6 for ZTUAC self.count_2 = 0 # variable self.stream_info_count = 0 # 0 self.zeros = numpy.zeros((7), dtype='uint') # 0 self.zeros_2 = numpy.zeros((2), dtype='uint') # data self.stream_infos = numpy.zeros((self.stream_info_count, 3), dtype='uint64') # data self.names = Array(self.context) # ext format subtypes self.extensions = Array(self.context) self.set_defaults() def set_defaults(self): self.size_b = 0 self.name_count = 0 self.count_2 = 0 self.stream_info_count = 0 self.zeros = numpy.zeros((7), dtype='uint') if (self.context.user_version.is_jwe and (self.context.version == 19)) or (self.context.user_version.is_jwe and (self.context.version == 20)): self.zeros_2 = numpy.zeros((2), dtype='uint') self.stream_infos = numpy.zeros((self.stream_info_count, 3), dtype='uint64') self.names = Array(self.context) self.extensions = Array(self.context) def read(self, stream): self.io_start = stream.tell() self.size_b = stream.read_uint64() self.name_count = stream.read_uint() self.count_2 = stream.read_uint() self.stream_info_count = stream.read_uint() self.zeros = stream.read_uints((7)) if (self.context.user_version.is_jwe and (self.context.version == 19)) or (self.context.user_version.is_jwe and (self.context.version == 20)): self.zeros_2 = stream.read_uints((2)) self.stream_infos = stream.read_uint64s((self.stream_info_count, 3)) self.names = stream.read_zstrings((self.name_count)) self.extensions = stream.read_zstrings((self.count_2)) self.io_size = stream.tell() - self.io_start def write(self, stream): self.io_start = stream.tell() stream.write_uint64(self.size_b) stream.write_uint(self.name_count) stream.write_uint(self.count_2) stream.write_uint(self.stream_info_count) stream.write_uints(self.zeros) if (self.context.user_version.is_jwe and (self.context.version == 19)) or (self.context.user_version.is_jwe and (self.context.version == 20)): stream.write_uints(self.zeros_2) stream.write_uint64s(self.stream_infos) stream.write_zstrings(self.names) stream.write_zstrings(self.extensions) self.io_size = stream.tell() - self.io_start def get_info_str(self): return f'BnkFileContainer [Size: {self.io_size}, Address: {self.io_start}] {self.name}' def get_fields_str(self): s = '' s += f'\n * size_b = {self.size_b.__repr__()}' s += f'\n * name_count = {self.name_count.__repr__()}' s += f'\n * count_2 = {self.count_2.__repr__()}' s += f'\n * stream_info_count = {self.stream_info_count.__repr__()}' s += f'\n * zeros = {self.zeros.__repr__()}' s += f'\n * zeros_2 = {self.zeros_2.__repr__()}' s += f'\n * stream_infos = {self.stream_infos.__repr__()}' s += f'\n * names = {self.names.__repr__()}' s += f'\n * extensions = {self.extensions.__repr__()}' return s def __repr__(self): s = self.get_info_str() s += self.get_fields_str() s += '\n' return s
class SizedStrData: context = ContextReference() def __init__(self, context, arg=None, template=None): self.name = '' self._context = context self.arg = arg self.template = template self.io_size = 0 self.io_start = 0 self.a = 0 self.hash_block_size = 0 self.zeros = numpy.zeros((2), dtype='int') self.c_1 = 0 self.zeros_end = numpy.zeros((9), dtype='ushort') self.set_defaults() def set_defaults(self): self.a = 0 self.hash_block_size = 0 self.zeros = numpy.zeros((2), dtype='int') self.c_1 = 0 if (not self.context.user_version.is_jwe) and (self.context.version == 20): self.zeros_end = numpy.zeros((9), dtype='ushort') def read(self, stream): self.io_start = stream.tell() self.a = stream.read_ushort() self.hash_block_size = stream.read_ushort() self.zeros = stream.read_ints((2)) self.c_1 = stream.read_ushort() if (not self.context.user_version.is_jwe) and (self.context.version == 20): self.zeros_end = stream.read_ushorts((9)) self.io_size = stream.tell() - self.io_start def write(self, stream): self.io_start = stream.tell() stream.write_ushort(self.a) stream.write_ushort(self.hash_block_size) stream.write_ints(self.zeros) stream.write_ushort(self.c_1) if (not self.context.user_version.is_jwe) and (self.context.version == 20): stream.write_ushorts(self.zeros_end) self.io_size = stream.tell() - self.io_start def get_info_str(self): return f'SizedStrData [Size: {self.io_size}, Address: {self.io_start}] {self.name}' def get_fields_str(self): s = '' s += f'\n * a = {self.a.__repr__()}' s += f'\n * hash_block_size = {self.hash_block_size.__repr__()}' s += f'\n * zeros = {self.zeros.__repr__()}' s += f'\n * c_1 = {self.c_1.__repr__()}' s += f'\n * zeros_end = {self.zeros_end.__repr__()}' return s def __repr__(self): s = self.get_info_str() s += self.get_fields_str() s += '\n' return s
class TexHeader: """ DLA: 24 bytes, no pointers ZTUAC, PC: 24 bytes, with 1 pointer JWE, PZ, JWE2: 40 bytes, with 2 pointers """ context = ContextReference() def __init__(self, context, arg=None, template=None): self.name = '' self._context = context self.arg = arg self.template = template self.io_size = 0 self.io_start = 0 self.zero_0 = 0 self.zero_0 = 0 self.zero_1 = 0 # 8 bytes, all 0 self.ptr_0 = 0 # 8 bytes, all 0 self.ptr_1 = 0 self.compression_type = DdsType() self.compression_type = DdsTypeCoaster() # 0 or 1 self.one_0 = 0 self.num_mips = 0 self.width = 0 self.height = 0 # amount of files combined in this texture, usually 1 or 2, 3 for JWE2 rex self.stream_count = 0 # usually as above self.stream_count_repeat = 0 # 0 self.pad = 0 self.pad_dla = 0 self.set_defaults() def set_defaults(self): if self.context.version <= 15: self.zero_0 = 0 if self.context.version >= 17: self.zero_0 = 0 if self.context.version >= 19: self.zero_1 = 0 if self.context.version >= 17: self.ptr_0 = 0 if self.context.version >= 19: self.ptr_1 = 0 if not (self.context.version < 19): self.compression_type = DdsType() if self.context.version < 19: self.compression_type = DdsTypeCoaster() self.one_0 = 0 if self.context.version <= 15: self.num_mips = 0 if self.context.version <= 15: self.width = 0 if self.context.version <= 15: self.height = 0 if self.context.version >= 17: self.stream_count = 0 if self.context.version >= 17: self.stream_count_repeat = 0 self.pad = 0 if self.context.version <= 15: self.pad_dla = 0 def read(self, stream): self.io_start = stream.tell() if self.context.version <= 15: self.zero_0 = stream.read_uint() if self.context.version >= 17: self.zero_0 = stream.read_uint64() if self.context.version >= 19: self.zero_1 = stream.read_uint64() if self.context.version >= 17: self.ptr_0 = stream.read_uint64() if self.context.version >= 19: self.ptr_1 = stream.read_uint64() if not (self.context.version < 19): self.compression_type = DdsType(stream.read_ubyte()) if self.context.version < 19: self.compression_type = DdsTypeCoaster(stream.read_ubyte()) self.one_0 = stream.read_ubyte() if self.context.version <= 15: self.num_mips = stream.read_ushort() self.width = stream.read_ushort() if self.context.version <= 15: self.height = stream.read_ushort() if self.context.version >= 17: self.stream_count = stream.read_ubyte() self.stream_count_repeat = stream.read_ubyte() self.pad = stream.read_uint() if self.context.version <= 15: self.pad_dla = stream.read_uint64() self.io_size = stream.tell() - self.io_start def write(self, stream): self.io_start = stream.tell() if self.context.version <= 15: stream.write_uint(self.zero_0) if self.context.version >= 17: stream.write_uint64(self.zero_0) if self.context.version >= 19: stream.write_uint64(self.zero_1) if self.context.version >= 17: stream.write_uint64(self.ptr_0) if self.context.version >= 19: stream.write_uint64(self.ptr_1) if not (self.context.version < 19): stream.write_ubyte(self.compression_type.value) if self.context.version < 19: stream.write_ubyte(self.compression_type.value) stream.write_ubyte(self.one_0) if self.context.version <= 15: stream.write_ushort(self.num_mips) stream.write_ushort(self.width) if self.context.version <= 15: stream.write_ushort(self.height) if self.context.version >= 17: stream.write_ubyte(self.stream_count) stream.write_ubyte(self.stream_count_repeat) stream.write_uint(self.pad) if self.context.version <= 15: stream.write_uint64(self.pad_dla) self.io_size = stream.tell() - self.io_start def get_info_str(self): return f'TexHeader [Size: {self.io_size}, Address: {self.io_start}] {self.name}' def get_fields_str(self): s = '' s += f'\n * zero_0 = {self.zero_0.__repr__()}' s += f'\n * zero_1 = {self.zero_1.__repr__()}' s += f'\n * ptr_0 = {self.ptr_0.__repr__()}' s += f'\n * ptr_1 = {self.ptr_1.__repr__()}' s += f'\n * compression_type = {self.compression_type.__repr__()}' s += f'\n * one_0 = {self.one_0.__repr__()}' s += f'\n * num_mips = {self.num_mips.__repr__()}' s += f'\n * width = {self.width.__repr__()}' s += f'\n * height = {self.height.__repr__()}' s += f'\n * stream_count = {self.stream_count.__repr__()}' s += f'\n * stream_count_repeat = {self.stream_count_repeat.__repr__()}' s += f'\n * pad = {self.pad.__repr__()}' s += f'\n * pad_dla = {self.pad_dla.__repr__()}' return s def __repr__(self): s = self.get_info_str() s += self.get_fields_str() s += '\n' return s
class ModelInfo: """ Linked to by the ms2, part of an array 120 bytes for JWE2 """ context = ContextReference() def __init__(self, context, arg=None, template=None): self.name = '' self._context = context self.arg = arg self.template = template self.io_size = 0 self.io_start = 0 # the smallest coordinates across all axes self.bounds_min = Vector3(self.context, None, None) # not sure, for PZ often 40 00 00 37 for animals self.unk_float_a = 0 # the biggest coordinates across all axes self.bounds_max = Vector3(self.context, None, None) # scale: pack_offset / 512, also added as offset self.pack_offset = 0 # cog? medium of bounds? self.center = Vector3(self.context, None, None) # probably from center to max self.radius = 0 # seen 6 or 1, matches lod count self.num_lods_2 = 0 # zero self.zero = 0 # verbatim repeat self.bounds_min_repeat = Vector3(self.context, None, None) # verbatim repeat self.bounds_max_repeat = Vector3(self.context, None, None) self.num_materials = 0 self.num_lods = 0 self.num_objects = 0 # count of MeshData fragments for the mdl2 this struct refers to self.num_meshes = 0 # ? self.last_count = 0 # this has influence on whether newly added shells draw correctly; for PZ usually 4, except for furry animals; ZT african ele female self.render_flag = RenderFlag() # ? self.unks = numpy.zeros((7), dtype='ushort') self.pad = numpy.zeros((3), dtype='ushort') self.materials_ptr = 0 self.lods_ptr = 0 self.objects_ptr = 0 self.models_ptr = 0 self.first_materials_ptr = 0 self.zeros_ztuac = numpy.zeros((4), dtype='uint64') # unknown, probably used to increment skeleton self.increment_flag = 0 self.zero_0 = 0 self.zero_1 = 0 self.zero_2 = 0 self.set_defaults() def set_defaults(self): self.bounds_min = Vector3(self.context, None, None) if self.context.version >= 47: self.unk_float_a = 0 self.bounds_max = Vector3(self.context, None, None) if self.context.version >= 47: self.pack_offset = 0 self.center = Vector3(self.context, None, None) self.radius = 0 if self.context.version >= 48: self.num_lods_2 = 0 if self.context.version >= 48: self.zero = 0 if self.context.version >= 32: self.bounds_min_repeat = Vector3(self.context, None, None) if self.context.version >= 32: self.bounds_max_repeat = Vector3(self.context, None, None) self.num_materials = 0 self.num_lods = 0 self.num_objects = 0 self.num_meshes = 0 self.last_count = 0 self.render_flag = RenderFlag() self.unks = numpy.zeros((7), dtype='ushort') self.pad = numpy.zeros((3), dtype='ushort') self.materials_ptr = 0 self.lods_ptr = 0 self.objects_ptr = 0 self.models_ptr = 0 self.first_materials_ptr = 0 if self.context.version == 13: self.zeros_ztuac = numpy.zeros((4), dtype='uint64') self.increment_flag = 0 self.zero_0 = 0 if not (self.context.version == 32): self.zero_1 = 0 if self.context.version >= 47: self.zero_2 = 0 def read(self, stream): self.io_start = stream.tell() self.bounds_min = stream.read_type(Vector3, (self.context, None, None)) if self.context.version >= 47: self.unk_float_a = stream.read_float() self.bounds_max = stream.read_type(Vector3, (self.context, None, None)) if self.context.version >= 47: self.pack_offset = stream.read_float() self.center = stream.read_type(Vector3, (self.context, None, None)) self.radius = stream.read_float() if self.context.version >= 48: self.num_lods_2 = stream.read_uint64() self.zero = stream.read_uint64() if self.context.version >= 32: self.bounds_min_repeat = stream.read_type( Vector3, (self.context, None, None)) self.bounds_max_repeat = stream.read_type( Vector3, (self.context, None, None)) self.num_materials = stream.read_ushort() self.num_lods = stream.read_ushort() self.num_objects = stream.read_ushort() self.num_meshes = stream.read_ushort() self.last_count = stream.read_ushort() self.render_flag = stream.read_type(RenderFlag) self.unks = stream.read_ushorts((7)) self.pad = stream.read_ushorts((3)) self.materials_ptr = stream.read_uint64() self.lods_ptr = stream.read_uint64() self.objects_ptr = stream.read_uint64() self.models_ptr = stream.read_uint64() self.first_materials_ptr = stream.read_uint64() if self.context.version == 13: self.zeros_ztuac = stream.read_uint64s((4)) self.increment_flag = stream.read_uint64() self.zero_0 = stream.read_uint64() if not (self.context.version == 32): self.zero_1 = stream.read_uint64() if self.context.version >= 47: self.zero_2 = stream.read_uint64() self.io_size = stream.tell() - self.io_start def write(self, stream): self.io_start = stream.tell() stream.write_type(self.bounds_min) if self.context.version >= 47: stream.write_float(self.unk_float_a) stream.write_type(self.bounds_max) if self.context.version >= 47: stream.write_float(self.pack_offset) stream.write_type(self.center) stream.write_float(self.radius) if self.context.version >= 48: stream.write_uint64(self.num_lods_2) stream.write_uint64(self.zero) if self.context.version >= 32: stream.write_type(self.bounds_min_repeat) stream.write_type(self.bounds_max_repeat) stream.write_ushort(self.num_materials) stream.write_ushort(self.num_lods) stream.write_ushort(self.num_objects) stream.write_ushort(self.num_meshes) stream.write_ushort(self.last_count) stream.write_type(self.render_flag) stream.write_ushorts(self.unks) stream.write_ushorts(self.pad) stream.write_uint64(self.materials_ptr) stream.write_uint64(self.lods_ptr) stream.write_uint64(self.objects_ptr) stream.write_uint64(self.models_ptr) stream.write_uint64(self.first_materials_ptr) if self.context.version == 13: stream.write_uint64s(self.zeros_ztuac) stream.write_uint64(self.increment_flag) stream.write_uint64(self.zero_0) if not (self.context.version == 32): stream.write_uint64(self.zero_1) if self.context.version >= 47: stream.write_uint64(self.zero_2) self.io_size = stream.tell() - self.io_start def get_info_str(self): return f'ModelInfo [Size: {self.io_size}, Address: {self.io_start}] {self.name}' def get_fields_str(self): s = '' s += f'\n * bounds_min = {self.bounds_min.__repr__()}' s += f'\n * unk_float_a = {self.unk_float_a.__repr__()}' s += f'\n * bounds_max = {self.bounds_max.__repr__()}' s += f'\n * pack_offset = {self.pack_offset.__repr__()}' s += f'\n * center = {self.center.__repr__()}' s += f'\n * radius = {self.radius.__repr__()}' s += f'\n * num_lods_2 = {self.num_lods_2.__repr__()}' s += f'\n * zero = {self.zero.__repr__()}' s += f'\n * bounds_min_repeat = {self.bounds_min_repeat.__repr__()}' s += f'\n * bounds_max_repeat = {self.bounds_max_repeat.__repr__()}' s += f'\n * num_materials = {self.num_materials.__repr__()}' s += f'\n * num_lods = {self.num_lods.__repr__()}' s += f'\n * num_objects = {self.num_objects.__repr__()}' s += f'\n * num_meshes = {self.num_meshes.__repr__()}' s += f'\n * last_count = {self.last_count.__repr__()}' s += f'\n * render_flag = {self.render_flag.__repr__()}' s += f'\n * unks = {self.unks.__repr__()}' s += f'\n * pad = {self.pad.__repr__()}' s += f'\n * materials_ptr = {self.materials_ptr.__repr__()}' s += f'\n * lods_ptr = {self.lods_ptr.__repr__()}' s += f'\n * objects_ptr = {self.objects_ptr.__repr__()}' s += f'\n * models_ptr = {self.models_ptr.__repr__()}' s += f'\n * first_materials_ptr = {self.first_materials_ptr.__repr__()}' s += f'\n * zeros_ztuac = {self.zeros_ztuac.__repr__()}' s += f'\n * increment_flag = {self.increment_flag.__repr__()}' s += f'\n * zero_0 = {self.zero_0.__repr__()}' s += f'\n * zero_1 = {self.zero_1.__repr__()}' s += f'\n * zero_2 = {self.zero_2.__repr__()}' return s def __repr__(self): s = self.get_info_str() s += self.get_fields_str() s += '\n' return s
class Size: context = ContextReference() def __init__(self, context, arg=None, template=None): self.name = '' self._context = context self.arg = arg self.template = template self.io_size = 0 self.io_start = 0 # index into name list self.id = 0 self.width_1 = 0 self.height_1 = 0 self.width_2 = 0 self.height_2 = 0 self.set_defaults() def set_defaults(self): self.id = 0 self.width_1 = 0 self.height_1 = 0 self.width_2 = 0 self.height_2 = 0 def read(self, stream): self.io_start = stream.tell() self.id = stream.read_uint64() self.width_1 = stream.read_uint64() self.height_1 = stream.read_uint64() self.width_2 = stream.read_uint64() self.height_2 = stream.read_uint64() self.io_size = stream.tell() - self.io_start def write(self, stream): self.io_start = stream.tell() stream.write_uint64(self.id) stream.write_uint64(self.width_1) stream.write_uint64(self.height_1) stream.write_uint64(self.width_2) stream.write_uint64(self.height_2) self.io_size = stream.tell() - self.io_start def get_info_str(self): return f'Size [Size: {self.io_size}, Address: {self.io_start}] {self.name}' def get_fields_str(self): s = '' s += f'\n * id = {self.id.__repr__()}' s += f'\n * width_1 = {self.width_1.__repr__()}' s += f'\n * height_1 = {self.height_1.__repr__()}' s += f'\n * width_2 = {self.width_2.__repr__()}' s += f'\n * height_2 = {self.height_2.__repr__()}' return s def __repr__(self): s = self.get_info_str() s += self.get_fields_str() s += '\n' return s
class MotiongraphRootFrag: context = ContextReference() def __init__(self, context, arg=None, template=None): self.name = '' self._context = context self.arg = arg self.template = template self.io_size = 0 self.io_start = 0 self.count_0 = 0 self.ptr_0 = Pointer(self.context, None, None) self.count_1 = 0 self.ptr_1 = Pointer(self.context, None, None) self.count_2 = 0 self.ptr_2 = Pointer(self.context, None, None) self.num_xmls = 0 self.ptr_xmls = Pointer(self.context, None, None) self.set_defaults() def set_defaults(self): self.count_0 = 0 self.ptr_0 = Pointer(self.context, None, None) self.count_1 = 0 self.ptr_1 = Pointer(self.context, None, None) self.count_2 = 0 self.ptr_2 = Pointer(self.context, None, None) self.num_xmls = 0 self.ptr_xmls = Pointer(self.context, None, None) def read(self, stream): self.io_start = stream.tell() self.count_0 = stream.read_uint64() self.ptr_0 = stream.read_type(Pointer, (self.context, None, None)) self.count_1 = stream.read_uint64() self.ptr_1 = stream.read_type(Pointer, (self.context, None, None)) self.count_2 = stream.read_uint64() self.ptr_2 = stream.read_type(Pointer, (self.context, None, None)) self.num_xmls = stream.read_uint64() self.ptr_xmls = stream.read_type(Pointer, (self.context, None, None)) self.io_size = stream.tell() - self.io_start def write(self, stream): self.io_start = stream.tell() stream.write_uint64(self.count_0) stream.write_type(self.ptr_0) stream.write_uint64(self.count_1) stream.write_type(self.ptr_1) stream.write_uint64(self.count_2) stream.write_type(self.ptr_2) stream.write_uint64(self.num_xmls) stream.write_type(self.ptr_xmls) self.io_size = stream.tell() - self.io_start def get_info_str(self): return f'MotiongraphRootFrag [Size: {self.io_size}, Address: {self.io_start}] {self.name}' def get_fields_str(self): s = '' s += f'\n * count_0 = {self.count_0.__repr__()}' s += f'\n * ptr_0 = {self.ptr_0.__repr__()}' s += f'\n * count_1 = {self.count_1.__repr__()}' s += f'\n * ptr_1 = {self.ptr_1.__repr__()}' s += f'\n * count_2 = {self.count_2.__repr__()}' s += f'\n * ptr_2 = {self.ptr_2.__repr__()}' s += f'\n * num_xmls = {self.num_xmls.__repr__()}' s += f'\n * ptr_xmls = {self.ptr_xmls.__repr__()}' return s def __repr__(self): s = self.get_info_str() s += self.get_fields_str() s += '\n' return s
class Triplet: """ 3 bytes - constant per mime (and probably version) """ context = ContextReference() def __init__(self, context, arg=None, template=None): self.name = '' self._context = context self.arg = arg self.template = template self.io_size = 0 self.io_start = 0 # ? self.a = 0 # ? self.b = 0 # ? self.c = 0 self.set_defaults() def set_defaults(self): self.a = 0 self.b = 0 self.c = 0 def read(self, stream): self.io_start = stream.tell() self.a = stream.read_ubyte() self.b = stream.read_ubyte() self.c = stream.read_ubyte() self.io_size = stream.tell() - self.io_start def write(self, stream): self.io_start = stream.tell() stream.write_ubyte(self.a) stream.write_ubyte(self.b) stream.write_ubyte(self.c) self.io_size = stream.tell() - self.io_start def get_info_str(self): return f'Triplet [Size: {self.io_size}, Address: {self.io_start}] {self.name}' def get_fields_str(self): s = '' s += f'\n * a = {self.a.__repr__()}' s += f'\n * b = {self.b.__repr__()}' s += f'\n * c = {self.c.__repr__()}' return s def __repr__(self): s = self.get_info_str() s += self.get_fields_str() s += '\n' return s def __eq__(self, other): if isinstance(other, Triplet): return self.a == other.a and self.b == other.b and self.c == other.c