Пример #1
0
def pytest_collection_modifyitems(items):
    def test(*args, **kwargs):
        print(kwargs)
        return False

    for item in items:
        if item.originalname in ('test_load', 'test_rom', 'test_state',
                                 'test_hash'):
            for key in item.keywords.keys():
                if '[' + key + ']' not in item.nodeid:
                    continue
                try:
                    retro.get_romfile_path(key.replace('_', '-'))
                except FileNotFoundError:
                    item.add_marker(pytest.mark.skip)
Пример #2
0
def state(game):
    errors = []
    states = retro.list_states(game)
    if not states:
        return [], []

    rom = retro.get_romfile_path(game)
    path = retro.get_game_path(game)
    emu = retro.RetroEmulator(rom)
    for statefile in states:
        try:
            with gzip.open(os.path.join(path, statefile + '.state'),
                           'rb') as fh:
                state = fh.read()
        except (IOError, zlib.error):
            errors.append((game, 'state failed to decode: %s' % statefile))
            continue

        emu.set_state(state)
        emu.step()

    del emu
    gc.collect()

    return [], errors
Пример #3
0
def verify_rom(game):
    try:
        rom = retro.get_romfile_path(game)
    except FileNotFoundError:
        return [], [(game, 'ROM file missing')]

    if game.endswith('-Genesis'):
        return verify_genesis(game)

    return [], []
Пример #4
0
def load(game):
    errors = []
    rom = retro.get_romfile_path(game)
    emu = retro.RetroEmulator(rom)

    emu.step()

    del emu
    gc.collect()

    return [], errors
Пример #5
0
def verify_genesis(game):
    warnings = []
    errors = []
    whitelist = {}
    rom = retro.get_romfile_path(game)
    if not rom.endswith('.md'):
        errors.append((game, 'invalid extension for %s' % rom))
    if game in whitelist:
        return [], []
    with open(rom, 'rb') as f:
        header = f.read(768)
    if header[0x100:0x105] not in (b'SEGA ', b' SEGA'):
        errors.append((game, 'invalid genesis rom'))
    return warnings, errors
Пример #6
0
def verify_hash(game):
    errors = []
    gamedir = retro.get_game_path(game)
    rom = retro.get_romfile_path(game)
    system = retro.get_romfile_system(rom)
    with open(os.path.join(gamedir, 'rom.sha')) as f:
        expected_shas = f.read().strip().split('\n')
    with open(rom, 'rb') as f:
        if system == 'Nes':
            # Chop off header for checksum
            f.read(16)
        real_sha = hashlib.sha1(f.read()).hexdigest()
    if real_sha not in expected_shas:
        errors.append((game, 'sha mismatch'))
    return [], errors
Пример #7
0
    def __init__(self,
                 game,
                 state=retro.STATE_DEFAULT,
                 scenario=None,
                 info=None,
                 use_restricted_actions=retro.ACTIONS_FILTERED,
                 record=False):
        if not hasattr(self, 'spec'):
            self.spec = None
        self.img = None
        self.viewer = None
        self.gamename = game
        self.statename = state

        game_path = retro.get_game_path(game)
        rom_path = retro.get_romfile_path(game)
        metadata_path = os.path.join(game_path, 'metadata.json')

        if state == retro.STATE_NONE:
            self.initial_state = None
        elif state == retro.STATE_DEFAULT:
            self.initial_state = None
            try:
                with open(metadata_path) as f:
                    metadata = json.load(f)
                if 'default_state' in metadata:
                    with gzip.open(
                            os.path.join(game_path, metadata['default_state'])
                            + '.state', 'rb') as fh:
                        self.initial_state = fh.read()
            except (IOError, json.JSONDecodeError):
                pass
        else:
            if not state.endswith('.state'):
                state += '.state'

            with gzip.open(os.path.join(game_path, state), 'rb') as fh:
                self.initial_state = fh.read()

        self.data = GameData()

        if info is None:
            info = 'data'

        if info.endswith('.json'):
            # assume it's a path
            info_path = info
        else:
            info_path = os.path.join(game_path, info + '.json')

        if scenario is None:
            scenario = 'scenario'

        if scenario.endswith('.json'):
            # assume it's a path
            scenario_path = scenario
        else:
            scenario_path = os.path.join(game_path, scenario + '.json')

        system = retro.get_romfile_system(rom_path)

        # We can't have more than one emulator per process. Before creating an
        # emulator, ensure that unused ones are garbage-collected
        gc.collect()
        self.em = retro.RetroEmulator(rom_path)
        self.em.configure_data(self.data)
        self.em.step()
        img = self.em.get_screen()

        core = retro.get_system_info(system)
        self.BUTTONS = core['buttons']
        self.NUM_BUTTONS = len(self.BUTTONS)
        self.BUTTON_COMBOS = self.data.valid_actions()

        try:
            assert self.data.load(
                info_path,
                scenario_path), 'Failed to load info (%s) or scenario (%s)' % (
                    info_path, scenario_path)
        except Exception:
            del self.em
            raise

        if use_restricted_actions == retro.ACTIONS_DISCRETE:
            combos = 1
            for combo in self.BUTTON_COMBOS:
                combos *= len(combo)
            self.action_space = gym.spaces.Discrete(combos)
        elif use_restricted_actions == retro.ACTIONS_MULTI_DISCRETE:
            self.action_space = gym.spaces.MultiDiscrete([
                len(combos) if gym_version >= (0, 9, 6) else
                (0, len(combos) - 1) for combos in self.BUTTON_COMBOS
            ])
        else:
            self.action_space = gym.spaces.MultiBinary(self.NUM_BUTTONS)

        kwargs = {}
        if gym_version >= (0, 9, 6):
            kwargs['dtype'] = np.uint8
        self.observation_space = gym.spaces.Box(low=0,
                                                high=255,
                                                shape=img.shape,
                                                **kwargs)

        self.use_restricted_actions = use_restricted_actions
        self.movie = None
        self.movie_id = 0
        self.movie_path = None
        if record is True:
            self.auto_record()
        elif record is not False:
            self.auto_record(record)
        self.seed()
        if gym_version < (0, 9, 6):
            self._seed = self.seed
            self._step = self.step
            self._reset = self.reset
            self._render = self.render
            self._close = self.close