示例#1
0
 def __init__(self, start, end, duration):
     self.start = start
     self.end = end
     self.__diff_x = end[0]-start[0]
     self.__diff_y = end[1]-start[1]
     self.duration = duration
     self.freq = float(sdl2.SDL_GetPerformanceFrequency())
示例#2
0
    def run(self, screen, draw_func, update_func, fps=DEFAULT_FPS):
        self._screen = screen
        self._running = True
        self._fps = fps
        self._frame_time_ms = 1000 / fps
        event = sdl2.SDL_Event()

        time_accumulator_ms = 0
        old_time = sdl2.SDL_GetPerformanceCounter()
        timer_resolution = sdl2.SDL_GetPerformanceFrequency() / 1000  # ms

        while self._running:
            while sdl2.SDL_PollEvent(ctypes.byref(event)) != 0:
                if event.type == sdl2.SDL_QUIT:
                    self._running = False

            # Adjust the loop speed based on the time passed
            current_time = sdl2.SDL_GetPerformanceCounter()
            delta_time_ms = (current_time - old_time) / timer_resolution

            time_accumulator_ms += delta_time_ms
            while time_accumulator_ms > self._frame_time_ms:
                update_func(delta_time_ms)
                time_accumulator_ms -= self._frame_time_ms
            old_time = current_time

            # Update the screen
            screen.begin_update()
            draw_func(screen)
            screen.end_update()

        self.stop()
示例#3
0
 def getTime():
     return sdl2.SDL_GetPerformanceCounter(
     ) * 1.0 / sdl2.SDL_GetPerformanceFrequency()
