tung-tea 0.0.4

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,299 @@
1
+ # This file holds the key press and modifier events.
2
+
3
+ require 'sdl'
4
+
5
+ #
6
+ module Tea
7
+
8
+ module Kbd
9
+ # Event generated when a key is pressed down.
10
+ #
11
+ # +key+:: Physical key that was pressed, as a symbol (see key reference).
12
+ # +mods+:: Hash of the active key modifiers. Values are +true+ or
13
+ # +false+, and the keys can be: +:L_SHIFT+, +:R_SHIFT+,
14
+ # +:L_CTRL+, +:R_CTRL+, +:L_ALT+, +:R_ALT+, +:NUM_LOCK+,
15
+ # +:CAPS_LOCK+, +:ALT_GR+. Also, +:SHIFT+, +:CTRL+ and +:ALT+
16
+ # are provided for convenience, and Tea key constants with the
17
+ # same names can be used instead.
18
+ # +char+:: String character generated by that key and those modifiers.
19
+ # With Ruby >= 1.9, the encoding of this character is UTF-8,
20
+ # otherwise it varies with the running environment.
21
+ class Down
22
+ attr_reader :key, :mods, :char
23
+ def initialize(sdl_event)
24
+ @key = Kbd.instance_variable_get(:@sdl_key_table)[sdl_event.sym]
25
+ @mods = Kbd.send(:decode_modifiers, sdl_event.mod)
26
+
27
+ # Ruby 1.9 uses UTF-8 Unicode encoding. Below this, who knows how
28
+ # Unicode code points are interpreted?
29
+ if sdl_event.unicode != 0
30
+ unicode_field = "%c"
31
+ ruby_minor = RUBY_VERSION.match(/\.(\d+)\./)
32
+ if ruby_minor && ruby_minor[1].to_i >= 9
33
+ unicode_field = unicode_field.encode('utf-8')
34
+ end
35
+ @char = unicode_field % sdl_event.unicode
36
+ else
37
+ @char = ''
38
+ end
39
+ end
40
+ end
41
+
42
+ # Event generated when a held-down key is released. +key+ and +mods+ are
43
+ # the same as in KeyDown.
44
+ #
45
+ # +key+:: Physical key that was pressed, as a symbol (see key reference).
46
+ # +mods+:: Hash of the active key modifiers. Values are +true+ or
47
+ # +false+, and the keys can be: +:L_SHIFT+, +:R_SHIFT+,
48
+ # +:L_CTRL+, +:R_CTRL+, +:L_ALT+, +:R_ALT+, +:NUM_LOCK+,
49
+ # +:CAPS_LOCK+, +:ALT_GR+. Also, +:SHIFT+, +:CTRL+ and +:ALT+
50
+ # are provided for convenience, and Tea key constants with the
51
+ # same names can be used instead.
52
+ class Up
53
+ attr_reader :key, :mods
54
+ def initialize(sdl_event)
55
+ @key = Kbd.instance_variable_get(:@sdl_key_table)[sdl_event.sym]
56
+ @mods = Kbd.send(:decode_modifiers, sdl_event.mod)
57
+ end
58
+ end
59
+
60
+ # Returns +true+ if +key+ is being pressed down.
61
+ def Kbd.key_down?(key)
62
+ if (down = @key_states[key]) == nil
63
+ raise Tea::Error, "Can't find key #{key} to check", caller
64
+ end
65
+ down
66
+ end
67
+
68
+ # Returns true if the modifier is 'active'. For +:L_SHIFT+, +:R_SHIFT+,
69
+ # +:L_CTRL+, +:R_CTRL+, +:L_ALT+, and +:ALT_GR+ (and convenience modifier
70
+ # constants +:SHIFT+, +:CTRL+ and +:ALT+), this means they're being held
71
+ # down. For +:NUM_LOCK+ and +:CAPS_LOCK+, this means their toggle is on.
72
+ def Kbd.mod_active?(mod)
73
+ if (active = @mod_states[mod]) == nil
74
+ raise Tea::Error, "Can't find modifier #{mod} to check", caller
75
+ end
76
+ active
77
+ end
78
+
79
+ # Returns true if the keyboard is focused in the screen window.
80
+ def Kbd.in_app?
81
+ @in_app = true if !instance_variable_defined?(:@in_app)
82
+ @in_app
83
+ end
84
+
85
+ # Update the keyboard state, so that Kbd.key_down? and Kbd.mod_active?
86
+ # provide fresh data. Called automatically by Event.get.
87
+ def Kbd.update_state(tea_event)
88
+ case tea_event
89
+ when Down, Up
90
+ @key_states[tea_event.key] = (tea_event.class == Down)
91
+ @mod_states.merge! tea_event.mods
92
+ when Lost then @in_app = false
93
+ when Gained then @in_app = true
94
+ end
95
+ end
96
+
97
+ # Decode the SDL key event mod into a hash of easily consulted key modifier
98
+ # symbols. For internal use only.
99
+ def Kbd.decode_modifiers(sdl_key_event_mod)
100
+ mods = {}
101
+
102
+ mods[:L_SHIFT] = (sdl_key_event_mod & SDL::Key::MOD_LSHIFT) != 0
103
+ mods[:R_SHIFT] = (sdl_key_event_mod & SDL::Key::MOD_RSHIFT) != 0
104
+ mods[:SHIFT] = mods[:L_SHIFT] || mods[:R_SHIFT]
105
+
106
+ mods[:L_CTRL] = (sdl_key_event_mod & SDL::Key::MOD_LCTRL) != 0
107
+ mods[:R_CTRL] = (sdl_key_event_mod & SDL::Key::MOD_RCTRL) != 0
108
+ mods[:CTRL] = mods[:L_CTRL] || mods[:R_CTRL]
109
+
110
+ mods[:L_ALT] = (sdl_key_event_mod & SDL::Key::MOD_LALT) != 0
111
+ mods[:R_ALT] = (sdl_key_event_mod & SDL::Key::MOD_RALT) != 0
112
+ mods[:ALT] = mods[:L_ALT] || mods[:R_ALT]
113
+
114
+ mods[:NUM_LOCK] = (sdl_key_event_mod & SDL::Key::MOD_NUM) != 0
115
+ mods[:CAPS_LOCK] = (sdl_key_event_mod & SDL::Key::MOD_CAPS) != 0
116
+ mods[:ALT_GR] = (sdl_key_event_mod & SDL::Key::MOD_MODE) != 0
117
+
118
+ mods
119
+ end
120
+ private_class_method :decode_modifiers
121
+
122
+ # Big fat table of SDL keys to Ruby strings. For internal use only.
123
+ @sdl_key_table = { SDL::Key::BACKSPACE => :BACKSPACE,
124
+ SDL::Key::TAB => :TAB,
125
+ #SDL::Key::CLEAR => clear, # ???
126
+ SDL::Key::RETURN => :ENTER,
127
+ SDL::Key::PAUSE => :PAUSE,
128
+ SDL::Key::ESCAPE => :ESCAPE,
129
+ SDL::Key::SPACE => :SPACE,
130
+ SDL::Key::EXCLAIM => :EXCLAMATION_MARK,
131
+ SDL::Key::QUOTEDBL => :DOUBLE_QUOTE,
132
+ SDL::Key::HASH => :HASH,
133
+ SDL::Key::DOLLAR => :DOLLAR,
134
+ SDL::Key::AMPERSAND => :AMPERSAND,
135
+ SDL::Key::QUOTE => :QUOTE,
136
+ SDL::Key::LEFTPAREN => :OPEN_PAREN,
137
+ SDL::Key::RIGHTPAREN => :CLOSE_PAREN,
138
+ SDL::Key::ASTERISK => :ASTERISK,
139
+ SDL::Key::PLUS => :PLUS,
140
+ SDL::Key::COMMA => :COMMA,
141
+ SDL::Key::MINUS => :MINUS,
142
+ SDL::Key::PERIOD => :PERIOD,
143
+ SDL::Key::SLASH => :SLASH,
144
+ SDL::Key::K0 => :K0,
145
+ SDL::Key::K1 => :K1,
146
+ SDL::Key::K2 => :K2,
147
+ SDL::Key::K3 => :K3,
148
+ SDL::Key::K4 => :K4,
149
+ SDL::Key::K5 => :K5,
150
+ SDL::Key::K6 => :K6,
151
+ SDL::Key::K7 => :K7,
152
+ SDL::Key::K8 => :K8,
153
+ SDL::Key::K9 => :K9,
154
+ SDL::Key::COLON => :COLON,
155
+ SDL::Key::SEMICOLON => :SEMICOLON,
156
+ SDL::Key::LESS => :LESS_THAN,
157
+ SDL::Key::EQUALS => :EQUALS,
158
+ SDL::Key::GREATER => :GREATER_THAN,
159
+ SDL::Key::QUESTION => :QUESTION_MARK,
160
+ SDL::Key::AT => :AT,
161
+ SDL::Key::LEFTBRACKET => :OPEN_SQUARE_BRACKET,
162
+ SDL::Key::BACKSLASH => :BACKSLASH,
163
+ SDL::Key::RIGHTBRACKET => :CLOSE_SQUARE_BRACKET,
164
+ SDL::Key::CARET => :CARET,
165
+ SDL::Key::UNDERSCORE => :UNDERSCORE,
166
+ SDL::Key::BACKQUOTE => :BACKTICK,
167
+ SDL::Key::A => :A,
168
+ SDL::Key::B => :B,
169
+ SDL::Key::C => :C,
170
+ SDL::Key::D => :D,
171
+ SDL::Key::E => :E,
172
+ SDL::Key::F => :F,
173
+ SDL::Key::G => :G,
174
+ SDL::Key::H => :H,
175
+ SDL::Key::I => :I,
176
+ SDL::Key::J => :J,
177
+ SDL::Key::K => :K,
178
+ SDL::Key::L => :L,
179
+ SDL::Key::M => :M,
180
+ SDL::Key::N => :N,
181
+ SDL::Key::O => :O,
182
+ SDL::Key::P => :P,
183
+ SDL::Key::Q => :Q,
184
+ SDL::Key::R => :R,
185
+ SDL::Key::S => :S,
186
+ SDL::Key::T => :T,
187
+ SDL::Key::U => :U,
188
+ SDL::Key::V => :V,
189
+ SDL::Key::W => :W,
190
+ SDL::Key::X => :X,
191
+ SDL::Key::Y => :Y,
192
+ SDL::Key::Z => :Z,
193
+ SDL::Key::DELETE => :DELETE,
194
+ SDL::Key::KP0 => :NP0,
195
+ SDL::Key::KP1 => :NP1,
196
+ SDL::Key::KP2 => :NP2,
197
+ SDL::Key::KP3 => :NP3,
198
+ SDL::Key::KP4 => :NP4,
199
+ SDL::Key::KP5 => :NP5,
200
+ SDL::Key::KP6 => :NP6,
201
+ SDL::Key::KP7 => :NP7,
202
+ SDL::Key::KP8 => :NP8,
203
+ SDL::Key::KP9 => :NP9,
204
+ SDL::Key::KP_PERIOD => :NP_PERIOD,
205
+ SDL::Key::KP_DIVIDE => :NP_DIVIDE,
206
+ SDL::Key::KP_MULTIPLY => :NP_MULTIPLY,
207
+ SDL::Key::KP_MINUS => :NP_MINUS,
208
+ SDL::Key::KP_PLUS => :NP_PLUS,
209
+ SDL::Key::KP_ENTER => :NP_ENTER,
210
+ SDL::Key::KP_EQUALS => :NP_EQUALS,
211
+ SDL::Key::UP => :UP,
212
+ SDL::Key::DOWN => :DOWN,
213
+ SDL::Key::RIGHT => :RIGHT,
214
+ SDL::Key::LEFT => :LEFT,
215
+ SDL::Key::INSERT => :INSERT,
216
+ SDL::Key::HOME => :HOME,
217
+ SDL::Key::END => :END,
218
+ SDL::Key::PAGEUP => :PAGE_UP,
219
+ SDL::Key::PAGEDOWN => :PAGE_DOWN,
220
+ SDL::Key::F1 => :F1,
221
+ SDL::Key::F2 => :F2,
222
+ SDL::Key::F3 => :F3,
223
+ SDL::Key::F4 => :F4,
224
+ SDL::Key::F5 => :F5,
225
+ SDL::Key::F6 => :F6,
226
+ SDL::Key::F7 => :F7,
227
+ SDL::Key::F8 => :F8,
228
+ SDL::Key::F9 => :F9,
229
+ SDL::Key::F10 => :F10,
230
+ SDL::Key::F11 => :F11,
231
+ SDL::Key::F12 => :F12,
232
+ #SDL::Key::F13 => F13, # Who
233
+ #SDL::Key::F14 => F14, # has
234
+ #SDL::Key::F15 => F15, # these?
235
+ SDL::Key::NUMLOCK => :NUM_LOCK,
236
+ SDL::Key::CAPSLOCK => :CAPS_LOCK,
237
+ SDL::Key::SCROLLOCK => :SCROLL_LOCK,
238
+ SDL::Key::RSHIFT => :R_SHIFT,
239
+ SDL::Key::LSHIFT => :L_SHIFT,
240
+ SDL::Key::RCTRL => :R_CTRL,
241
+ SDL::Key::LCTRL => :L_CTRL,
242
+ SDL::Key::RALT => :R_ALT,
243
+ SDL::Key::LALT => :L_ALT,
244
+ #SDL::Key::RMETA => right meta, # 'meta' should
245
+ #SDL::Key::LMETA => left meta, # be 'alt'?
246
+ SDL::Key::LSUPER => :L_SUPER,
247
+ SDL::Key::RSUPER => :R_SUPER,
248
+ SDL::Key::MODE => :ALT_GR,
249
+ #SDL::Key::HELP => help, # Rare enough to cause problems.
250
+ SDL::Key::PRINT => :PRINT_SCREEN,
251
+ SDL::Key::SYSREQ => :SYS_REQ,
252
+ SDL::Key::BREAK => :BREAK,
253
+ SDL::Key::MENU => :MENU,
254
+ #SDL::Key::POWER => power, # "Power Macintosh" power key
255
+ SDL::Key::EURO => :EURO, # Some European keyboards need this.
256
+ }
257
+
258
+ # Define Tea key symbols as constants to avoid typo errors.
259
+ @sdl_key_table.each_value { |sym| const_set(sym, sym) }
260
+
261
+ # Extra modifier constants for making modifier detection more consistent.
262
+ SHIFT = :shift
263
+ CTRL = :ctrl
264
+ ALT = :alt
265
+
266
+ # Initialise key states to false, as opposed to nil.
267
+ @key_states = {}
268
+ @sdl_key_table.each_value { |sym| @key_states[sym] = false }
269
+
270
+ # Modifier states, same deal.
271
+ @mod_states = { :L_SHIFT => false, :R_SHIFT => false, :SHIFT => false,
272
+ :L_CTRL => false, :R_CTRL => false, :CTRL => false,
273
+ :L_ALT => false, :R_ALT => false, :ALT => false,
274
+ :NUM_LOCK => false,
275
+ :CAPS_LOCK => false,
276
+ :ALT_GR => false }
277
+ end
278
+
279
+ module Event
280
+
281
+ # Convert a keyboard-related SDL::Event into a Tea event. For internal use
282
+ # only.
283
+ def Event.translate_keyboard_event(sdl_event)
284
+ out_events = []
285
+
286
+ case sdl_event
287
+ when SDL::Event::KeyDown
288
+ out_events.push Kbd::Down.new(sdl_event)
289
+ when SDL::Event::KeyUp
290
+ out_events.push Kbd::Up.new(sdl_event)
291
+ end
292
+
293
+ out_events
294
+ end
295
+ private_class_method :translate_keyboard_event
296
+
297
+ end
298
+
299
+ end
@@ -0,0 +1,190 @@
1
+ # This file holds the mouse motion and button events.
2
+
3
+ require 'sdl'
4
+
5
+ # Hot-patch for Ruby/SDL for missing mouse wheel constants.
6
+ module SDL
7
+ module Mouse
8
+ BUTTON_WHEELUP = 4
9
+ BUTTON_WHEELDOWN = 5
10
+ end
11
+ end
12
+
13
+ #
14
+ module Tea
15
+
16
+ module Mouse
17
+
18
+ # Mouse button constants for mouse events.
19
+ LEFT = :LEFT
20
+ MIDDLE = :MIDDLE
21
+ RIGHT = :RIGHT
22
+
23
+ # Event generated when the mouse cursor is moved.
24
+ #
25
+ # +x+, +y+:: coordinates of the mouse cursor
26
+ # +buttons+:: an array that may contain +:left+, +:middle+ and +:right+
27
+ class Move
28
+ attr_reader :x, :y, :buttons
29
+ def initialize(sdl_event)
30
+ @x = sdl_event.x
31
+ @y = sdl_event.y
32
+ @buttons = {}
33
+ @buttons[Mouse::LEFT] = (sdl_event.state & SDL::Mouse::BUTTON_LMASK) != 0
34
+ @buttons[Mouse::MIDDLE] = (sdl_event.state & SDL::Mouse::BUTTON_MMASK) != 0
35
+ @buttons[Mouse::RIGHT] = (sdl_event.state & SDL::Mouse::BUTTON_RMASK) != 0
36
+ end
37
+ end
38
+
39
+ # Event generated when a mouse button is held down.
40
+ #
41
+ # +x+, +y+:: coordinates of the mouse cursor
42
+ # +button+:: the mouse button that is down: +:left+, +:middle+ or +:right+
43
+ class Down
44
+ attr_reader :x, :y, :button
45
+ def initialize(sdl_event)
46
+ @x = sdl_event.x
47
+ @y = sdl_event.y
48
+ case sdl_event.button
49
+ when SDL::Mouse::BUTTON_LEFT then @button = Mouse::LEFT
50
+ when SDL::Mouse::BUTTON_MIDDLE then @button = Mouse::MIDDLE
51
+ when SDL::Mouse::BUTTON_RIGHT then @button = Mouse::RIGHT
52
+ end
53
+ end
54
+ end
55
+
56
+ # Event generated when a mouse button that was held down is released.
57
+ #
58
+ # +x+, +y+:: coordinates of the mouse cursor
59
+ # +button+:: the mouse button that was released: +:left+, +:middle+ or
60
+ # +:right+
61
+ class Up
62
+ attr_reader :x, :y, :button
63
+ def initialize(sdl_event)
64
+ @x = sdl_event.x
65
+ @y = sdl_event.y
66
+ case sdl_event.button
67
+ when SDL::Mouse::BUTTON_LEFT then @button = Mouse::LEFT
68
+ when SDL::Mouse::BUTTON_MIDDLE then @button = Mouse::MIDDLE
69
+ when SDL::Mouse::BUTTON_RIGHT then @button = Mouse::RIGHT
70
+ end
71
+ end
72
+ end
73
+
74
+ # Event generated when the mouse wheel is scrolled.
75
+ #
76
+ # +x+, +y+:: coordinates of the mouse cursor.
77
+ # +delta+:: 1 when scrolling down, -1 when scrolling up.
78
+ class Scroll
79
+ attr_reader :x, :y, :delta
80
+ def initialize(sdl_event)
81
+ @x = sdl_event.x
82
+ @y = sdl_event.y
83
+ case sdl_event.button
84
+ when SDL::Mouse::BUTTON_WHEELDOWN then @delta = 1
85
+ when SDL::Mouse::BUTTON_WHEELUP then @delta = -1
86
+ else
87
+ raise Tea::Error, "Tea::Mouse::Scroll given an unexpected event: #{sdl_event.inspect}", caller
88
+ end
89
+ end
90
+ end
91
+
92
+ # Report the x position of the mouse in the screen window. Updated when
93
+ # Event.get is called.
94
+ def Mouse.x
95
+ @x = 0 if !instance_variable_defined?(:@x)
96
+ @x
97
+ end
98
+
99
+ # Report the y position of the mouse in the screen window. Updated when
100
+ # Event.get is called.
101
+ def Mouse.y
102
+ @y = 0 if !instance_variable_defined?(:@y)
103
+ @y
104
+ end
105
+
106
+ # Returns true if the left mouse button is down. Updated when Event.get is
107
+ # called.
108
+ def Mouse.left?
109
+ @left = false if !instance_variable_defined?(:@left)
110
+ @left
111
+ end
112
+
113
+ # Returns true if the middle mouse button is down. Updated when Event.get
114
+ # is called.
115
+ def Mouse.middle?
116
+ @middle = false if !instance_variable_defined?(:@middle)
117
+ @middle
118
+ end
119
+
120
+ # Returns true if the right mouse button is down. Updated when Event.get
121
+ # is called.
122
+ def Mouse.right?
123
+ @right = false if !instance_variable_defined?(:@right)
124
+ @right
125
+ end
126
+
127
+ # Returns true if the mouse is in the screen window
128
+ def Mouse.in_app?
129
+ @in_app = true if !instance_variable_defined?(:@in_app)
130
+ @in_app
131
+ end
132
+
133
+ # Update the mouse state, so that Mouse.x, Mouse.y, Mouse.left?,
134
+ # Mouse.middle? and Mouse.right? return recent data.
135
+ def Mouse.update_state(tea_event)
136
+ case tea_event
137
+ when Move
138
+ @x = tea_event.x
139
+ @y = tea_event.y
140
+ when Down
141
+ case tea_event.button
142
+ when LEFT then @left = true
143
+ when MIDDLE then @middle = true
144
+ when RIGHT then @right = true
145
+ end
146
+ when Up
147
+ case tea_event.button
148
+ when LEFT then @left = false
149
+ when MIDDLE then @middle = false
150
+ when RIGHT then @right = false
151
+ end
152
+ when Lost
153
+ @in_app = false
154
+ when Gained
155
+ @in_app = true
156
+ end
157
+ end
158
+ end
159
+
160
+ module Event
161
+
162
+ # Convert a mouse-related SDL::Event into a Tea event. For internal use only.
163
+ def Event.translate_mouse_event(sdl_event)
164
+ out_events = []
165
+
166
+ case sdl_event
167
+ when SDL::Event::MouseMotion
168
+ out_events.push Mouse::Move.new(sdl_event)
169
+ when SDL::Event::MouseButtonDown
170
+ case sdl_event.button
171
+ when SDL::Mouse::BUTTON_LEFT, SDL::Mouse::BUTTON_MIDDLE, SDL::Mouse::BUTTON_RIGHT
172
+ out_events.push Mouse::Down.new(sdl_event)
173
+ when SDL::Mouse::BUTTON_WHEELDOWN, SDL::Mouse::BUTTON_WHEELUP
174
+ out_events.push Mouse::Scroll.new(sdl_event)
175
+ end
176
+ when SDL::Event::MouseButtonUp
177
+ # Ignore MouseButtonUp for the scroll wheel.
178
+ case sdl_event.button
179
+ when SDL::Mouse::BUTTON_LEFT, SDL::Mouse::BUTTON_MIDDLE, SDL::Mouse::BUTTON_RIGHT
180
+ out_events.push Mouse::Up.new(sdl_event)
181
+ end
182
+ end
183
+
184
+ out_events
185
+ end
186
+ private_class_method :translate_mouse_event
187
+
188
+ end
189
+
190
+ end
@@ -0,0 +1,79 @@
1
+ # This file holds the classes and methods needed to draw primitives on Bitmaps.
2
+
3
+ require 'sdl'
4
+
5
+ #
6
+ module Tea
7
+
8
+ private
9
+
10
+ # The PrimitiveDrawing mixin enables primitive shapes to be drawn to classes
11
+ # with an internal SDL::Surface.
12
+ #
13
+ # To use this mixin, include it and implement/alias a +primitive_buffer+
14
+ # method that gets the object's SDL::Surface.
15
+ #
16
+ # include 'PrimitiveDrawing'
17
+ # def primitive_buffer
18
+ # @internal_sdl_buffer
19
+ # end
20
+ module PrimitiveDrawing
21
+
22
+ # Clear the drawing buffer. This is the same as drawing a completely black
23
+ # rectangle over the whole buffer.
24
+ def clear
25
+ primitive_buffer.fill_rect 0, 0, primitive_buffer.w, primitive_buffer.h,
26
+ primitive_color(0x000000ff)
27
+ end
28
+
29
+ # Plot a point at (x, y) with the given color (0xRRGGBBAA) on the Bitmap.
30
+ def point(x, y, color)
31
+ primitive_buffer[x, y] = primitive_color(color)
32
+ end
33
+
34
+ # Draw a rectangle of size w * h with the top-left corner at (x, y) with
35
+ # the given color (0xRRGGBBAA).
36
+ def rect(x, y, w, h, color)
37
+ primitive_buffer.fill_rect x, y, w, h, primitive_color(color)
38
+ end
39
+
40
+ # Draw a line from (x1, y1) to (x2, y2) with the given color (0xRRGGBBAA).
41
+ # Optional hash arguments:
42
+ #
43
+ # +:antialias+:: If true, smooth the line with antialiasing.
44
+ def line(x1, y1, x2, y2, color, options=nil)
45
+ primitive_buffer.draw_line x1, y1, x2, y2,
46
+ primitive_color(color),
47
+ (options[:antialias] if options)
48
+ end
49
+
50
+ # Draw a circle centred at (x, y) with the given radius and color.
51
+ # Optional hash arguments:
52
+ #
53
+ # +:outline+:: If true, do not fill the circle, just draw an outline.
54
+ # +:antialias+:: If true, smooth the edges of the circle with
55
+ # antialiasing.
56
+ def circle(x, y, radius, color, options=nil)
57
+ if options
58
+ primitive_buffer.draw_circle x, y, radius, primitive_color(color),
59
+ !options[:outline], options[:antialias]
60
+ else
61
+ primitive_buffer.draw_circle x, y, radius, primitive_color(color), true
62
+ end
63
+ end
64
+
65
+ private
66
+
67
+ # Convert hex_color of the form 0xRRGGBBAA to a color value the
68
+ # primitive_buffer understands.
69
+ def primitive_color(hex_color)
70
+ red = (hex_color & 0xff000000) >> 24
71
+ green = (hex_color & 0x00ff0000) >> 16
72
+ blue = (hex_color & 0x0000ff00) >> 8
73
+ alpha = (hex_color & 0x000000ff)
74
+ primitive_buffer.map_rgba(red, green, blue, alpha)
75
+ end
76
+
77
+ end
78
+
79
+ end
data/lib/tea/screen.rb ADDED
@@ -0,0 +1,59 @@
1
+ # This file contains the Screen class.
2
+
3
+ require 'sdl'
4
+
5
+ require 'tea/m_blitting'
6
+ require 'tea/m_primitive_drawing'
7
+
8
+ #
9
+ module Tea
10
+
11
+ # A Bitmap-like object that displays its contents on the screen when drawn to
12
+ # and updated.
13
+ class Screen
14
+
15
+ # Video buffer depth.
16
+ BITS_PER_PIXEL = 32
17
+
18
+ # Set or change the screen video mode, giving a width * height screen buffer.
19
+ def Screen.set_mode(width, height)
20
+ begin
21
+ @screen = SDL::Screen.open(width, height, BITS_PER_PIXEL, SDL::SWSURFACE)
22
+ @set_mode_callbacks.each { |c| c.call }
23
+ rescue SDL::Error => e
24
+ raise Tea::Error, e.message, e.backtrace
25
+ end
26
+ end
27
+
28
+ # Check if Screen.set_mode has been called yet.
29
+ def Screen.mode_set?
30
+ @screen ? true : false
31
+ end
32
+
33
+ # Set a proc to be called when Screen.set_mode is called. The proc will be
34
+ # called after the new screen mode is set. The callback ordering is not
35
+ # defined, so don't make callbacks that depend on other callbacks being
36
+ # called first.
37
+ def Screen.on_set_mode(callback)
38
+ @set_mode_callbacks << callback
39
+ end
40
+ @set_mode_callbacks = []
41
+
42
+ # Get the screen width in pixels.
43
+ def Screen.w; @screen.w; end
44
+
45
+ # Get the screen height in pixels.
46
+ def Screen.h; @screen.h; end
47
+
48
+ # Update the screen so that things drawn on it are displayed.
49
+ def Screen.update; @screen.flip; end
50
+
51
+ extend Blitting
52
+ def Screen.blittable_buffer; @screen; end
53
+
54
+ extend PrimitiveDrawing
55
+ def Screen.primitive_buffer; @screen; end
56
+
57
+ end
58
+
59
+ end
data/lib/tea.rb ADDED
@@ -0,0 +1,29 @@
1
+ # Tea is a simple 2D game development library for Ruby.
2
+
3
+ require 'sdl'
4
+
5
+ require 'tea/c_bitmap'
6
+ require 'tea/c_error'
7
+ require 'tea/m_event'
8
+ require 'tea/screen'
9
+
10
+ # The Tea module acts as a namespace for all Tea-related objects and
11
+ # methods.
12
+ module Tea
13
+
14
+ # Initialise Tea. This needs to be called before using any of Tea's
15
+ # objects or methods.
16
+ #
17
+ # May throw Tea::Error if initialisation fails.
18
+ def Tea.init
19
+ begin
20
+ SDL.init(SDL::INIT_VIDEO)
21
+
22
+ # Get typed characters from keys when pressed.
23
+ SDL::Event.enable_unicode
24
+ rescue SDL::Error => e
25
+ raise Tea::Error, e.message, e.backtrace
26
+ end
27
+ end
28
+
29
+ end