def import_yakuza_shader_file(path: WindowsPath) -> 'YkShaderFile': byte_data = None with path.open("rb") as f: byte_data = bytearray(f.read()) if not byte_data or len(byte_data) < 4: raise YkError(f"Couldn't open {path} and extract >4 bytes.") return FirstPossibleOf([YkPixelShaderFile, YkEffectShaderFile], [YkError])(byte_data)
def scripts_serving(file): target_path = Path(BASE_DIR.joinpath("scripts"), file) if target_path.exists() and not target_path.is_dir(): return send_file(target_path.open(mode="rb"), attachment_filename=target_path.name) abort(404)
def main(): parser = argparse.ArgumentParser( description= "Extract the pixel shader HLSL from a Yakuza .pso or .fxo file") parser.add_argument("yakuza_file", help="The file to extract from.", type=windows_path_arg) parser.add_argument( "-o", help="The file to output. Defaults to \"ORIGINAL_FILE.pxo.hlsl\"") parser.add_argument( "-i", help="Ignore compilation errors for disassembled shader", action="store_true", dest="ignore") args = parser.parse_args() if not args.o: args.o = args.yakuza_file.with_suffix(args.yakuza_file.suffix + ".hlsl") output_path = WindowsPath(args.o) yk_file = import_yakuza_shader_file(args.yakuza_file) shader_assembly = decompile_shader(yk_file.get_pixel_shader_data()) print(shader_assembly) dp = DisassemblyParser(shader_assembly) pg = ProgramGenerator() program = pg.build_program(dp.declarations, dp.instructions, dp.input_semantics, dp.output_semantics, dp.global_flags) try: flags = (1 << 11) | (1 << 21) | (1 << 15) compile_shader(program.get_disassembled_shader(), "DISASSEMBLED_SHADER", flags) except DXCallError as e: if not args.ignore: reraise( e, "Got error when compiling disassembled shader, use -i to ignore." + "\n{}") with output_path.open("w") as f: f.write(program.get_disassembled_shader())
def write_to_path(self, path: WindowsPath): with path.open("wb") as f: f.write(self[0:HEADER_SIZE + self.data_length])