Mercurial > touhou
comparison pytouhou/ui/gamerunner.pyx @ 423:d8630c086926
Replace Pyglet with our own Cython OpenGL wrapper.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Tue, 16 Jul 2013 21:07:15 +0200 |
parents | pytouhou/ui/gamerunner.py@52829ebe2561 |
children | f4d76d3d6f2a |
comparison
equal
deleted
inserted
replaced
422:52829ebe2561 | 423:d8630c086926 |
---|---|
1 # -*- encoding: utf-8 -*- | |
2 ## | |
3 ## Copyright (C) 2011 Thibaut Girka <thib@sitedethib.com> | |
4 ## | |
5 ## This program is free software; you can redistribute it and/or modify | |
6 ## it under the terms of the GNU General Public License as published | |
7 ## by the Free Software Foundation; version 3 only. | |
8 ## | |
9 ## This program is distributed in the hope that it will be useful, | |
10 ## but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 ## GNU General Public License for more details. | |
13 ## | |
14 | |
15 from pytouhou.lib import sdl | |
16 | |
17 from pytouhou.lib.opengl cimport \ | |
18 (glMatrixMode, glEnable, glDisable, glViewport, glScissor, | |
19 glLoadMatrixf, glGenBuffers, glDeleteBuffers, GL_MODELVIEW, | |
20 GL_FOG, GL_SCISSOR_TEST) | |
21 | |
22 from pytouhou.utils.helpers import get_logger | |
23 from pytouhou.utils.maths cimport perspective, setup_camera, ortho_2d | |
24 from pytouhou.utils.matrix cimport matrix_to_floats | |
25 | |
26 from .gamerenderer import GameRenderer | |
27 from .background import BackgroundRenderer | |
28 from .music import MusicPlayer, SFXPlayer, NullPlayer | |
29 from .shaders.eosd import GameShader, BackgroundShader | |
30 | |
31 | |
32 logger = get_logger(__name__) | |
33 | |
34 | |
35 class GameRunner(GameRenderer): | |
36 def __init__(self, window, resource_loader, replay=None, skip=False): | |
37 self.use_fixed_pipeline = window.use_fixed_pipeline #XXX | |
38 | |
39 GameRenderer.__init__(self, resource_loader) | |
40 | |
41 self.window = window | |
42 self.replay_level = None | |
43 self.skip = skip | |
44 self.keystate = 0 | |
45 | |
46 self.width = window.width #XXX | |
47 self.height = window.height #XXX | |
48 | |
49 if not self.use_fixed_pipeline: | |
50 self.game_shader = GameShader() | |
51 self.background_shader = BackgroundShader() | |
52 self.interface_shader = self.game_shader | |
53 | |
54 | |
55 def load_game(self, game=None, background=None, bgms=None, replay=None, save_keystates=None): | |
56 self.game = game | |
57 self.background = background | |
58 | |
59 self.texture_manager.preload(game.resource_loader.instanced_anms.values()) | |
60 | |
61 if background: | |
62 self.background_renderer = BackgroundRenderer(self.texture_manager, self.use_fixed_pipeline) | |
63 self.background_renderer.prerender(background) | |
64 | |
65 self.set_input(replay) | |
66 if replay and replay.levels[game.stage - 1]: | |
67 game.players[0].state.lives = self.replay_level.lives | |
68 game.players[0].state.power = self.replay_level.power | |
69 game.players[0].state.bombs = self.replay_level.bombs | |
70 game.difficulty = self.replay_level.difficulty | |
71 | |
72 self.save_keystates = save_keystates | |
73 | |
74 game.music = MusicPlayer(game.resource_loader, bgms) | |
75 game.music.play(0) | |
76 game.sfx_player = SFXPlayer(game.resource_loader) if not self.skip else NullPlayer() | |
77 | |
78 | |
79 def set_input(self, replay=None): | |
80 if not replay or not replay.levels[self.game.stage-1]: | |
81 self.replay_level = None | |
82 else: | |
83 self.replay_level = replay.levels[self.game.stage-1] | |
84 self.keys = self.replay_level.iter_keystates() | |
85 | |
86 | |
87 def start(self): | |
88 width = self.game.interface.width if self.game else 640 | |
89 height = self.game.interface.height if self.game else 480 | |
90 if (width, height) != (self.width, self.height): | |
91 self.window.set_size(width, height) | |
92 | |
93 self.proj = perspective(30, float(self.game.width) / float(self.game.height), | |
94 101010101./2010101., 101010101./10101.) | |
95 game_view = setup_camera(0, 0, 1) | |
96 self.game_mvp = game_view * self.proj | |
97 self.interface_mvp = ortho_2d(0., float(self.width), float(self.height), 0.) | |
98 | |
99 | |
100 def finish(self): | |
101 #TODO: actually clean after buffers are not needed anymore. | |
102 #if not self.use_fixed_pipeline: | |
103 # vbo_array = (c_uint * 2)(self.vbo, self.back_vbo) | |
104 # glDeleteBuffers(2, vbo_array) | |
105 pass | |
106 | |
107 | |
108 def update(self): | |
109 if self.background: | |
110 self.background.update(self.game.frame) | |
111 for event in sdl.poll_events(): | |
112 type_ = event[0] | |
113 if type_ == sdl.KEYDOWN: | |
114 scancode = event[1] | |
115 if scancode == sdl.SCANCODE_ESCAPE: | |
116 return False #TODO: implement the pause. | |
117 elif type_ == sdl.QUIT: | |
118 return False | |
119 if self.game: | |
120 if not self.replay_level: | |
121 #TODO: allow user settings | |
122 keys = sdl.get_keyboard_state() | |
123 keystate = 0 | |
124 if keys[sdl.SCANCODE_Z]: | |
125 keystate |= 1 | |
126 if keys[sdl.SCANCODE_X]: | |
127 keystate |= 2 | |
128 if keys[sdl.SCANCODE_LSHIFT]: | |
129 keystate |= 4 | |
130 if keys[sdl.SCANCODE_UP]: | |
131 keystate |= 16 | |
132 if keys[sdl.SCANCODE_DOWN]: | |
133 keystate |= 32 | |
134 if keys[sdl.SCANCODE_LEFT]: | |
135 keystate |= 64 | |
136 if keys[sdl.SCANCODE_RIGHT]: | |
137 keystate |= 128 | |
138 if keys[sdl.SCANCODE_LCTRL]: | |
139 keystate |= 256 | |
140 else: | |
141 try: | |
142 keystate = self.keys.next() | |
143 except StopIteration: | |
144 keystate = 0 | |
145 if self.skip: | |
146 self.set_input() | |
147 self.skip = False | |
148 self.game.sfx_player = SFXPlayer(self.game.resource_loader) | |
149 | |
150 if self.save_keystates is not None: | |
151 self.save_keystates.append(keystate) | |
152 | |
153 self.game.run_iter(keystate) | |
154 if not self.skip: | |
155 self.render_game() | |
156 self.render_interface() | |
157 return True | |
158 | |
159 | |
160 def render_game(self): | |
161 # Switch to game projection | |
162 #TODO: move that to GameRenderer? | |
163 x, y = self.game.interface.game_pos | |
164 glViewport(x, y, self.game.width, self.game.height) | |
165 glScissor(x, y, self.game.width, self.game.height) | |
166 glEnable(GL_SCISSOR_TEST) | |
167 | |
168 GameRenderer.render(self) | |
169 | |
170 glDisable(GL_SCISSOR_TEST) | |
171 | |
172 | |
173 def render_interface(self): | |
174 interface = self.game.interface | |
175 interface.labels['framerate'].set_text('%.2ffps' % self.window.clock.get_fps()) | |
176 | |
177 if self.use_fixed_pipeline: | |
178 glMatrixMode(GL_MODELVIEW) | |
179 glLoadMatrixf(matrix_to_floats(self.interface_mvp)) | |
180 glDisable(GL_FOG) | |
181 else: | |
182 self.interface_shader.bind() | |
183 #self.interface_shader.uniform_matrixf('mvp', matrix_to_floats(self.interface_mvp)) | |
184 self.interface_shader.uniform_matrixf('mvp', self.interface_mvp.get_c_data()) | |
185 glViewport(0, 0, self.width, self.height) | |
186 | |
187 items = [item for item in interface.items if item.anmrunner and item.anmrunner.running] | |
188 labels = interface.labels.values() | |
189 | |
190 if items: | |
191 # Redraw all the interface | |
192 self.render_elements(items) | |
193 else: | |
194 # Redraw only changed labels | |
195 labels = [label for label in labels if label.changed] | |
196 | |
197 self.render_elements(interface.level_start) | |
198 | |
199 if self.game.boss: | |
200 self.render_elements(interface.boss_items) | |
201 | |
202 self.render_elements(labels) | |
203 for label in labels: | |
204 label.changed = False | |
205 |