tung-tea 0.2.4 → 0.3.0

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.
data/README.rdoc CHANGED
@@ -68,7 +68,7 @@ Below is a simple bouncing circle demo.
68
68
  What's working:
69
69
 
70
70
  * Events/Input - done
71
- * Graphics - nearly done, still need sub-bitmap grabbing
71
+ * Graphics - done
72
72
 
73
73
  What isn't done yet:
74
74
 
@@ -0,0 +1,28 @@
1
+ # Test that grabbing from bitmaps works.
2
+ # Expected results are a smiley on the screen, but with its quarters swapped.
3
+
4
+ require 'tea'
5
+
6
+ puts <<TEST
7
+ You should see a smiley in the centre of the screen for 5 seconds, but with its
8
+ quarters swapped.
9
+ TEST
10
+
11
+ Tea.init
12
+ Tea::Screen.set_mode 320, 240
13
+
14
+ smiley = Tea::Bitmap.new("smile.png")
15
+ sw2 = smiley.w / 2
16
+ sh2 = smiley.h / 2
17
+ top_left = smiley.grab( 0, 0, sw2, sh2)
18
+ top_right = smiley.grab(sw2, 0, sw2, sh2)
19
+ bottom_left = smiley.grab( 0, sh2, sw2, sh2)
20
+ bottom_right = smiley.grab(sw2, sh2, sw2, sh2)
21
+
22
+ Tea::Screen.blit bottom_right, Tea::Screen.w / 2 - sw2, Tea::Screen.h / 2 - sh2
23
+ Tea::Screen.blit bottom_left, Tea::Screen.w / 2, Tea::Screen.h / 2 - sh2
24
+ Tea::Screen.blit top_right, Tea::Screen.w / 2 - sw2, Tea::Screen.h / 2
25
+ Tea::Screen.blit top_left, Tea::Screen.w / 2, Tea::Screen.h / 2
26
+ Tea::Screen.update
27
+
28
+ sleep 5
@@ -29,6 +29,12 @@ x, y = 205, 15
29
29
  up, down, left, right = false, false, false, false
30
30
  wait_for_event = true
31
31
 
32
+ b = Tea::Bitmap.new(180, 130, 0x00000000)
33
+ b.rect 45, 32, 90, 65, 0xff0000ff
34
+ b.rect 0, 0, 90, 65, 0x00ff0080, :mix => :blend
35
+ b.rect 90, 65, 90, 65, 0x0000ff80, :mix => :replace
36
+ b.rect 0, 65, 90, 65, 0xffffff80
37
+
32
38
  begin
33
39
  Tea::Screen.clear
34
40
 
@@ -37,11 +43,6 @@ begin
37
43
  Tea::Screen.rect 200, 150, 200, 150, 0x0000ff80, :mix => :replace
38
44
  Tea::Screen.rect 0, 150, 200, 150, 0xffffff80
39
45
 
40
- b = Tea::Bitmap.new(180, 130, 0x00000000)
41
- b.rect 45, 32, 90, 65, 0xff0000ff
42
- b.rect 0, 0, 90, 65, 0x00ff0080, :mix => :blend
43
- b.rect 90, 65, 90, 65, 0x0000ff80, :mix => :replace
44
- b.rect 0, 65, 90, 65, 0xffffff80
45
46
  Tea::Screen.blit b, x, y
46
47
 
47
48
  Tea::Screen.update
@@ -63,8 +64,8 @@ begin
63
64
  end
64
65
  end
65
66
  wait_for_event = !(up || down || left || right)
66
- x -= 8 if left
67
- x += 8 if right
68
- y -= 8 if up
69
- y += 8 if down
67
+ x -= 1 if left
68
+ x += 1 if right
69
+ y -= 1 if up
70
+ y += 1 if down
70
71
  end until e.class == Tea::App::Exit || (e.class == Tea::Kbd::Down && e.key == Tea::Kbd::ESCAPE)
@@ -32,6 +32,16 @@ Tea::Clipping:
32
32
 
33
33
  These clip methods get, set and run a block with a clipping rectangle respectively. While a clipping rectangle is set, drawing will be clipped inside it.
34
34
 
35
+ Tea::Grabbing:
36
+ * grab([x, y, w, h])
37
+
38
+ This grab method copies a sub-section of the Bitmap (or all of it if no arguments are given) and returns it as a new Bitmap object.
39
+
40
+ Tea::ImageSaving:
41
+ * save(path)
42
+
43
+ The save method saves the Bitmap as an image file.
44
+
35
45
  Tea::Primitive:
36
46
  * clear()
