comparison pytouhou/ui/gamerunner.py @ 418:63f59be04a54

Replace Pyglet with SDL2 for window creation and events; disables framerate control/display and sound.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Tue, 16 Jul 2013 21:07:15 +0200
parents 5fe6cd6ceb48
children 1c92721f8e49
comparison
equal deleted inserted replaced
417:efae61ad6efe 418:63f59be04a54
10 ## but WITHOUT ANY WARRANTY; without even the implied warranty of 10 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 ## GNU General Public License for more details. 12 ## GNU General Public License for more details.
13 ## 13 ##
14 14
15 import pyglet 15 from pytouhou.lib import sdl
16 import traceback
17 16
18 from pyglet.gl import (glMatrixMode, glLoadIdentity, glEnable, glDisable, 17 from pyglet.gl import (glMatrixMode, glLoadIdentity, glEnable, glDisable,
19 glHint, glEnableClientState, glViewport, glScissor, 18 glHint, glEnableClientState, glViewport, glScissor,
20 glLoadMatrixf, glGenBuffers, glDeleteBuffers, 19 glLoadMatrixf, glGenBuffers, glDeleteBuffers,
21 GL_MODELVIEW, GL_PROJECTION, 20 GL_MODELVIEW, GL_PROJECTION,
35 34
36 35
37 logger = get_logger(__name__) 36 logger = get_logger(__name__)
38 37
39 38
40 class GameRunner(pyglet.window.Window, GameRenderer): 39 class GameRunner(GameRenderer):
41 def __init__(self, resource_loader, game=None, background=None, replay=None, double_buffer=True, fps_limit=60, fixed_pipeline=False, skip=False): 40 def __init__(self, resource_loader, game=None, background=None, replay=None, double_buffer=True, fps_limit=60, fixed_pipeline=False, skip=False):
42 GameRenderer.__init__(self, resource_loader, game, background) 41 GameRenderer.__init__(self, resource_loader, game, background)
43 42
44 config = pyglet.gl.Config(double_buffer=double_buffer) 43 sdl.init(sdl.INIT_VIDEO)
45 width, height = (game.interface.width, game.interface.height) if game else (None, None) 44 sdl.gl_set_attribute(sdl.GL_CONTEXT_MAJOR_VERSION, 2)
46 pyglet.window.Window.__init__(self, width=width, height=height, 45 sdl.gl_set_attribute(sdl.GL_CONTEXT_MINOR_VERSION, 1)
47 caption='PyTouhou', resizable=False, 46 sdl.gl_set_attribute(sdl.GL_DOUBLEBUFFER, int(double_buffer))
48 config=config) 47 sdl.gl_set_attribute(sdl.GL_DEPTH_SIZE, 24)
48
49 self.width, self.height = (game.interface.width, game.interface.height) if game else (640, 480)
50 self.win = sdl.Window('PyTouhou',
51 sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED,
52 self.width, self.height,
53 sdl.WINDOW_OPENGL | sdl.WINDOW_SHOWN)
54 self.win.gl_create_context()
49 55
50 self.fps_limit = fps_limit 56 self.fps_limit = fps_limit
51 self.use_fixed_pipeline = fixed_pipeline 57 self.use_fixed_pipeline = fixed_pipeline
52 self.replay_level = None 58 self.replay_level = None
53 self.skip = skip 59 self.skip = skip
60 self.has_exit = False
61 self.keystate = 0
54 62
55 if not self.use_fixed_pipeline: 63 if not self.use_fixed_pipeline:
56 self.game_shader = GameShader() 64 self.game_shader = GameShader()
57 self.background_shader = BackgroundShader() 65 self.background_shader = BackgroundShader()
58 self.interface_shader = self.game_shader 66 self.interface_shader = self.game_shader
62 self.vbo, self.back_vbo = vbo_array 70 self.vbo, self.back_vbo = vbo_array
63 71
64 if game: 72 if game:
65 self.load_game(game, background, replay) 73 self.load_game(game, background, replay)
66 74
67 self.clock = pyglet.clock.get_default() 75 #self.clock = pyglet.clock.get_default()
68 76
69 77
70 def load_game(self, game=None, background=None, bgms=None, replay=None, save_keystates=None): 78 def load_game(self, game=None, background=None, bgms=None, replay=None, save_keystates=None):
71 GameRenderer.load_game(self, game, background) 79 GameRenderer.load_game(self, game, background)
72 self.set_input(replay) 80 self.set_input(replay)
83 game.sfx_player = SFXPlayer(game.resource_loader) if not self.skip else NullPlayer() 91 game.sfx_player = SFXPlayer(game.resource_loader) if not self.skip else NullPlayer()
84 92
85 93
86 def set_input(self, replay=None): 94 def set_input(self, replay=None):
87 if not replay or not replay.levels[self.game.stage-1]: 95 if not replay or not replay.levels[self.game.stage-1]:
88 self.keys = pyglet.window.key.KeyStateHandler()
89 self.push_handlers(self.keys)
90 self.replay_level = None 96 self.replay_level = None
91 else: 97 else:
92 self.replay_level = replay.levels[self.game.stage-1] 98 self.replay_level = replay.levels[self.game.stage-1]
93 self.keys = self.replay_level.iter_keystates() 99 self.keys = self.replay_level.iter_keystates()
100
101
102 def set_size(self, width, height):
103 self.win.set_window_size(width, height)
94 104
95 105
96 def start(self, width=None, height=None): 106 def start(self, width=None, height=None):
97 width = width or (self.game.interface.width if self.game else 640) 107 width = width or (self.game.interface.width if self.game else 640)
98 height = height or (self.game.interface.height if self.game else 480) 108 height = height or (self.game.interface.height if self.game else 480)
113 101010101./2010101., 101010101./10101.) 123 101010101./2010101., 101010101./10101.)
114 game_view = setup_camera(0, 0, 1) 124 game_view = setup_camera(0, 0, 1)
115 self.game_mvp = game_view * self.proj 125 self.game_mvp = game_view * self.proj
116 self.interface_mvp = ortho_2d(0., float(self.width), float(self.height), 0.) 126 self.interface_mvp = ortho_2d(0., float(self.width), float(self.height), 0.)
117 127
118 if self.fps_limit > 0: 128 #if self.fps_limit > 0:
119 pyglet.clock.set_fps_limit(self.fps_limit) 129 # pyglet.clock.set_fps_limit(self.fps_limit)
120 while not self.has_exit: 130 while not self.has_exit:
121 if not self.skip: 131 if not self.skip:
122 pyglet.clock.tick()
123 self.dispatch_events()
124 self.update() 132 self.update()
125 self.render_game() 133 self.render_game()
126 self.render_interface() 134 self.render_interface()
127 self.flip() 135 self.win.gl_swap_window()
128 else: 136 else:
129 self.update() 137 self.update()
130 138
131 if not self.use_fixed_pipeline: 139 if not self.use_fixed_pipeline:
132 vbo_array = (c_uint * 2)(self.vbo, self.back_vbo) 140 vbo_array = (c_uint * 2)(self.vbo, self.back_vbo)
133 glDeleteBuffers(2, vbo_array) 141 glDeleteBuffers(2, vbo_array)
134 142
135 143 self.win.gl_delete_context()
136 def _event_text_symbol(self, ev): 144 self.win.destroy_window()
137 # XXX: Ugly workaround to a pyglet bug on X11 145 sdl.quit()
138 #TODO: fix that bug in pyglet
139 try:
140 return pyglet.window.Window._event_text_symbol(self, ev)
141 except Exception as exc:
142 logger.warn('Pyglet error: %s', traceback.format_exc(exc))
143 return None, None
144
145
146 def on_key_press(self, symbol, modifiers):
147 if symbol == pyglet.window.key.ESCAPE:
148 self.has_exit = True
149 # XXX: Fullscreen will be enabled the day pyglet stops sucking
150 elif symbol == pyglet.window.key.F11:
151 self.set_fullscreen(not self.fullscreen)
152 146
153 147
154 def update(self): 148 def update(self):
155 if self.background: 149 if self.background:
156 self.background.update(self.game.frame) 150 self.background.update(self.game.frame)
151 for event in sdl.poll_events():
152 type_ = event[0]
153 if type_ == sdl.KEYDOWN:
154 scancode = event[1]
155 if scancode == sdl.SCANCODE_ESCAPE:
156 self.has_exit = True #TODO: implement the pause.
157 elif type_ == sdl.QUIT:
158 self.has_exit = True
157 if self.game: 159 if self.game:
158 if not self.replay_level: 160 if not self.replay_level:
159 #TODO: allow user settings 161 #TODO: allow user settings
162 keys = sdl.get_keyboard_state()
160 keystate = 0 163 keystate = 0
161 if self.keys[pyglet.window.key.W] or self.keys[pyglet.window.key.Z]: 164 if keys[sdl.SCANCODE_Z]:
162 keystate |= 1 165 keystate |= 1
163 if self.keys[pyglet.window.key.X]: 166 if keys[sdl.SCANCODE_X]:
164 keystate |= 2 167 keystate |= 2
165 #TODO: on some configurations, LSHIFT is Shift_L when pressed 168 if keys[sdl.SCANCODE_LSHIFT]:
166 # and ISO_Prev_Group when released, confusing the hell out of pyglet
167 # and leading to a always-on LSHIFT...
168 if self.keys[pyglet.window.key.LSHIFT]:
169 keystate |= 4 169 keystate |= 4
170 if self.keys[pyglet.window.key.UP]: 170 if keys[sdl.SCANCODE_UP]:
171 keystate |= 16 171 keystate |= 16
172 if self.keys[pyglet.window.key.DOWN]: 172 if keys[sdl.SCANCODE_DOWN]:
173 keystate |= 32 173 keystate |= 32
174 if self.keys[pyglet.window.key.LEFT]: 174 if keys[sdl.SCANCODE_LEFT]:
175 keystate |= 64 175 keystate |= 64
176 if self.keys[pyglet.window.key.RIGHT]: 176 if keys[sdl.SCANCODE_RIGHT]:
177 keystate |= 128 177 keystate |= 128
178 if self.keys[pyglet.window.key.LCTRL]: 178 if keys[sdl.SCANCODE_LCTRL]:
179 keystate |= 256 179 keystate |= 256
180 else: 180 else:
181 try: 181 try:
182 keystate = self.keys.next() 182 keystate = self.keys.next()
183 except StopIteration: 183 except StopIteration:
206 glDisable(GL_SCISSOR_TEST) 206 glDisable(GL_SCISSOR_TEST)
207 207
208 208
209 def render_interface(self): 209 def render_interface(self):
210 interface = self.game.interface 210 interface = self.game.interface
211 interface.labels['framerate'].set_text('%.2ffps' % self.clock.get_fps()) 211 #interface.labels['framerate'].set_text('%.2ffps' % self.clock.get_ticks())
212 212
213 if self.use_fixed_pipeline: 213 if self.use_fixed_pipeline:
214 glMatrixMode(GL_MODELVIEW) 214 glMatrixMode(GL_MODELVIEW)
215 glLoadMatrixf(self.interface_mvp.get_c_data()) 215 glLoadMatrixf(self.interface_mvp.get_c_data())
216 glDisable(GL_FOG) 216 glDisable(GL_FOG)