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)
예제 #2
0
    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
예제 #3
0
    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
예제 #4
0
    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
예제 #5
0
    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
예제 #6
0
    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
예제 #7
0
 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)
예제 #8
0
    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"
예제 #10
0
    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)
예제 #11
0
    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"
예제 #12
0
    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))
예제 #13
0
    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)
예제 #14
0
    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
예제 #15
0
    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)
예제 #16
0
    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
예제 #19
0
 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)
예제 #20
0
    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()
예제 #21
0
    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)