37
47
  * point(x, y, color)
@@ -76,6 +86,16 @@ Tea::Clipping:
76
86
 
77
87
  These clip methods get, set and run a block with a clipping rectangle respectively. While a clipping rectangle is set, drawing will be clipped inside it.
78
88
 
89
+ Tea::Grabbing:
90
+ * grab([x, y, w, h])
91
+
92
+ This grab method copies a sub-section of the screen (or all of it if no arguments are given) and returns it as a new Bitmap object.
93
+
94
+ Tea::ImageSaving:
95
+ * save(path)
96
+
97
+ The save method saves the Screen as an image file.
98
+
79
99
  Tea::Primitive:
80
100
  * clear()
81
101
  * point(x, y, color)
data/lib/tea/c_bitmap.rb CHANGED
@@ -5,6 +5,8 @@ require 'sdl'
5
5
 
6
6
  require 'tea/mix_blitting'
7
7
  require 'tea/mix_clipping'
8
+ require 'tea/mix_grabbing'
9
+ require 'tea/mix_image_saving'
8
10
  require 'tea/mix_primitive'
9
11
 
10
12
  #
@@ -39,17 +41,27 @@ module Tea
39
41
  @buffer.h
40
42
  end
41
43
 
42
- include Tea::Blitting
44
+ include Blitting
43
45
  def blitting_buffer
44
46
  @buffer
45
47
  end
46
48
 
47
- include Tea::Clipping
49
+ include Clipping
48
50
  def clipping_buffer
49
51
  @buffer
50
52
  end
51
53
 
52
- include Tea::Primitive
54
+ include Grabbing
55
+ def grabbing_buffer
56
+ @buffer
57
+ end
58
+
59
+ include ImageSaving
60
+ def image_saving_buffer
61
+ @buffer
62
+ end
63
+
64
+ include Primitive
53
65
  def primitive_buffer
54
66
  @buffer
55
67
  end
