ray 0.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
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