# HG changeset patch # User Emmanuel Gil Peyrot # Date 1412949551 -7200 # Node ID 0768122da81717c96fd2e74bba0a427c5300941f # Parent 7a82c4b52b165d0d377e08577424f2c776fc90c8 Add a frameskip option, and use swap interval to implement it. diff --git a/pytouhou/lib/_sdl.pxd b/pytouhou/lib/_sdl.pxd --- a/pytouhou/lib/_sdl.pxd +++ b/pytouhou/lib/_sdl.pxd @@ -56,6 +56,7 @@ cdef extern from "SDL_video.h" nogil: ctypedef void *SDL_GLContext int SDL_GL_SetAttribute(SDL_GLattr attr, int value) + int SDL_GL_SetSwapInterval(int interval) SDL_Window *SDL_CreateWindow(const char *title, int x, int y, int w, int h, Uint32 flags) SDL_GLContext SDL_GL_CreateContext(SDL_Window *window) void SDL_GL_SwapWindow(SDL_Window *window) diff --git a/pytouhou/lib/sdl.pxd b/pytouhou/lib/sdl.pxd --- a/pytouhou/lib/sdl.pxd +++ b/pytouhou/lib/sdl.pxd @@ -117,6 +117,7 @@ cdef void img_init(int flags) except * cdef void mix_init(int flags) except * cdef void ttf_init() except * cdef void gl_set_attribute(SDL_GLattr attr, int value) except * +cdef int gl_set_swap_interval(int interval) except * cdef list poll_events() cdef Surface load_png(file_) cdef Surface create_rgb_surface(int width, int height, int depth, Uint32 rmask=*, Uint32 gmask=*, Uint32 bmask=*, Uint32 amask=*) diff --git a/pytouhou/lib/sdl.pyx b/pytouhou/lib/sdl.pyx --- a/pytouhou/lib/sdl.pyx +++ b/pytouhou/lib/sdl.pyx @@ -280,6 +280,10 @@ cdef void gl_set_attribute(SDL_GLattr at if SDL_GL_SetAttribute(attr, value) < 0: raise SDLError(SDL_GetError()) +cdef int gl_set_swap_interval(int interval) except *: + if SDL_GL_SetSwapInterval(interval) < 0: + raise SDLError(SDL_GetError()) + cdef list poll_events(): cdef SDL_Event event diff --git a/pytouhou/options.py b/pytouhou/options.py --- a/pytouhou/options.py +++ b/pytouhou/options.py @@ -142,6 +142,7 @@ def parse_arguments(defaults): graphics_group = parser.add_argument_group('Graphics options') graphics_group.add_argument('--backend', metavar='BACKEND', choices=['opengl', 'sdl'], nargs='*', help='Which backend to use (opengl or sdl).') graphics_group.add_argument('--fps-limit', metavar='FPS', type=int, help='Set fps limit. A value of 0 disables fps limiting, while a negative value limits to 60 fps if and only if vsync doesn’t work.') + graphics_group.add_argument('--frameskip', metavar='FRAMESKIP', type=int, help='Set the frameskip, as 1/FRAMESKIP, or disabled if 0.') graphics_group.add_argument('--no-background', action='store_false', help='Disable background display (huge performance boost on slow systems).') graphics_group.add_argument('--no-particles', action='store_false', help='Disable particles handling (huge performance boost on slow systems).') graphics_group.add_argument('--no-sound', action='store_false', help='Disable music and sound effects.') diff --git a/pytouhou/ui/opengl/backend.pyx b/pytouhou/ui/opengl/backend.pyx --- a/pytouhou/ui/opengl/backend.pyx +++ b/pytouhou/ui/opengl/backend.pyx @@ -1,3 +1,4 @@ +from pytouhou.lib import sdl from pytouhou.lib cimport sdl from pytouhou.lib.sdl cimport Window @@ -74,7 +75,7 @@ def discover_features(): shader_header = '#version %s\n\nprecision highp float;\n\n' % glsl_version -def create_window(title, x, y, width, height): +def create_window(title, x, y, width, height, swap_interval): '''Create a window (using SDL) and an OpenGL context.''' sdl.gl_set_attribute(sdl.GL_CONTEXT_PROFILE_MASK, profile) @@ -115,4 +116,10 @@ def create_window(title, x, y, width, he if use_debug_group: glPopDebugGroup() + if swap_interval is not None: + try: + sdl.gl_set_swap_interval(swap_interval) + except sdl.SDLError: + pass + return window diff --git a/pytouhou/ui/sdl/backend.pyx b/pytouhou/ui/sdl/backend.pyx --- a/pytouhou/ui/sdl/backend.pyx +++ b/pytouhou/ui/sdl/backend.pyx @@ -10,7 +10,7 @@ def init(_): from pytouhou.ui.sdl.gamerenderer import GameRenderer -def create_window(title, x, y, width, height): +def create_window(title, x, y, width, height, _): window = Window(title, x, y, width, height, sdl.WINDOW_SHOWN) window.create_renderer(0) return window diff --git a/pytouhou/ui/window.pxd b/pytouhou/ui/window.pxd --- a/pytouhou/ui/window.pxd +++ b/pytouhou/ui/window.pxd @@ -22,6 +22,7 @@ cdef class Window: cdef sdl.Window win cdef Runner runner cdef Clock clock + cdef int frame, frameskip cdef void set_size(self, int width, int height) nogil cpdef set_runner(self, Runner runner=*) diff --git a/pytouhou/ui/window.pyx b/pytouhou/ui/window.pyx --- a/pytouhou/ui/window.pyx +++ b/pytouhou/ui/window.pyx @@ -77,14 +77,17 @@ cdef class Runner: cdef class Window: - def __init__(self, backend, long fps_limit=-1): + def __init__(self, backend, long fps_limit=-1, frameskip=1): if backend is not None: self.win = backend.create_window( 'PyTouhou', sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED, - 640, 480) #XXX + 640, 480, #XXX + frameskip) self.clock = Clock(fps_limit) + self.frame = 0 + self.frameskip = frameskip cdef void set_size(self, int width, int height) nogil: @@ -110,9 +113,10 @@ cdef class Window: cdef bint running = False if self.runner is not None: running = self.runner.update() - if self.win is not None: + if self.win is not None and (self.frameskip <= 1 or not self.frame % self.frameskip): self.win.present() self.clock.tick() + self.frame += 1 return running diff --git a/scripts/pytouhou b/scripts/pytouhou --- a/scripts/pytouhou +++ b/scripts/pytouhou @@ -31,7 +31,8 @@ defaults = {'data': default_data, 'gl-flavor': 'compatibility', 'gl-version': 2.1, 'double-buffer': None, - 'fps-limit': -1} + 'fps-limit': -1, + 'frameskip': 1} from pytouhou.options import parse_config, parse_arguments options = parse_config('pytouhou', defaults) @@ -279,7 +280,8 @@ def main(window, path, data, stage_num, with SDL(sound=args.no_sound): - window = Window(backend, fps_limit=args.fps_limit) + window = Window(backend, fps_limit=args.fps_limit, + frameskip=args.frameskip) main(window, args.path, tuple(args.data), args.stage, args.rank, args.character, args.replay, args.save_replay, args.skip_replay,