rubygame 2.1.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.
Files changed (68) hide show
  1. data/CREDITS +50 -0
  2. data/Changelog +162 -0
  3. data/LICENSE +504 -0
  4. data/README +122 -0
  5. data/Rakefile +380 -0
  6. data/TODO +45 -0
  7. data/doc/extended_readme.rdoc +49 -0
  8. data/doc/getting_started.rdoc +47 -0
  9. data/doc/macosx_install.rdoc +74 -0
  10. data/doc/windows_install.rdoc +124 -0
  11. data/ext/rubygame/MANIFEST +25 -0
  12. data/ext/rubygame/rubygame_event.c +644 -0
  13. data/ext/rubygame/rubygame_event.h +48 -0
  14. data/ext/rubygame/rubygame_gfx.c +951 -0
  15. data/ext/rubygame/rubygame_gfx.h +102 -0
  16. data/ext/rubygame/rubygame_gl.c +154 -0
  17. data/ext/rubygame/rubygame_gl.h +32 -0
  18. data/ext/rubygame/rubygame_image.c +108 -0
  19. data/ext/rubygame/rubygame_image.h +41 -0
  20. data/ext/rubygame/rubygame_joystick.c +247 -0
  21. data/ext/rubygame/rubygame_joystick.h +41 -0
  22. data/ext/rubygame/rubygame_main.c +155 -0
  23. data/ext/rubygame/rubygame_main.h +33 -0
  24. data/ext/rubygame/rubygame_mixer.c +764 -0
  25. data/ext/rubygame/rubygame_mixer.h +62 -0
  26. data/ext/rubygame/rubygame_screen.c +420 -0
  27. data/ext/rubygame/rubygame_screen.h +41 -0
  28. data/ext/rubygame/rubygame_shared.c +152 -0
  29. data/ext/rubygame/rubygame_shared.h +54 -0
  30. data/ext/rubygame/rubygame_surface.c +1107 -0
  31. data/ext/rubygame/rubygame_surface.h +62 -0
  32. data/ext/rubygame/rubygame_time.c +183 -0
  33. data/ext/rubygame/rubygame_time.h +32 -0
  34. data/ext/rubygame/rubygame_ttf.c +600 -0
  35. data/ext/rubygame/rubygame_ttf.h +69 -0
  36. data/lib/rubygame.rb +40 -0
  37. data/lib/rubygame/MANIFEST +12 -0
  38. data/lib/rubygame/clock.rb +128 -0
  39. data/lib/rubygame/constants.rb +238 -0
  40. data/lib/rubygame/event.rb +313 -0
  41. data/lib/rubygame/ftor.rb +370 -0
  42. data/lib/rubygame/hotspot.rb +265 -0
  43. data/lib/rubygame/keyconstants.rb +237 -0
  44. data/lib/rubygame/mediabag.rb +94 -0
  45. data/lib/rubygame/queue.rb +288 -0
  46. data/lib/rubygame/rect.rb +614 -0
  47. data/lib/rubygame/sfont.rb +223 -0
  48. data/lib/rubygame/sprite.rb +477 -0
  49. data/samples/FreeSans.ttf +0 -0
  50. data/samples/GPL.txt +340 -0
  51. data/samples/README +40 -0
  52. data/samples/chimp.bmp +0 -0
  53. data/samples/chimp.rb +313 -0
  54. data/samples/demo_gl.rb +151 -0
  55. data/samples/demo_gl_tex.rb +197 -0
  56. data/samples/demo_music.rb +75 -0
  57. data/samples/demo_rubygame.rb +279 -0
  58. data/samples/demo_sfont.rb +52 -0
  59. data/samples/demo_ttf.rb +193 -0
  60. data/samples/demo_utf8.rb +53 -0
  61. data/samples/fist.bmp +0 -0
  62. data/samples/load_and_blit.rb +22 -0
  63. data/samples/panda.png +0 -0
  64. data/samples/punch.wav +0 -0
  65. data/samples/ruby.png +0 -0
  66. data/samples/term16.png +0 -0
  67. data/samples/whiff.wav +0 -0
  68. metadata +123 -0
