def run(self): print("LaunchHandler.run") # self.on_progress(gettext("Starting FS-UAE...")) # current_task.set_progress(gettext("Starting FS-UAE...")) current_task.set_progress("__run__") config = self.create_config() if self.use_relative_paths: process, config_file = FSUAE.start_with_config( config, cwd=self.temp_dir ) else: process, config_file = FSUAE.start_with_config(config) pid_file = self.fsgc.settings[Option.EMULATOR_PID_FILE] GameDriver.write_emulator_pid_file(pid_file, process) process.wait() GameDriver.remove_emulator_pid_file(pid_file) print("LaunchHandler.start is done") if os.environ.get("FSGS_CLEANUP", "") == "0": print("Not removing", config_file) else: print("removing", config_file) try: os.remove(config_file) except Exception: print("could not remove config file", config_file)
def unpack_game_hard_drive(self, drive_index, src): print("unpack_game_hard_drive", drive_index, src) scheme, dummy, dummy, game_uuid, drive = src.split("/") drive_prefix = drive + "/" dir_name = "DH{0}".format(drive_index) dir_path = os.path.join(self.temp_dir, dir_name) file_list = self.get_file_list_for_game_uuid(game_uuid) for file_entry in file_list: if self.stop_flag: return name = file_entry["name"] if not name.startswith(drive_prefix): continue # extract Amiga relative path and convert each path component # to host file name (where needed). amiga_rel_path = name[len(drive_prefix):] print("amiga_rel_path", amiga_rel_path) amiga_rel_parts = amiga_rel_path.split("/") for i, part in enumerate(amiga_rel_parts): # part can be blank if amiga_rel_parts is a directory # (ending with /) if part: amiga_rel_parts[i] = amiga_filename_to_host_filename(part) amiga_rel_path = "/".join(amiga_rel_parts) dst_file = os.path.join(dir_path, amiga_rel_path) print(repr(dst_file)) if name.endswith("/"): os.makedirs(Paths.str(dst_file)) continue if not os.path.exists(os.path.dirname(dst_file)): os.makedirs(os.path.dirname(dst_file)) sha1 = file_entry["sha1"] # current_task.set_progress(os.path.basename(dst_file)) current_task.set_progress(amiga_rel_path) self.fsgs.file.copy_game_file("sha1://{0}".format(sha1), dst_file) # src_file = self.fsgs.file.find_by_sha1(sha1) # if not os.path.exists(os.path.dirname(dst_file)): # os.makedirs(os.path.dirname(dst_file)) # stream = self.fsgs.file.open(src_file) # # archive = Archive(src_file) # # f = archive.open(src_file) # data = stream.read() # assert hashlib.sha1(data).hexdigest() == sha1 # with open(dst_file, "wb") as out_file: # out_file.write(data) metadata = ["----rwed", " ", "2000-01-01 00:00:00.00", " ", "", "\n"] if "comment" in file_entry: metadata[4] = self.encode_file_comment(file_entry["comment"]) with open(dst_file + ".uaem", "wb") as out_file: out_file.write("".join(metadata).encode("UTF-8")) self.config["hard_drive_{0}".format(drive_index)] = dir_path
def start_emulator( self, emulator, args=None, env_vars=None, executable=None, cwd=None ): # if "/" in emulator: # if not executable: # executable = self.find_emulator_executable(emulator) # if not executable: # emulator = emulator.split("/")[-1] # # if not executable: # executable = self.find_emulator_executable("fs-" + emulator) # if not executable: # executable = self.find_emulator_executable(emulator) # # if not executable: # raise Exception("could not find executable for " + emulator) args = [] args.extend(self.emulator.args) if "SDL_VIDEODRIVER" in os.environ: print("SDL_VIDEODRIVER was present in environment, removing!") del os.environ["SDL_VIDEODRIVER"] env = os.environ.copy() FSUAE.add_environment_from_settings(env) self.update_environment(env) if self.bezel(): self.prepare_emulator_skin(env) if env_vars: env.update(env_vars) print("") for key in sorted(env.keys()): print("[ENV]", key, ":", repr(env[key])) print("") for arg in args: print("[ARG]", repr(arg)) print("") kwargs = {} if env is not None: kwargs["env"] = env if cwd is not None: kwargs["cwd"] = cwd else: kwargs["cwd"] = self.cwd.path print("[CWD]", kwargs["cwd"]) print("") if System.windows: kwargs["close_fds"] = True # print(" ".join(args)) current_task.set_progress( "Starting {emulator}".format(emulator=emulator) ) # import subprocess # return subprocess.Popen(["strace", emulator.path] + args, **kwargs) process = emulator.popen(args, **kwargs) self.write_emulator_pid_file(self.emulator_pid_file(), process) return process
def start_emulator( self, emulator, args=None, env_vars=None, executable=None, cwd=None ): # if "/" in emulator: # if not executable: # executable = self.find_emulator_executable(emulator) # if not executable: # emulator = emulator.split("/")[-1] # # if not executable: # executable = self.find_emulator_executable("fs-" + emulator) # if not executable: # executable = self.find_emulator_executable(emulator) # # if not executable: # raise Exception("could not find executable for " + emulator) args = [] args.extend(self.emulator.args) if "SDL_VIDEODRIVER" in os.environ: print("SDL_VIDEODRIVER was present in environment, removing!") del os.environ["SDL_VIDEODRIVER"] env = os.environ.copy() FSUAE.add_environment_from_settings(env) self.update_environment(env) if self.bezel(): self.prepare_emulator_skin(env) if env_vars: env.update(env_vars) print("") for key in sorted(env.keys()): print("[ENV]", key, ":", repr(env[key])) print("") for arg in args: print("[ARG]", repr(arg)) print("") kwargs = {} if env is not None: kwargs["env"] = env if cwd is not None: kwargs["cwd"] = cwd else: kwargs["cwd"] = self.cwd.path print("[CWD]", kwargs["cwd"]) print("") if System.windows: kwargs["close_fds"] = True # print(" ".join(args)) current_task.set_progress( "Starting {emulator}".format(emulator=emulator) ) # import subprocess # return subprocess.Popen(["strace", emulator.path] + args, **kwargs) process = emulator.popen(args, **kwargs) self.write_emulator_pid_file(self.emulator_pid_file(), process) return process
def prepare_cdroms(self): print("LaunchHandler.prepare_cdroms") if not self.config.get("cdrom_drive_count", ""): if self.config.get("cdrom_drive_0", "") or \ self.config.get("cdrom_image_0", ""): self.config["cdrom_drive_count"] = "1" cdrom_drive_0 = self.config.get("cdrom_drive_0", "") if cdrom_drive_0.startswith("game:"): scheme, dummy, game_uuid, name = cdrom_drive_0.split("/") file_list = self.get_file_list_for_game_uuid(game_uuid) for file_item in file_list: src = self.fsgs.file.find_by_sha1(file_item["sha1"]) src, archive = self.expand_default_path( src, self.fsgs.amiga.get_cdroms_dir()) dst_name = file_item["name"] current_task.set_progress(dst_name) dst = os.path.join(self.temp_dir, dst_name) self.fsgs.file.copy_game_file(src, dst) cue_sheets = self.get_cue_sheets_for_game_uuid(game_uuid) for cue_sheet in cue_sheets: # FIXME: Try to get this to work with the PyCharm type checker # noinspection PyTypeChecker with open(os.path.join(self.temp_dir, cue_sheet["name"]), "wb") as f: # noinspection PyTypeChecker f.write(cue_sheet["data"].encode("UTF-8")) for i in range(Amiga.MAX_CDROM_DRIVES): key = "cdrom_drive_{0}".format(i) value = self.config.get(key, "") if value: self.config[key] = os.path.join( self.temp_dir, os.path.basename(value)) for i in range(Amiga.MAX_CDROM_IMAGES): key = "cdrom_image_{0}".format(i) value = self.config.get(key, "") if value: self.config[key] = os.path.join( self.temp_dir, os.path.basename(value)) cdroms = [] for i in range(Amiga.MAX_CDROM_DRIVES): key = "cdrom_drive_{0}".format(i) if self.config.get(key, ""): cdroms.append(self.config[key]) for i in range(Amiga.MAX_CDROM_IMAGES): key = "cdrom_image_{0}".format(i) if self.config.get(key, ""): break else: print("CD-ROM image list is empty") for j, cdrom in enumerate(cdroms): self.config["cdrom_image_{0}".format(j)] = cdrom
def prepare_cdroms(self): print("LaunchHandler.prepare_cdroms") if not self.config.get("cdrom_drive_count", ""): if self.config.get("cdrom_drive_0", "") or \ self.config.get("cdrom_image_0", ""): self.config["cdrom_drive_count"] = "1" cdrom_drive_0 = self.config.get("cdrom_drive_0", "") if cdrom_drive_0.startswith("game:"): scheme, dummy, game_uuid, name = cdrom_drive_0.split("/") file_list = self.get_file_list_for_game_uuid(game_uuid) for file_item in file_list: src = self.fsgs.file.find_by_sha1(file_item["sha1"]) src, archive = self.expand_default_path( src, self.fsgs.amiga.get_cdroms_dir()) dst_name = file_item["name"] current_task.set_progress(dst_name) dst = os.path.join(self.temp_dir, dst_name) self.fsgs.file.copy_game_file(src, dst) cue_sheets = self.get_cue_sheets_for_game_uuid(game_uuid) for cue_sheet in cue_sheets: # FIXME: Try to get this to work with the PyCharm type checker # noinspection PyTypeChecker with open(os.path.join(self.temp_dir, cue_sheet["name"]), "wb") as f: # noinspection PyTypeChecker f.write(cue_sheet["data"].encode("UTF-8")) for i in range(Amiga.MAX_CDROM_DRIVES): key = "cdrom_drive_{0}".format(i) value = self.config.get(key, "") if value: self.config[key] = os.path.join(self.temp_dir, os.path.basename(value)) for i in range(Amiga.MAX_CDROM_IMAGES): key = "cdrom_image_{0}".format(i) value = self.config.get(key, "") if value: self.config[key] = os.path.join(self.temp_dir, os.path.basename(value)) cdroms = [] for i in range(Amiga.MAX_CDROM_DRIVES): key = "cdrom_drive_{0}".format(i) if self.config.get(key, ""): cdroms.append(self.config[key]) for i in range(Amiga.MAX_CDROM_IMAGES): key = "cdrom_image_{0}".format(i) if self.config.get(key, ""): break else: print("CD-ROM image list is empty") for j, cdrom in enumerate(cdroms): self.config["cdrom_image_{0}".format(j)] = cdrom
def run(self): print("LaunchHandler.run") # self.on_progress(gettext("Starting FS-UAE...")) # current_task.set_progress(gettext("Starting FS-UAE...")) current_task.set_progress("__run__") config = self.create_config() process, config_file = FSUAE.start_with_config(config) process.wait() print("LaunchHandler.start is done") print("removing", config_file) try: os.remove(config_file) except Exception: print("could not remove config file", config_file)
def prepare_hard_drives(self): print("LaunchHandler.prepare_hard_drives") current_task.set_progress(gettext("Preparing hard drives...")) # self.on_progress(gettext("Preparing hard drives...")) for i in range(0, 10): key = "hard_drive_{0}".format(i) src = self.config.get(key, "") dummy, ext = os.path.splitext(src) ext = ext.lower() if is_http_url(src): name = src.rsplit("/", 1)[-1] name = urllib.parse.unquote(name) self.on_progress(gettext("Downloading {0}...".format(name))) dest = os.path.join(self.temp_dir, name) Downloader.install_file_from_url(src, dest) src = dest elif src.startswith("hd://game/"): self.unpack_game_hard_drive(i, src) self.disable_save_states() return elif src.startswith("hd://template/workbench/"): self.prepare_workbench_hard_drive(i, src) self.disable_save_states() return elif src.startswith("hd://template/empty/"): self.prepare_empty_hard_drive(i, src) self.disable_save_states() return if ext in Archive.extensions: print("zipped hard drive", src) self.unpack_hard_drive(i, src) self.disable_save_states() elif src.endswith("HardDrive"): print("XML-described hard drive", src) self.unpack_hard_drive(i, src) self.disable_save_states() else: src = Paths.expand_path(src) self.config[key] = src
def prepare_floppies(self): print("LaunchHandler.copy_floppies") current_task.set_progress(gettext("Preparing floppy images...")) # self.on_progress(gettext("Preparing floppy images...")) floppies = [] for i in range(Amiga.MAX_FLOPPY_DRIVES): key = "floppy_drive_{0}".format(i) if self.config.get(key, ""): floppies.append(self.config[key]) self.prepare_floppy(key) for i in range(Amiga.MAX_FLOPPY_IMAGES): key = "floppy_image_{0}".format(i) if self.config.get(key, ""): break else: print("floppy image list is empty") for j, floppy in enumerate(floppies): self.config["floppy_image_{0}".format(j)] = floppy max_image = -1 for i in range(Amiga.MAX_FLOPPY_IMAGES): key = "floppy_image_{0}".format(i) self.prepare_floppy(key) if self.config.get(key, ""): max_image = i save_image = max_image + 1 if self.config.get("save_disk", "") != "0": s = Resources("fsgamesys").stream("amiga/adf_save_disk.dat") data = s.read() data = zlib.decompress(data) save_disk_sha1 = hashlib.sha1(data).hexdigest() # save_disk = os.path.join(self.temp_dir, "Save Disk.adf") save_disk = os.path.join( self.temp_dir, save_disk_sha1[:8].upper() + ".adf" ) with open(save_disk, "wb") as f: f.write(data) self.config[f"floppy_image_{save_image}"] = save_disk self.config[f"floppy_image_{save_image}_label"] = "Save Disk"
def prepare_floppy(self, key): src = self.config.get(key, "").strip() if not src: return src, archive = self.expand_default_path( src, self.fsgs.amiga.get_floppies_dir()) dst_name = os.path.basename(src) current_task.set_progress(dst_name) if self.config["writable_floppy_images"] == "1" and \ os.path.isfile(src): # the config value directly refers to a local file, and the config # value already refers to the file, but since we may have # changed floppy_dir and the path may be relative, we set the # resolved path directly self.config[key] = src else: dst = os.path.join(self.temp_dir, dst_name) self.fsgs.file.copy_game_file(src, dst) self.config[key] = os.path.basename(dst)
def prepare_floppies(self): print("LaunchHandler.copy_floppies") current_task.set_progress(gettext("Preparing floppy images...")) # self.on_progress(gettext("Preparing floppy images...")) floppies = [] for i in range(Amiga.MAX_FLOPPY_DRIVES): key = "floppy_drive_{0}".format(i) if self.config.get(key, ""): floppies.append(self.config[key]) self.prepare_floppy(key) for i in range(Amiga.MAX_FLOPPY_IMAGES): key = "floppy_image_{0}".format(i) if self.config.get(key, ""): break else: print("floppy image list is empty") for j, floppy in enumerate(floppies): self.config["floppy_image_{0}".format(j)] = floppy max_image = -1 for i in range(Amiga.MAX_FLOPPY_IMAGES): key = "floppy_image_{0}".format(i) self.prepare_floppy(key) if self.config.get(key, ""): max_image = i save_image = max_image + 1 if self.config.get("save_disk", "") != "0": s = Resources("fsgs", "res").stream("amiga/adf_save_disk.dat") data = s.read() data = zlib.decompress(data) save_disk = os.path.join(self.temp_dir, "Save Disk.adf") with open(save_disk, "wb") as f: f.write(data) key = "floppy_image_{0}".format(save_image) self.config[key] = "Save Disk.adf"
def copy_whdload_files(self, dest_dir, s_dir): whdload_args = self.config.get("x_whdload_args", "").strip() if not whdload_args: return print("LaunchHandler.copy_whdload_files") current_task.set_progress(gettext("Preparing WHDLoad...")) # self.on_progress(gettext("Preparing WHDLoad...")) print("copy_whdload_files, dest_dir = ", dest_dir) whdload_dir = "" slave = whdload_args.split(" ", 1)[0] slave = slave.lower() found_slave = False for dir_path, dir_names, file_names in os.walk(dest_dir): for name in file_names: # print(name, slave) if name.lower() == slave: print("found", name) found_slave = True whdload_dir = dir_path[len(dest_dir):] whdload_dir = whdload_dir.replace("\\", "/") if not whdload_dir: # slave was found in root directory pass elif whdload_dir[0] == "/": whdload_dir = whdload_dir[1:] break if found_slave: break if not found_slave: raise Exception( "Did not find the specified WHDLoad slave. " "Check the WHDLoad arguments") print("WHDLoad dir:", repr(whdload_dir)) print("WHDLoad args:", whdload_args) self.copy_whdload_kickstart( dest_dir, "kick34005.A500", ["891e9a547772fe0c6c19b610baf8bc4ea7fcb785"]) self.copy_whdload_kickstart( dest_dir, "kick40068.A1200", ["e21545723fe8374e91342617604f1b3d703094f1"]) self.copy_whdload_kickstart( dest_dir, "kick40068.A4000", ["5fe04842d04a489720f0f4bb0e46948199406f49"]) self.create_whdload_prefs_file(os.path.join(s_dir, "WHDLoad.prefs")) whdload_version = self.config["x_whdload_version"] if not whdload_version: whdload_version = DEFAULT_WHDLOAD_VERSION for key, value in whdload_files[whdload_version].items(): self.install_whdload_file(key, dest_dir, value) for key, value in whdload_support_files.items(): self.install_whdload_file(key, dest_dir, value) if self.config.get("__netplay_game", ""): print("WHDLoad key is not copied in net play mode") else: key_file = os.path.join( self.fsgs.amiga.get_base_dir(), "WHDLoad.key") if os.path.exists(key_file): print("found WHDLoad.key at ", key_file) shutil.copy(key_file, os.path.join(s_dir, "WHDLoad.key")) else: print("WHDLoad key not found in base dir (FS-UAE dir)") # temporary feature, at least until it's possible to set more # WHDLoad settings directly in the Launcher prefs_file = os.path.join( self.fsgs.amiga.get_base_dir(), "WHDLoad.prefs") if os.path.exists(prefs_file): print("found WHDLoad.prefs at ", prefs_file) shutil.copy(prefs_file, os.path.join(s_dir, "WHDLoad.prefs")) else: print("WHDLoad key not found in base dir (FS-UAE dir)") if self.config.get("__netplay_game", ""): print("WHDLoad base dir is not copied in net play mode") else: src_dir = self.fsgs.amiga.get_whdload_dir() if src_dir and os.path.exists(src_dir): print("WHDLoad base dir exists, copying resources...") self.copy_folder_tree(src_dir, dest_dir) # icon = self.config.get("__whdload_icon", "") icon = "" if icon: shutil.copy(os.path.expanduser("~/kgiconload"), os.path.join(dest_dir, "C", "kgiconload")) icon_path = os.path.join(dest_dir, icon) print("create icon at ", icon_path) create_slave_icon(icon_path, whdload_args) self.write_startup_sequence( s_dir, "cd \"{0}\"\n" "kgiconload {1}\n" "uae-configuration SPC_QUIT 1\n".format( whdload_dir, os.path.basename(icon))) else: self.write_startup_sequence( s_dir, whdload_sequence.format(whdload_dir, whdload_args))
def configure(self): self.configure_romset() self.default_xml = [ """\ufeff<?xml version="1.0"?> <!-- This file is autogenerated; comments and unknown tags will be stripped --> <mameconfig version="10"> <system name="default">\n""" ] self.game_xml = [ """\ufeff<?xml version="1.0"?> <!-- This file is autogenerated; comments and unknown tags will be stripped --> <mameconfig version="10"> <system name="{0}">\n""".format(self.romset) ] self.add_arg("-skip_gameinfo") # state_dir = self.get_state_dir() state_dir = self.emulator_state_dir(self.mame_emulator_name()) state_dir = state_dir + os.sep self.cwd_dir = self.create_temp_dir("mame-cwd") self.cfg_dir = self.create_temp_dir("mame-cfg") self.roms_dir = self.create_temp_dir("mame-roms") rom_path = self.roms_dir.path assert self.romset system_rom_path = os.path.join(rom_path, self.romset) os.makedirs(system_rom_path) for sha1, name in self.romset_files: file_uri = self.fsgs.file.find_by_sha1(sha1) current_task.set_progress("Preparing ROM {name}".format(name=name)) input_stream = self.fsgs.file.open(file_uri) if input_stream is None: raise Exception("Cannot not find required ROM " + repr(name)) path = os.path.join(system_rom_path, name) with open(path, "wb") as f: f.write(input_stream.read()) # shutil.copy(self.get_game_file(), # os.path.join(rom_path, self.romset + '.zip')) # MAME uses ; as path separator on all systems, apparently try: # self.args.extend(["-rompath", self.bios_dir()]) rom_path = rom_path + ";" + self.mame_get_bios_dir() except: pass # rom_path = rom_path + ";" + os.path.dirname(self.get_game_file()) # rom_path = rom_path + os.pathsep + os.path.dirname( # self.get_game_file()) self.add_arg("-rompath", rom_path) # copy initial nvram disk, if any, to nvram dir # p, e = os.path.splitext(self.get_game_file()) # initram = p + ".nv" # if os.path.exists(initram): # shutil.copy(initram, os.path.join(state_dir, self.romset + '.nv')) game_cfg_file = os.path.join(self.cfg_dir.path, "{romset}.cfg".format(romset=self.romset)) self.add_arg("-cfg_directory", self.cfg_dir.path) self.add_arg("-nvram_directory", state_dir) # self.add_arg("-memcard_directory", state_dir) # self.add_arg("-hiscore_directory", state_dir) self.add_arg("-state_directory", state_dir) self.add_arg("-diff_directory", state_dir) self.add_arg("-snapshot_directory", self.screenshots_dir()) self.add_arg("-snapname", "{0}-%i".format(self.screenshots_name())) # self.change_handler = GameChangeHandler(self.cfg_dir.path) # self.change_handler.init( # os.path.join(self.get_state_dir(), "cfg")) self.configure_input() self.configure_video() self.game_xml.append(' </system>\n') self.game_xml.append('</mameconfig>\n') with open(game_cfg_file, 'wb') as f: f.write("".join(self.game_xml).encode("UTF-8")) print("") print("") print("".join(self.game_xml)) print("") print("") self.default_xml.append(' </system>\n') self.default_xml.append('</mameconfig>\n') with open(os.path.join(self.cfg_dir.path, "default.cfg"), "wb") as f: f.write("".join(self.default_xml).encode("UTF-8")) print("") print("") print("".join(self.default_xml)) print("") print("") if self.use_doubling(): self.add_arg("-prescale", "2") if self.use_smoothing(): self.add_arg("-filter") else: self.add_arg("-nofilter") # start mame/mess with UI keyboard keys enabled by default, # full keyboard can be activated with INS / Scroll-Lock # self.add_arg("-ui_active") self.mame_configure() self.args.append(self.romset)
def prepare_roms(self): print("LaunchHandler.prepare_roms") current_task.set_progress(gettext("Preparing kickstart ROMs...")) amiga_model = self.config.get("amiga_model", "A500") model_config = Amiga.get_model_config(amiga_model) roms = [("kickstart_file", model_config["kickstarts"])] if self.config["kickstart_ext_file"] or model_config["ext_roms"]: # not all Amigas have extended ROMs roms.append(("kickstart_ext_file", model_config["ext_roms"])) if amiga_model.lower() == "cd32/fmv": roms.append(("fvm_rom", [CD32_FMV_ROM])) if self.config["graphics_card"].lower().startswith("picasso-iv"): roms.append(("graphics_card_rom", [PICASSO_IV_74_ROM])) if self.config["accelerator"].lower() == "cyberstorm-ppc": roms.append(("accelerator_rom", ["cyberstormppc.rom"])) if self.config["freezer_cartridge"] == "action-replay-2": # Ideally, we would want to recognize ROMs based on zeroing the # first four bytes, but right now we simply recognize a common # additional version. freezer_cartridge_rom isn't a real option, # we just want to copy the rom file and let FS-UAE find it roms.append(("[freezer_cartridge]", [ACTION_REPLAY_MK_II_2_14_ROM.sha1, ACTION_REPLAY_MK_II_2_14_MOD_ROM.sha1])) elif self.config["freezer_cartridge"] == "action-replay-3": roms.append(("[freezer_cartridge]", [ACTION_REPLAY_MK_III_3_17_ROM.sha1, ACTION_REPLAY_MK_III_3_17_MOD_ROM.sha1])) for config_key, default_roms in roms: print("ROM:", config_key, default_roms) src = self.config[config_key] if not src: for sha1 in default_roms: if is_sha1(sha1): rom_src = self.fsgs.file.find_by_sha1(sha1) if rom_src: src = rom_src break else: # roms_dir = FSGSDirectories.get_kickstarts_dir() # src = os.path.join(roms_dir, sha1) # if os.path.exists(src): # break # loop up file in roms dir instead src = sha1 elif src == "internal": continue elif src: src = Paths.expand_path(src) if not src: raise TaskFailure( gettext("Did not find required Kickstart or " "ROM for {}. Wanted one of these files: {}".format( config_key, repr(default_roms)))) use_temp_kickstarts_dir = False dest = os.path.join(self.temp_dir, os.path.basename(src)) archive = Archive(src) stream = None if not archive.exists(src): dirs = [self.fsgs.amiga.get_kickstarts_dir()] for dir in dirs: path = os.path.join(dir, src) print("checking", repr(path)) archive = Archive(path) if archive.exists(path): src = path break else: try: stream = self.fsgs.file.open(src) if stream is None: raise FileNotFoundError(src) except FileNotFoundError: raise TaskFailure(gettext( "Cannot find required ROM " "file: {name}".format(name=repr(src)))) with open(dest, "wb") as f: if stream: f.write(stream.read()) else: ROMManager.decrypt_archive_rom(archive, src, file=f) if use_temp_kickstarts_dir: self.config[config_key] = os.path.basename(src) else: self.config[config_key] = dest if use_temp_kickstarts_dir: self.config["kickstarts_dir"] = self.temp_dir
def start_emulator(self, emulator, args=None, env_vars=None, executable=None, cwd=None): # if "/" in emulator: # if not executable: # executable = self.find_emulator_executable(emulator) # if not executable: # emulator = emulator.split("/")[-1] # # if not executable: # executable = self.find_emulator_executable("fs-" + emulator) # if not executable: # executable = self.find_emulator_executable(emulator) # # if not executable: # raise Exception("could not find executable for " + emulator) args = [] args.extend(self.args) print(repr(args)) if "SDL_VIDEODRIVER" in os.environ: print("SDL_VIDEODRIVER was present in environment, removing!") del os.environ["SDL_VIDEODRIVER"] env = os.environ.copy() FSUAE.add_environment_from_settings(env) if self.use_fullscreen(): fullscreen_mode = self.config.get("fullscreen_mode", "") x, y, w, h = self.screen_rect() for key in ["FSGS_GEOMETRY", "FSGS_WINDOW"]: if env.get(key, ""): # Already specified externally, so we just use # the existing values... pass print("using existing fullscreen window rect") else: env[key] = "{0},{1},{2},{3}".format(x, y, w, h) print("fullscreen rect:", env.get("FSGS_GEOMETRY", "")) # SDL 1.2 multi-display support. Hopefully, SDL's display # enumeration is the same as QT's. env["SDL_VIDEO_FULLSCREEN_DISPLAY"] = str(self.screen_index()) if fullscreen_mode == "window": print("using fullscreen window mode") # env["FSGS_FULLSCREEN"] = "window" env["FSGS_FULLSCREEN"] = "1" else: del env["FSGS_WINDOW"] if fullscreen_mode == "fullscreen": print("using fullscreen (legacy) mode") # env["FSGS_FULLSCREEN"] = "fullscreen" env["FSGS_FULLSCREEN"] = "2" else: print("using fullscreen desktop mode") # env["FSGS_FULLSCREEN"] = "desktop" env["FSGS_FULLSCREEN"] = "3" else: print("using window mode (no fullscreen)") env["FSGS_FULLSCREEN"] = "0" env.update(self.env) env["HOME"] = self.home.path if env_vars: env.update(env_vars) print(env) kwargs = {} if env is not None: kwargs["env"] = env if cwd is not None: kwargs["cwd"] = cwd else: kwargs["cwd"] = self.cwd.path if windows: kwargs["close_fds"] = True print(" ".join(args)) current_task.set_progress( "Starting {emulator}".format(emulator=emulator)) # process = subprocess.Popen(*args, **kwargs) return emulator.popen(args, **kwargs)
def configure(self): self.configure_romset() self.default_xml = [ """\ufeff<?xml version="1.0"?> <!-- This file is autogenerated; comments and unknown tags will be stripped --> <mameconfig version="10"> <system name="default">\n""" ] self.game_xml = [ """\ufeff<?xml version="1.0"?> <!-- This file is autogenerated; comments and unknown tags will be stripped --> <mameconfig version="10"> <system name="{0}">\n""".format( self.romset ) ] self.emulator.args.extend(["-skip_gameinfo"]) # state_dir = self.get_state_dir() base_save_dir = self.emulator_state_dir(self.mame_emulator_name()) emu_save_dir = base_save_dir if hasattr(self, "save_handler"): # save_dir = self.save_handler.save_dir() base_save_dir = self.save_handler.save_dir() emu_save_dir = self.save_handler.emulator_save_dir() base_save_dir = base_save_dir + os.sep emu_save_dir = emu_save_dir + os.sep emu_state_dir = self.emulator_state_dir(self.mame_emulator_name()) if hasattr(self, "save_handler"): emu_state_dir = self.save_handler.emulator_state_dir() emu_state_dir = emu_state_dir + os.sep self.cwd_dir = self.create_temp_dir("mame-cwd") self.cfg_dir = self.create_temp_dir("mame-cfg") self.roms_dir = self.create_temp_dir("mame-roms") rom_path = self.roms_dir.path assert self.romset system_rom_path = os.path.join(rom_path, self.romset) os.makedirs(system_rom_path) # for sha1, name in self.romset_files: for name, sha1 in self.romset_files: file_uri = self.fsgs.file.find_by_sha1(sha1) current_task.set_progress("Preparing ROM {name}".format(name=name)) input_stream = self.fsgs.file.open(file_uri) if input_stream is None: raise Exception("Cannot not find required ROM " + repr(name)) path = os.path.join(system_rom_path, name) with open(path, "wb") as f: f.write(input_stream.read()) # shutil.copy(self.get_game_file(), # os.path.join(rom_path, self.romset + '.zip')) # MAME uses ; as path separator on all systems, apparently try: # self.args.extend(["-rompath", self.bios_dir()]) rom_path = rom_path + ";" + self.mame_get_bios_dir() except: pass # rom_path = rom_path + ";" + os.path.dirname(self.get_game_file()) # rom_path = rom_path + os.pathsep + os.path.dirname( # self.get_game_file()) self.add_arg("-rompath", rom_path) # copy initial nvram disk, if any, to nvram dir # p, e = os.path.splitext(self.get_game_file()) # initram = p + ".nv" # if os.path.exists(initram): # shutil.copy(initram, os.path.join(state_dir, self.romset + '.nv')) game_cfg_file = os.path.join( self.cfg_dir.path, "{romset}.cfg".format(romset=self.romset) ) self.emulator.args.extend(["-cfg_directory", self.cfg_dir.path]) # self.add_arg("-memcard_directory", state_dir) # self.add_arg("-hiscore_directory", state_dir) # FIXME: What is this? self.emulator.args.extend(["-diff_directory", emu_state_dir]) self.emulator.args.extend(["-nvram_directory", emu_save_dir]) # We not not need nor want system-specific sub-directories since we # already have unique save directories per game variant. self.emulator.args.extend(["-statename", "MAME"]) self.emulator.args.extend(["-state_directory", base_save_dir]) self.emulator.args.extend( ["-snapshot_directory", self.screenshots_dir()] ) self.emulator.args.extend( ["-snapname", "{0}-%i".format(self.screenshots_name())] ) # self.change_handler = GameChangeHandler(self.cfg_dir.path) # self.change_handler.init( # os.path.join(self.get_state_dir(), "cfg")) self.configure_input() self.configure_video() self.game_xml.append(" </system>\n") self.game_xml.append("</mameconfig>\n") with open(game_cfg_file, "wb") as f: f.write("".join(self.game_xml).encode("UTF-8")) print("") print("") print("".join(self.game_xml)) print("") print("") self.default_xml.append(" </system>\n") self.default_xml.append("</mameconfig>\n") with open(os.path.join(self.cfg_dir.path, "default.cfg"), "wb") as f: f.write("".join(self.default_xml).encode("UTF-8")) print("") print("") print("".join(self.default_xml)) print("") print("") if self.use_doubling(): self.emulator.args.extend(["-prescale", "2"]) if self.use_smoothing(): self.emulator.args.append("-filter") else: self.emulator.args.append("-nofilter") cheats_file_path = mame_cheat_file.path if not os.path.exists(cheats_file_path): # Data/MAME/Cheat/cheat.7z not found, trying plugin instead. cheats_file_path = self.cheats_file("MAME/cheat.7z") if cheats_file_path: print("[MAME] Using cheats file:".format(cheats_file_path)) self.emulator.args.extend( ["-cheatpath", cheats_file_path[:-3]] ) # Stripping .7z self.emulator.args.extend(["-cheat"]) else: print("[MAME] No cheats file found") self.emulator.args.append(self.romset) self.mame_configure()
def prepare_hard_drives(self): print("LaunchHandler.prepare_hard_drives") current_task.set_progress(gettext("Preparing hard drives...")) # self.on_progress(gettext("Preparing hard drives...")) for i in range(0, Amiga.MAX_HARD_DRIVES): self.prepare_hard_drive(i)
def prepare_roms(self): print("LaunchHandler.prepare_roms") current_task.set_progress(gettext("Preparing kickstart ROMs...")) amiga_model = self.config.get("amiga_model", "A500") model_config = Amiga.get_model_config(amiga_model) roms = [("kickstart_file", model_config["kickstarts"])] if self.config["kickstart_ext_file"] or model_config["ext_roms"]: # not all Amigas have extended ROMs roms.append(("kickstart_ext_file", model_config["ext_roms"])) if amiga_model.lower() == "cd32/fmv": roms.append(("fvm_rom", [CD32_FMV_ROM])) if self.config["graphics_card"].lower().startswith("picasso-iv"): roms.append(("graphics_card_rom", [PICASSO_IV_74_ROM])) if self.config["accelerator"].lower() == "cyberstorm-ppc": roms.append(("accelerator_rom", ["cyberstormppc.rom"])) if self.config["freezer_cartridge"] == "action-replay-2": # Ideally, we would want to recognize ROMs based on zeroing the # first four bytes, but right now we simply recognize a common # additional version. freezer_cartridge_rom isn't a real option, # we just want to copy the rom file and let FS-UAE find it roms.append( ( "[freezer_cartridge]", [ ACTION_REPLAY_MK_II_2_14_ROM.sha1, ACTION_REPLAY_MK_II_2_14_MOD_ROM.sha1, ], ) ) elif self.config["freezer_cartridge"] == "action-replay-3": roms.append( ( "[freezer_cartridge]", [ ACTION_REPLAY_MK_III_3_17_ROM.sha1, ACTION_REPLAY_MK_III_3_17_MOD_ROM.sha1, ], ) ) use_temp_kickstarts_dir = False for config_key, default_roms in roms: print("[ROM]", config_key, default_roms) src = self.config[config_key] print("[ROM]", src) if not src: for sha1 in default_roms: print("[ROM] Trying", sha1) if is_sha1(sha1): rom_src = self.fsgs.file.find_by_sha1(sha1) if rom_src: src = rom_src print("[ROM] Found", rom_src) break else: # roms_dir = FSGSDirectories.get_kickstarts_dir() # src = os.path.join(roms_dir, sha1) # if os.path.exists(src): # break # loop up file in roms dir instead src = sha1 elif src == "internal": continue elif src: src = Paths.expand_path(src) if not src: raise TaskFailure( gettext( "Did not find required Kickstart or " "ROM for {}. Wanted one of these files: {}".format( config_key, repr(default_roms) ) ) ) dest = os.path.join(self.temp_dir, os.path.basename(src)) def lookup_rom_from_src(src): parts = src.split(":", 1) if len(parts) == 2 and len(parts[0]) > 1: # src has a scheme (not a Windows drive letter). Assume # we can find this file. return src archive = Archive(src) if archive.exists(src): return src dirs = [self.fsgs.amiga.get_kickstarts_dir()] for dir_ in dirs: path = os.path.join(dir_, src) print("[ROM] Checking", repr(path)) archive = Archive(path) if archive.exists(path): return path return None org_src = src src = lookup_rom_from_src(src) if not src and org_src == "cyberstormppc.rom": src = lookup_rom_from_src( "ralphschmidt-cyberstorm-ppc-4471.rom" ) if not src: for ( dir_ ) in FSGSDirectories.get_amiga_forever_directories(): path = os.path.join( dir_, "Shared", "rom", "ralphschmidt-cyberstorm-ppc-4471.rom", ) if os.path.exists(path): src = path print("[ROM] Found", path) break else: print("[ROM] Trying", path) stream = None # FIXME: prepare_roms should be rewritten, it's kind of crap. # Rom patching and decryption should be handled differently. Should # use file database filters, and decryption via rom.key should only # be supported when using uncompressed files directly on disk. if not src or not os.path.exists(src): try: stream = self.fsgs.file.open(src) if stream is None: raise FileNotFoundError(src) except FileNotFoundError: raise TaskFailure( gettext( "Cannot find required ROM " "file: {name}".format(name=repr(org_src)) ) ) with open(dest, "wb") as f: if stream: print("[ROM] From stream => {}".format(dest)) rom = {} rom["data"] = stream.read() rom["sha1"] = hashlib.sha1(rom["data"]).hexdigest() ROMManager.patch_rom(rom) f.write(rom["data"]) else: archive = Archive(src) ROMManager.decrypt_archive_rom(archive, src, file=f) if use_temp_kickstarts_dir: self.config[config_key] = os.path.basename(src) else: self.config[config_key] = dest if use_temp_kickstarts_dir: self.config["kickstarts_dir"] = self.temp_dir
def prepare_hard_drives(self): print("LaunchHandler.prepare_hard_drives") current_task.set_progress(gettext("Preparing hard drives...")) # self.on_progress(gettext("Preparing hard drives...")) for i in range(0, 10): self.prepare_hard_drive(i)
def configure(self): self.configure_romset() self.default_xml = [ """\ufeff<?xml version="1.0"?> <!-- This file is autogenerated; comments and unknown tags will be stripped --> <mameconfig version="10"> <system name="default">\n""" ] self.game_xml = [ """\ufeff<?xml version="1.0"?> <!-- This file is autogenerated; comments and unknown tags will be stripped --> <mameconfig version="10"> <system name="{0}">\n""".format(self.romset) ] self.emulator.args.extend(["-skip_gameinfo"]) # state_dir = self.get_state_dir() base_save_dir = self.emulator_state_dir(self.mame_emulator_name()) emu_save_dir = base_save_dir if hasattr(self, "save_handler"): # save_dir = self.save_handler.save_dir() base_save_dir = self.save_handler.save_dir() emu_save_dir = self.save_handler.emulator_save_dir() base_save_dir = base_save_dir + os.sep emu_save_dir = emu_save_dir + os.sep emu_state_dir = self.emulator_state_dir(self.mame_emulator_name()) if hasattr(self, "save_handler"): emu_state_dir = self.save_handler.emulator_state_dir() emu_state_dir = emu_state_dir + os.sep self.cwd_dir = self.create_temp_dir("mame-cwd") self.cfg_dir = self.create_temp_dir("mame-cfg") self.roms_dir = self.create_temp_dir("mame-roms") rom_path = self.roms_dir.path assert self.romset system_rom_path = os.path.join(rom_path, self.romset) os.makedirs(system_rom_path) # for sha1, name in self.romset_files: for name, sha1 in self.romset_files: file_uri = self.fsgs.file.find_by_sha1(sha1) current_task.set_progress("Preparing ROM {name}".format(name=name)) input_stream = self.fsgs.file.open(file_uri) if input_stream is None: raise Exception("Cannot not find required ROM " + repr(name)) path = os.path.join(system_rom_path, name) with open(path, "wb") as f: f.write(input_stream.read()) # shutil.copy(self.get_game_file(), # os.path.join(rom_path, self.romset + '.zip')) # MAME uses ; as path separator on all systems, apparently try: # self.args.extend(["-rompath", self.bios_dir()]) rom_path = rom_path + ";" + self.mame_get_bios_dir() except: pass # rom_path = rom_path + ";" + os.path.dirname(self.get_game_file()) # rom_path = rom_path + os.pathsep + os.path.dirname( # self.get_game_file()) self.add_arg("-rompath", rom_path) # copy initial nvram disk, if any, to nvram dir # p, e = os.path.splitext(self.get_game_file()) # initram = p + ".nv" # if os.path.exists(initram): # shutil.copy(initram, os.path.join(state_dir, self.romset + '.nv')) game_cfg_file = os.path.join(self.cfg_dir.path, "{romset}.cfg".format(romset=self.romset)) self.emulator.args.extend(["-cfg_directory", self.cfg_dir.path]) # self.add_arg("-memcard_directory", state_dir) # self.add_arg("-hiscore_directory", state_dir) # FIXME: What is this? self.emulator.args.extend(["-diff_directory", emu_state_dir]) self.emulator.args.extend(["-nvram_directory", emu_save_dir]) # We not not need nor want system-specific sub-directories since we # already have unique save directories per game variant. self.emulator.args.extend(["-statename", "MAME"]) self.emulator.args.extend(["-state_directory", base_save_dir]) self.emulator.args.extend( ["-snapshot_directory", self.screenshots_dir()]) self.emulator.args.extend( ["-snapname", "{0}-%i".format(self.screenshots_name())]) # self.change_handler = GameChangeHandler(self.cfg_dir.path) # self.change_handler.init( # os.path.join(self.get_state_dir(), "cfg")) self.configure_input() self.configure_video() self.game_xml.append(" </system>\n") self.game_xml.append("</mameconfig>\n") with open(game_cfg_file, "wb") as f: f.write("".join(self.game_xml).encode("UTF-8")) print("") print("".join(self.game_xml)) self.default_xml.append(" </system>\n") self.default_xml.append("</mameconfig>\n") with open(os.path.join(self.cfg_dir.path, "default.cfg"), "wb") as f: f.write("".join(self.default_xml).encode("UTF-8")) print("") print("".join(self.default_xml)) print("") if self.use_doubling(): self.emulator.args.extend(["-prescale", "2"]) if self.use_smoothing(): self.emulator.args.append("-filter") else: self.emulator.args.append("-nofilter") cheats_file_path = mame_cheat_file.path if not os.path.exists(cheats_file_path): # Data/MAME/Cheat/cheat.7z not found, trying plugin instead. cheats_file_path = self.cheats_file("MAME/cheat.7z") if cheats_file_path: print("[MAME] Using cheats file:".format(cheats_file_path)) self.emulator.args.extend(["-cheatpath", cheats_file_path[:-3]]) # Stripping .7z self.emulator.args.extend(["-cheat"]) else: print("[MAME] No cheats file found") self.emulator.args.append(self.romset) self.mame_configure()
def start_emulator( self, emulator, args=None, env_vars=None, executable=None, cwd=None): # if "/" in emulator: # if not executable: # executable = self.find_emulator_executable(emulator) # if not executable: # emulator = emulator.split("/")[-1] # # if not executable: # executable = self.find_emulator_executable("fs-" + emulator) # if not executable: # executable = self.find_emulator_executable(emulator) # # if not executable: # raise Exception("could not find executable for " + emulator) args = [] args.extend(self.args) print(repr(args)) if "SDL_VIDEODRIVER" in os.environ: print("SDL_VIDEODRIVER was present in environment, removing!") del os.environ["SDL_VIDEODRIVER"] env = os.environ.copy() FSUAE.add_environment_from_settings(env) if self.use_fullscreen(): fullscreen_mode = self.config.get("fullscreen_mode", "") x, y, w, h = self.screen_rect() for key in ["FSGS_GEOMETRY", "FSGS_WINDOW"]: if env.get(key, ""): # Already specified externally, so we just use # the existing values... pass print("using existing fullscreen window rect") else: env[key] = "{0},{1},{2},{3}".format(x, y, w, h) print("fullscreen rect:", env.get("FSGS_GEOMETRY", "")) # SDL 1.2 multi-display support. Hopefully, SDL's display # enumeration is the same as QT's. env["SDL_VIDEO_FULLSCREEN_DISPLAY"] = str(self.screen_index()) if fullscreen_mode == "window": print("using fullscreen window mode") # env["FSGS_FULLSCREEN"] = "window" env["FSGS_FULLSCREEN"] = "1" else: del env["FSGS_WINDOW"] if fullscreen_mode == "fullscreen": print("using fullscreen (legacy) mode") # env["FSGS_FULLSCREEN"] = "fullscreen" env["FSGS_FULLSCREEN"] = "2" else: print("using fullscreen desktop mode") # env["FSGS_FULLSCREEN"] = "desktop" env["FSGS_FULLSCREEN"] = "3" else: print("using window mode (no fullscreen)") env["FSGS_FULLSCREEN"] = "0" env.update(self.env) env["HOME"] = self.home.path if env_vars: env.update(env_vars) print(env) kwargs = {} if env is not None: kwargs["env"] = env if cwd is not None: kwargs["cwd"] = cwd else: kwargs["cwd"] = self.cwd.path if windows: kwargs["close_fds"] = True print(" ".join(args)) current_task.set_progress( "Starting {emulator}".format(emulator=emulator)) # process = subprocess.Popen(*args, **kwargs) return emulator.popen(args, **kwargs)