Mercurial > touhou
view pytouhou/ui/gamerunner.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) 2011 Thibaut Girka <thib@sitedethib.com> ## ## 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 from pytouhou.lib cimport sdl from .window cimport Window, Runner from .music import BGMPlayer, SFXPlayer from pytouhou.game.game cimport Game from pytouhou.game.music cimport MusicPlayer cdef class GameRunner(Runner): cdef object background, con, resource_loader, keys, replay_level, common cdef Game game cdef Window window cdef list save_keystates cdef bint skip # Since we want to support multiple renderers, don’t specify its type. #TODO: find a way to still specify its interface. cdef object renderer def __init__(self, Window window, renderer, common, resource_loader, bint skip=False, con=None): self.renderer = renderer self.common = common self.resource_loader = resource_loader self.window = window self.replay_level = None self.skip = skip self.con = con self.width = common.interface.width self.height = common.interface.height def load_game(self, Game game, background=None, bgms=None, replay=None, save_keystates=None): self.game = game self.background = background if self.renderer is not None: self.renderer.load_textures(self.resource_loader.instanced_anms) self.renderer.load_background(background) self.set_input(replay) if replay and replay.levels[game.stage - 1]: game.players[0].lives = self.replay_level.lives game.players[0].power = self.replay_level.power game.players[0].bombs = self.replay_level.bombs game.difficulty = self.replay_level.difficulty self.save_keystates = save_keystates null_player = MusicPlayer() if bgms is not None: game.music = BGMPlayer(self.resource_loader, bgms) game.music.play(0) else: game.music = null_player game.sfx_player = SFXPlayer(self.resource_loader) if not self.skip else null_player cdef void set_input(self, replay=None) except *: if not replay or not replay.levels[self.game.stage-1]: self.replay_level = None else: self.replay_level = replay.levels[self.game.stage-1] self.keys = self.replay_level.iter_keystates() @cython.cdivision(True) cdef void set_renderer_size(self, long width, long height) except *: if self.renderer is not None: runner_width = float(self.width) runner_height = float(self.height) scale = min(width / runner_width, height / runner_height) new_width = <long>(runner_width * scale) new_height = <long>(runner_height * scale) x = (width - new_width) // 2 y = (height - new_height) // 2 self.renderer.size = x, y, new_width, new_height cdef void start(self) except *: if self.renderer is not None: self.set_renderer_size(self.width, self.height) self.renderer.start(self.common) cdef void capture(self) except *: if self.renderer is not None: filename = 'screenshot/frame%06d.ppm' % self.game.frame self.renderer.capture(filename, self.width, self.height) cpdef bint update(self, bint render) except -1: cdef long keystate capture = False if self.background is not None: self.background.update(self.game.frame) for event in sdl.poll_events(): type_ = event[0] if type_ == sdl.KEYDOWN: scancode = event[1] if scancode == sdl.SCANCODE_ESCAPE: return False #TODO: implement the pause. elif scancode == sdl.SCANCODE_P or scancode == sdl.SCANCODE_HOME: capture = True elif type_ == sdl.QUIT: return False elif type_ == sdl.WINDOWEVENT: event_ = event[1] if event_ == sdl.WINDOWEVENT_RESIZED: self.set_renderer_size(event[2], event[3]) if self.window is not None: self.window.set_size(event[2], event[3]) if self.replay_level is None: #TODO: allow user settings keys = sdl.keyboard_state keystate = 0 if keys[sdl.SCANCODE_Z]: keystate |= 1 if keys[sdl.SCANCODE_X]: keystate |= 2 if keys[sdl.SCANCODE_LSHIFT]: keystate |= 4 if keys[sdl.SCANCODE_UP]: keystate |= 16 if keys[sdl.SCANCODE_DOWN]: keystate |= 32 if keys[sdl.SCANCODE_LEFT]: keystate |= 64 if keys[sdl.SCANCODE_RIGHT]: keystate |= 128 if keys[sdl.SCANCODE_LCTRL]: keystate |= 256 else: try: keystate = self.keys.next() except StopIteration: keystate = 0 if self.skip: self.set_input() self.skip = False self.game.sfx_player = SFXPlayer(self.resource_loader) if self.save_keystates is not None: self.save_keystates.append(keystate) if self.con is not None: self.con.run_iter(self.game, keystate) else: self.game.run_iter([keystate]) labels = self.game.interface.labels if self.window is not None and 'framerate' in labels: labels['framerate'].set_text('%.2ffps' % self.window.get_fps()) if render and not self.skip and self.renderer is not None: self.renderer.render(self.game) if capture: self.capture() return True