Mercurial > touhou
view pytouhou/ui/window.pyx @ 612:73f134f84c7f
Request a RGB888 context, since SDL2’s default of RGB332 sucks.
On X11/GLX, it will select the first config available, that is the best
one, while on EGL it will iterate over them to select the one closest
to what the application requested.
Of course, anything lower than RGB888 looks bad and we really don’t
want that.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Thu, 26 Mar 2015 20:20:37 +0100 |
parents | 3c2f96f1d715 |
children | a6af3ff86612 |
line wrap: on
line source
# -*- encoding: utf-8 -*- ## ## Copyright (C) 2013 Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published ## by the Free Software Foundation; version 3 only. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## cimport cython cdef class Clock: def __init__(self, long fps=-1): self._target_fps = 0 self._ref_tick = 0 self._ref_frame = 0 self._fps_tick = 0 self._fps_frame = 0 self.fps = 0 self.set_target_fps(fps) cdef void set_target_fps(self, long fps) nogil: self._target_fps = fps self._ref_tick = 0 self._fps_tick = 0 @cython.cdivision(True) cdef void tick(self) nogil except *: current = sdl.get_ticks() if not self._ref_tick: self._ref_tick = current self._ref_frame = 0 if self._fps_frame >= (self._target_fps if self._target_fps > 0 else 60): self.fps = self._fps_frame * 1000. / (current - self._fps_tick) self._fps_tick = current self._fps_frame = 0 # If we are relying on vsync, but vsync doesn't work or is higher # than 60 fps, limit ourselves to 60 fps. if self._target_fps < 0 and self.fps > 64.: self._target_fps = 60 self._ref_frame += 1 self._fps_frame += 1 target_tick = self._ref_tick if self._target_fps > 0: target_tick += <unsigned long>(self._ref_frame * 1000 / self._target_fps) if current <= target_tick: sdl.delay(target_tick - current) else: self._ref_tick = current self._ref_frame = 0 cdef class Runner: cdef void start(self) except *: pass cdef void finish(self) except *: pass cpdef bint update(self, bint render) except -1: return False cdef class Window: def __init__(self, backend, int width=640, int height=480, long fps_limit=-1, frameskip=1): if backend is not None: self.win = backend.create_window( 'PyTouhou', sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED, width, height, frameskip) self.clock = Clock(fps_limit) self.frame = 0 self.frameskip = frameskip self.width = width self.height = height cdef void set_size(self, int width, int height) nogil: self.win.set_window_size(width, height) cpdef set_runner(self, Runner runner=None): self.runner = runner if runner is not None: runner.start() cpdef run(self): try: while self.run_frame(): pass finally: if self.runner is not None: self.runner.finish() @cython.cdivision(True) cdef bint run_frame(self) except -1: cdef bint render = (self.win is not None and (self.frameskip <= 1 or not self.frame % self.frameskip)) running = False if self.runner is not None: running = self.runner.update(render) if render: self.win.present() self.clock.tick() self.frame += 1 return running cdef double get_fps(self) nogil: return self.clock.fps