示例#4
0
    def run(self):
        prompt = CommandPrompt(self)
        print(">>> ", end='', flush=True)

        event = sdl2.SDL_Event()
        toc = 0
        tic_toc_freq = sdl2.SDL_GetPerformanceFrequency()
        period = 1
        excess = 0
        remaining_cycles = 0
        input_line = []

        if self.has_sdl_audio:
            sdl2.SDL_PauseAudioDevice(self.audio_dev, 0)

        cpu_clock_rate = self.atari.color_clock_rate / 3
        reasons = [Atari2600.StoppingReason.FRAME_DONE]

        current_input = self.input_stream[self.atari.frame_number]
        new_input = copy.deepcopy(current_input)

        while not self.done:
            # Timing.
            tic = toc
            toc = sdl2.timer.SDL_GetPerformanceCounter()
            elapsed = (toc - tic) / tic_toc_freq
            if elapsed > 1:
                # Too slow: reset counters. This may be caused by the program being
                # resumed or initialized.
                tic = toc
                elapsed = 0
            elif elapsed < 1 / self.max_fps:
                # Too fast: throttle the simulation. This may be caused by
                # VSYNC is not working, for instance because the game window is hidden.
                sdl2.SDL_Delay(int(1000 * (1 / self.max_fps - elapsed)))
                toc = sdl2.timer.SDL_GetPerformanceCounter()
                elapsed = (toc - tic) / tic_toc_freq
            period = 0.95 * period + 0.05 * elapsed

            # Parse the SDL events.
            while sdl2.SDL_PollEvent(ctypes.byref(event)) != 0:
                if event.type == sdl2.SDL_QUIT:
                    self.done = True
                elif (event.type == sdl2.SDL_KEYUP or event.type
                      == sdl2.SDL_KEYDOWN) and event.key.repeat == 0:
                    if event.type == sdl2.SDL_KEYDOWN:
                        if (event.key.keysym.sym == sdl2.SDLK_EQUALS
                                or event.key.keysym.sym == sdl2.SDLK_KP_PLUS):
                            self.speed = min(5., self.speed + 0.25)
                            print(f"Speed increased to {self.speed}")
                            continue
                        elif event.key.keysym.sym == sdl2.SDLK_0:
                            self.speed = 1.
                            print(f"Speed reset to {self.speed}")
                            continue
                        elif event.key.keysym.sym == sdl2.SDLK_MINUS:
                            self.speed = max(0., self.speed - 0.25)
                            print(f"Speed decreased to {self.speed}")
                            continue
                    if self.switches_interface.update(event.key, new_input):
                        continue
                    if new_input.peripheral_type == Input.Type.JOYSTICK:
                        if self.joysticks_interface.update(
                                event.key, new_input):
                            continue
                    elif new_input.peripheral_type == Input.Type.PADDLE:
                        if self.paddles_interface.update(event.key, new_input):
                            continue
                elif event.type == sdl2.SDL_WINDOWEVENT:
                    if event.window.event == sdl2.SDL_WINDOWEVENT_RESIZED:
                        pass
                elif (event.type == sdl2.SDL_JOYDEVICEADDED
                      or event.type == sdl2.SDL_CONTROLLERDEVICEADDED):
                    self.joysticks_interface.associate_sdl_joystick(
                        event.cdevice.which, verbose=self.verbosity > 0)
                elif (event.type == sdl2.SDL_JOYDEVICEREMOVED
                      or event.type == sdl2.SDL_CONTROLLERDEVICEREMOVED):
                    self.joysticks_interface.disassociate_sdl_device(
                        event.cdevice.which)
                elif (event.type == sdl2.SDL_JOYAXISMOTION
                      or event.type == sdl2.SDL_JOYHATMOTION
                      or event.type == sdl2.SDL_JOYBUTTONUP
                      or event.type == sdl2.SDL_JOYBUTTONDOWN):
                    if new_input.peripheral_type == Input.Type.JOYSTICK:
                        if self.joysticks_interface.update_sdl_joystick(
                                event, new_input):
                            continue
                    elif new_input.peripheral_type == Input.Type.PADDLE:
                        if self.paddles_interface.update_sdl_joystick(
                                event, new_input):
                            continue

            # Parse the console events.
            if os.name == 'nt':
                pass
            else:
                dr, _, _ = select.select([sys.stdin], [], [], 0.0)
                if sys.stdin in dr:
                    input_line = sys.stdin.read(1024)
                    prompt.onecmd(input_line)
                    print(">>> ", end='', flush=True)

            # Simulate an amount of CPU cycles equivalent to the real time elapsed.
            # Limit this to roughly two video frames.
            if not self.paused:
                remaining_cycles += cpu_clock_rate * elapsed * self.speed
                remaining_cycles = int(
                    min(remaining_cycles, cpu_clock_rate * 2 / 60))
                while remaining_cycles > 0:
                    # At the beginning of each new frame, adjust the input stream.
                    if Atari2600.StoppingReason.FRAME_DONE in reasons:
                        if new_input.peripheral_type == Input.Type.PADDLE:
                            self.paddles_interface.integrate(new_input)

                    # Feed the *current* input to the console.
                    if new_input != current_input:
                        self.input_stream[self.atari.frame_number] = new_input
                    current_input = self.input_stream[self.atari.frame_number]
                    self.atari.set_panel(current_input.panel)
                    if current_input.peripheral_type == Input.Type.JOYSTICK:
                        for k in range(2):
                            self.atari.set_joystick(
                                k, current_input.peripheral[k])
                    elif current_input.peripheral_type == Input.Type.PADDLE:
                        for k in range(4):
                            self.atari.set_paddle(k,
                                                  current_input.peripheral[k])
                    new_input = copy.deepcopy(current_input)

                    # Simulate.
                    reasons, remaining_cycles = self.atari.cycle(
                        remaining_cycles)

            # Copy the screen content to the video texture.
            frame = self.atari.get_last_frame()
            pixels = ctypes.c_void_p()
            pitch = ctypes.c_int()
            sdl2.SDL_LockTexture(self.texture, None, ctypes.byref(pixels),
                                 ctypes.byref(pitch))
            ctypes.memmove(pixels, bytes(frame),
                           frame.width * frame.height * 4)
            sdl2.SDL_UnlockTexture(self.texture)
            sdl2.SDL_SetRenderTarget(self.renderer, self.texture)

            # Render the video texture.
            bounds = [0, frame.height - 1]
            sdl2.SDL_SetRenderDrawColor(self.renderer, 0, 0, 0, 0xff)
            sdl2.SDL_RenderClear(self.renderer)
            w = ctypes.c_int()
            h = ctypes.c_int()
            sdl2.SDL_GetWindowSize(self.screen, w, h)
            scale = min(w.value / (frame.width * self.aspect),
                        h.value / (bounds[1] - bounds[0] + 1))
            w_ = int(frame.width * self.aspect * scale)
            h_ = int((bounds[1] - bounds[0] + 1) * scale)
            dh_ = int(bounds[0] * scale)
            r = sdl2.SDL_Rect((int(w.value) - w_) // 2,
                              (int(h.value) - h_) // 2 - dh_, w_, h_)
            sdl2.SDL_RenderCopy(self.renderer, self.texture, None, r)
            sdl2.SDL_RenderPresent(self.renderer)

        if self.has_sdl_audio:
            sdl2.SDL_PauseAudioDevice(self.audio_dev, 1)
示例#5
0
def stamperChildFunction(qTo,
                         qFrom,
                         windowSize=[200, 200],
                         windowPosition=[0, 0],
                         windowColor=[255, 255, 255],
                         doBorder=True):
    import sdl2
    import sdl2.ext
    import sys
    import time
    try:
        import appnope
        appnope.nope()
    except:
        pass
    sdl2.SDL_Init(sdl2.SDL_INIT_TIMER)
    timeFreq = 1.0 / sdl2.SDL_GetPerformanceFrequency()
    sdl2.SDL_Init(sdl2.SDL_INIT_VIDEO)
    if doBorder:
        flags = sdl2.SDL_WINDOW_SHOWN
    else:
        flags = sdl2.SDL_WINDOW_BORDERLESS | sdl2.SDL_WINDOW_SHOWN
    window = sdl2.ext.Window("pyStamper",
                             size=windowSize,
                             position=windowPosition,
                             flags=flags)
    windowID = sdl2.SDL_GetWindowID(window.window)
    windowSurf = sdl2.SDL_GetWindowSurface(window.window)
    red = sdl2.pixels.SDL_Color(r=255, g=0, b=0, a=255)
    green = sdl2.pixels.SDL_Color(r=0, g=255, b=0, a=255)
    black = sdl2.pixels.SDL_Color(r=0, g=0, b=0, a=255)
    white = sdl2.pixels.SDL_Color(r=255, g=255, b=255, a=255)
    if doBorder:
        sdl2.ext.fill(windowSurf.contents, green)
    else:
        sdl2.ext.fill(
            windowSurf.contents,
            sdl2.pixels.SDL_Color(r=windowColor[0],
                                  g=windowColor[1],
                                  b=windowColor[2],
                                  a=255))
    window.refresh()

    for i in range(10):
        sdl2.SDL_PumpEvents()  #to show the windows

    sdl2.SDL_Init(
        sdl2.SDL_INIT_JOYSTICK)  #uncomment if you want joystick input
    sdl2.SDL_JoystickOpen(0)  #uncomment if you want joystick input
    lostFocus = True
    lostColors = [red, black, red, white]
    lastRefreshTime = time.time()
    while True:
        if lostFocus and doBorder:
            if time.time() > (lastRefreshTime + (2.0 / 60)):
                sdl2.ext.fill(windowSurf.contents, lostColors[0])
                window.refresh()
                lostColors.append(lostColors.pop(0))
                lastRefreshTime = time.time()
        sdl2.SDL_PumpEvents()
        if not qTo.empty():
            message = qTo.get()
            if message == 'quit':
                sys.exit()
            elif message == 'raise':
                sdl2.SDL_RaiseWindow(window.window)
        for event in sdl2.ext.get_events():
            if event.type == sdl2.SDL_WINDOWEVENT:
                if event.window.windowID == windowID:
                    if (event.window.event == sdl2.SDL_WINDOWEVENT_CLOSE):
                        qFrom.put({
                            'type': 'key',
                            'time': event.window.timestamp * timeFreq,
                            'value': 'escape'
                        })
                        sys.exit()
                    elif event.window.event == sdl2.SDL_WINDOWEVENT_FOCUS_LOST:
                        lostFocus = True
                    elif event.window.event == sdl2.SDL_WINDOWEVENT_FOCUS_GAINED:
                        lostFocus = False
                        if doBorder:
                            sdl2.ext.fill(windowSurf.contents, green)
                            window.refresh()
            else:
                message = {}
                if event.type == sdl2.SDL_KEYDOWN:
                    message['type'] = 'key'
                    message['time'] = event.key.timestamp * timeFreq
                    message['value'] = sdl2.SDL_GetKeyName(
                        event.key.keysym.sym).lower()
                    message['keysym'] = event.key.keysym
                    qFrom.put(message)
                elif event.type == sdl2.SDL_JOYAXISMOTION:
                    message['type'] = 'axis'
                    message['axis'] = event.jaxis.axis
                    message['time'] = event.jaxis.timestamp * timeFreq
                    message['value'] = event.jaxis.value
                    qFrom.put(message)
                elif event.type == sdl2.SDL_JOYBUTTONDOWN:
                    message['type'] = 'button'
                    message['time'] = event.jbutton.timestamp * timeFreq
                    message['value'] = event.jbutton.button
                    qFrom.put(message)