rubygame 2.1.0

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