def run(self, status: Status): if not self.config['text']['story']: return status.done() status.step('Randomizing all script text: Reading strings...') all_strings_langs = {} for lang, _ in get_all_string_files(self.rom, self.static_data): all_strings = [] ssb_map: Dict[str, Ssb] = {} all_strings_langs[lang] = all_strings, ssb_map for file_path in get_files_from_rom_with_extension( self.rom, 'ssb'): script = get_script(file_path, self.rom, self.static_data) all_strings += script.strings[lang.name.lower()] ssb_map[file_path] = script status.step('Randomizing all script text: Writing strings...') for lang, (all_strings, ssb_map) in all_strings_langs.items(): shuffle(all_strings) for file_path, script in ssb_map.items(): samples = [] for _ in range(0, len(script.strings[lang.name.lower()])): samples.append(all_strings.pop()) script.strings[lang.name.lower()] = samples status.done()
def get_files_with_ext(self, ext, folder_name: Optional[str] = None): if folder_name is None: return get_files_from_rom_with_extension(self._rom, ext) else: return get_files_from_folder_with_extension( self._rom.filenames.subfolder(folder_name), ext) # type: ignore
def _outer_wrapper(wrapped_function): import inspect import pytest from ndspy.rom import NintendoDSRom from unittest import SkipTest from parameterized import parameterized rom = None if 'SKYTEMPLE_TEST_ROM' in os.environ and os.environ[ 'SKYTEMPLE_TEST_ROM'] != '': rom = NintendoDSRom.fromFile(os.environ['SKYTEMPLE_TEST_ROM']) if rom: def dataset_name_func(testcase_func, _, param): return f'{testcase_func.__name__}/{param.args[0]}' files = [(x, rom.getFileByName(x)) for x in get_files_from_rom_with_extension(rom, file_ext) if x.startswith(path)] if len(files) < 1: def no_files(*args, **kwargs): raise SkipTest("No matching files were found in the ROM.") return pytest.mark.romtest(no_files) else: spec = inspect.getfullargspec(wrapped_function) if "pmd2_data" in spec.args or "pmd2_data" in spec.kwonlyargs: pmd2_data = get_ppmdu_config_for_rom(rom) def pmd2datawrapper(*args, **kwargs): return wrapped_function(*args, **kwargs, pmd2_data=pmd2_data) pmd2datawrapper.__name__ = wrapped_function.__name__ parameterized.expand(files, name_func=dataset_name_func)( pytest.mark.romtest(pmd2datawrapper)) else: parameterized.expand(files, name_func=dataset_name_func)( pytest.mark.romtest(wrapped_function)) # since expands now adds the tests to our locals, we need to pass them back... # this isn't hacky at all wdym??????ßßß frame_locals = inspect.currentframe( ).f_back.f_locals # type: ignore for local_name, local in inspect.currentframe().f_locals.items( ): # type: ignore if local_name.startswith('test_'): frame_locals[local_name] = local else: def no_tests(*args, **kwargs): raise SkipTest("No ROM file provided or ROM not found.") return pytest.mark.romtest(no_tests)
async def main(executor): output_dir = os.path.join(os.path.dirname(__file__), 'dbg_output') base_dir = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', '..') os.makedirs(output_dir, exist_ok=True) rom = NintendoDSRom.fromFile( os.path.join(base_dir, 'skyworkcopy_us_unpatched.nds')) script_info = load_script_files(get_rom_folder(rom, SCRIPT_DIR)) # total, opening. decompiling, parsing, compiling, serializing times: List[Tuple[float, float, float, float, float, float]] = [] static_data = Pmd2XmlReader.load_default(for_version='EoS_NA') awaitables = [] for i, file_name in enumerate(get_files_from_rom_with_extension( rom, 'ssb')): # TODO: Those scripts fail for JP. if file_name in [ 'SCRIPT/D42P21A/enter23.ssb', 'SCRIPT/D73P11A/us0303.ssb', 'SCRIPT/D73P11A/us0305.ssb', 'SCRIPT/D73P11A/us2003.ssb', 'SCRIPT/D73P11A/us2005.ssb', 'SCRIPT/D73P11A/us2103.ssb', 'SCRIPT/D73P11A/us2105.ssb', 'SCRIPT/D73P11A/us2203.ssb', 'SCRIPT/D73P11A/us2205.ssb', 'SCRIPT/D73P11A/us2303.ssb', 'SCRIPT/D73P11A/us2305.ssb' ]: continue # Run multiple in parallel with asyncio executors. awaitables.append( loop.run_in_executor(executor, process_single, file_name, times, static_data, output_dir, rom)) pending = awaitables while len(pending) > 0: done, pending = await asyncio.wait(pending, return_when=asyncio.FIRST_COMPLETED) # to raise exceptions of tasks back to main loop: for fut in done: try: fut.result() except Exception: loop.stop() with poison_lock: poison_container[0] = True raise times_structured = list(zip(*times)) print_table_row("", "TOTAL", "OPENING", "DECOMPILING", "PARSING", "COMPILING", "SERIALIZING") print_table_row(*(["==========="] * 7)) print_table_row("TOTAL:", *[round(sum(t), 2) for t in times_structured]) print_table_row("AVG:", *[round(sum(t) / len(t), 2) for t in times_structured]) print_table_row("MAX:", *[round(max(t), 2) for t in times_structured]) print_table_row("MIN:", *[round(min(t), 2) for t in times_structured])
def main(rom_file, directory): rom = NintendoDSRom.fromFile(rom_file) for file_name in get_files_from_rom_with_extension(rom, 'ssb'): if os.path.exists(os.path.join(directory, file_name)): print(file_name) with open(os.path.join(directory, file_name), 'rb') as f: rom.setFileByName(file_name, f.read()) rom.saveToFile(rom_file)
def main(): output_dir = os.path.join(os.path.dirname(__file__), 'dbg_output', 'graphs') base_dir = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', '..') rom = NintendoDSRom.fromFile(os.path.join(base_dir, 'skyworkcopy.nds')) total_count_labels_before = 0 total_count_labels_after = 0 for file_name in get_files_from_rom_with_extension(rom, 'ssb'): print(file_name) bin_before = rom.getFileByName(file_name) ssb = SsbHandler.deserialize(bin_before) routine_ops = ssb.get_filled_routine_ops() resolver = OpsLabelJumpToResolver(routine_ops) routine_ops = list(resolver) grapher = SsbGraphMinimizer(routine_ops) total_count_labels_before += grapher.count_labels() draw_graphs(grapher, file_name, output_dir, 'before_optimize') grapher.optimize_paths() draw_graphs(grapher, file_name, output_dir, 'after_optimize') #grapher._graphs = [ grapher._graphs[86] ] grapher.build_branches() draw_graphs(grapher, file_name, output_dir, 'after_branch_before_group') grapher.group_branches() grapher.invert_branches() draw_graphs(grapher, file_name, output_dir, 'after_branch') grapher.build_and_group_switch_cases() grapher.group_switch_cases() grapher.build_switch_fallthroughs() draw_graphs(grapher, file_name, output_dir, 'after_switch') grapher.build_loops() draw_graphs(grapher, file_name, output_dir, 'after_loops') grapher.remove_label_markers() draw_graphs(grapher, file_name, output_dir, 'done') total_count_labels_after += grapher.count_labels() print("Total number labels before: " + str(total_count_labels_before)) print("Total number labels after: " + str(total_count_labels_after))
def replace_text_script(rom: NintendoDSRom, static_data: Pmd2Data, replace_map_lang: Dict[Pmd2Language, Dict[str, str]]): new_dict = {} for lang, replace_map in replace_map_lang.items(): for a, b in replace_map.items(): new_dict[a.upper()] = b.upper() replace_map.update(new_dict) for file_path in get_files_from_rom_with_extension(rom, 'ssb'): script = get_script(file_path, rom, static_data) script.constants = [ replace_strings(string, replace_map) for string in script.constants ] script.strings[lang.name.lower()] = [ replace_strings(string, replace_map) for string in script.strings[lang.name.lower()] ]
def main(): output_dir = os.path.join(os.path.dirname(__file__), 'dbg_output') base_dir = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', '..') os.makedirs(output_dir, exist_ok=True) rom = NintendoDSRom.fromFile(os.path.join(base_dir, 'skyworkcopy.nds')) for file_name in get_files_from_rom_with_extension(rom, 'ssb'): if 'm03a1310' not in file_name: continue print(file_name) out_file_name = os.path.join(output_dir, file_name.replace('/', '_') + '.txt') bin_before = rom.getFileByName(file_name) ssb = SsbHandler.deserialize(bin_before) with open(out_file_name, 'w') as f: f.write(export_ssb_as_txt(ssb))
def main(): base_dir = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', '..') rom = NintendoDSRom.fromFile(os.path.join(base_dir, 'skyworkcopy.nds')) for file_name in get_files_from_rom_with_extension(rom, 'ssb'): print(file_name) bin_before = rom.getFileByName(file_name) ssb_before = SsbHandler.deserialize(bin_before) bin_after = SsbHandler.serialize(ssb_before) after_header = SsbHeaderEu(bin_after) print("Header before:") print(str(ssb_before._header)) print("Header after:") print(str(after_header)) ssb_after = SsbHandler.deserialize(bin_after) assert (ssb_before._header.number_of_strings == ssb_after._header.number_of_strings) assert (ssb_before._header.const_table_length == ssb_after._header.const_table_length) assert (ssb_before._header.constant_strings_start == ssb_after._header.constant_strings_start) assert ( ssb_before._header.data_offset == ssb_after._header.data_offset) assert (ssb_before._header.number_of_constants == ssb_after._header.number_of_constants) assert (ssb_before._header.string_table_lengths == ssb_after._header.string_table_lengths) assert (ssb_before.routine_info == ssb_after.routine_info) assert (ssb_before.routine_ops == ssb_after.routine_ops) assert (ssb_before.constants == ssb_after.constants) assert (ssb_before.strings == ssb_after.strings) assert (len(bin_before) == len(bin_after)) assert (bin_before == bin_after)
def main(): output_dir = os.path.join(os.path.dirname(__file__), 'dbg_output') base_dir = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', '..') os.makedirs(output_dir, exist_ok=True) rom = NintendoDSRom.fromFile(os.path.join(base_dir, 'sky_jp.nds')) with open(os.path.join(output_dir, "enter23.ssb"), 'wb') as f: f.write(rom.getFileByName('SCRIPT/D42P21A/enter23.ssb')) for file_name in get_files_from_rom_with_extension(rom, 'ssb'): print(file_name) out_file_name = os.path.join(output_dir, file_name.replace('/', '_') + '.txt') bin_before = rom.getFileByName(file_name) ssb = SsbHandler.deserialize(bin_before, Pmd2XmlReader.load_default('EoS_JP')) with open(out_file_name, 'w') as f: f.write(export_ssb_as_txt(ssb))
def run(self, status: Status): if not self.config['starters_npcs']['overworld_music']: return status.step("Randomizing Overworld Music...") for script_name in get_files_from_rom_with_extension(self.rom, 'ssb'): ssb: Ssb = get_script(script_name, self.rom, self.static_data) for rtn in ssb.routine_ops: for op in rtn: op_c = self.static_data.script_data.op_codes__by_name[ op.op_code.name][0] for i, param_spec in enumerate(op_c.arguments): if param_spec.type == 'Bgm': # Only randomize real music (looping tracks) if any((b.id == op.params[i] for b in self.bgs)): op.params[i] = self._get_random_music_id() # We don't really support those, so replace them with 1 sec wait. if op_c.name == 'WaitBgmSignal' or op_c.name == 'WaitBgm' or op_c.name == 'WaitBgm2': op.op_code = self.static_data.script_data.op_codes__by_name[ 'Wait'][0] op.params = [60] status.done()
# but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with SkyTemple. If not, see <https://www.gnu.org/licenses/>. import os from ndspy.rom import NintendoDSRom from skytemple_files.common.types.file_types import FileType from skytemple_files.common.util import get_files_from_rom_with_extension, get_ppmdu_config_for_rom from skytemple_files.graphics.chr.handler import ChrHandler from skytemple_files.graphics.pal.handler import PalHandler base_dir = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', '..') out_dir = os.path.join(os.path.dirname(__file__), 'dbg_output') os.makedirs(out_dir, exist_ok=True) rom = NintendoDSRom.fromFile(os.path.join(base_dir, 'skyworkcopy_us.nds')) config = get_ppmdu_config_for_rom(rom) for fn in get_files_from_rom_with_extension(rom, 'chr'): font = ChrHandler.deserialize(rom.getFileByName(fn)) pal = PalHandler.deserialize(rom.getFileByName(fn[:-4] + ".pal")) font.set_palette(pal) font.to_pil().save(os.path.join(out_dir, fn.replace('/', '_') + f'.png')) assert rom.getFileByName(fn) == ChrHandler.serialize(font)
from ndspy.rom import NintendoDSRom from skytemple_files.common.types.file_types import FileType from skytemple_files.common.util import get_files_from_rom_with_extension from skytemple_files.compression_container.common_at.handler import CommonAtHandler from skytemple_files.graphics.bgp.handler import BgpHandler from skytemple_files.graphics.bgp.model import BGP_RES_WIDTH_IN_TILES os.makedirs(os.path.join(os.path.dirname(__file__), 'dbg_output'), exist_ok=True) base_dir = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', '..') rom = NintendoDSRom.fromFile(os.path.join(base_dir, 'skyworkcopy.nds')) for filename in get_files_from_rom_with_extension(rom, 'bgp'): print("Processing " + filename) bin_before = rom.getFileByName(filename) bgp = BgpHandler.deserialize(bin_before) bin_after = BgpHandler.serialize(bgp) bin_before_unpacked = CommonAtHandler.deserialize(bin_before).decompress() bin_after_unpacked = CommonAtHandler.deserialize(bin_after).decompress() assert bin_before_unpacked == bin_after_unpacked rom.setFileByName(filename, bin_after)
import sys from ndspy.rom import NintendoDSRom from skytemple_rust.pmd_wan import AnimationFrame from skytemple_files.common.types.file_types import FileType from skytemple_files.common.util import get_files_from_rom_with_extension output_dir = os.path.join(os.path.dirname(__file__), 'dbg_output') base_dir = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', '..') rom = NintendoDSRom.fromFile(os.path.join(base_dir, 'skyworkcopy.nds')) # Object sprites for path in get_files_from_rom_with_extension(rom, 'wan'): if path.startswith('FONT'): continue print(path) basename = os.path.basename(path) try: wan_bin = rom.getFileByName(path) wan_model = FileType.WAN.deserialize(wan_bin) except ValueError as e: print(f"FATAL Error for {basename}: {e}", file=sys.stderr) continue os.makedirs(os.path.join(output_dir, basename), exist_ok=True) for ag_i, group in enumerate(wan_model.anim_groups): if group is None:
def main(): output_dir = os.path.join(os.path.dirname(__file__), 'dbg_output') base_dir = os.path.join(os.path.dirname(__file__), '..', '..', '..', '..', '..') os.makedirs(output_dir, exist_ok=True) rom = NintendoDSRom.fromFile(os.path.join(base_dir, 'skyworkcopy.nds')) script_info = load_script_files(get_rom_folder(rom, SCRIPT_DIR)) # total, opening. decompiling, parsing, compiling, serializing times: List[Tuple[float, float, float, float, float, float]] = [] for i, file_name in enumerate(get_files_from_rom_with_extension( rom, 'ssb')): print(file_name) out_file_name = os.path.join(output_dir, file_name.replace('/', '_') + '.ssbs') time_before = time.time() bin_before = rom.getFileByName(file_name) time_opening = time.time() ssb_before = SsbHandler.deserialize(bin_before) ssb_script, source_map_before = ssb_before.to_ssb_script() time_decompiling = time.time() for pos_mark in source_map_before.get_position_marks__direct(): print(pos_mark) with open(out_file_name, 'w') as f: f.write(ssb_script) # Test the compiling and writing, by compiling the model, writing it to binary, and then loading it again, # and checking the generated ssb script. compiler = ScriptCompiler(Pmd2XmlReader.load_default()) time_parsing = 0 def callback_after_parsing(): nonlocal time_parsing time_parsing = time.time() ssb_after, source_map_after = compiler.compile_ssbscript( ssb_script, callback_after_parsing) time_compiling = time.time() bin_after = SsbHandler.serialize(ssb_after) time_serializing = time.time() ssb_after_after = SsbHandler.deserialize(bin_after) ssb_script_after = ssb_after_after.to_ssb_script()[0] with open('/tmp/diff1.ssb', 'w') as f: f.write(ssb_script) with open('/tmp/diff2.ssb', 'w') as f: f.write(ssb_script_after) assert (ssb_script == ssb_script_after) assert (source_map_before == source_map_after) times.append(( time_serializing - time_before, # total time_opening - time_before, # opening. time_decompiling - time_opening, # decompiling, time_parsing - time_decompiling, # parsing, time_compiling - time_parsing, # compiling, time_serializing - time_compiling, # serializing )) times_structured = list(zip(*times)) print_table_row("", "TOTAL", "OPENING", "DECOMPILING", "PARSING", "COMPILING", "SERIALIZING") print_table_row(*(["==========="] * 7)) print_table_row("TOTAL:", *[round(sum(t), 2) for t in times_structured]) print_table_row("AVG:", *[round(sum(t) / len(t), 2) for t in times_structured]) print_table_row("MAX:", *[round(max(t), 2) for t in times_structured]) print_table_row("MIN:", *[round(min(t), 2) for t in times_structured])
def get_files_with_ext(self, ext): return get_files_from_rom_with_extension(self._rom, ext)