retrograph_easy 0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,257 @@
1
+ # retrograph/easy/app
2
+ #
3
+ # Copyright (c) 2009 MenTaLguY <mental@rydia.net>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+ #
23
+
24
+ require 'sdl'
25
+ require 'retrograph/easy/display'
26
+ require 'retrograph/easy/periodic'
27
+ require 'retrograph/easy/sprites'
28
+ require 'retrograph/easy/controllers'
29
+
30
+ module Retrograph
31
+ module Easy
32
+
33
+ class Quit < Exception
34
+ def initialize(message="User quit")
35
+ super(message)
36
+ end
37
+ end
38
+
39
+ class App
40
+ def initialize(display)
41
+ @_retrograph_held_event = nil
42
+ @_retrograph_display = display
43
+ @_retrograph_sprite_manager = SpriteManager.new(display)
44
+ @_retrograph_controller_manager = ControllerManager.new
45
+ @_retrograph_controllers =
46
+ @_retrograph_controller_manager.controllers.freeze
47
+ @_retrograph_periodic_manager = PeriodicManager.new
48
+ end
49
+
50
+ attr_reader :_retrograph_controllers
51
+ alias_method :controllers, :_retrograph_controllers
52
+ remove_method :_retrograph_controllers
53
+
54
+ def title(new_title)
55
+ @_retrograph_display.title = new_title
56
+ self
57
+ end
58
+
59
+ def start(label, interval, phases=1)
60
+ @_retrograph_periodic_manager.start label, interval, phases
61
+ nil
62
+ end
63
+
64
+ def stop(label)
65
+ @_retrograph_periodic_manager.stop label
66
+ nil
67
+ end
68
+
69
+ def frame_for?(label)
70
+ @_retrograph_periodic_manager.frame_for? label
71
+ end
72
+
73
+ def phase_of(label)
74
+ @_retrograph_periodic_manager.phase_of label
75
+ end
76
+
77
+ def already?(label)
78
+ @_retrograph_periodic_manager.already? label
79
+ end
80
+
81
+ def clear_sprites
82
+ @_retrograph_sprite_manager.clear_sprites
83
+ self
84
+ end
85
+
86
+ def sprite(x, y, pattern, flags)
87
+ @_retrograph_sprite_manager.add_sprite(x, y, pattern, flags)
88
+ end
89
+
90
+ def multi_sprite(x, y, pattern, width_tiles, height_tiles, flags)
91
+ @_retrograph_sprite_manager.add_multi_sprite(x, y, pattern, width_tiles, height_tiles, flags)
92
+ end
93
+
94
+ def sprite_group(x, y, width, height, flags)
95
+ @_retrograph_sprite_manager.add_sprite_group(x, y, width, height, flags) do
96
+ yield
97
+ end
98
+ end
99
+
100
+ def palette_entry_rgb(index, r, g, b)
101
+ r = (r * 255).round if Float === r
102
+ g = (g * 255).round if Float === g
103
+ b = (b * 255).round if Float === b
104
+ raise RangeError, "index out of range" if index < 0 or index > 31
105
+ entry = ((r >> 2) & 0x30) |
106
+ ((g >> 4) & 0x0c) |
107
+ ((b >> 6) & 0x03)
108
+ palette_entry(index, entry)
109
+ self
110
+ end
111
+
112
+ def palette_entry(index, entry)
113
+ @_retrograph_display.write_vdu_byte(0x7f00+index, entry)
114
+ end
115
+
116
+ def reset_vdu
117
+ write_vdu(0x0000, "\000" * 0x4000)
118
+ self
119
+ end
120
+
121
+ def vdu_mode(mode)
122
+ write_vdu_byte(0x7ff8, mode)
123
+ self
124
+ end
125
+
126
+ def write_vdu(offset, data)
127
+ @_retrograph_display.write_vdu(offset, data)
128
+ self
129
+ end
130
+
131
+ def write_vdu_byte(offset, byte)
132
+ @_retrograph_display.write_vdu_byte(offset, byte)
133
+ self
134
+ end
135
+
136
+ def tile_pattern_1bit(base, index, data)
137
+ @_retrograph_display.write_vdu(base + index * 8, data)
138
+ self
139
+ end
140
+
141
+ def tile_pattern_2bit(base, index, data)
142
+ @_retrograph_display.write_vdu(base + index * 16, data)
143
+ self
144
+ end
145
+
146
+ def tile_pattern_4bit(base, index, data)
147
+ @_retrograph_display.write_vdu(base + index * 32, data)
148
+ self
149
+ end
150
+
151
+ def sprite_pattern(base, index, data)
152
+ tile_pattern_4bit(base + 0x2000, index, data)
153
+ self
154
+ end
155
+
156
+ def wait_scanlines(count)
157
+ @_retrograph_display.wait_scanlines(count)
158
+ self
159
+ end
160
+
161
+ def quit
162
+ raise Quit
163
+ end
164
+
165
+ def _suspend
166
+ while event = SDL::Event2.wait
167
+ case event
168
+ when SDL::Event2::Quit
169
+ quit
170
+ when SDL::Event2::Active
171
+ if event.gain and event.state == 2
172
+ break
173
+ end
174
+ end
175
+ end
176
+ while event = SDL::Event2.wait
177
+ case event
178
+ when SDL::Event2::Quit
179
+ quit
180
+ when SDL::Event2::KeyDown
181
+ case event.sym
182
+ when SDL::Key::RALT, SDL::Key::LALT
183
+ # ignore alt presses
184
+ else
185
+ @_retrograph_held_event = event
186
+ break
187
+ end
188
+ end
189
+ end
190
+ end
191
+ private :_suspend
192
+
193
+ def each_of_n_frames(n_frames)
194
+ each_frame(n_frames) { yield }
195
+ end
196
+
197
+ def each_frame(n_frames=nil)
198
+ count = 0
199
+ @_retrograph_display.each_frame do
200
+ break if n_frames == count
201
+ while event = (@_retrograph_held_event || SDL::Event2.poll)
202
+ @_retrograph_held_event = nil
203
+ case event
204
+ when SDL::Event2::Quit
205
+ quit
206
+ when SDL::Event2::Active
207
+ if not event.gain and event.state == 2
208
+ _suspend
209
+ next
210
+ end
211
+ when SDL::Event2::KeyDown
212
+ @_retrograph_controller_manager.key_pressed(event.sym)
213
+ if (event.mod & SDL::Key::MOD_ALT).nonzero?
214
+ case event.sym
215
+ when SDL::Key::RETURN
216
+ @_retrograph_display.toggle_fullscreen
217
+ when SDL::Key::F4
218
+ quit
219
+ when SDL::Key::TAB
220
+ if @_retrograph_display.managed and @_retrograph_display.fullscreen
221
+ @_retrograph_display.minimize
222
+ end
223
+ end
224
+ end
225
+ case event.sym
226
+ when SDL::Key::ESCAPE
227
+ quit
228
+ when SDL::Key::F11
229
+ @_retrograph_display.toggle_fullscreen
230
+ end
231
+ when SDL::Event2::KeyUp
232
+ @_retrograph_controller_manager.key_released(event.sym)
233
+ end
234
+ end
235
+ yield
236
+ @_retrograph_periodic_manager.tick()
237
+ count += 1 if n_frames
238
+ end
239
+ end
240
+ end
241
+
242
+ @display = Display.new
243
+
244
+ class << self
245
+ def app(&block)
246
+ begin
247
+ @display.open do
248
+ app = App.new(@display)
249
+ app.instance_eval &block
250
+ end
251
+ rescue Quit
252
+ end
253
+ end
254
+ end
255
+
256
+ end
257
+ end
@@ -0,0 +1,35 @@
1
+ # retrograph/easy/constants
2
+ #
3
+ # Copyright (c) 2009 MenTaLguY <mental@rydia.net>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+ #
23
+
24
+ module Retrograph
25
+ module Easy
26
+
27
+ TEXT_MODE_A = 0
28
+ TEXT_MODE_B = 1
29
+ GRAPHICS_MODE_A = 2
30
+ GRAPHICS_MODE_B = 3
31
+ ENABLE_SPRITES = 1 << 3
32
+ ENABLE_BG = 1 << 2
33
+
34
+ end
35
+ end
@@ -0,0 +1,184 @@
1
+ # retrograph/easy/controllers
2
+ #
3
+ # Copyright (c) 2009 MenTaLguY <mental@rydia.net>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+ #
23
+
24
+ module Retrograph
25
+ module Easy
26
+
27
+ class Rocker
28
+ attr_reader :state
29
+
30
+ def initialize(minus_state, neutral_state, plus_state)
31
+ @minus_state = minus_state
32
+ @neutral_state = neutral_state
33
+ @plus_state = plus_state
34
+ @state = @neutral_state
35
+ @both_pressed = false
36
+ end
37
+
38
+ def plus_pressed
39
+ @both_pressed = true if @state != @neutral_state
40
+ @state = @plus_state
41
+ self
42
+ end
43
+
44
+ def minus_pressed
45
+ @both_pressed = true if @state != @neutral_state
46
+ @state = @minus_state
47
+ self
48
+ end
49
+
50
+ def plus_released
51
+ if @both_pressed
52
+ @both_pressed = false
53
+ @state = @minus_state
54
+ else
55
+ @state = @neutral_state
56
+ end
57
+ self
58
+ end
59
+
60
+ def minus_released
61
+ if @both_pressed
62
+ @both_pressed = false
63
+ @state = @plus_state
64
+ else
65
+ @state = @neutral_state
66
+ end
67
+ self
68
+ end
69
+ end
70
+
71
+ button_names = %w(up down left right a b select start)
72
+ controller_fields = button_names.map { |n| "#{n}_pressed".intern } +
73
+ [:horizontal, :vertical]
74
+
75
+ Controller = Struct.new *controller_fields
76
+ Controller.class_eval do
77
+ FIELD_DEFAULTS = button_names.map { false } + [0, 0]
78
+
79
+ def initialize
80
+ super(*FIELD_DEFAULTS)
81
+ end
82
+
83
+ for name in button_names
84
+ field = "#{name}_pressed".intern
85
+ alias_method "#{field}?".intern, field
86
+ end
87
+ end
88
+
89
+ class ControllerManager
90
+ KEYMAP = {
91
+ SDL::Key::UP => :up,
92
+ SDL::Key::DOWN => :down,
93
+ SDL::Key::LEFT => :left,
94
+ SDL::Key::RIGHT => :right,
95
+ SDL::Key::LCTRL => :a,
96
+ SDL::Key::RCTRL => :a,
97
+ SDL::Key::SPACE => :b,
98
+ SDL::Key::LSHIFT => :select,
99
+ SDL::Key::RSHIFT => :select,
100
+ SDL::Key::TAB => :select,
101
+ SDL::Key::RETURN => :start,
102
+ SDL::Key::W => :up,
103
+ SDL::Key::S => :down,
104
+ SDL::Key::D => :right,
105
+ SDL::Key::A => :left,
106
+ SDL::Key::Z => :select,
107
+ SDL::Key::X => :b,
108
+ SDL::Key::C => :a,
109
+ SDL::Key::COMMA => :a,
110
+ SDL::Key::PERIOD => :b,
111
+ SDL::Key::SLASH => :select
112
+ }
113
+
114
+ def initialize
115
+ @controllers = (0...2).map { Controller.new }
116
+ @horizontal = @controllers.map { Rocker.new(-1, 0, 1) }
117
+ @vertical = @controllers.map { Rocker.new(-1, 0, 1) }
118
+ end
119
+
120
+ def controllers
121
+ @controllers.dup
122
+ end
123
+
124
+ def key_pressed(key)
125
+ case KEYMAP[key]
126
+ when :up
127
+ @controllers[0].up_pressed = true
128
+ @vertical[0].minus_pressed
129
+ @controllers[0].vertical = @vertical[0].state
130
+ when :down
131
+ @controllers[0].down_pressed = true
132
+ @vertical[0].plus_pressed
133
+ @controllers[0].vertical = @vertical[0].state
134
+ when :left
135
+ @controllers[0].left_pressed = true
136
+ @horizontal[0].minus_pressed
137
+ @controllers[0].horizontal = @horizontal[0].state
138
+ when :right
139
+ @controllers[0].right_pressed = true
140
+ @horizontal[0].plus_pressed
141
+ @controllers[0].horizontal = @horizontal[0].state
142
+ when :a
143
+ @controllers[0].a_pressed = true
144
+ when :b
145
+ @controllers[0].b_pressed = true
146
+ when :select
147
+ @controllers[0].select_pressed = true
148
+ when :start
149
+ @controllers[0].start_pressed = true
150
+ end
151
+ end
152
+
153
+ def key_released(key)
154
+ case KEYMAP[key]
155
+ when :up
156
+ @controllers[0].up_pressed = false
157
+ @vertical[0].minus_pressed
158
+ @controllers[0].vertical = @vertical[0].state
159
+ when :down
160
+ @controllers[0].down_pressed = false
161
+ @vertical[0].plus_released
162
+ @controllers[0].vertical = @vertical[0].state
163
+ when :left
164
+ @controllers[0].left_pressed = false
165
+ @horizontal[0].minus_released
166
+ @controllers[0].horizontal = @horizontal[0].state
167
+ when :right
168
+ @controllers[0].right_pressed = false
169
+ @horizontal[0].plus_released
170
+ @controllers[0].horizontal = @horizontal[0].state
171
+ when :a
172
+ @controllers[0].a_pressed = false
173
+ when :b
174
+ @controllers[0].b_pressed = false
175
+ when :select
176
+ @controllers[0].select_pressed = false
177
+ when :start
178
+ @controllers[0].start_pressed = false
179
+ end
180
+ end
181
+ end
182
+
183
+ end
184
+ end
@@ -0,0 +1,173 @@
1
+ # retrograph/easy/display
2
+ #
3
+ # Copyright (c) 2009 MenTaLguY <mental@rydia.net>
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+ #
23
+
24
+ require 'retrograph/sdl'
25
+
26
+ module Retrograph
27
+ module Easy
28
+
29
+ FRAMES_PER_SECOND = 25
30
+ FRAME_TIME_MS = 1000/FRAMES_PER_SECOND
31
+
32
+ class Display
33
+ BEZEL_THICKNESS = 16
34
+
35
+ def initialize(sdl=SDL, vdu_class=VDU)
36
+ @sdl = sdl
37
+ @vdu = nil
38
+ @vdu_class = vdu_class
39
+ @surface = nil
40
+ @managed = false
41
+ @fullscreen = false
42
+ @old_fullscreen = false
43
+ @screen = nil
44
+ @bezel_image = nil
45
+ @title = "Retrograph application"
46
+ end
47
+
48
+ attr_reader :title
49
+ attr_reader :fullscreen
50
+ attr_reader :managed
51
+
52
+ def title=(value)
53
+ @title = value.to_s
54
+ @sdl::WM.set_caption(@title, @title)
55
+ value
56
+ end
57
+
58
+ def fullscreen=(value)
59
+ @fullscreen = !!value
60
+ value
61
+ end
62
+
63
+ def toggle_fullscreen
64
+ @fullscreen = !@fullscreen
65
+ nil
66
+ end
67
+
68
+ def write_vdu(offset, data)
69
+ @vdu.write(offset, data)
70
+ end
71
+
72
+ def write_vdu_byte(offset, byte)
73
+ @vdu.write_byte(offset, byte)
74
+ end
75
+
76
+ def wait_scanlines(count)
77
+ @vdu.wait_scanlines(count)
78
+ end
79
+
80
+ def each_frame
81
+ while true
82
+ start_time = @sdl.get_ticks
83
+ @surface = @vdu.render_frame_sdl { yield }
84
+ _set_mode if @managed and @old_fullscreen != @fullscreen
85
+ @old_fullscreen = @fullscreen
86
+ _update_screen
87
+ end_time = @sdl.get_ticks
88
+ sleep_time = FRAME_TIME_MS - (end_time - start_time)
89
+ sleep(sleep_time / 1000.0) if sleep_time > 0
90
+ end
91
+ end
92
+
93
+ def open
94
+ @sdl.init SDL::INIT_VIDEO
95
+ info = @sdl::Screen.info
96
+ @managed = info.wm_available
97
+ @vdu = @vdu_class.new
98
+ @surface = @vdu.render_frame_sdl
99
+ _set_mode
100
+ if block_given?
101
+ begin
102
+ yield
103
+ ensure
104
+ close
105
+ end
106
+ else
107
+ nil
108
+ end
109
+ end
110
+
111
+ def minimize
112
+ @sdl::WM.iconify
113
+ nil
114
+ end
115
+
116
+ def close
117
+ nil
118
+ end
119
+
120
+ def _bezel_func(d)
121
+ ((1.0-(d-0.5)*2))**2 + 0.07
122
+ end
123
+ private :_bezel_func
124
+
125
+ def _generate_bezel
126
+ bezel_color = @bezel_image.format.map_rgb(8, 8, 8)
127
+ clear_color = @bezel_image.format.map_rgb(255, 255, 255)
128
+ @bezel_image.fill_rect(0, 0, OUTPUT_WIDTH, OUTPUT_HEIGHT, clear_color)
129
+ for i in 0...BEZEL_THICKNESS
130
+ section = _bezel_func(i.to_f / (BEZEL_THICKNESS-1))
131
+ section = 1.0 if section > 1.0
132
+ hlength = (OUTPUT_WIDTH / 2 * section).to_i
133
+ vlength = (OUTPUT_HEIGHT / 2 * section).to_i
134
+ @bezel_image.fill_rect(0, i, hlength, 1, bezel_color)
135
+ @bezel_image.fill_rect(0, OUTPUT_HEIGHT - 1 - i, hlength, 1, bezel_color)
136
+ @bezel_image.fill_rect(OUTPUT_WIDTH - hlength, i, hlength, 1, bezel_color)
137
+ @bezel_image.fill_rect(OUTPUT_WIDTH - hlength, OUTPUT_HEIGHT - 1 - i, hlength, 1, bezel_color)
138
+ @bezel_image.fill_rect(i, 0, 1, vlength, bezel_color)
139
+ @bezel_image.fill_rect(OUTPUT_WIDTH - 1 - i, 0, 1, vlength, bezel_color)
140
+ @bezel_image.fill_rect(i, OUTPUT_HEIGHT - vlength, 1, vlength, bezel_color)
141
+ @bezel_image.fill_rect(OUTPUT_WIDTH - 1 - i, OUTPUT_HEIGHT - vlength, 1, vlength, bezel_color)
142
+ end
143
+ @bezel_image.set_color_key(SDL::SRCCOLORKEY | SDL::RLEACCEL, clear_color)
144
+ end
145
+ private :_generate_bezel
146
+
147
+ def _set_mode
148
+ flags = SDL::HWSURFACE | SDL::DOUBLEBUF
149
+ flags |= SDL::FULLSCREEN if fullscreen?
150
+ @screen = @sdl::Screen.open(OUTPUT_WIDTH, OUTPUT_HEIGHT, 32, flags)
151
+ @bezel_image = @sdl::Surface.new(0, OUTPUT_WIDTH, OUTPUT_HEIGHT,
152
+ @screen.format)
153
+ _generate_bezel
154
+ @sdl::WM.set_caption(@title, @title)
155
+ @sdl::Mouse.hide
156
+ _update_screen
157
+ end
158
+ private :_set_mode
159
+
160
+ def _update_screen
161
+ @sdl::Surface.blit(@surface, 0, 0, 0, 0, @screen, 0, 0)
162
+ @sdl::Surface.blit(@bezel_image, 0, 0, 0, 0, @screen, 0, 0)
163
+ @screen.flip
164
+ end
165
+ private :_update_screen
166
+
167
+ def fullscreen?
168
+ not @managed or @fullscreen
169
+ end
170
+ end
171
+
172
+ end
173
+ end