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/.gitignore +7 -0
- data/Rakefile +47 -0
- data/VERSION +1 -0
- data/bin/ray +5 -0
- data/bin/ray_irb +4 -0
- data/ext/Makefile +189 -0
- data/ext/SDLMain.h +17 -0
- data/ext/SDLMain.m +381 -0
- data/ext/color.c +147 -0
- data/ext/extconf.rb +92 -0
- data/ext/image.c +192 -0
- data/ext/ray +0 -0
- data/ext/ray.bundle +0 -0
- data/ext/ray.c +125 -0
- data/ext/ray.h +82 -0
- data/ext/ray_ext.bundle +0 -0
- data/ext/ray_ext.so +0 -0
- data/ext/rect.c +204 -0
- data/ext/test.rb +21 -0
- data/lib/ray.rb +1 -0
- data/lib/ray/color.rb +30 -0
- data/lib/ray/ray.rb +11 -0
- data/lib/ray/rect.rb +13 -0
- data/spec/ray/color_spec.rb +44 -0
- data/spec/ray/image_spec.rb +34 -0
- data/spec/ray/ray_spec.rb +15 -0
- data/spec/ray/rect_spec.rb +74 -0
- data/spec_runner.rb +23 -0
- metadata +101 -0
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
|
data/ext/ray_ext.bundle
ADDED
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
data/lib/ray/rect.rb
ADDED
@@ -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
|