def write_rcol(self, stream, rcol): self.write_tag(stream) s = StreamWriter(stream) s.u32(self.version) s.u32(self.flags) s.u32(self.unknown) last = 0 for i in range(len(self.buffer)): cur = self.buffer[i] if Flag.is_set(self.flags, self.FLAGS.DIFFERENCED_INDICES): cur -= last last = self.buffer[i] s.i32(cur) if Flag.is_set(self.flags, self.FLAGS.INDEX_32) else s.i16(cur)
def read_rcol(self, stream, rcol): self.read_tag(stream) s = StreamReader(stream) self.version = s.u32() self.flags = s.u32() self.unknown = s.u32() start = stream.tell() stream.seek(0, SEEK_END) end = stream.tell() stream.seek(start, SEEK_SET) self.buffer = [] last = 0 while stream.tell() < end: cur = s.i32() if Flag.is_set(self.flags, self.FLAGS.INDEX_32) else s.i16() if Flag.is_set(self.flags, self.FLAGS.DIFFERENCED_INDICES): cur += last last = cur self.buffer.append(cur)
def s7(self, size=8, order='<'): b = self.u8() if not b: return '' length = b & 0x7F while Flag.is_set(b, 0x80): length += 128 b = self.u8() length += b & 0x7F if size == 16: length /= 2 return self.chars(int(length), size, order)
def load(self): if not self.stream: return s = StreamReader(self.stream) self.entries = [] self.header.read(self.stream) self.stream.seek(self.header.index_offset, SEEK_SET) self.index_flags = s.u32() if Flag.is_set(self.index_flags, self.INDEX_FLAG.TYPE): self.static_key.t = s.u32() if Flag.is_set(self.index_flags, self.INDEX_FLAG.GROUP): self.static_key.g = s.u32() if Flag.is_set(self.index_flags, self.INDEX_FLAG.INSTANCE_HI): self.static_key.i = s.u32() << 32 if Flag.is_set(self.index_flags, self.INDEX_FLAG.INSTANCE_LO): self.static_key.i |= s.u32() for i in range(self.header.index_entry_count): index = self.IndexEntry(self) index.key = ResourceKey() if Flag.is_set(self.index_flags, self.INDEX_FLAG.TYPE): index.key.t = self.static_key.t else: index.key.t = s.u32() if Flag.is_set(self.index_flags, self.INDEX_FLAG.GROUP): index.key.g = self.static_key.g else: index.key.g = s.u32() if Flag.is_set(self.index_flags, self.INDEX_FLAG.INSTANCE_HI): instance_hi = self.static_key.i >> 32 else: instance_hi = s.u32() if Flag.is_set(self.index_flags, self.INDEX_FLAG.INSTANCE_LO): instance_lo = self.static_key.i & 0xFFFFFFFF else: instance_lo = s.u32() index.key.i = (instance_hi << 32) + instance_lo index.offset = s.u32() index.file_size = s.u32() & 0x0FFFFFFF index.mem_size = s.u32() flag = s.u16() index.compressed = flag == 0xFFFF index.unknown = s.u16() self.entries.append(index) nmap = self.name_map for entry in self.entries: entry.name = nmap[entry.key.i] print("Done.")
def load(self): if not self.stream: return s = StreamReader(self.stream) self.entries = [] self.header.read(self.stream) self.stream.seek(self.header.index_offset, SEEK_SET) self.index_flags = s.u32() if Flag.is_set(self.index_flags, self.INDEX_FLAG.TYPE): self.static_key.t = s.u32() if Flag.is_set(self.index_flags, self.INDEX_FLAG.GROUP): self.static_key.g = s.u32() if Flag.is_set(self.index_flags, self.INDEX_FLAG.INSTANCE_HI): self.static_key.i = s.u32() <<32 if Flag.is_set(self.index_flags, self.INDEX_FLAG.INSTANCE_LO): self.static_key.i |= s.u32() for i in range(self.header.index_entry_count): index = self.IndexEntry(self) index.key = ResourceKey() if Flag.is_set(self.index_flags, self.INDEX_FLAG.TYPE): index.key.t = self.static_key.t else: index.key.t = s.u32() if Flag.is_set(self.index_flags, self.INDEX_FLAG.GROUP): index.key.g = self.static_key.g else: index.key.g = s.u32() if Flag.is_set(self.index_flags, self.INDEX_FLAG.INSTANCE_HI): instance_hi = self.static_key.i >> 32 else: instance_hi = s.u32() if Flag.is_set(self.index_flags, self.INDEX_FLAG.INSTANCE_LO): instance_lo = self.static_key.i & 0xFFFFFFFF else: instance_lo = s.u32() index.key.i = (instance_hi << 32) + instance_lo index.offset = s.u32() index.file_size = s.u32() & 0x0FFFFFFF index.mem_size = s.u32() flag = s.u16() index.compressed = flag == 0xFFFF index.unknown = s.u16() self.entries.append(index) nmap = self.name_map for entry in self.entries: entry.name =nmap[entry.key.i] print("Done.")
def get_rig(self): age_char = '' if Flag.is_set(self.age_gender_flags, Age.ADULT): age_char = 'a' elif Flag.is_set(self.age_gender_flags, Age.BABY): age_char = 'b' elif Flag.is_set(self.age_gender_flags, Age.CHILD): age_char = 'c' elif Flag.is_set(self.age_gender_flags, Age.ELDER): age_char = 'e' elif Flag.is_set(self.age_gender_flags, Age.TEEN): age_char = 't' elif Flag.is_set(self.age_gender_flags, Age.TODDLER): age_char = 'p' elif Flag.is_set(self.age_gender_flags, Age.YOUNG_ADULT): age_char = 'a' else: raise Exception('Unable to determine age') species_id = (self.age_gender_flags & 0x00000F00) print(hex(species_id)) species_char = 'u' if species_id == Species.HUMAN: species_char = 'u' elif species_id == Species.CAT: species_char = 'c' elif species_id == Species.DOG: species_char = 'd' elif species_id == Species.HORSE: species_char = 'h' elif species_id == Species.RACCOON: species_char = 'r' elif species_id == Species.DEER: species_char = 'h' elif species_id == Species.LITTLE_DOG: species_char = 'd' rig_name = "%s%sRig" % (age_char, species_char) return rig_name
def get_vertex_format(self): return self.vertex_format if self.vertex_format != None else VertexFormat.default_sunshadow() if Flag.is_set(self.flags,self.Flags.SHADOW_CASTER) else VertexFormat.default_drop_shadow()
def get_has_position(self): return Flag.is_set(self.value, self.FLAG_HAS_POSITION)
def get_has_normal(self): return Flag.is_set(self.value, self.FLAG_HAS_NORMAL)
def default_mesh(mesh): return VertexFormat.default_sunshadow() if Flag.is_set(mesh.flags, ObjectMesh.Flags.SHADOW_CASTER) else VertexFormat.default_drop_shadow()
def set_has_normal(self, value): self.value = Flag.set( self.value, self.FLAG_HAS_NORMAL) if value else Flag.unset( self.value, self.FLAG_HAS_NORMAL)
def set_has_position(self, value): self.value = Flag.set(self.value, self.FLAG_HAS_POSITION) if value else Flag.unset(self.value, self.FLAG_HAS_POSITION)
def save(self,out_file=None): """ """ #temporary file to flush data to tmp_filename = tempfile.mktemp() tmp_stream = io.open(tmp_filename,'wb') s = StreamWriter(tmp_stream) self.header.index_entry_count = len(self.entries) #current package stream pkg_stream = None if self.stream: pkg_stream = self.stream elif exists(self.filename): pkg_stream = io.open(self.filename,'rb') #skip over header #this will be written at the end tmp_stream.seek(self.Header.SIZE, SEEK_SET) # Write data, update header and index self.index_flags = 0 self.static_key = ResourceKey() if any(self.entries): self.index_flags = self.INDEX_FLAG.TYPE | self.INDEX_FLAG.GROUP static_key = None for index in self.entries: if index.delete_pending: self.entries.remove(index) continue data = None if index.key in self.__loaded_resources: # index.compressed = False wrapper = self.__loaded_resources[index.key] with BytesIO() as wrapper_stream: wrapper.write(wrapper_stream) wrapper_stream.seek(0,SEEK_SET) data = wrapper_stream.read(-1) #memsize is uncompressed index.mem_size = len(data) elif isinstance(pkg_stream, io.FileIO): pkg_stream.seek(index.offset) data = pkg_stream.read(index.mem_size) else: continue if index.compressed: data = Package.Compression.compress(data) #filesize could change if the index was compressed index.file_size = len(data) if static_key is None: static_key = index.key.clone() if not index.key.t == static_key.t: static_key.t = 0 self.index_flags = Flag.unset(self.index_flags, self.INDEX_FLAG.TYPE) if not index.key.g == static_key.g: static_key.g = 0 self.index_flags = Flag.unset(self.index_flags, self.INDEX_FLAG.GROUP) #record offset of this entry index.offset = tmp_stream.tell() #write data tmp_stream.write(bytearray(data)) if self.index_flags: self.static_key = static_key # record offset for index table self.header.index_offset = tmp_stream.tell() # write index table s.u32(0) if Flag.is_set(self.index_flags, self.INDEX_FLAG.TYPE): s.u32(self.static_key.t) if Flag.is_set(self.index_flags, self.INDEX_FLAG.GROUP): s.u32(self.static_key.g) for index in self.entries: if not Flag.is_set(self.index_flags, self.INDEX_FLAG.TYPE): s.u32(index.key.t) if not Flag.is_set(self.index_flags, self.INDEX_FLAG.GROUP): s.u32(index.key.g) s.u32(index.key.t) s.u32(index.key.g) instance_hi = index.key.i >> 32 instance_lo = index.key.i & 0xFFFFFFFF s.u32(instance_hi) s.u32(instance_lo) s.u32(index.offset) s.u32(index.file_size | 0x80000000) s.u32(index.mem_size) s.u16(0 if not index.compressed else 0xFFFF) s.u16(index.unknown) end = tmp_stream.tell() self.header.index_size = end - self.header.index_offset # Go back and write header tmp_stream.seek(0, SEEK_SET) self.header.write(tmp_stream) if pkg_stream: pkg_stream.close() if not out_file: out_file = self.filename tmp_stream.close() shutil.move(tmp_filename,self.filename)
def get_vertex_format(self): return self.vertex_format if self.vertex_format != None else VertexFormat.default_sunshadow( ) if Flag.is_set(self.flags, self.Flags.SHADOW_CASTER ) else VertexFormat.default_drop_shadow()
def default_mesh(mesh): return VertexFormat.default_sunshadow() if Flag.is_set( mesh.flags, ObjectMesh.Flags.SHADOW_CASTER ) else VertexFormat.default_drop_shadow()
def set_has_position(self, value): self.value = Flag.set( self.value, self.FLAG_HAS_POSITION) if value else Flag.unset( self.value, self.FLAG_HAS_POSITION)
def set_has_normal(self, value): self.value = Flag.set(self.value, self.FLAG_HAS_NORMAL) if value else Flag.unset(self.value, self.FLAG_HAS_NORMAL)