def update(self):
     amiga = Amiga.get_model_config(self.model)
     for sha1 in amiga["kickstarts"]:
         if fsgs.file.find_by_sha1(sha1):
             self.icon.set_image(self.ok_image)
             return
     self.icon.set_image(self.na_image)
예제 #2
0
    def update_kickstart_in_config_dict(config_dict):
        print("update_kickstart_in_config")
        model = config_dict.setdefault("amiga_model",
                                       default_config["amiga_model"])

        kickstart_file = config_dict.setdefault("kickstart_file", "")
        if kickstart_file:
            config_dict["x_kickstart_file"] = config_dict["kickstart_file"]
            if kickstart_file == "internal":
                config_dict["x_kickstart_file_sha1"] = Amiga.INTERNAL_ROM_SHA1
            else:
                # FIXME: set checksum
                pass
        else:
            checksums = Amiga.get_model_config(model)["kickstarts"]
            for checksum in checksums:
                path = fsgs.file.find_by_sha1(checksum)
                if path:
                    config_dict["x_kickstart_file"] = path
                    config_dict["x_kickstart_file_sha1"] = checksum
                    break
            else:
                print("WARNING: no suitable kickstart file found")
                config_dict["x_kickstart_file"] = ""
                config_dict["x_kickstart_file_sha1"] = Amiga.INTERNAL_ROM_SHA1

        if config_dict.setdefault("kickstart_ext_file", ""):
            config_dict["x_kickstart_ext_file"] = config_dict[
                "kickstart_ext_file"]
            # FIXME: set checksum
        else:
            checksums = Amiga.get_model_config(model)["ext_roms"]
            if len(checksums) == 0:
                config_dict["x_kickstart_ext_file"] = ""
                config_dict["x_kickstart_ext_file_sha1"] = ""
            else:
                for checksum in checksums:
                    path = fsgs.file.find_by_sha1(checksum)
                    if path:
                        config_dict["x_kickstart_ext_file"] = path
                        config_dict["x_kickstart_ext_file_sha1"] = checksum
                        break
                else:
                    # print("WARNING: no suitable kickstart ext file found")
                    config_dict["x_kickstart_ext_file"] = ""
                    config_dict["x_kickstart_ext_file_sha1"] = ""
    def update_media_type(self):
        if self.__platform in AMIGA_PLATFORMS:
            self.set_cd_mode(Amiga.is_cd_based(get_config(self)))
        elif self.__platform in [Platform.C64]:
            if self._c64_model == C64_MODEL_C64C_1541_II:
                self.set_mode(self.FLOPPY_MODE)
            else:
                self.set_mode(self.TAPE_MODE)
        elif self.__platform in [Platform.CPC]:
            if self._cpc_model == CPC_MODEL_464:
                self.set_mode(self.TAPE_MODE)
            else:
                self.set_mode(self.FLOPPY_MODE)
        elif self.__platform in [Platform.DOS]:
            self.set_mode(self.FLOPPY_MODE)
        elif self.__platform in [Platform.PSX]:
            self.set_mode(self.CD_MODE)
        elif self.__platform in [Platform.ST]:
            self.set_mode(self.FLOPPY_MODE)
        elif self.__platform in [Platform.SPECTRUM]:
            if self._spectrum_model == SPECTRUM_MODEL_PLUS3:
                self.set_mode(self.FLOPPY_MODE)
            else:
                self.set_mode(self.TAPE_MODE)
        else:
            self.set_mode(self.CARTRIDGE_MODE)

        if self._main:
            if self.__platform == Platform.A7800:
                self.selectors[1].hide()
                self._a78_header_widget.show()
                self._command_widget.hide()
                self._ines_header_widget.hide()
            elif self.__platform in [
                    Platform.CPC,
                    Platform.DOS,
                    Platform.SPECTRUM,
            ]:
                self.selectors[1].hide()
                self._a78_header_widget.hide()
                self._command_widget.show()
                self._ines_header_widget.hide()
            elif self.__platform == Platform.NES:
                # if self.selectors[1].is_visible():
                self.selectors[1].hide()
                self._a78_header_widget.hide()
                self._command_widget.hide()
                self._ines_header_widget.show()
            else:
                # if not self.selectors[1].is_visible():
                self.selectors[1].show()
                self._command_widget.hide()
                self._a78_header_widget.hide()
                self._ines_header_widget.hide()
            self.layout.update()
    def kickstart_startup_scan(cls):
        if cls._kickstart_scanned:
            return
        cls._kickstart_scanned = True

        print("kickstart_startup_scan")
        kickstarts_dir = FSGSDirectories.get_kickstarts_dir()
        if LauncherSettings.get("kickstarts_dir_mtime"
                                ) == cls.get_dir_mtime_str(kickstarts_dir):
            print("... mtime not changed")
        else:
            file_database = FileDatabase.get_instance()
            print("... database.find_local_roms")
            local_roms = file_database.find_local_roms()
            print("... walk kickstarts_dir")
            for dir_path, dir_names, file_names in os.walk(kickstarts_dir):
                for file_name in file_names:
                    if not file_name.lower().endswith(
                            ".rom") and not file_name.lower().endswith(".bin"):
                        continue
                    path = Paths.join(dir_path, file_name)
                    if path in local_roms:
                        local_roms[path] = None
                        # already exists in database
                        continue
                    print("[startup] adding kickstart", path)
                    ROMManager.add_rom_to_database(path, file_database)
            print(local_roms)
            for path, file_id in local_roms.items():
                if file_id is not None:
                    print("[startup] removing kickstart", path)
                    file_database.delete_file(id=file_id)
            print("... commit")
            file_database.commit()
            LauncherSettings.set("kickstarts_dir_mtime",
                                 cls.get_dir_mtime_str(kickstarts_dir))

        amiga = Amiga.get_model_config("A500")
        for sha1 in amiga["kickstarts"]:
            if fsgs.file.find_by_sha1(sha1=sha1):
                break
        else:
            file_database = FileDatabase.get_instance()
            cls.amiga_forever_kickstart_scan()
            file_database.commit()
    def on_sub_model_changed(self):
        print("ModelGroup.on_sub_model_change\n")
        if self.sub_model_updating:
            print("sub model list is currently updating")
            return
        index = self.sub_model_choice.index()
        # if index == 0:
        #     # The default model (A500) can be specified with the empty string
        #     model = ""
        # else:
        model = self.model_ids[self.model_choice.index()]
        sub_model = self.sub_model_ids[index]
        config = get_config(self)
        if sub_model:
            config.set("amiga_model", model + "/" + sub_model)
        else:
            config.set("amiga_model", model)

        if Amiga.is_cd_based(config):
            FloppyManager.clear_all(config=config)
        else:
            CDManager.clear_all(config=config)
