def save_as(self, e=None, initial_dir=None): handler = self.active_image_handler if handler is None: return None fp = asksaveasfilename(initialdir=initial_dir, defaultextension='.dds', title="Save bitmap as...", parent=self, filetypes=(("DirectDraw surface", "*.dds"), ('Portable network graphics', '*.png'), ('Truevision graphics adapter', '*.tga'), ('Raw pixel data', '*.bin'))) fp, ext = os.path.splitext(fp) if not fp: return elif not ext: ext = ".dds" mip_levels = "all" if ext.lower() == ".dds" else self.mipmap_index.get( ) handler.arby.save_to_file(output_path=fp, ext=ext, overwrite=True, mip_levels=mip_levels, bitmap_indexes="all", keep_alpha=handler.channels.get("A"), swizzle_mode=False, channel_mapping=handler.channel_mapping, target_big_endian=False, tile_mode=False)
def model_animations_path_browse(self, force=False): if not force and (self._compiling or self._loading or self._saving): return antr_dir = os.path.dirname(self.model_animations_path.get()) if self.tags_dir.get() and not antr_dir: antr_dir = self.tags_dir.get() fp = asksaveasfilename(initialdir=antr_dir, title="Save model_animations to...", parent=self, filetypes=(("Model animations graph", "*.model_animations"), ('All', '*'))) if not fp: return fp = Path(fp).with_suffix(".model_animations") self.app_root.last_load_dir = str(fp.parent) self.model_animations_path.set(str(fp)) self.tags_dir.set( path_split(self.app_root.last_load_dir, "tags", after=True))
def browse_shader_path(self): if self._compiling or self._loading or self._saving: return tags_dir = self.tags_dir.get() if not tags_dir or not os.path.exists(tags_dir): return shader_dir = os.path.dirname( os.path.join(tags_dir, self.shader_path_string_var.get())) shader_exts = tuple((typ, "*.shader_%s" % typ) for typ in shader_types) fp = asksaveasfilename( initialdir=shader_dir, parent=self, title="Select the shader to use(or where to make one)", filetypes=shader_exts + (('All', '*'), )) fp, ext = os.path.splitext(fp) if fp: if not is_in_dir(fp, tags_dir): print("Specified shader is not located in the tags directory.") return ext = ext.strip(".").lower() self.shader_path_string_var.set(os.path.relpath(fp, tags_dir)) mat = self.get_material(self.shader_names_menu.sel_index) if mat and ext in shader_type_map: self.shader_types_menu.sel_index = shader_type_map[ext] mat.shader_type = ext
def tags_list_browse(self): try: init_dir = os.path.dirname(self.tagslist_path.get()) except Exception: init_dir = None dirpath = asksaveasfilename( initialdir=init_dir, parent=self, title="Select where to save the tag list log", filetypes=(("text log", "*.txt"), ("All", "*"))) if not dirpath: return self.tagslist_path.set(str(Path(dirpath)))
def log_browse(self): if self._scanning: return filepath = asksaveasfilename( initialdir=os.path.dirname(self.logfile_entry.get()), title="Save scan log to...", parent=self, filetypes=(("tag scanner log", "*.log"), ('All', '*'))) if not filepath: return filepath = Path(filepath) self.app_root.last_load_dir = filepath.parent self.logfile_path.set(filepath)
def sound_path_browse(self, force=False): if not force and (self._compiling or self._loading or self._saving): return snd__dir = os.path.dirname(self.sound_path.get()) fp = asksaveasfilename( initialdir=snd__dir, title="Save sound to...", parent=self, filetypes=(("Sound", "*.sound"), ('All', '*'))) if not fp: return if not os.path.splitext(fp)[-1]: fp += ".sound" self.app_root.last_load_dir = os.path.dirname(fp) self.sound_path.set(fp)
def gbxmodel_path_browse(self, force=False): if not force and (self._compiling or self._loading or self._saving): return mod2_dir = os.path.dirname(self.gbxmodel_path.get()) if self.tags_dir.get() and not mod2_dir: mod2_dir = self.tags_dir.get() fp = asksaveasfilename(initialdir=mod2_dir, title="Save gbxmodel to...", parent=self, filetypes=(("Gearbox model", "*.gbxmodel"), ('All', '*'))) if not fp: return fp = Path(fp).with_suffix(".gbxmodel") self.app_root.last_load_dir = str(fp.parent) self.gbxmodel_path.set(str(fp)) self.tags_dir.set( path_split(self.app_root.last_load_dir, "tags", after=True))
def do_recursive_zip(self): tag_path = self.tag_filepath.get() if not tag_path: return app = self.app_root handler = self.handler = app.handler handler_name = app.handler_names[app._curr_handler_index] if handler_name not in app.tags_dir_relative: print("Change the current tag set.") return tag_path = Path(tag_path) if not is_in_dir(tag_path, self.handler.tagsdir): print("Specified tag is not located within the tags directory") return tagzip_path = asksaveasfilename(initialdir=self.app_root.last_load_dir, parent=self, title="Save zipfile to...", filetypes=(("zipfile", "*.zip"), )) if not tagzip_path: return try: rel_filepath = tag_path.relative_to(self.handler.tagsdir) tag = self.get_tag(rel_filepath) except ValueError: tag = None if tag is None: print("Could not load tag:\n %s" % tag_path) return # make the zipfile to put everything in tagzip_path = os.path.splitext(tagzip_path)[0] + ".zip" tags_to_zip = [rel_filepath] new_tags_to_zip = [] seen_tags = set() with zipfile.ZipFile(str(tagzip_path), mode='w') as tagzip: # loop over all the tags and add them to the zipfile while tags_to_zip: for rel_filepath in tags_to_zip: tag_path = tagpath_to_fullpath( self.handler.tagsdir, PureWindowsPath(rel_filepath)) if self.stop_zipping: print('Recursive zip operation cancelled.\n') return if rel_filepath in seen_tags: continue seen_tags.add(rel_filepath) try: print("Adding '%s' to zipfile" % rel_filepath) app.update_idletasks() tag = self.get_tag(rel_filepath) new_tags_to_zip.extend(self.get_dependencies(tag)) # try to conserve memory a bit del tag tagzip.write(str(tag_path), arcname=str(rel_filepath)) except Exception: print(format_exc()) print(" Could not add '%s' to zipfile." % rel_filepath) # replace the tags to zip with the newly collected ones tags_to_zip[:] = new_tags_to_zip del new_tags_to_zip[:] print("\nRecursive zip completed.\n")
def _compile_model_animations(self): if not self.jma_anim_set: return print("Compiling...") while not self.model_animations_path.get(): self.model_animations_path_browse(True) if (not self.model_animations_path.get()) and self.warn_cancel(): print(" Model_animations compilation cancelled.") return try: antr_tag = antr_def.build( filepath=self.model_animations_path.get()) except Exception: antr_tag = None mod2_nodes = None if self.calculate_limp_limb_vectors.get(): antr_path = self.model_animations_path.get() antr_dir = os.path.dirname(antr_path) mod2_path = os.path.join( antr_dir, os.path.splitext(os.path.basename(antr_path))[0] + ".gbxmodel") while mod2_nodes is None: try: mod2_nodes = partial_mod2_def.build(filepath=mod2_path).\ data.tagdata.nodes.STEPTREE break except Exception: print("Could not load the selected gbxmodel.") mod2_path = asksaveasfilename( initialdir=antr_dir, parent=self, title="Select the gbxmodel to get nodes from", filetypes=(("Gearbox model", "*.gbxmodel"), ('All', '*'))) if (not mod2_path) and self.warn_cancel(): print(" Model_animations compilation cancelled.") return updating = antr_tag is not None if updating: print("Updating existing model_animations tag.") else: print("Creating new model_animations tag.") antr_tag = antr_def.build() antr_tag.filepath = self.model_animations_path.get() self.update() errors = compile_model_animations(antr_tag, self.jma_anim_set, False, self.animation_count_limit.get(), self.animation_delta_tolerance, self.update_mode.get(), mod2_nodes) if errors: for error in errors: print(error) self.update() if not messagebox.askyesno( "Model_animations compilation failed", "Errors occurred while compiling animations(check console). " "Do you want to save the model_animations tag anyway?", icon='warning', parent=self): print(" Model_animations compilation failed.") return try: antr_tag.calc_internal_data() antr_tag.serialize(temp=False, backup=False, calc_pointers=False, int_test=False) print(" Finished") except Exception: print(format_exc()) print(" Could not save compiled model_animations.")
def export_node(self): try: initialdir = self.tag_window.app_root.last_load_dir except AttributeError: initialdir = None def_ext = self.field_ext filepath = asksaveasfilename( initialdir=initialdir, title="Export sound data to...", parent=self, filetypes=[(self.name, '*' + def_ext), ('All', '*')]) if not filepath: return filepath = Path(filepath) if not filepath.suffix: filepath = filepath.with_suffix(def_ext) if filepath.suffix.lower() == '.wav': # if the file is wav, we need to give it a header try: wav_file = wav_def.build() wav_file.filepath = filepath sound_data = self.parent.get_root().data.tagdata wav_format = wav_file.data.wav_format wav_chunks = wav_file.data.wav_chunks wav_chunks.append(case="data") data_chunk = wav_chunks[-1] wav_format.bits_per_sample = 16 wav_format.channels = sound_data.encoding.data + 1 wav_format.sample_rate = 22050 * (sound_data.sample_rate.data + 1) wav_format.byte_rate = ((wav_format.sample_rate * wav_format.bits_per_sample * wav_format.channels) // 8) typ = "ima_adpcm" if self.parent.parent.compression.enum_name == 'none': typ = "pcm" audio_data = copy.deepcopy(self.parent) if typ == "pcm": wav_format.fmt.set_to('pcm') wav_format.block_align = 2 * wav_format.channels byteswap_pcm16_samples(audio_data) else: wav_format.fmt.set_to('ima_adpcm') wav_format.block_align = 36 * wav_format.channels data_chunk.data = audio_data.data wav_file.data.wav_header.filesize = wav_file.data.binsize - 12 wav_file.serialize(temp=False, backup=False, int_test=False) except Exception: print(format_exc()) print("Could not export sound data.") return try: if hasattr(self.node, 'serialize'): self.node.serialize( filepath=filepath, clone=self.export_clone, calc_pointers=self.export_calc_pointers) else: # the node isnt a block, so we need to call its parents # serialize method with the attr_index necessary to export. self.parent.serialize( filepath=filepath, clone=self.export_clone, calc_pointers=self.export_calc_pointers, attr_index=self.attr_index) except Exception: print(format_exc()) print("Could not export sound data.")