rubygame 2.2.0-i586-linux

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