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)
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
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 [], []
def load(game): errors = [] rom = retro.get_romfile_path(game) emu = retro.RetroEmulator(rom) emu.step() del emu gc.collect() return [], errors
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
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
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