示例#1
0
def main():
    argv = parser.parse_args()
    if argv.no_logger:
        logger.disabled = True
    else:
        addconsolehandler()

    if argv.record_input and not argv.loadstate:
        logger.warning(
            "To replay input consistently later, it is required to load a state at boot. This will be"
            "embedded into the .replay file.")

    # Start PyBoy and run loop
    pyboy = PyBoy(
        argv.ROM,
        window_type=argv.window,
        window_scale=argv.scale,
        bootrom_file=argv.bootrom,
        autopause=argv.autopause,
        debugging=argv.debug,
        profiling=argv.profiling,
        record_input=argv.record_input is not None,
        disable_input=argv.no_input,
        enable_rewind=argv.rewind,
    )

    if argv.loadstate is not None:
        if argv.loadstate != '':
            # Use filepath given
            with open(argv.loadstate, 'rb') as f:
                pyboy.load_state(f)
        else:
            # Guess filepath from ROM path
            with open(argv.ROM + ".state", 'rb') as f:
                pyboy.load_state(f)

    while not pyboy.tick():
        pass

    pyboy.stop()

    if argv.profiling:
        print("\n".join(profiling_printer(pyboy._get_cpu_hitrate())))

    if argv.record_input:
        save_replay(argv.ROM, argv.loadstate, argv.record_input,
                    pyboy._get_recorded_input())
示例#2
0
def test_record_replay():
    pyboy = PyBoy(tetris_rom,
                  window_type="headless",
                  bootrom_file=utils.boot_rom,
                  record_input=True)
    pyboy.tick()
    pyboy.send_input(windowevent.PRESS_ARROW_DOWN)
    pyboy.tick()
    pyboy.send_input(windowevent.PRESS_ARROW_UP)
    pyboy.tick()
    pyboy.tick()
    pyboy.send_input(windowevent.PRESS_ARROW_DOWN)
    pyboy.tick()
    pyboy.send_input(windowevent.PRESS_ARROW_UP)
    pyboy.tick()

    events = pyboy._get_recorded_input()
    assert len(
        events
    ) == 4, "We assumed only 4 frames were recorded, as frames without events are skipped."
    frame_no, keys, frame_data = events[0]
    assert frame_no == 1, "We inserted the key on the second frame"
    assert keys[
        0] == windowevent.PRESS_ARROW_DOWN, "Check we have the right keypress"
    assert sum(
        base64.b64decode(frame_data)
    ) / 0xFF == 144 * 160 * 3, "Frame does not contain 160x144 of RGB data"

    pyboy.stop(save=False)

    test_file = 'test.replay'
    main.save_replay(tetris_rom, None, test_file, events)
    with open(test_file, 'rb') as f:
        m = hashlib.sha256()
        m.update(f.read())
        digest = m.digest()

    os.remove(test_file)

    assert digest == b'\xd1\xe2\x13B\xf0$\xaa\xaa\xe2\xf2\xf3Iz\x9aj\x98\xc8^\xc4J:\x08\x1d\xf4n}\x80\x08o\x03)\xda', \
        "The replay did not result in the expected output"
示例#3
0
def replay(ROM,
           replay,
           window='headless',
           verify=True,
           record_gif=None,
           gif_destination=None,
           enable_rewind=False,
           overwrite=False):
    with open(replay, 'rb') as f:
        recorded_input, b64_romhash, b64_state = json.loads(
            zlib.decompress(f.read()).decode('ascii'))

    verify_rom_hash(ROM, b64_romhash)
    state_data = io.BytesIO(base64.b64decode(
        b64_state.encode('utf8'))) if b64_state is not None else None

    pyboy = PyBoy(ROM,
                  window_type=window,
                  bootrom_file=utils.boot_rom,
                  disable_input=True,
                  hide_window=False,
                  enable_rewind=enable_rewind,
                  record_input=(RESET_REPLAYS
                                and window in ['SDL2', 'headless', 'OpenGL']))
    pyboy.set_emulation_speed(0)
    if state_data is not None:
        pyboy.load_state(state_data)

    # Filters out the blacklisted events
    recorded_input = list(
        map(
            lambda event_tuple:
            (event_tuple[0],
             list(filter(lambda x: x not in event_filter, event_tuple[1])),
             event_tuple[2]), recorded_input))

    frame_count = 0
    next_event = recorded_input.pop(0)

    recording = False
    while recorded_input != []:
        if record_gif is not None and (frame_count in record_gif):
            pyboy.send_input(windowevent.SCREEN_RECORDING_TOGGLE)
            recording ^= True

        if next_event[0] == frame_count:
            for e in next_event[1]:
                pyboy.send_input(e)

                if verify and not overwrite:
                    verify_screen_image_np(
                        pyboy, base64.b64decode(next_event[2].encode('utf8')))
            next_event = recorded_input.pop(0)
        frame_count += 1
        # if frame_count % 30 == 0:
        #     print(frame_count)
        #     breakpoint()
        pyboy.tick()

    # If end-frame in record_gif is high than frame counter
    # if recording:
    #     pyboy.send_input(windowevent.SCREEN_RECORDING_TOGGLE)
    #     recording ^= True

    if gif_destination:
        move_gif(pyboy.get_cartridge_title(), gif_destination)

    if overwrite:
        with open(replay, 'wb') as f:
            f.write(
                zlib.compress(
                    json.dumps((pyboy._get_recorded_input(), b64_romhash,
                                b64_state)).encode()))

    pyboy.stop(save=False)