Mercurial > touhou
comparison pytouhou/ui/window.pyx @ 455:6864a38b2413
Make pytouhou.lib.sdl cimportable, and convert pytouhou.ui.window.* to extension types.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Mon, 02 Sep 2013 22:16:38 +0200 |
parents | 1f5156093785 |
children | cae1ae9de430 |
comparison
equal
deleted
inserted
replaced
454:a502887557ac | 455:6864a38b2413 |
---|---|
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 | 15 |
16 from pytouhou.lib import sdl | 16 from pytouhou.lib cimport sdl |
17 | 17 |
18 from pytouhou.lib.opengl cimport \ | 18 from pytouhou.lib.opengl cimport \ |
19 (glEnable, glHint, glEnableClientState, GL_TEXTURE_2D, GL_BLEND, | 19 (glEnable, glHint, glEnableClientState, GL_TEXTURE_2D, GL_BLEND, |
20 GL_PERSPECTIVE_CORRECTION_HINT, GL_FOG_HINT, GL_NICEST, | 20 GL_PERSPECTIVE_CORRECTION_HINT, GL_FOG_HINT, GL_NICEST, |
21 GL_COLOR_ARRAY, GL_VERTEX_ARRAY, GL_TEXTURE_COORD_ARRAY) | 21 GL_COLOR_ARRAY, GL_VERTEX_ARRAY, GL_TEXTURE_COORD_ARRAY) |
22 | 22 |
23 IF USE_GLEW: | 23 IF USE_GLEW: |
24 from pytouhou.lib.opengl cimport glewInit | 24 from pytouhou.lib.opengl cimport glewInit |
25 | 25 |
26 | 26 |
27 class Clock: | 27 cdef class Clock: |
28 def __init__(self, fps=None): | 28 cdef long _target_fps, _ref_tick, _ref_frame, _fps_tick, _fps_frame |
29 cdef double _rate | |
30 | |
31 def __init__(self, long fps=-1): | |
29 self._target_fps = 0 | 32 self._target_fps = 0 |
30 self._ref_tick = 0 | 33 self._ref_tick = 0 |
31 self._ref_frame = 0 | 34 self._ref_frame = 0 |
32 self._fps_tick = 0 | 35 self._fps_tick = 0 |
33 self._fps_frame = 0 | 36 self._fps_frame = 0 |
34 self._rate = 0 | 37 self._rate = 0 |
35 self.set_target_fps(fps) | 38 self.set_target_fps(fps) |
36 | 39 |
37 | 40 |
38 def set_target_fps(self, fps): | 41 cdef void set_target_fps(self, long fps) nogil: |
39 self._target_fps = fps | 42 self._target_fps = fps |
40 self._ref_tick = 0 | 43 self._ref_tick = 0 |
41 self._fps_tick = 0 | 44 self._fps_tick = 0 |
42 | 45 |
43 | 46 |
44 def get_fps(self): | 47 cdef double get_fps(self) nogil: |
45 return self._rate | 48 return self._rate |
46 | 49 |
47 | 50 |
48 def tick(self): | 51 cdef void tick(self) nogil except *: |
49 current = sdl.get_ticks() | 52 current = sdl.get_ticks() |
50 | 53 |
51 if not self._ref_tick: | 54 if not self._ref_tick: |
52 self._ref_tick = current | 55 self._ref_tick = current |
53 self._ref_frame = 0 | 56 self._ref_frame = 0 |
64 self._ref_frame += 1 | 67 self._ref_frame += 1 |
65 self._fps_frame += 1 | 68 self._fps_frame += 1 |
66 | 69 |
67 target_tick = self._ref_tick | 70 target_tick = self._ref_tick |
68 if self._target_fps: | 71 if self._target_fps: |
69 target_tick += int(self._ref_frame * 1000 / self._target_fps) | 72 target_tick += <long>(self._ref_frame * 1000 / self._target_fps) |
70 | 73 |
71 if current <= target_tick: | 74 if current <= target_tick: |
72 sdl.delay(target_tick - current) | 75 sdl.delay(target_tick - current) |
73 else: | 76 else: |
74 self._ref_tick = current | 77 self._ref_tick = current |
75 self._ref_frame = 0 | 78 self._ref_frame = 0 |
76 | 79 |
77 | 80 |
78 | 81 |
79 class Window(object): | 82 cdef class Window: |
80 def __init__(self, size=None, double_buffer=True, fps_limit=60, | 83 cdef sdl.Window win |
81 fixed_pipeline=False, sound=True): | 84 cdef long fps_limit |
85 cdef public long width, height | |
86 cdef public bint use_fixed_pipeline | |
87 cdef object runner | |
88 cdef Clock clock | |
89 | |
90 def __init__(self, size=None, bint double_buffer=True, long fps_limit=-1, | |
91 bint fixed_pipeline=False, bint sound=True): | |
82 self.fps_limit = fps_limit | 92 self.fps_limit = fps_limit |
83 self.use_fixed_pipeline = fixed_pipeline | 93 self.use_fixed_pipeline = fixed_pipeline |
84 self.runner = None | 94 self.runner = None |
85 | 95 |
86 IF UNAME_SYSNAME == "Windows": | 96 IF UNAME_SYSNAME == "Windows": |
93 sdl.gl_set_attribute(sdl.GL_CONTEXT_MAJOR_VERSION, 2) | 103 sdl.gl_set_attribute(sdl.GL_CONTEXT_MAJOR_VERSION, 2) |
94 sdl.gl_set_attribute(sdl.GL_CONTEXT_MINOR_VERSION, 1) | 104 sdl.gl_set_attribute(sdl.GL_CONTEXT_MINOR_VERSION, 1) |
95 sdl.gl_set_attribute(sdl.GL_DOUBLEBUFFER, int(double_buffer)) | 105 sdl.gl_set_attribute(sdl.GL_DOUBLEBUFFER, int(double_buffer)) |
96 sdl.gl_set_attribute(sdl.GL_DEPTH_SIZE, 24) | 106 sdl.gl_set_attribute(sdl.GL_DEPTH_SIZE, 24) |
97 | 107 |
98 self.width, self.height = size if size else (640, 480) | 108 self.width, self.height = size if size is not None else (640, 480) |
99 | 109 |
100 self.win = sdl.Window('PyTouhou', | 110 self.win = sdl.Window('PyTouhou', |
101 sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED, | 111 sdl.WINDOWPOS_CENTERED, sdl.WINDOWPOS_CENTERED, |
102 self.width, self.height, | 112 self.width, self.height, |
103 sdl.WINDOW_OPENGL | sdl.WINDOW_SHOWN) | 113 sdl.WINDOW_OPENGL | sdl.WINDOW_SHOWN) |
123 sdl.mix_allocate_channels(26) #TODO: make it dependent on the SFX number. | 133 sdl.mix_allocate_channels(26) #TODO: make it dependent on the SFX number. |
124 | 134 |
125 self.clock = Clock(self.fps_limit) | 135 self.clock = Clock(self.fps_limit) |
126 | 136 |
127 | 137 |
128 def set_size(self, width, height): | 138 cdef void set_size(self, int width, int height) nogil: |
129 self.win.set_window_size(width, height) | 139 self.win.set_window_size(width, height) |
130 | 140 |
131 | 141 |
132 def set_runner(self, runner): | 142 cpdef set_runner(self, runner=None): |
133 self.runner = runner | 143 self.runner = runner |
134 runner.start() | 144 if runner is not None: |
145 runner.start() | |
135 | 146 |
136 | 147 |
137 def run(self): | 148 cpdef run(self): |
138 try: | 149 try: |
139 while self.run_frame(): | 150 while self.run_frame(): |
140 pass | 151 pass |
141 finally: | 152 finally: |
142 self.runner.finish() | 153 self.runner.finish() |
143 | 154 |
144 | 155 |
145 def run_frame(self): | 156 cdef bint run_frame(self) except? False: |
146 if self.runner: | 157 cdef bint running = False |
158 if self.runner is not None: | |
147 running = self.runner.update() | 159 running = self.runner.update() |
148 self.win.gl_swap_window() | 160 self.win.gl_swap_window() |
149 self.clock.tick() | 161 self.clock.tick() |
150 return running | 162 return running |
151 | 163 |
152 | 164 |
165 cpdef double get_fps(self): | |
166 return self.clock.get_fps() | |
167 | |
168 | |
153 def __dealloc__(self): | 169 def __dealloc__(self): |
154 self.win.gl_delete_context() | |
155 self.win.destroy_window() | |
156 sdl.mix_close_audio() | 170 sdl.mix_close_audio() |
157 sdl.mix_quit() | 171 sdl.mix_quit() |
158 sdl.img_quit() | 172 sdl.img_quit() |
159 sdl.quit() | 173 sdl.quit() |