# HG changeset patch # User Emmanuel Gil Peyrot # Date 1378152998 -7200 # Node ID 6864a38b24136659e0a1dd7f6530a545631cd904 # Parent a502887557ac8756c3c0a6230f998a0e9de5deb3 Make pytouhou.lib.sdl cimportable, and convert pytouhou.ui.window.* to extension types. diff --git a/pytouhou/lib/sdl.pxd b/pytouhou/lib/_sdl.pxd copy from pytouhou/lib/sdl.pxd copy to pytouhou/lib/_sdl.pxd --- a/pytouhou/lib/sdl.pxd +++ b/pytouhou/lib/_sdl.pxd @@ -12,7 +12,7 @@ ## GNU General Public License for more details. ## -cdef extern from "SDL.h": +cdef extern from "SDL.h" nogil: ctypedef unsigned int Uint32 ctypedef unsigned short Uint16 ctypedef unsigned char Uint8 @@ -24,15 +24,15 @@ cdef extern from "SDL.h": IF UNAME_SYSNAME == "Windows": - cdef extern from "SDL_main.h": + cdef extern from "SDL_main.h" nogil: void SDL_SetMainReady() -cdef extern from "SDL_error.h": +cdef extern from "SDL_error.h" nogil: const char *SDL_GetError() -cdef extern from "SDL_video.h": +cdef extern from "SDL_video.h" nogil: ctypedef enum SDL_GLattr: SDL_GL_CONTEXT_MAJOR_VERSION SDL_GL_CONTEXT_MINOR_VERSION @@ -59,7 +59,7 @@ cdef extern from "SDL_video.h": void SDL_SetWindowSize(SDL_Window *window, int w, int h) -cdef extern from "SDL_scancode.h": +cdef extern from "SDL_scancode.h" nogil: ctypedef enum SDL_Scancode: SDL_SCANCODE_Z SDL_SCANCODE_X @@ -72,7 +72,7 @@ cdef extern from "SDL_scancode.h": SDL_SCANCODE_ESCAPE -cdef extern from "SDL_events.h": +cdef extern from "SDL_events.h" nogil: ctypedef enum SDL_EventType: SDL_KEYDOWN SDL_QUIT @@ -91,22 +91,22 @@ cdef extern from "SDL_events.h": int SDL_PollEvent(SDL_Event *event) -cdef extern from "SDL_keyboard.h": +cdef extern from "SDL_keyboard.h" nogil: const Uint8 *SDL_GetKeyboardState(int *numkeys) -cdef extern from "SDL_timer.h": +cdef extern from "SDL_timer.h" nogil: Uint32 SDL_GetTicks() void SDL_Delay(Uint32 ms) -cdef extern from "SDL_rect.h": +cdef extern from "SDL_rect.h" nogil: ctypedef struct SDL_Rect: int x, y int w, h -cdef extern from "SDL_surface.h": +cdef extern from "SDL_surface.h" nogil: ctypedef struct SDL_Surface: int w, h unsigned char *pixels @@ -116,7 +116,7 @@ cdef extern from "SDL_surface.h": SDL_Surface *SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) -cdef extern from "SDL_rwops.h": +cdef extern from "SDL_rwops.h" nogil: ctypedef struct SDL_RWops: pass @@ -124,7 +124,7 @@ cdef extern from "SDL_rwops.h": int SDL_RWclose(SDL_RWops *context) -cdef extern from "SDL_image.h": +cdef extern from "SDL_image.h" nogil: int IMG_INIT_PNG int IMG_Init(int flags) @@ -132,7 +132,7 @@ cdef extern from "SDL_image.h": SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src) -cdef extern from "SDL_mixer.h": +cdef extern from "SDL_mixer.h" nogil: ctypedef enum: MIX_DEFAULT_FORMAT diff --git a/pytouhou/lib/sdl.pxd b/pytouhou/lib/sdl.pxd --- a/pytouhou/lib/sdl.pxd +++ b/pytouhou/lib/sdl.pxd @@ -12,155 +12,89 @@ ## GNU General Public License for more details. ## -cdef extern from "SDL.h": - ctypedef unsigned int Uint32 - ctypedef unsigned short Uint16 - ctypedef unsigned char Uint8 - - int SDL_INIT_VIDEO - - int SDL_Init(Uint32 flags) - void SDL_Quit() - - -IF UNAME_SYSNAME == "Windows": - cdef extern from "SDL_main.h": - void SDL_SetMainReady() - - -cdef extern from "SDL_error.h": - const char *SDL_GetError() +from _sdl cimport * -cdef extern from "SDL_video.h": - ctypedef enum SDL_GLattr: - SDL_GL_CONTEXT_MAJOR_VERSION - SDL_GL_CONTEXT_MINOR_VERSION - SDL_GL_DOUBLEBUFFER - SDL_GL_DEPTH_SIZE +cdef Uint32 INIT_VIDEO +cdef Uint32 INIT_PNG - ctypedef enum SDL_WindowFlags: - SDL_WINDOWPOS_CENTERED - SDL_WINDOW_OPENGL - SDL_WINDOW_SHOWN +cdef SDL_GLattr GL_CONTEXT_MAJOR_VERSION +cdef SDL_GLattr GL_CONTEXT_MINOR_VERSION +cdef SDL_GLattr GL_DOUBLEBUFFER +cdef SDL_GLattr GL_DEPTH_SIZE + +cdef SDL_WindowFlags WINDOWPOS_CENTERED +cdef SDL_WindowFlags WINDOW_OPENGL +cdef SDL_WindowFlags WINDOW_SHOWN - ctypedef struct SDL_Window: - pass - - ctypedef void *SDL_GLContext +#TODO: should be SDL_Scancode, but Cython doesn’t allow enum for array indexing. +cdef long SCANCODE_Z +cdef long SCANCODE_X +cdef long SCANCODE_LSHIFT +cdef long SCANCODE_UP +cdef long SCANCODE_DOWN +cdef long SCANCODE_LEFT +cdef long SCANCODE_RIGHT +cdef long SCANCODE_LCTRL +cdef long SCANCODE_ESCAPE - int SDL_GL_SetAttribute(SDL_GLattr attr, int value) - 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) - void SDL_GL_DeleteContext(SDL_GLContext context) - void SDL_DestroyWindow(SDL_Window *window) +cdef SDL_EventType KEYDOWN +cdef SDL_EventType QUIT - void SDL_SetWindowSize(SDL_Window *window, int w, int h) +cdef Uint16 DEFAULT_FORMAT -cdef extern from "SDL_scancode.h": - ctypedef enum SDL_Scancode: - SDL_SCANCODE_Z - SDL_SCANCODE_X - SDL_SCANCODE_LSHIFT - SDL_SCANCODE_UP - SDL_SCANCODE_DOWN - SDL_SCANCODE_LEFT - SDL_SCANCODE_RIGHT - SDL_SCANCODE_LCTRL - SDL_SCANCODE_ESCAPE +cdef class Window: + cdef SDL_Window *window + cdef SDL_GLContext context + + cdef void gl_create_context(self) except * + cdef void gl_swap_window(self) nogil + cdef void set_window_size(self, int width, int height) nogil -cdef extern from "SDL_events.h": - ctypedef enum SDL_EventType: - SDL_KEYDOWN - SDL_QUIT - - ctypedef struct SDL_Keysym: - SDL_Scancode scancode +cdef class Surface: + cdef SDL_Surface *surface - ctypedef struct SDL_KeyboardEvent: - Uint32 type - SDL_Keysym keysym - - ctypedef union SDL_Event: - Uint32 type - SDL_KeyboardEvent key - - int SDL_PollEvent(SDL_Event *event) + cdef void blit(self, Surface other) except * + cdef void set_alpha(self, Surface alpha_surface) nogil -cdef extern from "SDL_keyboard.h": - const Uint8 *SDL_GetKeyboardState(int *numkeys) - +cdef class Music: + cdef Mix_Music *music -cdef extern from "SDL_timer.h": - Uint32 SDL_GetTicks() - void SDL_Delay(Uint32 ms) + cdef void play(self, int loops) nogil + cdef void set_loop_points(self, double start, double end) nogil -cdef extern from "SDL_rect.h": - ctypedef struct SDL_Rect: - int x, y - int w, h - +cdef class Chunk: + cdef Mix_Chunk *chunk -cdef extern from "SDL_surface.h": - ctypedef struct SDL_Surface: - int w, h - unsigned char *pixels - - void SDL_FreeSurface(SDL_Surface *surface) - int SDL_BlitSurface(SDL_Surface *src, const SDL_Rect *srcrect, SDL_Surface *dst, SDL_Rect *dstrect) - SDL_Surface *SDL_CreateRGBSurface(Uint32 flags, int width, int height, int depth, Uint32 Rmask, Uint32 Gmask, Uint32 Bmask, Uint32 Amask) + cdef void play(self, int channel, int loops) nogil + cdef void set_volume(self, float volume) nogil -cdef extern from "SDL_rwops.h": - ctypedef struct SDL_RWops: - pass - - SDL_RWops *SDL_RWFromConstMem(const void *mem, int size) - int SDL_RWclose(SDL_RWops *context) - - -cdef extern from "SDL_image.h": - int IMG_INIT_PNG +cdef void init(Uint32 flags) except * +cdef void img_init(Uint32 flags) except * +cdef void mix_init(int flags) except * - int IMG_Init(int flags) - void IMG_Quit() - SDL_Surface *IMG_LoadPNG_RW(SDL_RWops *src) - - -cdef extern from "SDL_mixer.h": - ctypedef enum: - MIX_DEFAULT_FORMAT - - ctypedef struct Mix_Music: - pass +IF UNAME_SYSNAME == "Windows": + cdef void set_main_ready() - ctypedef struct Mix_Chunk: - pass - - int Mix_Init(int flags) - void Mix_Quit() - - int Mix_OpenAudio(int frequency, Uint16 format_, int channels, int chunksize) - void Mix_CloseAudio() - - int Mix_AllocateChannels(int numchans) - - Mix_Music *Mix_LoadMUS(const char *filename) - Mix_Chunk *Mix_LoadWAV_RW(SDL_RWops *src, int freesrc) - - void Mix_FreeMusic(Mix_Music *music) - void Mix_FreeChunk(Mix_Chunk *chunk) - - int Mix_PlayMusic(Mix_Music *music, int loops) - #int Mix_SetLoopPoints(Mix_Music *music, double start, double end) - - int Mix_Volume(int channel, int volume) - int Mix_VolumeChunk(Mix_Chunk *chunk, int volume) - int Mix_VolumeMusic(int volume) - - int Mix_PlayChannel(int channel, Mix_Chunk *chunk, int loops) +cdef void quit() nogil +cdef void img_quit() nogil +cdef void mix_quit() nogil +cdef void gl_set_attribute(SDL_GLattr attr, int value) except * +cdef list poll_events() +cdef const Uint8* get_keyboard_state() nogil +cdef Surface load_png(file_) +cdef Surface create_rgb_surface(int width, int height, int depth, Uint32 rmask=*, Uint32 gmask=*, Uint32 bmask=*, Uint32 amask=*) +cdef void mix_open_audio(int frequency, Uint16 format_, int channels, int chunksize) except * +cdef void mix_close_audio() nogil +cdef void mix_allocate_channels(int numchans) except * +cdef int mix_volume(int channel, float volume) nogil +cdef int mix_volume_music(float volume) nogil +cdef Music load_music(const char *filename) +cdef Chunk load_chunk(file_) +cdef Uint32 get_ticks() nogil +cdef void delay(Uint32 ms) nogil diff --git a/pytouhou/lib/sdl.pyx b/pytouhou/lib/sdl.pyx --- a/pytouhou/lib/sdl.pyx +++ b/pytouhou/lib/sdl.pyx @@ -45,56 +45,43 @@ class SDLError(Exception): cdef class Window: - cdef SDL_Window *window - cdef SDL_GLContext context - def __init__(self, const char *title, int x, int y, int w, int h, Uint32 flags): self.window = SDL_CreateWindow(title, x, y, w, h, flags) if self.window == NULL: raise SDLError(SDL_GetError()) - def destroy_window(self): - SDL_DestroyWindow(self.window) + def __dealloc__(self): + if self.context != NULL: + SDL_GL_DeleteContext(self.context) + if self.window != NULL: + SDL_DestroyWindow(self.window) - def gl_create_context(self): + cdef void gl_create_context(self) except *: self.context = SDL_GL_CreateContext(self.window) if self.context == NULL: raise SDLError(SDL_GetError()) - def gl_swap_window(self): + cdef void gl_swap_window(self) nogil: SDL_GL_SwapWindow(self.window) - def gl_delete_context(self): - SDL_GL_DeleteContext(self.context) - - def set_window_size(self, width, height): + cdef void set_window_size(self, int width, int height) nogil: SDL_SetWindowSize(self.window, width, height) cdef class Surface: - cdef SDL_Surface *surface - def __dealloc__(self): if self.surface != NULL: SDL_FreeSurface(self.surface) - property width: - def __get__(self): - return self.surface.w - - property height: - def __get__(self): - return self.surface.h - property pixels: def __get__(self): return bytes(self.surface.pixels[:self.surface.w * self.surface.h * 4]) - def blit(self, Surface other): + cdef void blit(self, Surface other): if SDL_BlitSurface(other.surface, NULL, self.surface, NULL) < 0: raise SDLError(SDL_GetError()) - def set_alpha(self, Surface alpha_surface): + cdef void set_alpha(self, Surface alpha_surface) nogil: nb_pixels = self.surface.w * self.surface.h image = self.surface.pixels alpha = alpha_surface.surface.pixels @@ -105,73 +92,68 @@ cdef class Surface: cdef class Music: - cdef Mix_Music *music - def __dealloc__(self): if self.music != NULL: Mix_FreeMusic(self.music) - def play(self, int loops): + cdef void play(self, int loops) nogil: Mix_PlayMusic(self.music, loops) - def set_loop_points(self, double start, double end): + cdef void set_loop_points(self, double start, double end) nogil: #Mix_SetLoopPoints(self.music, start, end) pass cdef class Chunk: - cdef Mix_Chunk *chunk - def __dealloc__(self): if self.chunk != NULL: Mix_FreeChunk(self.chunk) - property volume: - def __set__(self, float volume): - Mix_VolumeChunk(self.chunk, int(volume * 128)) - - def play(self, int channel, int loops): + cdef void play(self, int channel, int loops) nogil: Mix_PlayChannel(channel, self.chunk, loops) + cdef void set_volume(self, float volume) nogil: + Mix_VolumeChunk(self.chunk, int(volume * 128)) -def init(Uint32 flags): + +cdef void init(Uint32 flags) except *: if SDL_Init(flags) < 0: raise SDLError(SDL_GetError()) -def img_init(Uint32 flags): +cdef void img_init(Uint32 flags) except *: if IMG_Init(flags) != flags: raise SDLError(SDL_GetError()) -def mix_init(int flags): +cdef void mix_init(int flags) except *: if Mix_Init(flags) != flags: raise SDLError(SDL_GetError()) IF UNAME_SYSNAME == "Windows": - def set_main_ready(): + cdef void set_main_ready(): SDL_SetMainReady() -def quit(): +cdef void quit() nogil: SDL_Quit() -def img_quit(): +cdef void img_quit() nogil: IMG_Quit() -def mix_quit(): +cdef void mix_quit() nogil: Mix_Quit() -def gl_set_attribute(SDL_GLattr attr, int value): +cdef void gl_set_attribute(SDL_GLattr attr, int value) except *: if SDL_GL_SetAttribute(attr, value) < 0: raise SDLError(SDL_GetError()) -def poll_events(): +cdef list poll_events(): cdef SDL_Event event ret = [] while SDL_PollEvent(&event): @@ -182,15 +164,11 @@ def poll_events(): return ret -def get_keyboard_state(): - cdef int numkeys - cdef bint k - cdef const Uint8 *state - state = SDL_GetKeyboardState(&numkeys) - return tuple([k is not False for k in state[:numkeys]]) +cdef const Uint8* get_keyboard_state() nogil: + return SDL_GetKeyboardState(NULL) -def load_png(file_): +cdef Surface load_png(file_): data = file_.read() rwops = SDL_RWFromConstMem(data, len(data)) surface = Surface() @@ -201,7 +179,7 @@ def load_png(file_): return surface -def create_rgb_surface(int width, int height, int depth, Uint32 rmask=0, Uint32 gmask=0, Uint32 bmask=0, Uint32 amask=0): +cdef Surface create_rgb_surface(int width, int height, int depth, Uint32 rmask=0, Uint32 gmask=0, Uint32 bmask=0, Uint32 amask=0): surface = Surface() surface.surface = SDL_CreateRGBSurface(0, width, height, depth, rmask, gmask, bmask, amask) if surface.surface == NULL: @@ -209,29 +187,29 @@ def create_rgb_surface(int width, int he return surface -def mix_open_audio(int frequency, Uint16 format_, int channels, int chunksize): +cdef void mix_open_audio(int frequency, Uint16 format_, int channels, int chunksize) except *: if Mix_OpenAudio(frequency, format_, channels, chunksize) < 0: raise SDLError(SDL_GetError()) -def mix_close_audio(): +cdef void mix_close_audio() nogil: Mix_CloseAudio() -def mix_allocate_channels(int numchans): +cdef void mix_allocate_channels(int numchans) except *: if Mix_AllocateChannels(numchans) != numchans: raise SDLError(SDL_GetError()) -def mix_volume(int channel, float volume): +cdef int mix_volume(int channel, float volume) nogil: return Mix_Volume(channel, int(volume * 128)) -def mix_volume_music(float volume): +cdef int mix_volume_music(float volume) nogil: return Mix_VolumeMusic(int(volume * 128)) -def load_music(const char *filename): +cdef Music load_music(const char *filename): music = Music() music.music = Mix_LoadMUS(filename) if music.music == NULL: @@ -239,7 +217,7 @@ def load_music(const char *filename): return music -def load_chunk(file_): +cdef Chunk load_chunk(file_): cdef SDL_RWops *rwops chunk = Chunk() data = file_.read() @@ -250,9 +228,9 @@ def load_chunk(file_): return chunk -def get_ticks(): +cdef Uint32 get_ticks() nogil: return SDL_GetTicks() -def delay(Uint32 ms): +cdef void delay(Uint32 ms) nogil: SDL_Delay(ms) diff --git a/pytouhou/ui/anmrenderer.pyx b/pytouhou/ui/anmrenderer.pyx --- a/pytouhou/ui/anmrenderer.pyx +++ b/pytouhou/ui/anmrenderer.pyx @@ -24,7 +24,7 @@ from pytouhou.utils.maths cimport perspe from .renderer import Renderer from .shaders.eosd import GameShader -from pytouhou.lib import sdl +from pytouhou.lib cimport sdl logger = get_logger(__name__) diff --git a/pytouhou/ui/gamerunner.pyx b/pytouhou/ui/gamerunner.pyx --- a/pytouhou/ui/gamerunner.pyx +++ b/pytouhou/ui/gamerunner.pyx @@ -12,7 +12,7 @@ ## GNU General Public License for more details. ## -from pytouhou.lib import sdl +from pytouhou.lib cimport sdl from pytouhou.lib.opengl cimport \ (glMatrixMode, glEnable, glDisable, glViewport, glScissor, @@ -179,7 +179,7 @@ class GameRunner(GameRenderer): def render_interface(self): elements = [] interface = self.game.interface - interface.labels['framerate'].set_text('%.2ffps' % self.window.clock.get_fps()) + interface.labels['framerate'].set_text('%.2ffps' % self.window.get_fps()) if self.use_fixed_pipeline: glMatrixMode(GL_MODELVIEW) diff --git a/pytouhou/ui/music.py b/pytouhou/ui/music.pyx rename from pytouhou/ui/music.py rename to pytouhou/ui/music.pyx --- a/pytouhou/ui/music.py +++ b/pytouhou/ui/music.pyx @@ -15,7 +15,7 @@ from os.path import join from glob import glob -from pytouhou.lib import sdl +from pytouhou.lib cimport sdl from pytouhou.utils.helpers import get_logger logger = get_logger(__name__) @@ -53,6 +53,7 @@ class MusicPlayer(object): logger.warn(u'No working music file for “%s”, disabling bgm.', globname) def play(self, index): + cdef sdl.Music bgm bgm = self.bgms[index] if bgm: bgm.play(-1) @@ -75,11 +76,13 @@ class SFXPlayer(object): def get_sound(self, name): if name not in self.sounds: wave_file = self.loader.get_file(name) - self.sounds[name] = sdl.load_chunk(wave_file) - self.sounds[name].volume = self.volume + chunk = sdl.load_chunk(wave_file) + chunk.set_volume(self.volume) + self.sounds[name] = chunk return self.sounds[name] def play(self, name, volume=None): + cdef sdl.Chunk sound sound = self.get_sound(name) channel = self.get_channel(name) if volume: diff --git a/pytouhou/ui/texture.pyx b/pytouhou/ui/texture.pyx --- a/pytouhou/ui/texture.pyx +++ b/pytouhou/ui/texture.pyx @@ -19,7 +19,7 @@ from pytouhou.lib.opengl cimport \ glGenTextures, glBindTexture, glTexImage2D, GL_TEXTURE_2D, GLuint, glDeleteTextures) -from pytouhou.lib.sdl import load_png, create_rgb_surface +from pytouhou.lib.sdl cimport load_png, create_rgb_surface from pytouhou.formats.thtx import Texture #TODO: perhaps define that elsewhere? import os @@ -52,7 +52,7 @@ class TextureManager(object): cdef decode_png(loader, first_name, secondary_name): image_file = load_png(loader.get_file(os.path.basename(first_name))) - width, height = image_file.width, image_file.height + width, height = image_file.surface.w, image_file.surface.h # Support only 32 bits RGBA. Paletted surfaces are awful to work with. #TODO: verify it doesn’t blow up on big-endian systems. @@ -61,7 +61,7 @@ cdef decode_png(loader, first_name, seco if secondary_name: alpha_file = load_png(loader.get_file(os.path.basename(secondary_name))) - assert (width == alpha_file.width and height == alpha_file.height) + assert (width == alpha_file.surface.w and height == alpha_file.surface.h) new_alpha_file = create_rgb_surface(width, height, 24) new_alpha_file.blit(alpha_file) diff --git a/pytouhou/ui/window.pyx b/pytouhou/ui/window.pyx --- a/pytouhou/ui/window.pyx +++ b/pytouhou/ui/window.pyx @@ -13,7 +13,7 @@ ## -from pytouhou.lib import sdl +from pytouhou.lib cimport sdl from pytouhou.lib.opengl cimport \ (glEnable, glHint, glEnableClientState, GL_TEXTURE_2D, GL_BLEND, @@ -24,8 +24,11 @@ IF USE_GLEW: from pytouhou.lib.opengl cimport glewInit -class Clock: - def __init__(self, fps=None): +cdef class Clock: + cdef long _target_fps, _ref_tick, _ref_frame, _fps_tick, _fps_frame + cdef double _rate + + def __init__(self, long fps=-1): self._target_fps = 0 self._ref_tick = 0 self._ref_frame = 0 @@ -35,17 +38,17 @@ class Clock: self.set_target_fps(fps) - def set_target_fps(self, fps): + cdef void set_target_fps(self, long fps) nogil: self._target_fps = fps self._ref_tick = 0 self._fps_tick = 0 - def get_fps(self): + cdef double get_fps(self) nogil: return self._rate - def tick(self): + cdef void tick(self) nogil except *: current = sdl.get_ticks() if not self._ref_tick: @@ -66,7 +69,7 @@ class Clock: target_tick = self._ref_tick if self._target_fps: - target_tick += int(self._ref_frame * 1000 / self._target_fps) + target_tick += (self._ref_frame * 1000 / self._target_fps) if current <= target_tick: sdl.delay(target_tick - current) @@ -76,9 +79,16 @@ class Clock: -class Window(object): - def __init__(self, size=None, double_buffer=True, fps_limit=60, - fixed_pipeline=False, sound=True): +cdef class Window: + cdef sdl.Window win + cdef long fps_limit + cdef public long width, height + cdef public bint use_fixed_pipeline + cdef object runner + cdef Clock clock + + def __init__(self, size=None, bint double_buffer=True, long fps_limit=-1, + bint fixed_pipeline=False, bint sound=True): self.fps_limit = fps_limit self.use_fixed_pipeline = fixed_pipeline self.runner = None @@ -95,7 +105,7 @@ class Window(object): sdl.gl_set_attribute(sdl.GL_DOUBLEBUFFER, int(double_buffer)) sdl.gl_set_attribute(sdl.GL_DEPTH_SIZE, 24) - self.width, self.height = size if size else (640, 480) + self.width, self.height = size if size is not None else (640, 480) self.win = sdl.Window('PyTouhou', sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED, @@ -125,16 +135,17 @@ class Window(object): self.clock = Clock(self.fps_limit) - def set_size(self, width, height): + cdef void set_size(self, int width, int height) nogil: self.win.set_window_size(width, height) - def set_runner(self, runner): + cpdef set_runner(self, runner=None): self.runner = runner - runner.start() + if runner is not None: + runner.start() - def run(self): + cpdef run(self): try: while self.run_frame(): pass @@ -142,17 +153,20 @@ class Window(object): self.runner.finish() - def run_frame(self): - if self.runner: + cdef bint run_frame(self) except? False: + cdef bint running = False + if self.runner is not None: running = self.runner.update() self.win.gl_swap_window() self.clock.tick() return running + cpdef double get_fps(self): + return self.clock.get_fps() + + def __dealloc__(self): - self.win.gl_delete_context() - self.win.destroy_window() sdl.mix_close_audio() sdl.mix_quit() sdl.img_quit() diff --git a/setup.py b/setup.py --- a/setup.py +++ b/setup.py @@ -45,8 +45,8 @@ for directory, _, files in os.walk('pyto compile_args = get_arguments('--cflags', SDL_LIBRARIES) link_args = get_arguments('--libs', SDL_LIBRARIES) elif extension_name.startswith('pytouhou.ui.'): #XXX - compile_args = get_arguments('--cflags', ['gl']) - link_args = get_arguments('--libs', ['gl']) + compile_args = get_arguments('--cflags', ['gl'] + SDL_LIBRARIES) + link_args = get_arguments('--libs', ['gl'] + SDL_LIBRARIES) else: compile_args = None link_args = None