@@ -0,0 +1,86 @@
1
+ # This file contains the Grabbing mixin, which makes a new Bitmap object based
2
+ # on some part of a bitmap-like pixel buffer.
3
+
4
+ require 'sdl'
5
+
6
+ require 'tea/c_bitmap'
7
+
8
+ #
9
+ module Tea
10
+
11
+ # This module gives bitmap-like objects a +grab+ method that takes a
12
+ # 'snapshot' of some part of it and returns it as a new Bitmap.
13
+ #
14
+ # To use this mixin, include it and define a +grabbing_buffer+ method:
15
+ #
16
+ # include Grabbing
17
+ # def grabbing_buffer
18
+ # @my_sdl_buffer
19
+ # end
20
+ #
21
+ module Grabbing
22
+
23
+ # Grab some part of the bitmap-like object, and return it as a new
24
+ # Tea::Bitmap object.
25
+ #
26
+ # This can be called in two ways:
27
+ #
28
+ # * ():: create a deep-copy of the whole bitmap-like object.
29
+ # * (x, y, w, h):: copy the pixels within the box at (x, y) of size w * h.
30
+ #
31
+ # May raise Tea::Error if the box given (if any) is outside the bitmap.
32
+ def grab(*box)
33
+ buffer = grabbing_buffer
34
+
35
+ case box.length
36
+ when 0
37
+ x = 0
38
+ y = 0
39
+ w = buffer.w
40
+ h = buffer.h
41
+ when 4
42
+ if clipped_box = grabbing_clip(*box, 0, 0, buffer.w, buffer.h)
43
+ x, y, w, h = clipped_box
44
+ else
45
+ raise Tea::Error, "cannot grab (#{x}, #{y}, #{w}, #{h}), not within (#{buffer.x}, #{buffer.y}, #{buffer.w}, #{buffer.h})", caller
46
+ end
47
+ else
48
+ raise ArgumentError, "wrong number of arguments (#{box.length} for 0 or 4)", caller
49
+ end
50
+
51
+ bitmap = Bitmap.new(w, h, 0x00000000)
52
+
53
+ for buf_y in y..(y + h)
54
+ for buf_x in x..(x + w)
55
+ red, green, blue, alpha = buffer.get_rgba(buffer[buf_x, buf_y])
56
+ bitmap.point buf_x - x, buf_y - y, ((red << 24) | (green << 16) | (blue << 8) | alpha)
57
+ end
58
+ end
59
+
60
+ bitmap
61
+ end
62
+
63
+ # Keep the rect (x, y, w, h) within the rect (bound_x, bound_y, bound_w, bound_h).
64
+ #
65
+ # Returns [in_x, in_y, in_w, in_h], defining a rect like (x, y, w, h), but
66
+ # within the bounding rect. Returns nil if the rect given is not within
67
+ # the bounding rect at all, i.e. w or h would be less than 1.
68
+ def grabbing_clip(x, y, w, h, bound_x, bound_y, bound_w, bound_h)
69
+ return nil if x + w <= bound_x || x >= bound_x + bound_w || y + h <= bound_y || y >= bound_y + bound_h
70
+
71
+ in_x = (x >= bound_x) ? x : bound_x
72
+ in_y = (y >= bound_y) ? y : bound_y
73
+
74
+ x2 = x + w
75
+ y2 = y + h
76
+ in_x2 = (x2 <= bound_x + bound_w) ? x2 : bound_x + bound_w
77
+ in_y2 = (y2 <= bound_y + bound_h) ? y2 : bound_y + bound_h
78
+ in_w = in_x2 - in_x
79
+ in_h = in_y2 - in_y
80
+
81
+ [in_x, in_y, in_w, in_h]
82
+ end
83
+
84
+ end
85
+
86
+ end
@@ -0,0 +1,50 @@
1
+ # This file holds the ImageSaving mixin.
2
+
3
+ require 'sdl'
4
+
5
+ require 'tea/c_error'
6
+
7
+ #
8
+ module Tea
9
+
10
+ # This mixin allows SDL surface-backed classes to be saved as image files.
11
+ #
12
+ # To use, include the mixin and implement an image_saving_buffer method:
13
+ #
14
+ # include ImageSaving
15
+ # def image_saving_buffer
16
+ # @my_sdl_buffer
17
+ # end
18
+ module ImageSaving
19
+
20
+ # Save the object as an image file at the given path.
21
+ #
22
+ # The format is determined by the extension at the end of the path. ".bmp"
23
+ # will save it as Windows Bitmap image.
24
+ #
25
+ # May raise Tea::Error if the desired image file format can't be
26
+ # determined, or isn't supported.
27
+ def save(path)
28
+ extension_match = /\..+$/.match(path)
29
+
30
+ if extension_match
31
+ ext = extension_match[0]
32
+ case ext
33
+ when '.bmp'
34
+ image_saving_buffer.save_bmp(path)
35
+ when '.png'
36
+ raise Tea::Error, "PNG format not supported for saving yet", caller
37
+ else
38
+ raise Tea::Error, "can't determine image format '#{ext}' for saving", caller
39
+ end
40
+ else
41
+ raise Tea::Error, "can't determine desired image file format for #{path}", caller
42
+ end
43
+
44
+ rescue SDL::Error => e
45
+ raise Tea::Error, e.message, e.backtrace
46
+ end
47
+
48
+ end
49
+
50
+ end
@@ -68,16 +68,21 @@ module Tea
68
68
  raise Tea::Error, "can't draw rectangle of size #{w}x#{h}", caller
69
69
  end
70
70
 
71
- if options == nil || options[:mix] == nil
72
- mix = :blend
73
- else
74
- unless [:blend, :replace].include?(options[:mix])
75
- raise Tea::Error, "invalid mix option \"#{options[:mix]}\"", caller
71
+ r, g, b, a = primitive_hex_to_rgba(color)
72
+
73
+ if a < 0xff
74
+ if options == nil || options[:mix] == nil
75
+ mix = :blend
76
+ else
77
+ unless [:blend, :replace].include?(options[:mix])
78
+ raise Tea::Error, "invalid mix option \"#{options[:mix]}\"", caller
79
+ end
80
+ mix = options[:mix]
76
81
  end
77
- mix = options[:mix]
82
+ else
83
+ mix = :replace
78
84
  end
79
85
 
80
- r, g, b, a = primitive_hex_to_rgba(color)
81
86
  case mix
82
87
  when :blend
83
88
  if a == 0xff
@@ -107,19 +112,20 @@ module Tea
107
112
  # +:replace+ writes over the RGBA parts of the line
108
113
  # destination pixels.
109
114
  def line(x1, y1, x2, y2, color, options=nil)
115
+ r, g, b, a = primitive_hex_to_rgba(color)
116
+
110
117
  if options == nil
111
118
  antialias = false
112
- mix = :blend
119
+ mix = (a < 0xff) ? :blend : :replace
113
120
  else
114
121
  antialias = options[:antialias] || false
115
- mix = options[:mix] || :blend
122
+ mix = options[:mix] || ((a < 0xff) ? :blend : :replace)
116
123
 
117
124
  unless [:blend, :replace].include?(mix)