예제 #6
0
def prepare_amiga_roms(config: ConfigType, files: FilesType):
    amiga_model = config.get("amiga_model", "A500")
    # To avoid circular import
    from fsgamesys.amiga.amiga import Amiga

    model_config = Amiga.get_model_config(amiga_model)

    roms = [("kickstart_file", model_config["kickstarts"])]
    if 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]))

    for config_key, rom_sha1_list in roms:
        assert len(rom_sha1_list) == 1
        sha1 = rom_sha1_list[0]
        rom_name = sha1[:8].upper() + ".rom"
        # rom_path = f"ROMs/{rom_name}"
        # rom_path = f"{rom_name}"
        rom_path = rom_name
        files[rom_path] = {"sha1": sha1}
        config[config_key] = os.path.join(config["run_dir"], rom_path)
예제 #7
0
    def prepare(self):
        print("FSUAEAmigaDriver.prepare")

        if not self.options["joystick_port_0_mode"]:
            self.options["joystick_port_0_mode"] = "mouse"
        if not self.options["joystick_port_1_mode"]:
            if self.options["amiga_model"].startswith("CD32"):
                self.options["joystick_port_1_mode"] = "cd32 gamepad"
            else:
                self.options["joystick_port_1_mode"] = "joystick"
        if not self.options["joystick_port_2_mode"]:
            self.options["joystick_port_2_mode"] = "none"
        if not self.options["joystick_port_3_mode"]:
            self.options["joystick_port_3_mode"] = "none"

        from launcher.devicemanager import DeviceManager

        devices = DeviceManager.get_devices_for_ports(self.options)
        for port in range(4):
            key = "joystick_port_{0}".format(port)
            if not self.options[key]:
                # key not set, use calculated default value
                self.options[key] = devices[port].id

        for remove_key in [
                "database_username",
                "database_password",
                "database_username",
                "database_email",
                "database_auth",
                "device_id",
        ]:
            if remove_key in self.options:
                del self.options[remove_key]

        # overwrite netplay config

        if self.options["__netplay_host"]:
            self.options["netplay_server"] = self.options["__netplay_host"]
        if self.options["__netplay_password"]:
            self.options["netplay_password"] = self.options[
                "__netplay_password"]
        if self.options["__netplay_port"]:
            self.options["netplay_port"] = self.options["__netplay_port"]

        # copy actual kickstart options from x_ options

        self.options["kickstart_file"] = self.options["x_kickstart_file"]
        self.options["kickstart_ext_file"] = self.options[
            "x_kickstart_ext_file"]

        # FIXME: Temporarily disabled
        # if not self.options["kickstart_file"]:
        #     # Warning will have been shown on the status bar
        #    self.options["kickstart_file"] = "internal"

        # Copy default configuration values from model defaults. The main
        # purpose of this is to let the launch code know about implied defaults
        # so it can for example configure correct ROM files for expansions.

        model_config = Amiga.get_current_config(self.options)
        for key, value in model_config["defaults"].items():
            if not self.options[key]:
                self.options[key] = value

        # make sure FS-UAE does not load other config files (Host.fs-uae)
        self.options["end_config"] = "1"
        # Make FS-UAE check that version matches (except for development)
        if VERSION != "9.8.7dummy":
            self.options[Option.EXPECT_VERSION] = VERSION

        if self.options["__netplay_game"]:
            print("\nfixing config for netplay game")
            for key in [x for x in config.keys() if x.startswith("uae_")]:
                print("* removing option", key)
                del self.options[key]

        # self.temp_dir = self.fsgc.temp_dir("amiga")

        # self.change_handler = GameChangeHandler(self.temp_dir)

        # self.firmware_dir = self.prepare_firmware("Amiga Firmware")
        # config = self.fsgc.config.copy()

        model = self.options[Option.AMIGA_MODEL]
        if model.startswith("CD32"):
            platform = "CD32"
        elif model == "CDTV":
            platform = "CDTV"
        else:
            platform = "Amiga"
        # name = Settings.get("config_name")
        # name = self.fsgc.game.name

        # uuid = Config.get("x_game_uuid")
        # uuid = None

        from fsgamesys.saves import SaveHandler

        # save_state_handler = SaveHandler(self.fsgc, self.get_name(), platform)
        save_state_handler = SaveHandler(
            self.fsgc,
            self.options["config_name"],
            platform,
            options=self.options,
        )

        print(
            "[INPUT] joystick_port_1",
            self.options["joystick_port_1"],
            "->",
            self.ports[0].device_id or "none",
        )
        print(
            "[INPUT] joystick_port_0",
            self.options["joystick_port_0"],
            "->",
            self.ports[1].device_id or "none",
        )
        # self.options["joystick_port_1"] = self.ports[0].device_id or "none"
        # self.options["joystick_port_0"] = self.ports[1].device_id or "none"

        self.launch_handler = LaunchHandler(
            self.fsgc,
            self.get_name(),
            self.options,
            save_state_handler,
            temp_dir=self.filesdir.path,
        )

        # self.change_handler.init(self.fsgc.get_game_state_dir(),
        #         ignore=["*.uss", "*.sdf"])

        # self.launch_handler.config["joystick_port_0"] = \
        #         self.inputs[1].device_id
        # self.launch_handler.config["joystick_port_1"] = \
        #         self.inputs[0].device_id

        if self.use_fullscreen():
            self.launch_handler.config["fullscreen"] = "1"
            if not self.launch_handler.config.get("fullscreen_mode", ""):
                # Check if fullscreen mode is overridden by temporary setting.
                if self.options.get("__fullscreen_mode"):
                    self.launch_handler.config[
                        "fullscreen_mode"] = self.options.get(
                            "__fullscreen_mode")
            if self.options.get("__arcade"):
                # Remove window border when launched from FS-UAE Arcade in
                # order to reduce flickering
                self.launch_handler.config["window_border"] = "0"
                # Set fade out duration to 500, if not already specified.
                if not self.launch_handler.config.get("fade_out_duration", ""):
                    self.launch_handler.config["fade_out_duration"] = "500"
        else:
            self.launch_handler.config["fullscreen"] = "0"

        self.launch_handler.prepare()

        run_dir = self.filesdir.path
        from fsgamesys.amiga.amigaconfig import AmigaConfig

        # config = AmigaConfig(self.options)
        self.options = self.launch_handler.config.copy()

        self.options["run_dir"] = run_dir

        files = prepare_amiga(self.options)

        # FIXME: Move function
        def file_sha1_to_stream(sha1):
            stream = self.fsgs.file.open("sha1://{0}".format(sha1))
            if stream is not None:
                return stream

            # FIXME: Move import
            from fsgamesys.plugins.pluginmanager import PluginManager

            path = PluginManager.instance().find_file_by_sha1(sha1)
            if path:
                return open(path, "rb")
                # dst = path
                # dst_partial = dst + ".partial"
                # sha1_obj = hashlib.sha1()
                # with open(src, "rb") as fin:
                #     with open(dst_partial, "wb") as fout:
                #         while True:
                #             data = fin.read(65536)
                #             if not data:
                #                 break
                #             fout.write(data)
                #             sha1_obj.update(data)
                # if sha1_obj.hexdigest() != sha1:
                #     raise Exception("File from plugin does not match SHA-1")
                # os.rename(dst_partial, dst)
                # return

                # pass
            return None

        install_files(files, run_dir, file_sha1_to_stream)

        config = ConfigWriter(self.config).create_fsuae_config()
        config_file = self.temp_file("Config.fs-uae").path

        with open(config_file, "w", encoding="UTF-8") as f:
            for line in config:
                print(line)
                f.write(line + "\n")
        self.emulator.args.extend([config_file])
    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