def initialize(self): if os.name == "nt": ctypes.windll.shcore.SetProcessDpiAwareness(1) sdl2.SDL_Init(sdl2.SDL_INIT_EVERYTHING) IMG_Init(IMG_INIT_PNG) # Ugly hack to determine resolution scaling factor as early as possible. win = sdl2.SDL_CreateWindow( "ResolutionTest".encode("utf-8"), sdl2.SDL_WINDOWPOS_UNDEFINED, sdl2.SDL_WINDOWPOS_UNDEFINED, 100, 100, sdl2.SDL_WINDOW_HIDDEN | sdl2.SDL_WINDOW_ALLOW_HIGHDPI, ) rend = sdl2.SDL_CreateRenderer(win, -1, sdl2.SDL_RENDERER_ACCELERATED) win_w = ctypes.c_int() rend_w = ctypes.c_int() sdl2.SDL_GetWindowSize(win, ctypes.byref(win_w), None) sdl2.SDL_GetRendererOutputSize(rend, ctypes.byref(rend_w), None) # Windows HiDPI is silly like this. You get back different window sizes than you put in. self.win_scale = win_w.value / 100.0 Environment.scale.default = rend_w.value / 100.0 sdl2.SDL_DestroyRenderer(rend) sdl2.SDL_DestroyWindow(win) # Initialize our font cache and calculate DPI scaling. Font.initialize()
def getWindowSize(self): '''Get SDL2 Window width & height ''' w = ctypes.c_int() # Represents the C signed int datatype h = ctypes.c_int() sdl2.SDL_GetWindowSize(self.window, w, h) logging.info('sdlWindowsize = {}'.format([w.value, h.value])) return w, h
def _resize_display(self, width, height): """Change the display size.""" maximised = sdl2.SDL_GetWindowFlags( self.display) & sdl2.SDL_WINDOW_MAXIMIZED # workaround for maximised state not reporting correctly (at least on Ubuntu Unity) # detect if window is very large compared to screen; force maximise if so. to_maximised = (width >= 0.95 * self.physical_size[0] and height >= 0.9 * self.physical_size[1]) if not maximised: if to_maximised: # force maximise for large windows sdl2.SDL_MaximizeWindow(self.display) else: # regular resize on non-maximised windows sdl2.SDL_SetWindowSize(self.display, width, height) else: # resizing throws us out of maximised mode if not to_maximised: sdl2.SDL_RestoreWindow(self.display) # get window size w, h = ctypes.c_int(), ctypes.c_int() sdl2.SDL_GetWindowSize(self.display, ctypes.byref(w), ctypes.byref(h)) self.window_width, self.window_height = w.value, h.value self.display_surface = sdl2.SDL_GetWindowSurface(self.display) self.screen_changed = True
def loop(window, renderer, inputfoo, renderfoo, choke_ms = 100): while True: loopstart = sdl2.SDL_GetTicks() while True: event = sdl2.SDL_Event() rv = sdl2.SDL_PollEvent(ctypes.byref(event)) if rv == 0: break elif event.type == sdl2.SDL_QUIT: return elif event.type == sdl2.SDL_KEYUP: if event.key.keysym.sym == sdl2.SDLK_ESCAPE: if inputfoo(): return elif event.type == sdl2.SDL_WINDOWEVENT: if event.window.event == sdl2.SDL_WINDOWEVENT_RESIZED: sz = Size2(event.window.data1, event.window.data2) sdl2.SDL_GetWindowSize(window, ctypes.byref(w_w), ctypes.byref(w_h)) elif sdl2.SDL_WINDOWEVENT_CLOSE: inputfoo() else: continue print(event.window.event) elif event.type == sdl2.SDL_MOUSEBUTTONDOWN: inputfoo() elapsed = sdl2.SDL_GetTicks() - loopstart if choke_ms > elapsed: sdl2.SDL_Delay(choke_ms - elapsed) renderfoo(window, renderer)
def GetWindowRect(self): x, y, w, h = ctypes.c_int(), ctypes.c_int(), ctypes.c_int( ), ctypes.c_int() sdl2.SDL_GetWindowPosition(self.window, ctypes.byref(x), ctypes.byref(y)) sdl2.SDL_GetWindowSize(self.window, ctypes.byref(w), ctypes.byref(h)) return sdl2.SDL_Rect(x.value, y.value, w.value, h.value)
def _vispy_get_size(self): if self._id is None: return w, h = ctypes.c_int(), ctypes.c_int() sdl2.SDL_GetWindowSize(self._id.window, ctypes.byref(w), ctypes.byref(h)) w, h = w.value, h.value return w, h
def process_inputs(self): io = imgui.get_io() s_w = ctypes.pointer(ctypes.c_int(0)) s_h = ctypes.pointer(ctypes.c_int(0)) sdl2.SDL_GetWindowSize(self.window, s_w, s_h) w = s_w.contents.value h = s_h.contents.value f_w = ctypes.pointer(ctypes.c_int(0)) f_h = ctypes.pointer(ctypes.c_int(0)) sdl2.SDL_GL_GetDrawableSize(self.window, f_w, f_h) f_w = f_w.contents.value f_h = f_h.contents.value io.display_size = w, h io.display_fb_scale = compute_fb_scale((w, h), (f_w, f_h)) current_time = sdl2.SDL_GetTicks() / 1000.0 if self._gui_time: # print("1") self.io.delta_time = current_time - self._gui_time else: # print("2") self.io.delta_time = 1. / 60. if self.io.delta_time == 0.0: self.io.delta_time = 1. / 60. # print("") # print(f"{self.io.delta_time:.32f}") # print(f"{current_time:.32f}") # if self._gui_time: # print(f"{self._gui_time:.32f}") self._gui_time = current_time mx = ctypes.pointer(ctypes.c_int(0)) my = ctypes.pointer(ctypes.c_int(0)) mouse_mask = sdl2.SDL_GetMouseState(mx, my) if sdl2.SDL_GetWindowFlags(self.window) & sdl2.SDL_WINDOW_MOUSE_FOCUS: io.mouse_pos = mx.contents.value, my.contents.value else: io.mouse_pos = -1, -1 io.mouse_down[0] = self._mouse_pressed[0] or ( mouse_mask & sdl2.SDL_BUTTON(sdl2.SDL_BUTTON_LEFT)) != 0 io.mouse_down[1] = self._mouse_pressed[1] or ( mouse_mask & sdl2.SDL_BUTTON(sdl2.SDL_BUTTON_RIGHT)) != 0 io.mouse_down[2] = self._mouse_pressed[2] or ( mouse_mask & sdl2.SDL_BUTTON(sdl2.SDL_BUTTON_MIDDLE)) != 0 self._mouse_pressed = [False, False, False] io.mouse_wheel = self._mouse_wheel self._mouse_wheel = 0
def get_window_size(self): """Retrieve the window size. Returns ------- hienoi.Vector2i The window size. """ window_size_x = ctypes.c_int() window_size_y = ctypes.c_int() sdl2.SDL_GetWindowSize(self._handles.window, ctypes.byref(window_size_x), ctypes.byref(window_size_y)) return Vector2i(window_size_x.value, window_size_y.value)
def __init__(self, window): super(SDL2Renderer, self).__init__() self.window = window self._mouse_pressed = [False, False, False] self._mouse_wheel = 0.0 self._gui_time = None width_ptr = ctypes.pointer(ctypes.c_int(0)) height_ptr = ctypes.pointer(ctypes.c_int(0)) sdl2.SDL_GetWindowSize(self.window, width_ptr, height_ptr) self.io.display_size = width_ptr[0], height_ptr[0] self._map_keys()
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)
def size(self): width = ctypes.c_int() height = ctypes.c_int() sdl2.SDL_GetWindowSize(self.sdl_window, ctypes.byref(width), ctypes.byref(height)) return width.value, height.value
def window_size(self): w = ctypes.c_int() h = ctypes.c_int() sdl2.SDL_GetWindowSize(self.win, ctypes.byref(w), ctypes.byref(h)) return Size(w.value, h.value)
def get_size(self): width = ctypes.c_int() height = ctypes.c_int() sdl2.SDL_GetWindowSize(self.window, ctypes.byref(width), ctypes.byref(height)) return width, height