118
125
  raise Tea::Error, "invalid mix option \"#{mix}\"", caller
119
126
  end
120
127
  end
121
128
 
122
- r, g, b, a = primitive_hex_to_rgba(color)
123
129
  if primitive_buffer.class == SDL::Screen
124
130
  primitive_buffer.draw_line x1, y1, x2, y2, primitive_rgba_to_color(r, g, b, (mix == :replace ? a : 255)), antialias, (mix == :blend ? a : nil)
125
131
  else
@@ -149,14 +155,16 @@ module Tea
149
155
  raise Tea::Error, "can't draw circle with radius #{radius}", caller
150
156
  end
151
157
 
158
+ r, g, b, a = primitive_hex_to_rgba(color)
159
+
152
160
  if options == nil
153
161
  outline = false
154
162
  antialias = false
155
- mix = :blend
163
+ mix = (a < 0xff) ? :blend : :replace
156
164
  else
157
165
  outline = options[:outline] || false
158
166
  antialias = options[:antialias] || false
159
- mix = options[:mix] || :blend
167
+ mix = options[:mix] || ((a < 0xff) ? :blend : :replace)
160
168
 
161
169
  unless [:blend, :replace].include?(mix)
162
170
  raise Tea::Error, "invalid mix option \"#{mix}\"", caller
@@ -166,8 +174,7 @@ module Tea
166
174
  if primitive_buffer.class == SDL::Screen
167
175
  case mix
168
176
  when :blend
169
- r, g, b, a = primitive_hex_to_rgba(color)
170
- if !outline && antialias && a < 0xff
177
+ if !outline && antialias
171
178
  # rubysdl can't draw filled antialiased alpha circles for some reason.
172
179
  # Big endian because the SGE-powered circle antialiasing apparently
173
180
  # doesn't like it any other way.
@@ -188,7 +195,6 @@ module Tea
188
195
  else
189
196
  # SGE and alpha mixing don't... mix. Gotta do it ourselves.
190
197
  mixer = (mix == :blend) ? BLEND_MIXER : REPLACE_MIXER
191
- r, g, b, a = primitive_hex_to_rgba(color)
192
198
  primitive_circle x, y, radius, !outline, antialias, r, g, b, a, mixer
193
199
  end
194
200
  end
data/lib/tea/o_screen.rb CHANGED
@@ -4,6 +4,8 @@ require 'sdl'
4
4
 
5
5
  require 'tea/mix_blitting'
6
6
  require 'tea/mix_clipping'
7
+ require 'tea/mix_grabbing'
8
+ require 'tea/mix_image_saving'
7
9
  require 'tea/mix_primitive'
8
10
 
9
11
  #
@@ -65,6 +67,16 @@ module Tea
65
67
  @screen
66
68
  end
67
69
 
70
+ extend Grabbing
71
+ def Screen.grabbing_buffer
72
+ @screen
73
+ end
74
+
75
+ extend ImageSaving
76
+ def Screen.image_saving_buffer
77
+ @screen
78
+ end
79
+
68
80
  extend Primitive
69
81
  def Screen.primitive_buffer
70
82
  @screen
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tung-tea
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tung Nguyen
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-08-21 00:00:00 -07:00
12
+ date: 2009-08-29 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -45,6 +45,7 @@ files:
45
45
  - doc/example/event_app.rb
46
46
  - doc/example/event_keyboard.rb
47
47
  - doc/example/event_mouse.rb
48
+ - doc/example/grab.rb
48
49
  - doc/example/init.rb
49
50
  - doc/example/lines.rb
50
51
  - doc/example/lines_aa.rb
@@ -74,11 +75,12 @@ files:
74
75
  - lib/tea/m_event_mouse.rb
75
76
  - lib/tea/mix_blitting.rb
76
77
  - lib/tea/mix_clipping.rb
78
+ - lib/tea/mix_grabbing.rb
79
+ - lib/tea/mix_image_saving.rb
77
80
  - lib/tea/mix_primitive.rb
78
81
  - lib/tea/o_screen.rb
79
82
  has_rdoc: false
80
83
  homepage: http://github.com/tung/tea
81
- licenses:
82
84
  post_install_message:
83
85
  rdoc_options:
84
86
  - --charset=UTF-8
@@ -99,7 +101,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
99
101
  requirements: []
100
102
 
101
103
  rubyforge_project:
102
- rubygems_version: 1.3.5
104
+ rubygems_version: 1.2.0
103
105
  signing_key:
104
106
  specification_version: 3
105
107
  summary: A simple game development library for Ruby.