@@ -0,0 +1,48 @@
1
+ /*
2
+ * Rubygame -- Ruby code and bindings to SDL to facilitate game creation
3
+ * Copyright (C) 2004-2007 John Croisant
4
+ *
5
+ * This library is free software; you can redistribute it and/or
6
+ * modify it under the terms of the GNU Lesser General Public
7
+ * License as published by the Free Software Foundation; either
8
+ * version 2.1 of the License, or (at your option) any later version.
9
+ *
10
+ * This library is distributed in the hope that it will be useful,
11
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ * Lesser General Public License for more details.
14
+ *
15
+ * You should have received a copy of the GNU Lesser General Public
16
+ * License along with this library; if not, write to the Free Software
17
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
+ *
19
+ */
20
+
21
+
22
+ #ifndef _RUBYGAME_EVENT_H
23
+ #define _RUBYGAME_EVENT_H
24
+
25
+ extern void Rubygame_Init_Event();
26
+ extern VALUE cEvent;
27
+ extern VALUE cActiveEvent;
28
+ extern VALUE cKeyDownEvent;
29
+ extern VALUE cKeyUpEvent;
30
+ extern VALUE cMouseMotionEvent;
31
+ extern VALUE cMouseDownEvent;
32
+ extern VALUE cMouseUpEvent;
33
+ extern VALUE cJoyAxisEvent;
34
+ extern VALUE cJoyBallEvent;
35
+ extern VALUE cJoyHatEvent;
36
+ extern VALUE cJoyDownEvent;
37
+ extern VALUE cJoyUpEvent;
38
+ extern VALUE cQuitEvent;
39
+ extern VALUE cSysWMEvent;
40
+ extern VALUE cResizeEvent;
41
+ extern VALUE cExposeEvent;
42
+ extern VALUE convert_active(Uint8);
43
+ extern VALUE convert_keymod(SDLMod);
44
+ extern VALUE convert_mousebuttons(Uint8);
45
+ extern VALUE rbgm_convert_sdlevent(SDL_Event);
46
+ extern VALUE rbgm_fetchevents(VALUE);
47
+
48
+ #endif
@@ -0,0 +1,951 @@
1
+ /*
2
+ *--
3
+ * Rubygame -- Ruby code and bindings to SDL to facilitate game creation
4
+ * Copyright (C) 2004-2007 John Croisant
5
+ *
6
+ * This library is free software; you can redistribute it and/or
7
+ * modify it under the terms of the GNU Lesser General Public
8
+ * License as published by the Free Software Foundation; either
9
+ * version 2.1 of the License, or (at your option) any later version.
10
+ *
11
+ * This library is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ * Lesser General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU Lesser General Public
17
+ * License along with this library; if not, write to the Free Software
18
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ *++
20
+ */
21
+
22
+ #include "rubygame_shared.h"
23
+ #include "rubygame_gfx.h"
24
+
25
+ void Init_rubygame_gfx();
26
+ void extract_color(VALUE, Uint8*, Uint8*, Uint8*, Uint8*);
27
+ void extract_xy(VALUE, Sint16*, Sint16*);
28
+
29
+ void draw_line(VALUE, VALUE, VALUE, VALUE, int);
30
+ VALUE rbgm_draw_line(VALUE, VALUE, VALUE, VALUE);
31
+ VALUE rbgm_draw_aaline(VALUE, VALUE, VALUE, VALUE);
32
+
33
+ void draw_rect(VALUE, VALUE, VALUE, VALUE, int);
34
+ VALUE rbgm_draw_rect(VALUE, VALUE, VALUE, VALUE);
35
+ VALUE rbgm_draw_fillrect(VALUE, VALUE, VALUE, VALUE);
36
+
37
+ void draw_circle(VALUE, VALUE, VALUE, VALUE, int, int);
38
+ VALUE rbgm_draw_circle(VALUE, VALUE, VALUE, VALUE);
39
+ VALUE rbgm_draw_aacircle(VALUE, VALUE, VALUE, VALUE);
40
+ VALUE rbgm_draw_fillcircle(VALUE, VALUE, VALUE, VALUE);
41
+
42
+ void draw_ellipse(VALUE, VALUE, VALUE, VALUE, int, int);
43
+ VALUE rbgm_draw_ellipse(VALUE, VALUE, VALUE, VALUE);
44
+ VALUE rbgm_draw_aaellipse(VALUE, VALUE, VALUE, VALUE);
45
+ VALUE rbgm_draw_fillellipse(VALUE, VALUE, VALUE, VALUE);
46
+
47
+ void draw_pie(VALUE, VALUE, VALUE, VALUE, VALUE, int);
48
+ VALUE rbgm_draw_pie(VALUE, VALUE, VALUE, VALUE, VALUE);
49
+ VALUE rbgm_draw_fillpie(VALUE, VALUE, VALUE, VALUE, VALUE);
50
+
51
+ void draw_polygon(VALUE, VALUE, VALUE, int, int);
52
+ VALUE rbgm_draw_polygon(VALUE, VALUE, VALUE);
53
+ VALUE rbgm_draw_aapolygon(VALUE, VALUE, VALUE);
54
+ VALUE rbgm_draw_fillpolygon(VALUE, VALUE, VALUE);
55
+
56
+ /*
57
+ * TODO:
58
+ * Minimize redundancy (e.g. point and color checks). DRY.
59
+ * Clean up this ugly mess of code!
60
+ */
61
+
62
+ void extract_color(VALUE rgba, Uint8* r, Uint8* g, Uint8* b, Uint8* a)
63
+ {
64
+ rgba = convert_to_array(rgba);
65
+ if(RARRAY(rgba)->len < 3)
66
+ rb_raise(rb_eArgError,"color must be [r,g,b] or [r,g,b,a] form");
67
+ *r = NUM2UINT(rb_ary_entry(rgba,0));
68
+ *g = NUM2UINT(rb_ary_entry(rgba,1));
69
+ *b = NUM2UINT(rb_ary_entry(rgba,2));
70
+
71
+ if(RARRAY(rgba)->len > 3)
72
+ *a = NUM2UINT(rb_ary_entry(rgba,3));
73
+ else
74
+ *a = 255;
75
+ }
76
+
77
+ void extract_xy(VALUE point, Sint16* x, Sint16* y)
78
+ {
79
+ point = convert_to_array(point);
80
+ if(RARRAY(point)->len < 2)
81
+ rb_raise(rb_eArgError,"expected argument as [x,y] form");
82
+ *x = NUM2INT(rb_ary_entry(point,0));
83
+ *y = NUM2INT(rb_ary_entry(point,1));
84
+ }
85
+
86
+ /*********
87
+ * LINES *
88
+ *********/
89
+
90
+ /* This is wrapped by rbgm_draw_line and rbgm_draw_aaline */
91
+ void draw_line(VALUE target, VALUE pt1, VALUE pt2, VALUE rgba, int aa)
92
+ {
93
+ SDL_Surface *dest;
94
+ Uint8 r,g,b,a;
95
+ Sint16 x1, y1, x2, y2;
96
+
97
+ extract_xy(pt1, &x1, &y1);
98
+ extract_xy(pt2, &x2, &y2);
99
+
100
+ extract_color(rgba, &r, &g, &b, &a);
101
+
102
+ Data_Get_Struct(target,SDL_Surface,dest);
103
+ //printf("dest: %dx%d\n",dest->w,dest->h);
104
+
105
+ /* call the appropriate function for the circumstances */
106
+ if(y1 == y2) /* horizontal line */
107
+ {
108
+ //printf("horizontal line.\n");
109
+ hlineRGBA(dest, x1, x2, y1, r,g,b,a);
110
+ }
111
+ else if(x1 == x2) /* vertical line */
112
+ {
113
+ //printf("vertical line.\n");
114
+ vlineRGBA(dest, x1, y1, y2, r,g,b,a);
115
+ }
116
+ else
117
+ {
118
+ if(aa)
119
+ {
120
+ //printf("aa line.\n");
121
+ aalineRGBA(dest, x1, y1, x2, y2, r,g,b,a);
122
+ }
123
+ else
124
+ {
125
+ //printf("no-aa line.\n");
126
+ lineRGBA(dest, x1, y1, x2, y2, r,g,b,a);
127
+ }
128
+ }
129
+ return;
130
+ }
131
+
132
+ /* call-seq:
133
+ * draw_line(point1, point2, color)
134
+ *
135
+ * Draw a line segment between two points on the Surface.
136
+ * See also #draw_line_a
137
+ *
138
+ * This method takes these arguments:
139
+ * point1:: the coordinates of one end of the line, [x1,y1].
140
+ * point2:: the coordinates of the other end of the line, [x2,y2].
141
+ * color:: the color of the shape, [r,g,b,a]. If alpha
142
+ * is omitted, it is drawn at full opacity.
143
+ */
144
+ VALUE rbgm_draw_line(VALUE target, VALUE pt1, VALUE pt2, VALUE rgba)
145
+ {
146
+ draw_line(target,pt1,pt2,rgba,0); /* no anti-aliasing */
147
+ return target;
148
+ }
149
+ /* call-seq:
150
+ * draw_line_a(point1, point2, color)
151
+ *
152
+ * Like #draw_line, but the line will be anti-aliased.
153
+ */
154
+ VALUE rbgm_draw_aaline(VALUE target, VALUE pt1, VALUE pt2, VALUE rgba)
155
+ {
156
+ draw_line(target,pt1,pt2,rgba,1); /* anti-aliasing */
157
+ return target;
158
+ }
159
+
160
+ /**********************
161
+ * RECTANGLES (BOXES) *
162
+ **********************/
163
+
164
+ /* This is wrapped by rbgm_draw_rect and rbgm_draw_fillrect */
165
+ void draw_rect(VALUE target, VALUE pt1, VALUE pt2, VALUE rgba, int fill)
166
+ {
167
+ SDL_Surface *dest;
168
+ Uint8 r,g,b,a;
169
+ Sint16 x1, y1, x2, y2;
170
+
171
+ extract_xy(pt1, &x1, &y1);
172
+ extract_xy(pt2, &x2, &y2);
173
+
174
+ extract_color(rgba, &r, &g, &b, &a);
175
+
176
+ Data_Get_Struct(target,SDL_Surface,dest);
177
+ //printf("dest: %dx%d\n",dest->w,dest->h);
178
+
179
+ /* call the appropriate function for the circumstances */
180
+
181
+ if(fill)
182
+ {
183
+ //printf("filled rect\n");
184
+ boxRGBA(dest,x1,y1,x2,y2,r,g,b,a);
185
+ }
186
+ else
187
+ {
188
+ //printf("unfilled rect\n");
189
+ rectangleRGBA(dest,x1,y1,x2,y2,r,g,b,a);
190
+ }
191
+ return;
192
+ }
193
+ /* call-seq:
194
+ * draw_box(point1, point2, color)
195
+ *
196
+ * Draw a non-solid box (rectangle) on the Surface, given the coordinates of
197
+ * its top-left corner and bottom-right corner. See also #draw_box_s
198
+ *
199
+ * This method takes these arguments:
200
+ * point1:: the coordinates of top-left corner, [x1,y1].
201
+ * point2:: the coordinates of bottom-right corner, [x2,y2].
202
+ * color:: the color of the shape, [r,g,b,a]. If alpha
203
+ * is omitted, it is drawn at full opacity.
204
+ */
205
+ VALUE rbgm_draw_rect(VALUE target, VALUE pt1, VALUE pt2, VALUE rgba)
206
+ {
207
+ draw_rect(target,pt1,pt2,rgba,0); /* no fill */
208
+ return target;
209
+ }
210
+
211
+ /* call-seq:
212
+ * draw_box_s(point1, point2, color)
213
+ *
214
+ * Like #draw_box, but the shape is solid, instead of an outline.
215
+ * (You may find using #fill to be more convenient and perhaps faster than
216
+ * this method.)
217
+ */
218
+ VALUE rbgm_draw_fillrect(VALUE target, VALUE pt1, VALUE pt2, VALUE rgba)
219
+ {
220
+ draw_rect(target,pt1,pt2,rgba,1); /* fill */
221
+ return target;
222
+ }
223
+
224
+ /***********
225
+ * CIRCLES *
226
+ ***********/
227
+
228
+ /* This is wrapped by rbgm_draw_(|aa|fill)circle */
229
+ void draw_circle(VALUE target, VALUE center, VALUE radius, VALUE rgba, int aa, int fill)
230
+ {
231
+ SDL_Surface *dest;
232
+ Uint8 r,g,b,a;
233
+ Sint16 x, y, rad;
234
+
235
+ extract_xy(center, &x, &y);
236
+ rad = NUM2INT(radius);
237
+
238
+ extract_color(rgba, &r, &g, &b, &a);
239
+
240
+ Data_Get_Struct(target,SDL_Surface,dest);
241
+ //printf("dest: %dx%d\n",dest->w,dest->h);
242
+
243
+ /* call the appropriate function for the circumstances */
244
+
245
+ if(fill)
246
+ {
247
+ //printf("filled circle\n");
248
+ filledCircleRGBA(dest,x,y,rad,r,g,b,a);
249
+ }
250
+ else
251
+ {
252
+ if(aa)
253
+ {
254
+ //printf("aa circle\n");
255
+ aacircleRGBA(dest,x,y,rad,r,g,b,a);
256
+ }
257
+ else
258
+ {
259
+ //printf("circle\n");
260
+ circleRGBA(dest,x,y,rad,r,g,b,a);
261
+ }
262
+ }
263
+ return;
264
+ }
265
+
266
+ /*
267
+ * call-seq:
268
+ * draw_circle(center, radius, color)
269
+ *
270
+ * Draw a non-solid circle on the Surface, given the coordinates of its
271
+ * center and its radius. See also #draw_circle_a and #draw_circle_s
272
+ *
273
+ * This method takes these arguments:
274
+ * center:: the coordinates of circle's center, [x,y].
275
+ * radius:: the radius (pixels) of the circle.
276
+ * color:: the color of the shape, [r,g,b,a]. If alpha
277
+ * is omitted, it is drawn at full opacity.
278
+ */
279
+ VALUE rbgm_draw_circle(VALUE target, VALUE center, VALUE radius, VALUE rgba)
280
+ {
281
+ draw_circle(target,center,radius,rgba,0,0); /* no aa, no fill */
282
+ return target;
283
+ }
284
+ /*
285
+ * call-seq:
286
+ * draw_circle_a(center, radius, color)
287
+ *
288
+ * Like #draw_circle, but the outline is anti-aliased.
289
+ */
290
+ VALUE rbgm_draw_aacircle(VALUE target, VALUE center, VALUE radius, VALUE rgba)
291
+ {
292
+ draw_circle(target,center,radius,rgba,1,0); /* aa, no fill */
293
+ return target;
294
+ }
295
+ /*
296
+ * call-seq:
297
+ * draw_circle_s(center, radius, color)
298
+ *
299
+ * Like #draw_circle, but the shape is solid, instead of an outline.
300
+ */
301
+ VALUE rbgm_draw_fillcircle(VALUE target, VALUE center, VALUE radius, VALUE rgba)
302
+ {
303
+ draw_circle(target,center,radius,rgba,0,1); /* no aa, fill */
304
+ return target;
305
+ }
306
+
307
+ /************
308
+ * ELLIPSES *
309
+ ************/
310
+
311
+ /* This is wrapped by rbgm_draw_(|aa|fill)ellipse */
312
+ void draw_ellipse(VALUE target, VALUE center, VALUE radii, VALUE rgba, int aa, int fill)
313
+ {
314
+ SDL_Surface *dest;
315
+ Uint8 r,g,b,a;
316
+ Sint16 x, y, radx,rady;
317
+
318
+ extract_xy(center, &x, &y);
319
+ extract_xy(radii, &radx, &rady);
320
+
321
+ extract_color(rgba, &r, &g, &b, &a);
322
+
323
+ Data_Get_Struct(target,SDL_Surface,dest);
324
+
325
+ /* call the appropriate function for the circumstances */
326
+
327
+ if(fill)
328
+ {
329
+ //printf("filled ellipse\n");
330
+ filledEllipseRGBA(dest,x,y,radx,rady,r,g,b,a);
331
+ }
332
+ else
333
+ {
334
+ if(aa)
335
+ {
336
+ //printf("aa ellipse\n");
337
+ aaellipseRGBA(dest,x,y,radx,rady,r,g,b,a);
338
+ }
339
+ else
340
+ {
341
+ //printf("ellipse\n");
342
+ ellipseRGBA(dest,x,y,radx,rady,r,g,b,a);
343
+ }
344
+ }
345
+ return;
346
+ }
347
+
348
+ /*
349
+ * call-seq:
350
+ * draw_ellipse(center, radius, color)
351
+ *
352
+ * Draw a non-solid ellipse (oval) on the Surface, given the
353
+ * coordinates of its center and its horizontal and vertical radii.
354
+ * See also #draw_ellipse_a and #draw_ellipse_s
355
+ *
356
+ * This method takes these arguments:
357
+ * center:: the coordinates of ellipse's center, [x,y].
358
+ * radii:: the x and y radii (pixels), [rx,ry].
359
+ * color:: the color of the shape, [r,g,b,a]. If alpha
360
+ * is omitted, it is drawn at full opacity.
361
+ */
362
+ VALUE rbgm_draw_ellipse(VALUE target, VALUE center, VALUE radii, VALUE rgba)
363
+ {
364
+ draw_ellipse(target,center,radii,rgba,0,0); /* no aa, no fill */
365
+ return target;
366
+ }
367
+ /*
368
+ * call-seq:
369
+ * draw_ellipse_a(center, radius, color)
370
+ *
371
+ * Like #draw_ellipse, but the ellipse border is anti-aliased.
372
+ */
373
+ VALUE rbgm_draw_aaellipse(VALUE target, VALUE center, VALUE radii, VALUE rgba)
374
+ {
375
+ draw_ellipse(target,center,radii,rgba,1,0); /* aa, no fill */
376
+ return target;
377
+ }
378
+
379
+ /*
380
+ * call-seq:
381
+ * draw_ellipse_s(center, radius, color)
382
+ *
383
+ * Like #draw_ellipse, but the shape is solid, instead of an outline.
384
+ */
385
+ VALUE rbgm_draw_fillellipse(VALUE target, VALUE center, VALUE radii, VALUE rgba)
386
+ {
387
+ draw_ellipse(target,center,radii,rgba,0,1); /* no aa, fill */
388
+ return target;
389
+ }
390
+
391
+ /********
392
+ * PIES *
393
+ ********/
394
+
395
+ /* This is wrapped by rbgm_draw_(|aa|fill)pie */
396
+ void draw_pie(VALUE target, VALUE center, VALUE radius, VALUE angles, VALUE rgba, int fill)
397
+ {
398
+ SDL_Surface *dest;
399
+ Uint8 r,g,b,a;
400
+ Sint16 x, y, rad, start, end;
401
+
402
+ extract_xy(center, &x, &y);
403
+ extract_xy(angles, &start, &end);
404
+ rad = NUM2INT(radius);
405
+
406
+ extract_color(rgba, &r, &g, &b, &a);
407
+
408
+ Data_Get_Struct(target,SDL_Surface,dest);
409
+
410
+ /* call the appropriate function for the circumstances */
411
+
412
+ if(fill)
413
+ {
414
+ //printf("filled pie\n");
415
+ #ifdef HAVE_UPPERCASEPIE
416
+ filledPieRGBA(dest,x,y,rad,start,end,r,g,b,a);
417
+ #else
418
+ /* before sdl-gfx 2.0.12, it used to be a lowercase pie: */
419
+ filledpieRGBA(dest,x,y,rad,start,end,r,g,b,a);
420
+ #endif
421
+ }
422
+ else
423
+ {
424
+ /* this function did not exist until sdl-gfx 2.0.11, but
425
+ rbgm_draw_fillpie checks the version. You should too if you
426
+ directly call this function with fill==1. */
427
+ pieRGBA(dest,x,y,rad,start,end,r,g,b,a);
428
+ }
429
+ return;
430
+ }
431
+
432
+ /*
433
+ * call-seq:
434
+ * draw_pie(center, radius, angles, color)
435
+ *
436
+ * Draw a non-solid arc (part of a circle), given the coordinates of
437
+ * its center, radius, and starting/ending angles.
438
+ * See also #draw_arc_s
439
+ *
440
+ * *IMPORTANT:* This method will only be defined if Rubygame was compiled
441
+ * with SDL_gfx-2.0.11 or greater. (Note: #draw_arc_s does not have
442
+ * this requirement.)
443
+ *
444
+ * This method takes these arguments:
445
+ * center:: the coordinates of circle's center, [x,y].
446
+ * radius:: the radius (pixels) of the circle.
447
+ * angles:: the start and end angles (in degrees) of the arc, [start,end].
448
+ * Angles are given *CLOCKWISE* from the positive x
449
+ * (remember that the positive Y direction is down, rather than up).
450
+ * color:: the color of the shape, [r,g,b,a]. If alpha
451
+ * is omitted, it is drawn at full opacity.
452
+ */
453
+ VALUE rbgm_draw_pie(VALUE target, VALUE center, VALUE radius, VALUE angles, VALUE rgba)
454
+ {
455
+ #ifdef HAVE_NONFILLEDPIE
456
+ draw_pie(target,center,radius,angles,rgba,0); /* no fill */
457
+ return target;
458
+ #else
459
+ return Qnil;
460
+ #endif
461
+ }
462
+
463
+ /*
464
+ * call-seq:
465
+ * draw_arc_s(center, radius, angles, color)
466
+ *
467
+ * Like #draw_arc, but the shape is solid, instead an outline.
468
+ * (This method does not require SDL_gfx 2.0.11 or greater,
469
+ * but #draw_arc does.)
470
+ */
471
+ VALUE rbgm_draw_fillpie(VALUE target, VALUE center, VALUE radius, VALUE angles, VALUE rgba)
472
+ {
473
+ draw_pie(target,center,radius,angles,rgba,1); /* fill */
474
+ return target;
475
+ }
476
+
477
+ /************
478
+ * POLYGONS *
479
+ ************/
480
+
481
+ /* This is wrapped by rbgm_draw_(|aa|fill)polygon */
482
+ void draw_polygon(VALUE target, VALUE points, VALUE rgba, int aa, int fill)
483
+ {
484
+ SDL_Surface *dest;
485
+ VALUE each_point;
486
+ int length,loop;
487
+ Uint8 r,g,b,a;
488
+ Sint16 *x, *y;
489
+
490
+ /* separate points into arrays of x and y values */
491
+ points = convert_to_array(points);
492
+ length = RARRAY(points)->len;
493
+ x = alloca(sizeof (Sint16) * length);
494
+ y = alloca(sizeof (Sint16) * length);
495
+
496
+ for(loop=0;loop<length;loop++)
497
+ {
498
+ each_point = rb_ary_entry(points,loop);
499
+ extract_xy(each_point, &(x[loop]), &(y[loop]));
500
+ }
501
+
502
+ extract_color(rgba, &r, &g, &b, &a);
503
+
504
+ Data_Get_Struct(target,SDL_Surface,dest);
505
+
506
+ /* call the appropriate function for the circumstances */
507
+
508
+ if(fill)
509
+ {
510
+ //printf("filled polygon\n");
511
+ filledPolygonRGBA(dest,x,y,length,r,g,b,a);
512
+ }
513
+ else
514
+ {
515
+ if(aa)
516
+ {
517
+ //printf("aa polygon\n");
518
+ aapolygonRGBA(dest,x,y,length,r,g,b,a);
519
+ }
520
+ else
521
+ {
522
+ //printf("polygon\n");
523
+ polygonRGBA(dest,x,y,length,r,g,b,a);
524
+ }
525
+ }
526
+ return;
527
+ }
528
+ /*
529
+ * call-seq:
530
+ * draw_polygon(points, color)
531
+ *
532
+ * Draw a non-solid polygon, given the coordinates of its vertices, in the
533
+ * order that they are connected. This is essentially a series of connected
534
+ * dots. See also #draw_polygon_a and #draw_polygon_s.
535
+ *
536
+ * This method takes these arguments:
537
+ * points:: an Array containing the coordinate pairs for each vertex of the
538
+ * polygon, in the order that they are connected, e.g.
539
+ * <tt>[ [x1,y1], [x2,y2], ..., [xn,yn] ]</tt>. To draw a closed
540
+ * shape, the final coordinate pair should match the first.
541
+ * color:: the color of the shape, [r,g,b,a]. If alpha
542
+ * is omitted, it is drawn at full opacity.
543
+ */
544
+ VALUE rbgm_draw_polygon(VALUE target, VALUE points, VALUE rgba)
545
+ {
546
+ draw_polygon(target,points,rgba,0,0); /* no aa, no fill */
547
+ return target;
548
+ }
549
+ /*
550
+ * call-seq:
551
+ * draw_polygon_a(points, color)
552
+ *
553
+ * Like #draw_polygon, but the lines are anti-aliased.
554
+ */
555
+ VALUE rbgm_draw_aapolygon(VALUE target, VALUE points, VALUE rgba)
556
+ {
557
+ draw_polygon(target,points,rgba,1,0); /* aa, no fill */
558
+ return target;
559
+ }
560
+
561
+ /*
562
+ * call-seq:
563
+ * draw_polygon_s(points, color)
564
+ *
565
+ * Like #draw_polygon, but the shape is solid, not an outline.
566
+ */
567
+ VALUE rbgm_draw_fillpolygon(VALUE target, VALUE points, VALUE rgba)
568
+ {
569
+ draw_polygon(target,points,rgba,0,1); /* no aa, fill */
570
+ return target;
571
+ }
572
+
573
+
574
+ VALUE rbgm_transform_rotozoom(int, VALUE*, VALUE);
575
+ VALUE rbgm_transform_rotozoomsize(int, VALUE*, VALUE);
576
+
577
+ VALUE rbgm_transform_zoom(int, VALUE*, VALUE);
578
+ VALUE rbgm_transform_zoomsize(int, VALUE*, VALUE);
579
+
580
+ /*
581
+ * call-seq:
582
+ * rotozoom( angle, zoom, smooth=false ) -> Surface
583
+ *
584
+ * Return a rotated and/or zoomed version of the given surface. Note that
585
+ * rotating a Surface anything other than a multiple of 90 degrees will
586
+ * cause the new surface to be larger than the original to accomodate the
587
+ * corners (which would otherwise extend beyond the surface).
588
+ *
589
+ * If Rubygame was compiled with SDL_gfx-2.0.13 or greater, +zoom+ can be
590
+ * an Array of 2 Numerics for separate X and Y scaling. Also, it can be
591
+ * negative to indicate flipping horizontally or vertically.
592
+ *
593
+ * Will raise SDLError if you attempt to use separate X and Y zoom factors
594
+ * or negative zoom factors with an unsupported version of SDL_gfx.
595
+ *
596
+ * This method takes these arguments:
597
+ * angle:: degrees to rotate counter-clockwise (negative for clockwise).
598
+ * zoom:: scaling factor(s). A single positive Numeric, unless you have
599
+ * SDL_gfx-2.0.13 or greater (see above).
600
+ * smooth:: whether to anti-alias the new surface.
601
+ * By the way, if true, the new surface will be 32bit RGBA.
602
+ */
603
+ VALUE rbgm_transform_rotozoom(int argc, VALUE *argv, VALUE self)
604
+ {
605
+ SDL_Surface *src, *dst;
606
+ double angle, zoomx, zoomy;
607
+ int smooth = 0;
608
+
609
+ VALUE vangle, vzoom, vsmooth;
610
+
611
+ rb_scan_args(argc, argv, "21", &vangle, &vzoom, &vsmooth);
612
+
613
+ Data_Get_Struct(self,SDL_Surface,src);
614
+
615
+ angle = NUM2DBL(vangle);
616
+ smooth = RTEST(vsmooth) ? 1 : 0;
617
+
618
+ switch( TYPE(vzoom) )
619
+ {
620
+ case T_ARRAY: {
621
+ /* separate X and Y factors */
622
+ #ifdef HAVE_ROTOZOOMXY
623
+ /* Do the real function. */
624
+ zoomx = NUM2DBL(rb_ary_entry(vzoom,0));
625
+ zoomy = NUM2DBL(rb_ary_entry(vzoom,1));
626
+ dst = rotozoomSurfaceXY(src, angle, zoomx, zoomy, smooth);
627
+ if(dst == NULL)
628
+ rb_raise(eSDLError,"Could not rotozoom surface: %s",SDL_GetError());
629
+ #else
630
+ /* Raise SDLError. You should have checked first! */
631
+ rb_raise(eSDLError,"Separate X/Y rotozoom scale factors is not supported by your version of SDL_gfx (%d,%d,%d). Please upgrade to 2.0.13 or later.", SDL_GFXPRIMITIVES_MAJOR, SDL_GFXPRIMITIVES_MINOR, SDL_GFXPRIMITIVES_MICRO);
632
+ return Qnil;
633
+ #endif
634
+ break;
635
+ }
636
+
637
+ case T_FLOAT:
638
+ case T_FIXNUM: {
639
+ /* uniform factor for both X and Y */
640
+ zoomx = NUM2DBL(vzoom);
641
+ #ifndef HAVE_ROTOZOOMXY
642
+ if(zoomx < 0) /* negative zoom (for flipping) */
643
+ {
644
+ /* Raise SDLError. You should have checked first! */
645
+ rb_raise(eSDLError,"Negative rotozoom scale factor is not supported by your version of SDL_gfx (%d,%d,%d). Please upgrade to 2.0.13 or later.", SDL_GFXPRIMITIVES_MAJOR, SDL_GFXPRIMITIVES_MINOR, SDL_GFXPRIMITIVES_MICRO);
646
+ }
647
+ #endif
648
+ dst = rotozoomSurface(src, angle, zoomx, smooth);
649
+ if(dst == NULL)
650
+ rb_raise(eSDLError,"Could not rotozoom surface: %s",SDL_GetError());
651
+ break;
652
+ }
653
+
654
+ default: {
655
+ rb_raise(rb_eArgError,
656
+ "wrong zoom factor type (expected Array or Numeric)");
657
+ break;
658
+ }
659
+
660
+ }
661
+
662
+ return Data_Wrap_Struct(cSurface,0,SDL_FreeSurface,dst);
663
+ }
664
+
665
+ /*
666
+ * call-seq:
667
+ * rotozoom_size( size, angle, zoom ) -> [width, height] or nil
668
+ *
669
+ * Return the dimensions of the surface that would be returned if
670
+ * #rotozoom() were called on a Surface of the given size, with
671
+ * the same angle and zoom factors.
672
+ *
673
+ * If Rubygame was compiled with SDL_gfx-2.0.13 or greater, +zoom+ can be
674
+ * an Array of 2 Numerics for separate X and Y scaling. Also, it can be
675
+ * negative to indicate flipping horizontally or vertically.
676
+ *
677
+ * Will return +nil+ if you attempt to use separate X and Y zoom factors
678
+ * or negative zoom factors with an unsupported version of SDL_gfx.
679
+ *
680
+ * This method takes these arguments:
681
+ * size:: an Array with the hypothetical Surface width and height (pixels)
682
+ * angle:: degrees to rotate counter-clockwise (negative for clockwise).
683
+ * zoom:: scaling factor(s). A single positive Numeric, unless you have
684
+ * SDL_gfx-2.0.13 or greater (see above).
685
+ */
686
+ VALUE rbgm_transform_rzsize(int argc, VALUE *argv, VALUE module)
687
+ {
688
+ int w,h, dstw,dsth;
689
+ double angle, zoomx, zoomy;
690
+
691
+ VALUE vsize, vangle, vzoom;
692
+
693
+ rb_scan_args(argc,argv,"3", &vsize, &vangle, &vzoom);
694
+
695
+ vsize = convert_to_array(vsize);
696
+ w = NUM2INT(rb_ary_entry(argv[0],0));
697
+ h = NUM2INT(rb_ary_entry(argv[0],0));
698
+ angle = NUM2DBL(vangle);
699
+
700
+ switch( TYPE(vzoom) )
701
+ {
702
+ case T_ARRAY: {
703
+ /* Separate X/Y rotozoom scaling was not supported prior to 2.0.13. */
704
+ /* Check if we have at least version 2.0.13 of SDL_gfxPrimitives */
705
+ #ifdef HAVE_ROTOZOOMXY
706
+ /* Do the real function. */
707
+ zoomx = NUM2DBL(rb_ary_entry(vzoom,0));
708
+ zoomy = NUM2DBL(rb_ary_entry(vzoom,1));
709
+ rotozoomSurfaceSizeXY(w, h, angle, zoomx, zoomy, &dstw, &dsth);
710
+ #else
711
+ /* Return nil, because it's not supported. */
712
+ return Qnil;
713
+ #endif
714
+ break;
715
+ }
716
+
717
+ case T_FLOAT:
718
+ case T_FIXNUM: {
719
+ zoomx = NUM2DBL(argv[1]);
720
+ #ifndef HAVE_ROTOZOOMXY
721
+ if(zoomx < 0) /* negative zoom (for flipping) */
722
+ {
723
+ /* Return nil, because it's not supported. */
724
+ return Qnil;
725
+ }
726
+ #endif
727
+ rotozoomSurfaceSize(w, h, angle, zoomx, &dstw, &dsth);
728
+ break;
729
+ }
730
+
731
+ default: {
732
+ rb_raise(rb_eArgError,
733
+ "wrong zoom factor type (expected Array or Numeric)");
734
+ break;
735
+ }
736
+
737
+ }
738
+
739
+ /* if(dstw == NULL || dsth == NULL)
740
+ rb_raise(eSDLError,"Could not rotozoom surface: %s",SDL_GetError());*/
741
+ return rb_ary_new3(2,INT2NUM(dstw),INT2NUM(dsth));
742
+
743
+ }
744
+
745
+ /*
746
+ * call-seq:
747
+ * zoom(zoom, smooth=false) -> Surface
748
+ *
749
+ * Return a zoomed version of the Surface.
750
+ *
751
+ * This method takes these arguments:
752
+ * zoom:: a Numeric factor to scale by in both x and y directions,
753
+ * or an Array with separate x and y scale factors.
754
+ * smooth:: whether to anti-alias the new surface.
755
+ * By the way, if true, the new surface will be 32bit RGBA.
756
+ */
757
+ VALUE rbgm_transform_zoom(int argc, VALUE *argv, VALUE self)
758
+ {
759
+ SDL_Surface *src, *dst;
760
+ double zoomx, zoomy;
761
+ int smooth = 0;
762
+
763
+ VALUE vzoom, vsmooth;
764
+
765
+ rb_scan_args(argc, argv, "11", &vzoom, &vsmooth);
766
+
767
+ Data_Get_Struct(self,SDL_Surface,src);
768
+
769
+ smooth = RTEST(vsmooth) ? 1 : 0;
770
+
771
+ switch( TYPE(vzoom) )
772
+ {
773
+ case T_ARRAY:{
774
+ zoomx = NUM2DBL(rb_ary_entry(vzoom,0));
775
+ zoomy = NUM2DBL(rb_ary_entry(vzoom,1));
776
+ break;
777
+ }
778
+ case T_FLOAT:
779
+ case T_FIXNUM: {
780
+ zoomx = NUM2DBL(argv[0]);
781
+ zoomy = zoomx;
782
+ break;
783
+ }
784
+ default: {
785
+ rb_raise(rb_eArgError,
786
+ "wrong zoom factor type (expected Array or Numeric)");
787
+ break;
788
+ }
789
+
790
+ }
791
+ dst = zoomSurface(src,zoomx,zoomy,smooth);
792
+ if(dst == NULL)
793
+ rb_raise(eSDLError,"Could not rotozoom surface: %s",SDL_GetError());
794
+ return Data_Wrap_Struct(cSurface,0,SDL_FreeSurface,dst);
795
+ }
796
+
797
+ /*
798
+ * call-seq:
799
+ * zoom_to(width, height, smooth=false) -> Surface
800
+ *
801
+ * Return a zoomed version of the Surface.
802
+ *
803
+ * This method takes these arguments:
804
+ * width:: the width to scale to. If nil is given, will keep x axis unscaled.
805
+ * height:: the height to scale to. If nil is given, will keep x axis
806
+ * unscaled.
807
+ * smooth:: whether to anti-alias the new surface. This option can be
808
+ * omitted, in which case the surface will not be anti-aliased.
809
+ * If true, the new surface will be 32bit RGBA.
810
+ */
811
+ VALUE rbgm_transform_zoom_to(int argc, VALUE *argv, VALUE self)
812
+ {
813
+ SDL_Surface *src, *dst;
814
+ VALUE v_width, v_height, v_smooth;
815
+ double zoomx, zoomy;
816
+ int smooth;
817
+
818
+ rb_scan_args(argc, argv, "21", &v_width, &v_height, &v_smooth);
819
+
820
+ Data_Get_Struct(self,SDL_Surface,src);
821
+ smooth = RTEST(v_smooth) ? 1 : 0;
822
+ zoomx = NIL_P(v_width) ? 1.0 : NUM2DBL(v_width)/src->w;
823
+ zoomy = NIL_P(v_height) ? 1.0 : NUM2DBL(v_height)/src->h;
824
+ dst = zoomSurface(src,zoomx,zoomy,smooth);
825
+
826
+ if(dst == NULL)
827
+ rb_raise(eSDLError,"Could not rotozoom surface: %s",SDL_GetError());
828
+
829
+ return Data_Wrap_Struct(cSurface,0,SDL_FreeSurface,dst);
830
+ }
831
+
832
+ /*
833
+ * call-seq:
834
+ * zoom_size(size, zoom) -> [width, height]
835
+ *
836
+ * Return the dimensions of the surface that would be returned if
837
+ * #zoom were called with a surface of the given size and zoom factors.
838
+ *
839
+ * This method takes these arguments:
840
+ * size:: an Array with the hypothetical surface width and height (pixels)
841
+ * zoom:: the factor to scale by in both x and y directions, or an Array
842
+ * with separate x and y scale factors.
843
+ */
844
+ VALUE rbgm_transform_zoomsize(int argc, VALUE *argv, VALUE module)
845
+ {
846
+ int w,h, dstw,dsth;
847
+ double zoomx, zoomy;
848
+
849
+ VALUE vsize, vzoom;
850
+
851
+ rb_scan_args(argc,argv,"2", &vsize, &vzoom);
852
+
853
+ vsize = convert_to_array(vsize);
854
+ w = NUM2INT(rb_ary_entry(vsize,0));
855
+ h = NUM2INT(rb_ary_entry(vsize,1));
856
+
857
+ switch( TYPE(vzoom) )
858
+ {
859
+ case T_ARRAY: {
860
+ zoomx = NUM2DBL(rb_ary_entry(vzoom,0));
861
+ zoomy = NUM2DBL(rb_ary_entry(vzoom,1));
862
+ break;
863
+ }
864
+
865
+ case T_FLOAT:
866
+ case T_FIXNUM: {
867
+ zoomx = NUM2DBL(vzoom);
868
+ zoomy = zoomx;
869
+ break;
870
+ }
871
+ default: {
872
+ rb_raise(rb_eArgError,
873
+ "wrong zoom factor type (expected Array or Numeric)");
874
+ break;
875
+ }
876
+ }
877
+
878
+ zoomSurfaceSize(w, h, zoomx, zoomy, &dstw, &dsth);
879
+ return rb_ary_new3(2,INT2NUM(dstw),INT2NUM(dsth));
880
+ }
881
+
882
+
883
+ /*
884
+ * Document-class: Rubygame::Surface
885
+ *
886
+ * Surface's draw_* methods provide an interface to SDL_gfx's functions for
887
+ * drawing colored shapes onto the Surface. Some methods (#draw_arc_s)
888
+ * require a minimum SDL_gfx version (at compile time) to exist.
889
+ *
890
+ * The base methods (e.g. #draw_circle), draw the outline of the shape,
891
+ * without any color inside of it.
892
+ *
893
+ * Most shapes also have an anti-aliased version, denoted by the 'a' in its
894
+ * name (e.g. #draw_circle_a). These methods draw smooth outlines with no
895
+ * aliasing (pixelated "jaggies").
896
+ * Please note that anti-aliased drawing methods take longer than their
897
+ * aliased counterparts.
898
+ *
899
+ * Most shapes also have a solid version, denoted by the 's' in its name
900
+ * (e.g. #draw_circle_s). These methods draw the shape as solid, rather than
901
+ * an outline.
902
+ *
903
+ * At this time, there are no methods to draw shapes which are both filled
904
+ * and anti-aliased. For some shapes, it may be possible to approximate this
905
+ * effect by drawing a filled shape, then an anti-aliased outline in the same
906
+ * position.
907
+ */
908
+ void Init_rubygame_gfx()
909
+ {
910
+ #if 0
911
+ mRubygame = rb_define_module("Rubygame");
912
+ cSurface = rb_define_class_under(mRubygame,"Surface",rb_cObject);
913
+ #endif
914
+
915
+ Init_rubygame_shared();
916
+
917
+ rb_hash_aset(rb_ivar_get(mRubygame,rb_intern("VERSIONS")),
918
+ ID2SYM(rb_intern("sdl_gfx")),
919
+ rb_ary_new3(3,
920
+ INT2NUM(SDL_GFXPRIMITIVES_MAJOR),
921
+ INT2NUM(SDL_GFXPRIMITIVES_MINOR),
922
+ INT2NUM(SDL_GFXPRIMITIVES_MICRO)));
923
+
924
+ rb_define_method(cSurface,"draw_line",rbgm_draw_line,3);
925
+ rb_define_method(cSurface,"draw_line_a",rbgm_draw_aaline,3);
926
+ rb_define_method(cSurface,"draw_box",rbgm_draw_rect,3);
927
+ rb_define_method(cSurface,"draw_box_s",rbgm_draw_fillrect,3);
928
+ rb_define_method(cSurface,"draw_circle",rbgm_draw_circle,3);
929
+ rb_define_method(cSurface,"draw_circle_a",rbgm_draw_aacircle,3);
930
+ rb_define_method(cSurface,"draw_circle_s",rbgm_draw_fillcircle,3);
931
+ rb_define_method(cSurface,"draw_ellipse",rbgm_draw_ellipse,3);
932
+ rb_define_method(cSurface,"draw_ellipse_a",rbgm_draw_aaellipse,3);
933
+ rb_define_method(cSurface,"draw_ellipse_s",rbgm_draw_fillellipse,3);
934
+ #ifdef HAVE_NONFILLEDPIE
935
+ rb_define_method(cSurface,"draw_arc",rbgm_draw_pie,4);
936
+ #endif
937
+ rb_define_method(cSurface,"draw_arc_s",rbgm_draw_fillpie,4);
938
+ rb_define_method(cSurface,"draw_polygon",rbgm_draw_polygon,2);
939
+ rb_define_method(cSurface,"draw_polygon_a",rbgm_draw_aapolygon,2);
940
+ rb_define_method(cSurface,"draw_polygon_s",rbgm_draw_fillpolygon,2);
941
+
942
+
943
+ rb_define_method(cSurface,"rotozoom",rbgm_transform_rotozoom,-1);
944
+ rb_define_method(cSurface,"zoom",rbgm_transform_zoom,-1);
945
+ rb_define_method(cSurface,"zoom_to",rbgm_transform_zoom_to,-1);
946
+
947
+ rb_define_module_function(cSurface,"rotozoom_size",rbgm_transform_rzsize,-1);
948
+ rb_define_module_function(cSurface,"zoom_size",rbgm_transform_zoomsize,-1);
949
+
950
+
951
+ }