Mercurial > touhou
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) |