Mercurial > touhou
diff pytouhou/ui/gamerunner.py @ 422:52829ebe2561
Refactor window management in its own class.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Tue, 16 Jul 2013 21:07:15 +0200 |
parents | b1248bab2d0f |
children |
line wrap: on
line diff
--- a/pytouhou/ui/gamerunner.py +++ b/pytouhou/ui/gamerunner.py @@ -14,14 +14,9 @@ from pytouhou.lib import sdl -from pyglet.gl import (glMatrixMode, glLoadIdentity, glEnable, glDisable, - glHint, glEnableClientState, glViewport, glScissor, - glLoadMatrixf, glGenBuffers, glDeleteBuffers, - GL_MODELVIEW, GL_PROJECTION, - GL_TEXTURE_2D, GL_BLEND, GL_FOG, - GL_PERSPECTIVE_CORRECTION_HINT, GL_FOG_HINT, GL_NICEST, - GL_COLOR_ARRAY, GL_VERTEX_ARRAY, GL_TEXTURE_COORD_ARRAY, - GL_SCISSOR_TEST) +from pyglet.gl import (glMatrixMode, glEnable, glDisable, glViewport, + glScissor, glLoadMatrixf, glGenBuffers, glDeleteBuffers, + GL_MODELVIEW, GL_PROJECTION, GL_FOG, GL_SCISSOR_TEST) from pytouhou.utils.helpers import get_logger from pytouhou.utils.maths import perspective, setup_camera, ortho_2d @@ -36,83 +31,19 @@ from ctypes import c_uint, byref logger = get_logger(__name__) -class Clock(object): - def __init__(self, fps=None): - self._target_fps = 0 - self._ref_tick = 0 - self._ref_frame = 0 - self._fps_tick = 0 - self._fps_frame = 0 - self._rate = 0 - self.set_target_fps(fps) - - - def set_target_fps(self, fps): - self._target_fps = fps - self._ref_tick = 0 - self._fps_tick = 0 - - - def get_fps(self): - return self._rate - - - def tick(self): - current = sdl.get_ticks() - - if not self._ref_tick: - self._ref_tick = current - self._ref_frame = 0 - - if self._fps_frame >= (self._target_fps or 60): - self._rate = self._fps_frame * 1000. / (current - self._fps_tick) - self._fps_tick = current - self._fps_frame = 0 - - self._ref_frame += 1 - self._fps_frame += 1 +class GameRunner(GameRenderer): + def __init__(self, window, resource_loader, replay=None, skip=False): + GameRenderer.__init__(self, resource_loader) - target_tick = self._ref_tick - if self._target_fps: - target_tick += int(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 - - -class GameRunner(GameRenderer): - def __init__(self, resource_loader, game=None, background=None, replay=None, double_buffer=True, fps_limit=60, fixed_pipeline=False, skip=False): - GameRenderer.__init__(self, resource_loader, game, background) - - sdl.init(sdl.INIT_VIDEO) - sdl.img_init(sdl.INIT_PNG) - sdl.mix_init(0) - - sdl.gl_set_attribute(sdl.GL_CONTEXT_MAJOR_VERSION, 2) - sdl.gl_set_attribute(sdl.GL_CONTEXT_MINOR_VERSION, 1) - sdl.gl_set_attribute(sdl.GL_DOUBLEBUFFER, int(double_buffer)) - sdl.gl_set_attribute(sdl.GL_DEPTH_SIZE, 24) - - self.width, self.height = (game.interface.width, game.interface.height) if game else (640, 480) - self.win = sdl.Window('PyTouhou', - sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED, - self.width, self.height, - sdl.WINDOW_OPENGL | sdl.WINDOW_SHOWN) - self.win.gl_create_context() - - sdl.mix_open_audio(44100, sdl.DEFAULT_FORMAT, 2, 4096) - sdl.mix_allocate_channels(26) #TODO: make it dependent on the SFX number. - - self.fps_limit = fps_limit - self.use_fixed_pipeline = fixed_pipeline + self.window = window self.replay_level = None self.skip = skip - self.has_exit = False self.keystate = 0 + self.use_fixed_pipeline = window.use_fixed_pipeline #XXX + self.width = window.width #XXX + self.height = window.height #XXX + if not self.use_fixed_pipeline: self.game_shader = GameShader() self.background_shader = BackgroundShader() @@ -122,14 +53,16 @@ class GameRunner(GameRenderer): glGenBuffers(2, vbo_array) self.vbo, self.back_vbo = vbo_array - if game: - self.load_game(game, background, replay) - - self.clock = Clock(self.fps_limit) - def load_game(self, game=None, background=None, bgms=None, replay=None, save_keystates=None): - GameRenderer.load_game(self, game, background) + self.game = game + self.background = background + + self.texture_manager.preload(game.resource_loader.instanced_anms.values()) + + if background: + self.prerender_background(background) + self.set_input(replay) if replay and replay.levels[game.stage - 1]: game.players[0].state.lives = self.replay_level.lives @@ -152,25 +85,11 @@ class GameRunner(GameRenderer): self.keys = self.replay_level.iter_keystates() - def set_size(self, width, height): - self.win.set_window_size(width, height) - - - def start(self, width=None, height=None): - width = width or (self.game.interface.width if self.game else 640) - height = height or (self.game.interface.height if self.game else 480) + def start(self): + width = self.game.interface.width if self.game else 640 + height = self.game.interface.height if self.game else 480 if (width, height) != (self.width, self.height): - self.set_size(width, height) - - # Initialize OpenGL - glEnable(GL_BLEND) - if self.use_fixed_pipeline: - glEnable(GL_TEXTURE_2D) - glHint(GL_FOG_HINT, GL_NICEST) - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST) - glEnableClientState(GL_COLOR_ARRAY) - glEnableClientState(GL_VERTEX_ARRAY) - glEnableClientState(GL_TEXTURE_COORD_ARRAY) + self.window.set_size(width, height) self.proj = perspective(30, float(self.game.width) / float(self.game.height), 101010101./2010101., 101010101./10101.) @@ -178,26 +97,13 @@ class GameRunner(GameRenderer): self.game_mvp = game_view * self.proj self.interface_mvp = ortho_2d(0., float(self.width), float(self.height), 0.) - while not self.has_exit: - if not self.skip: - self.update() - self.render_game() - self.render_interface() - self.win.gl_swap_window() - self.clock.tick() - else: - self.update() - if not self.use_fixed_pipeline: - vbo_array = (c_uint * 2)(self.vbo, self.back_vbo) - glDeleteBuffers(2, vbo_array) - - self.win.gl_delete_context() - self.win.destroy_window() - sdl.mix_close_audio() - sdl.mix_quit() - sdl.img_quit() - sdl.quit() + def finish(self): + #TODO: actually clean after buffers are not needed anymore. + #if not self.use_fixed_pipeline: + # vbo_array = (c_uint * 2)(self.vbo, self.back_vbo) + # glDeleteBuffers(2, vbo_array) + pass def update(self): @@ -208,9 +114,9 @@ class GameRunner(GameRenderer): if type_ == sdl.KEYDOWN: scancode = event[1] if scancode == sdl.SCANCODE_ESCAPE: - self.has_exit = True #TODO: implement the pause. + return False #TODO: implement the pause. elif type_ == sdl.QUIT: - self.has_exit = True + return False if self.game: if not self.replay_level: #TODO: allow user settings @@ -246,6 +152,10 @@ class GameRunner(GameRenderer): self.save_keystates.append(keystate) self.game.run_iter(keystate) + if not self.skip: + self.render_game() + self.render_interface() + return True def render_game(self): @@ -263,7 +173,7 @@ class GameRunner(GameRenderer): def render_interface(self): interface = self.game.interface - interface.labels['framerate'].set_text('%.2ffps' % self.clock.get_fps()) + interface.labels['framerate'].set_text('%.2ffps' % self.window.clock.get_fps()) if self.use_fixed_pipeline: glMatrixMode(GL_MODELVIEW)