changeset 589:0768122da817

Add a frameskip option, and use swap interval to implement it.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Fri, 10 Oct 2014 15:59:11 +0200
parents 7a82c4b52b16
children e15672733c93
files pytouhou/lib/_sdl.pxd pytouhou/lib/sdl.pxd pytouhou/lib/sdl.pyx pytouhou/options.py pytouhou/ui/opengl/backend.pyx pytouhou/ui/sdl/backend.pyx pytouhou/ui/window.pxd pytouhou/ui/window.pyx scripts/pytouhou
diffstat 9 files changed, 28 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- 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)
--- 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=*)
--- 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
--- 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.')
--- 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
--- 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
--- 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=*)
--- 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
 
 
--- 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,