ray 0.0.0.pre1

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/ext/ray.h ADDED
@@ -0,0 +1,82 @@
1
+ #include "ruby.h"
2
+
3
+ #if defined(HAVE_SDL_H) || defined(RAY_USE_FRAMEWORK)
4
+ # include <SDL.h>
5
+ #else
6
+ # include <SDL/SDL.h>
7
+ #endif
8
+
9
+ #ifdef __cplusplus
10
+ extern "C" {
11
+ #if 0
12
+ }
13
+ #endif
14
+ #endif
15
+
16
+ /* Classes and modules */
17
+ extern VALUE ray_mRay;
18
+
19
+ extern VALUE ray_cImage;
20
+ extern VALUE ray_cColor;
21
+ extern VALUE ray_cRect;
22
+
23
+ /* Macros for Ruby's C API */
24
+
25
+ #define RAY_IS_A(obj, klass) (RTEST(rb_obj_is_kind_of(obj, klass)))
26
+
27
+ #define RAY_OBJ_CLASSNAME(obj) (rb_class2name(rb_class_of(obj)))
28
+
29
+ #define RAY_SYM(string) (ID2SYM(rb_intern(string)))
30
+ #define RAY_METH(string) (rb_intern(string))
31
+
32
+ /* Data types */
33
+
34
+ typedef struct {
35
+ VALUE self;
36
+ SDL_Surface *surface;
37
+
38
+ int mustFree; /* Should we call SDL_FreeSurface? */
39
+ } ray_image;
40
+
41
+ typedef struct {
42
+ uint8_t r, g, b, a;
43
+ } ray_color;
44
+
45
+ typedef SDL_Rect ray_rect;
46
+
47
+ /* Convertion functions */
48
+
49
+ /** Converts a surface into a ruby object */
50
+ VALUE ray_create_image(SDL_Surface *surface);
51
+
52
+ /** Converts a color into a ruby object */
53
+ VALUE ray_col2rb(ray_color color);
54
+
55
+ /** Converts a rect into a ruby object */
56
+ VALUE ray_rect2rb(ray_rect rect);
57
+
58
+ /** Converts a ruby object into a color */
59
+ ray_color ray_rb2col(VALUE object);
60
+
61
+ /** Converts a ruby object into an image*/
62
+ ray_image *ray_rb2image(VALUE object);
63
+
64
+ /** Converts a ruby object into a color */
65
+ SDL_Surface *ray_rb2surface(VALUE object);
66
+
67
+ /** Converts a ruby object into a rect */
68
+ ray_rect ray_rb2rect(VALUE object);
69
+
70
+ /* Initilizers */
71
+
72
+ void Init_ray_ext();
73
+ void Init_ray_image();
74
+ void Init_ray_color();
75
+ void Init_ray_rect();
76
+
77
+ #ifdef __cplusplus
78
+ #if 0
79
+ {
80
+ #endif
81
+ }
82
+ #endif
Binary file
data/ext/ray_ext.so ADDED
Binary file
data/ext/rect.c ADDED
@@ -0,0 +1,204 @@
1
+ #include "ray.h"
2
+
3
+ VALUE ray_cRect = Qnil;
4
+
5
+ void ray_free_rect(ray_rect *ptr) {
6
+ free(ptr);
7
+ }
8
+
9
+ VALUE ray_rect2rb(ray_rect rect) {
10
+ ray_rect *ptr = malloc(sizeof(ray_rect));
11
+ memcpy(ptr, &rect, sizeof(ray_rect));
12
+
13
+ VALUE obj = Data_Wrap_Struct(ray_cRect, NULL, ray_free_rect, ptr);
14
+ return obj;
15
+ }
16
+
17
+ ray_rect ray_rb2rect(VALUE obj) {
18
+ if (!RAY_IS_A(obj, ray_cRect)) {
19
+ rb_raise(rb_eTypeError, "Can't convert %s into Ray::Rect",
20
+ RAY_OBJ_CLASSNAME(obj));
21
+ }
22
+
23
+ ray_rect *rect;
24
+ Data_Get_Struct(obj, ray_rect, rect);
25
+
26
+ return *rect;
27
+ }
28
+
29
+ VALUE ray_alloc_rect(VALUE self) {
30
+ ray_rect *rect = malloc(sizeof(ray_rect));
31
+ VALUE ret = Data_Wrap_Struct(self, 0, ray_free_rect, rect);
32
+
33
+ return ret;
34
+ }
35
+
36
+ /*
37
+ @overload initialize(x, y)
38
+ Creates a new rect with size set to 0, 0.
39
+
40
+ @overload initialize(x, y, w, h)
41
+ Creates a new rect with the specified size.
42
+
43
+ @overload initialize(hash)
44
+ Creates a new rect according to the keys specified in hash.
45
+
46
+ @option hash [Integer] :x
47
+ @option hash [Integer] :y
48
+ @option hash [Integer, optional] :width
49
+ @option hash [Integer, optional] :height required if width is set
50
+ */
51
+ VALUE ray_init_rect(int argc, VALUE *argv, VALUE self) {
52
+ VALUE x_or_hash, y, w, h;
53
+ rb_scan_args(argc, argv, "13", &x_or_hash, &y, &w, &h);
54
+
55
+ int type = TYPE(x_or_hash);
56
+ if (type == T_HASH) {
57
+ if (!NIL_P(y)) {
58
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)",
59
+ argc);
60
+ }
61
+
62
+ VALUE hash = x_or_hash;
63
+
64
+ x_or_hash = rb_hash_aref(hash, RAY_SYM("x"));
65
+ y = rb_hash_aref(hash, RAY_SYM("y"));
66
+
67
+ w = rb_hash_aref(hash, RAY_SYM("width"));
68
+ h = rb_hash_aref(hash, RAY_SYM("height"));
69
+
70
+ if (NIL_P(w)) w = rb_hash_aref(hash, RAY_SYM("w"));
71
+ if (NIL_P(h)) h = rb_hash_aref(hash, RAY_SYM("h"));
72
+
73
+ if (NIL_P(y)) {
74
+ rb_raise(rb_eArgError, "Missing argument 'y'");
75
+ }
76
+
77
+ if (!NIL_P(w) && NIL_P(h)) {
78
+ rb_raise(rb_eArgError, "missing argument 'height'");
79
+ }
80
+ }
81
+ else {
82
+ if (NIL_P(y)) {
83
+ rb_raise(rb_eArgError, "wrong number of arguments (1 for 2)");
84
+ }
85
+
86
+ if (!NIL_P(w) && NIL_P(h)) {
87
+ rb_raise(rb_eArgError, "wrong number of arguments (3 for 4)");
88
+ }
89
+ }
90
+
91
+ ray_rect *rect;
92
+ Data_Get_Struct(self, ray_rect, rect);
93
+
94
+ rect->x = NUM2INT(x_or_hash);
95
+ rect->y = NUM2INT(y);
96
+
97
+ if (!NIL_P(w)) {
98
+ rect->w = NUM2INT(w);
99
+ rect->h = NUM2INT(h);
100
+ }
101
+ else {
102
+ rect->w = 0;
103
+ rect->h = 0;
104
+ }
105
+
106
+ return Qnil;
107
+ }
108
+
109
+ /* @return [Integer] position of the rect */
110
+ VALUE ray_rect_x(VALUE self) {
111
+ ray_rect *rect;
112
+ Data_Get_Struct(self, ray_rect, rect);
113
+
114
+ return INT2FIX(rect->x);
115
+ }
116
+
117
+ /* @return [Integer] position of the rect */
118
+ VALUE ray_rect_y(VALUE self) {
119
+ ray_rect *rect;
120
+ Data_Get_Struct(self, ray_rect, rect);
121
+
122
+ return INT2FIX(rect->y);
123
+ }
124
+
125
+ /* @return [Integer] size of the rect */
126
+ VALUE ray_rect_w(VALUE self) {
127
+ ray_rect *rect;
128
+ Data_Get_Struct(self, ray_rect, rect);
129
+
130
+ return INT2FIX(rect->w);
131
+ }
132
+
133
+ /* @return [Integer] size of the rect */
134
+ VALUE ray_rect_h(VALUE self) {
135
+ ray_rect *rect;
136
+ Data_Get_Struct(self, ray_rect, rect);
137
+
138
+ return INT2FIX(rect->h);
139
+ }
140
+
141
+ /* Sets the position of the rect */
142
+ VALUE ray_rect_set_x(VALUE self, VALUE val) {
143
+ ray_rect *rect;
144
+ Data_Get_Struct(self, ray_rect, rect);
145
+
146
+ rect->x = NUM2INT(val);
147
+
148
+ return val;
149
+ }
150
+
151
+ /* Sets the position of the rect */
152
+ VALUE ray_rect_set_y(VALUE self, VALUE val) {
153
+ ray_rect *rect;
154
+ Data_Get_Struct(self, ray_rect, rect);
155
+
156
+ rect->y = NUM2INT(val);
157
+
158
+ return val;
159
+ }
160
+
161
+ /* Sets the size of the rect */
162
+ VALUE ray_rect_set_w(VALUE self, VALUE val) {
163
+ ray_rect *rect;
164
+ Data_Get_Struct(self, ray_rect, rect);
165
+
166
+ rect->w = NUM2INT(val);
167
+
168
+ return val;
169
+ }
170
+
171
+ /* Sets the size of the rect */
172
+ VALUE ray_rect_set_h(VALUE self, VALUE val) {
173
+ ray_rect *rect;
174
+ Data_Get_Struct(self, ray_rect, rect);
175
+
176
+ rect->h = NUM2INT(val);
177
+
178
+ return val;
179
+ }
180
+
181
+ /*
182
+ Document-class: Ray::Rect
183
+
184
+ Rects are used to represent a part of a surface, using
185
+ two attributes to represent its position, and two
186
+ others to represent its size.
187
+ */
188
+
189
+ void Init_ray_rect() {
190
+ ray_cRect = rb_define_class_under(ray_mRay, "Rect", rb_cObject);
191
+
192
+ rb_define_alloc_func(ray_cRect, ray_alloc_rect);
193
+ rb_define_method(ray_cRect, "initialize", ray_init_rect, -1);
194
+
195
+ rb_define_method(ray_cRect, "x", ray_rect_x, 0);
196
+ rb_define_method(ray_cRect, "y", ray_rect_y, 0);
197
+ rb_define_method(ray_cRect, "width", ray_rect_w, 0);
198
+ rb_define_method(ray_cRect, "height", ray_rect_h, 0);
199
+
200
+ rb_define_method(ray_cRect, "x=", ray_rect_set_x, 1);
201
+ rb_define_method(ray_cRect, "y=", ray_rect_set_y, 1);
202
+ rb_define_method(ray_cRect, "width=", ray_rect_set_w, 1);
203
+ rb_define_method(ray_cRect, "height=", ray_rect_set_h, 1);
204
+ }
data/ext/test.rb ADDED
@@ -0,0 +1,21 @@
1
+ Ray.init
2
+
3
+ width = 255
4
+ height = 1
5
+
6
+ win = Ray.create_window(:width => width, :height => 255 * height)
7
+ win.fill Ray::Color.new(0, 0, 255)
8
+ win.flip
9
+
10
+ (0...256).each do |i|
11
+ img = Ray::Image.new(:w => width, :h => height)
12
+ img.fill Ray::Color.new(i, i, i)
13
+
14
+ img.blit(:from => [0, 0], :to => win, :at => [0, i * height])
15
+ end
16
+
17
+ win.flip
18
+
19
+ sleep 3
20
+
21
+ Ray.stop
data/lib/ray.rb ADDED
@@ -0,0 +1 @@
1
+ require 'ray/ray'
data/lib/ray/color.rb ADDED
@@ -0,0 +1,30 @@
1
+ module Ray
2
+ class Color
3
+ class << self
4
+ def red; new(255, 0, 0); end
5
+ def green; new(0, 255, 0); end
6
+ def blue; new(0, 0, 255); end
7
+ def black; new(0, 0,0); end
8
+ def white; new(255, 255, 255); end
9
+ def none; new(0, 0, 0, 0); end
10
+ def gray; new(128, 128, 128); end
11
+ def cyan; new(0, 255, 255); end
12
+ def yellow; new(255, 255, 0); end
13
+ def fuschia; new(255, 0, 255); end
14
+ end
15
+
16
+ def inspect
17
+ "RGBA(#{r}, #{g}, #{b}, #{a})"
18
+ end
19
+
20
+ alias :red :r
21
+ alias :green :g
22
+ alias :blue :b
23
+ alias :alpha :a
24
+
25
+ alias :red= :r=
26
+ alias :green= :g=
27
+ alias :blue= :b=
28
+ alias :alpha= :a=
29
+ end
30
+ end
data/lib/ray/ray.rb ADDED
@@ -0,0 +1,11 @@
1
+ unless defined? Ray
2
+ unless RUBY_PLATFORM =~ /darwin/
3
+ require 'ray_ext'
4
+ else
5
+ $stderr.puts "Please run this program using ray: ray #$0"
6
+ exit 1
7
+ end
8
+ end
9
+
10
+ require 'ray/color'
11
+ require 'ray/rect'
data/lib/ray/rect.rb ADDED
@@ -0,0 +1,13 @@
1
+ module Ray
2
+ class Rect
3
+ def inspect
4
+ "#<#{self.class} {{#{x}, #{y}}, {#{w}, #{h}}}>"
5
+ end
6
+
7
+ alias :w :width
8
+ alias :h :height
9
+
10
+ alias :w= :width=
11
+ alias :h= :height=
12
+ end
13
+ end
@@ -0,0 +1,44 @@
1
+ describe Ray::Color do
2
+ describe "#initialize" do
3
+ it "should accept 3 integers" do
4
+ lambda {
5
+ Ray::Color.new(10, 20, 30)
6
+ }.should_not raise_exception(ArgumentError)
7
+ end
8
+
9
+ it "should accept 4 integers" do
10
+ lambda {
11
+ Ray::Color.new(10, 20, 30, 40)
12
+ }.should_not raise_exception(ArgumentError)
13
+ end
14
+
15
+ it "should only work with numerics" do
16
+ [Ray, "string", Ray::Color].each do |obj|
17
+ lambda {
18
+ Ray::Color.new(obj, 0, 0, obj)
19
+ }.should raise_exception(TypeError)
20
+ end
21
+ end
22
+ end
23
+
24
+ [:r, :g, :b, :a].each do |meth|
25
+ describe "#{meth}=" do
26
+ it "should only work with numerics" do
27
+ color = Ray::Color.new(0, 0, 0, 0)
28
+ [Ray, "string", Ray::Color].each do |obj|
29
+ lambda {
30
+ color.send("#{meth}=", obj)
31
+ }.should raise_exception(TypeError)
32
+ end
33
+ end
34
+
35
+ it "should set a new value" do
36
+ color = Ray::Color.new(0, 0, 0, 0)
37
+
38
+ lambda {
39
+ color.send("#{meth}=", 30)
40
+ }.should change(color, meth).from(0).to(30)
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,34 @@
1
+ describe Ray::Image do
2
+ before :each do
3
+ Ray.init
4
+ @win = Ray.create_window(:w => 100, :h => 100)
5
+ end
6
+
7
+ describe "#blit" do
8
+ context "when trying to blit on a non-surface" do
9
+ it "should raise a type error" do
10
+ img = Ray::Image.new(:w => 50, :h => 50)
11
+ lambda {
12
+ img.blit(:on => Ray::Color.new(10, 20, 30))
13
+ }.should raise_exception(TypeError)
14
+ end
15
+ end
16
+
17
+ context "when trying to use a non-rect as a position" do
18
+ it "should raise a type error" do
19
+ img = Ray::Image.new(:w => 50, :h => 50)
20
+ lambda {
21
+ img.blit(:from => Ray::Color.new(10, 20, 30), :on => @win)
22
+ }.should raise_exception(TypeError)
23
+
24
+ lambda {
25
+ img.blit(:on => @win, :at => Ray::Color.new(10, 20, 30))
26
+ }.should raise_exception(TypeError)
27
+ end
28
+ end
29
+ end
30
+
31
+ after :each do
32
+ Ray.stop
33
+ end
34
+ end