ruby2d 0.10.0 → 0.11.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.
data/ext/ruby2d/gles.c CHANGED
@@ -202,40 +202,22 @@ void R2D_GLES_DrawTriangle(GLfloat x1, GLfloat y1,
202
202
 
203
203
 
204
204
  /*
205
- * Draw a texture
205
+ * Draw a texture (New method with vertices pre-calculated)
206
206
  */
207
- static void R2D_GLES_DrawTexture(int x, int y, int w, int h,
208
- GLfloat angle, GLfloat rx, GLfloat ry,
209
- GLfloat r, GLfloat g, GLfloat b, GLfloat a,
210
- GLfloat tx1, GLfloat ty1, GLfloat tx2, GLfloat ty2,
211
- GLfloat tx3, GLfloat ty3, GLfloat tx4, GLfloat ty4,
212
- GLuint texture_id) {
213
-
214
- R2D_GL_Point v1 = { .x = x, .y = y };
215
- R2D_GL_Point v2 = { .x = x + w, .y = y };
216
- R2D_GL_Point v3 = { .x = x + w, .y = y + h };
217
- R2D_GL_Point v4 = { .x = x, .y = y + h };
218
-
219
- // Rotate vertices
220
- if (angle != 0) {
221
- v1 = R2D_RotatePoint(v1, angle, rx, ry);
222
- v2 = R2D_RotatePoint(v2, angle, rx, ry);
223
- v3 = R2D_RotatePoint(v3, angle, rx, ry);
224
- v4 = R2D_RotatePoint(v4, angle, rx, ry);
225
- }
226
-
207
+ void R2D_GLES_DrawTexture(GLfloat coordinates[], GLfloat texture_coordinates[], GLfloat color[], int texture_id);
227
208
  GLfloat vertices[] =
228
209
  // x, y coords | x, y texture coords
229
- { v1.x, v1.y, 0.f, tx1, ty1,
230
- v2.x, v2.y, 0.f, tx2, ty2,
231
- v3.x, v3.y, 0.f, tx3, ty3,
232
- v4.x, v4.y, 0.f, tx4, ty4 };
210
+ {
211
+ coordinates[0], coordinates[1], 0.f, texture_coordinates[0], texture_coordinates[1],
212
+ coordinates[2], coordinates[3], 0.f, texture_coordinates[2], texture_coordinates[3],
213
+ coordinates[4], coordinates[5], 0.f, texture_coordinates[4], texture_coordinates[5],
214
+ coordinates[6], coordinates[7], 0.f, texture_coordinates[6], texture_coordinates[7] };
233
215
 
234
216
  GLfloat colors[] =
235
- { r, g, b, a,
236
- r, g, b, a,
237
- r, g, b, a,
238
- r, g, b, a };
217
+ { color[0], color[1], color[2], color[3],
218
+ color[0], color[1], color[2], color[3],
219
+ color[0], color[1], color[2], color[3],
220
+ color[0], color[1], color[2], color[3] };
239
221
 
240
222
  glUseProgram(texShaderProgram);
241
223
 
@@ -264,60 +246,4 @@ static void R2D_GLES_DrawTexture(int x, int y, int w, int h,
264
246
  }
265
247
 
266
248
 
267
- /*
268
- * Draw image
269
- */
270
- void R2D_GLES_DrawImage(R2D_Image *img) {
271
- R2D_GLES_DrawTexture(
272
- img->x, img->y, img->width, img->height,
273
- img->rotate, img->rx, img->ry,
274
- img->color.r, img->color.g, img->color.b, img->color.a,
275
- 0.f, 0.f, 1.f, 0.f, 1.f, 1.f, 0.f, 1.f,
276
- img->texture_id
277
- );
278
- }
279
-
280
-
281
- /*
282
- * Draw sprite
283
- */
284
- void R2D_GLES_DrawSprite(R2D_Sprite *spr) {
285
- R2D_GLES_DrawTexture(
286
- spr->x, spr->y, spr->width, spr->height,
287
- spr->rotate, spr->rx, spr->ry,
288
- spr->color.r, spr->color.g, spr->color.b, spr->color.a,
289
- spr->tx1, spr->ty1, spr->tx2, spr->ty2, spr->tx3, spr->ty3, spr->tx4, spr->ty4,
290
- spr->img->texture_id
291
- );
292
- }
293
-
294
-
295
- /*
296
- * Draw a tile
297
- */
298
- void R2D_GLES_DrawTile(R2D_Image *img, int x, int y, int tw, int th, GLfloat tx1, GLfloat ty1, GLfloat tx2,
299
- GLfloat ty2, GLfloat tx3, GLfloat ty3, GLfloat tx4, GLfloat ty4) {
300
- R2D_GLES_DrawTexture(
301
- x, y, tw, th,
302
- img->rotate, img->rx, img->ry,
303
- img->color.r, img->color.g, img->color.b, img->color.a,
304
- tx1, ty1, tx2, ty2, tx3, ty3, tx4, ty4,
305
- img->texture_id
306
- );
307
- }
308
-
309
-
310
- /*
311
- * Draw text
312
- */
313
- void R2D_GLES_DrawText(R2D_Text *txt) {
314
- R2D_GLES_DrawTexture(
315
- txt->x, txt->y, txt->width, txt->height,
316
- txt->rotate, txt->rx, txt->ry,
317
- txt->color.r, txt->color.g, txt->color.b, txt->color.a,
318
- 0.f, 0.f, 1.f, 0.f, 1.f, 1.f, 0.f, 1.f,
319
- txt->texture_id
320
- );
321
- }
322
-
323
249
  #endif
data/ext/ruby2d/image.c CHANGED
@@ -3,75 +3,39 @@
3
3
  #include "ruby2d.h"
4
4
 
5
5
 
6
- /*
7
- * Create an image, given a file path
8
- */
9
- R2D_Image *R2D_CreateImage(const char *path) {
6
+ SDL_Surface *R2D_CreateImageSurface(const char *path) {
10
7
  R2D_Init();
11
8
 
12
9
  // Check if image file exists
13
10
  if (!R2D_FileExists(path)) {
14
- R2D_Error("R2D_CreateImage", "Image file `%s` not found", path);
15
- return NULL;
16
- }
17
-
18
- // Allocate the image structure
19
- R2D_Image *img = (R2D_Image *) malloc(sizeof(R2D_Image));
20
- if (!img) {
21
- R2D_Error("R2D_CreateImage", "Out of memory!");
11
+ R2D_Error("R2D_CreateImageSurface", "Image file `%s` not found", path);
22
12
  return NULL;
23
13
  }
24
14
 
25
15
  // Load image from file as SDL_Surface
26
- img->surface = IMG_Load(path);
27
- if (!img->surface) {
28
- R2D_Error("IMG_Load", IMG_GetError());
29
- free(img);
30
- return NULL;
31
- }
16
+ SDL_Surface *surface = IMG_Load(path);
32
17
 
33
- int bits_per_color = img->surface->format->Amask == 0 ?
34
- img->surface->format->BitsPerPixel / 3 :
35
- img->surface->format->BitsPerPixel / 4;
18
+ int bits_per_color = surface->format->Amask == 0 ?
19
+ surface->format->BitsPerPixel / 3 :
20
+ surface->format->BitsPerPixel / 4;
36
21
 
37
22
  if (bits_per_color < 8) {
38
23
  R2D_Log(R2D_WARN, "`%s` has less than 8 bits per color and will likely not render correctly", path, bits_per_color);
39
24
  }
40
25
 
41
- // Initialize values
42
- img->path = path;
43
- img->x = 0;
44
- img->y = 0;
45
- img->color.r = 1.f;
46
- img->color.g = 1.f;
47
- img->color.b = 1.f;
48
- img->color.a = 1.f;
49
- img->orig_width = img->surface->w;
50
- img->orig_height = img->surface->h;
51
- img->width = img->orig_width;
52
- img->height = img->orig_height;
53
- img->rotate = 0;
54
- img->rx = 0;
55
- img->ry = 0;
56
- img->texture_id = 0;
57
-
58
- // Detect image mode
59
- img->format = GL_RGB;
60
- if (img->surface->format->BytesPerPixel == 4) {
61
- img->format = GL_RGBA;
62
- }
63
-
64
- // Flip image bits if BGA
26
+ return surface;
27
+ }
65
28
 
66
- Uint32 r = img->surface->format->Rmask;
67
- Uint32 g = img->surface->format->Gmask;
68
- Uint32 a = img->surface->format->Amask;
29
+ void R2D_ImageConvertToRGB(SDL_Surface *surface) {
30
+ Uint32 r = surface->format->Rmask;
31
+ Uint32 g = surface->format->Gmask;
32
+ Uint32 a = surface->format->Amask;
69
33
 
70
34
  if (r&0xFF000000 || r&0xFF0000) {
71
- char *p = (char *)img->surface->pixels;
72
- int bpp = img->surface->format->BytesPerPixel;
73
- int w = img->surface->w;
74
- int h = img->surface->h;
35
+ char *p = (char *)surface->pixels;
36
+ int bpp = surface->format->BytesPerPixel;
37
+ int w = surface->w;
38
+ int h = surface->h;
75
39
  char tmp;
76
40
  for (int i = 0; i < bpp * w * h; i += bpp) {
77
41
  if (a&0xFF) {
@@ -91,48 +55,4 @@ R2D_Image *R2D_CreateImage(const char *path) {
91
55
  }
92
56
  }
93
57
  }
94
-
95
- return img;
96
- }
97
-
98
-
99
- /*
100
- * Rotate an image
101
- */
102
- void R2D_RotateImage(R2D_Image *img, GLfloat angle, int position) {
103
-
104
- R2D_GL_Point p = R2D_GetRectRotationPoint(
105
- img->x, img->y, img->width, img->height, position
106
- );
107
-
108
- img->rotate = angle;
109
- img->rx = p.x;
110
- img->ry = p.y;
111
- }
112
-
113
-
114
- /*
115
- * Draw an image
116
- */
117
- void R2D_DrawImage(R2D_Image *img) {
118
- if (!img) return;
119
-
120
- if (img->texture_id == 0) {
121
- R2D_GL_CreateTexture(&img->texture_id, img->format,
122
- img->orig_width, img->orig_height,
123
- img->surface->pixels, GL_NEAREST);
124
- SDL_FreeSurface(img->surface);
125
- }
126
-
127
- R2D_GL_DrawImage(img);
128
- }
129
-
130
-
131
- /*
132
- * Free an image
133
- */
134
- void R2D_FreeImage(R2D_Image *img) {
135
- if (!img) return;
136
- R2D_GL_FreeTexture(&img->texture_id);
137
- free(img);
138
58
  }
data/ext/ruby2d/ruby2d.c CHANGED
@@ -108,18 +108,6 @@ static R2D_Window *window;
108
108
 
109
109
  // Method signatures and structures for Ruby 2D classes
110
110
  #if MRUBY
111
- static void free_image(mrb_state *mrb, void *p_);
112
- static const struct mrb_data_type image_data_type = {
113
- "image", free_image
114
- };
115
- static void free_sprite(mrb_state *mrb, void *p_);
116
- static const struct mrb_data_type sprite_data_type = {
117
- "sprite", free_sprite
118
- };
119
- static void free_text(mrb_state *mrb, void *p_);
120
- static const struct mrb_data_type text_data_type = {
121
- "text", free_text
122
- };
123
111
  static void free_sound(mrb_state *mrb, void *p_);
124
112
  static const struct mrb_data_type sound_data_type = {
125
113
  "sound", free_sound
@@ -129,11 +117,10 @@ static R2D_Window *window;
129
117
  "music", free_music
130
118
  };
131
119
  #else
132
- static void free_image(R2D_Image *img);
133
- static void free_sprite(R2D_Sprite *spr);
134
- static void free_text(R2D_Text *txt);
135
120
  static void free_sound(R2D_Sound *snd);
136
121
  static void free_music(R2D_Music *mus);
122
+ static void free_font(TTF_Font *font);
123
+ static void free_surface(SDL_Surface *font);
137
124
  #endif
138
125
 
139
126
 
@@ -368,353 +355,190 @@ static R_VAL ruby2d_circle_ext_draw(R_VAL self, R_VAL a) {
368
355
 
369
356
 
370
357
  /*
371
- * Ruby2D::Image#ext_init
372
- * Initialize image structure data
373
- */
374
- #if MRUBY
375
- static R_VAL ruby2d_image_ext_init(mrb_state* mrb, R_VAL self) {
376
- mrb_value path;
377
- mrb_get_args(mrb, "o", &path);
378
- #else
379
- static R_VAL ruby2d_image_ext_init(R_VAL self, R_VAL path) {
380
- #endif
381
- R2D_Image *img = R2D_CreateImage(RSTRING_PTR(path));
382
- if (!img) return R_FALSE;
383
-
384
- // Get width and height from Ruby class. If set, use it, else choose the
385
- // native dimensions of the image.
386
- R_VAL w = r_iv_get(self, "@width");
387
- R_VAL h = r_iv_get(self, "@height");
388
- r_iv_set(self, "@width" , r_test(w) ? w : INT2NUM(img->width));
389
- r_iv_set(self, "@height", r_test(h) ? h : INT2NUM(img->height));
390
- r_iv_set(self, "@data", r_data_wrap_struct(image, img));
391
-
392
- return R_TRUE;
393
- }
394
-
395
-
396
- /*
397
- * Ruby2D::Image#self.ext_draw
358
+ * Ruby2D::Image#ext_load_image
359
+ * Create an SDL surface from an image path, return the surface, width, and height
398
360
  */
399
- #if MRUBY
400
- static R_VAL ruby2d_image_ext_draw(mrb_state* mrb, R_VAL self) {
401
- mrb_value a;
402
- mrb_get_args(mrb, "o", &a);
403
- #else
404
- static R_VAL ruby2d_image_ext_draw(R_VAL self, R_VAL a) {
405
- #endif
406
- // `a` is the array representing the image
361
+ static R_VAL ruby2d_image_ext_load_image(R_VAL self, R_VAL path) {
362
+ R2D_Init();
407
363
 
408
- R2D_Image *img;
409
- r_data_get_struct(r_ary_entry(a, 0), "@data", &image_data_type, R2D_Image, img);
364
+ VALUE result = rb_ary_new2(3);
410
365
 
411
- img->x = NUM2DBL(r_ary_entry(a, 1));
412
- img->y = NUM2DBL(r_ary_entry(a, 2));
366
+ SDL_Surface *surface = R2D_CreateImageSurface(RSTRING_PTR(path));
367
+ R2D_ImageConvertToRGB(surface);
413
368
 
414
- R_VAL w = r_ary_entry(a, 3);
415
- R_VAL h = r_ary_entry(a, 4);
416
- if (r_test(w)) img->width = NUM2INT(w);
417
- if (r_test(h)) img->height = NUM2INT(h);
369
+ rb_ary_push(result, r_data_wrap_struct(surface, surface));
370
+ rb_ary_push(result, INT2NUM(surface->w));
371
+ rb_ary_push(result, INT2NUM(surface->h));
418
372
 
419
- R2D_RotateImage(img, NUM2DBL(r_ary_entry(a, 5)), R2D_CENTER);
420
-
421
- img->color.r = NUM2DBL(r_ary_entry(a, 6));
422
- img->color.g = NUM2DBL(r_ary_entry(a, 7));
423
- img->color.b = NUM2DBL(r_ary_entry(a, 8));
424
- img->color.a = NUM2DBL(r_ary_entry(a, 9));
425
-
426
- R2D_DrawImage(img);
427
- return R_NIL;
373
+ return result;
428
374
  }
429
375
 
430
376
 
431
377
  /*
432
- * Free image structure attached to Ruby 2D `Image` class
378
+ * Ruby2D::Text#ext_load_text
433
379
  */
434
- #if MRUBY
435
- static void free_image(mrb_state *mrb, void *p_) {
436
- R2D_Image *img = (R2D_Image *)p_;
437
- #else
438
- static void free_image(R2D_Image *img) {
439
- #endif
440
- R2D_FreeImage(img);
441
- }
380
+ static R_VAL ruby2d_text_ext_load_text(R_VAL self, R_VAL font, R_VAL message) {
381
+ R2D_Init();
442
382
 
383
+ VALUE result = rb_ary_new2(3);
443
384
 
444
- /*
445
- * Ruby2D::Sprite#ext_init
446
- * Initialize sprite structure data
447
- */
448
- #if MRUBY
449
- static R_VAL ruby2d_sprite_ext_init(mrb_state* mrb, R_VAL self) {
450
- mrb_value path;
451
- mrb_get_args(mrb, "o", &path);
452
- #else
453
- static R_VAL ruby2d_sprite_ext_init(R_VAL self, R_VAL path) {
454
- #endif
455
- R2D_Sprite *spr = R2D_CreateSprite(RSTRING_PTR(path));
456
- if (!spr) return R_FALSE;
385
+ TTF_Font *ttf_font;
386
+ Data_Get_Struct(font, TTF_Font, ttf_font);
457
387
 
458
- r_iv_set(self, "@img_width" , INT2NUM(spr->width));
459
- r_iv_set(self, "@img_height", INT2NUM(spr->height));
460
- r_iv_set(self, "@data", r_data_wrap_struct(sprite, spr));
388
+ SDL_Surface *surface = R2D_TextCreateSurface(ttf_font, RSTRING_PTR(message));
389
+ if (!surface) {
390
+ return result;
391
+ }
461
392
 
462
- return R_TRUE;
463
- }
393
+ rb_ary_push(result, r_data_wrap_struct(surface, surface));
394
+ rb_ary_push(result, INT2NUM(surface->w));
395
+ rb_ary_push(result, INT2NUM(surface->h));
464
396
 
397
+ return result;
398
+ }
465
399
 
466
400
  /*
467
- * Ruby2D::Sprite#ext_draw
401
+ * Ruby2D::Texture#ext_create
468
402
  */
469
- #if MRUBY
470
- static R_VAL ruby2d_sprite_ext_draw(mrb_state* mrb, R_VAL self) {
471
- mrb_value a;
472
- mrb_get_args(mrb, "o", &a);
473
- #else
474
- static R_VAL ruby2d_sprite_ext_draw(R_VAL self, R_VAL a) {
475
- #endif
476
- // `a` is the array representing the sprite
477
-
478
- R2D_Sprite *spr;
479
- r_data_get_struct(r_ary_entry(a, 0), "@data", &sprite_data_type, R2D_Sprite, spr);
480
-
481
- spr->x = NUM2DBL(r_ary_entry(a, 1));
482
- spr->y = NUM2DBL(r_ary_entry(a, 2));
483
-
484
- R_VAL w = r_ary_entry(a, 3);
485
- if (r_test(w)) spr->width = NUM2DBL(w);
486
-
487
- R_VAL h = r_ary_entry(a, 4);
488
- if (r_test(h)) spr->height = NUM2DBL(h);
489
-
490
- R2D_RotateSprite(spr, NUM2DBL(r_ary_entry(a, 5)), R2D_CENTER);
491
-
492
- R2D_ClipSprite(
493
- spr,
494
- NUM2INT(r_ary_entry(a, 6)),
495
- NUM2INT(r_ary_entry(a, 7)),
496
- NUM2INT(r_ary_entry(a, 8)),
497
- NUM2INT(r_ary_entry(a, 9))
498
- );
499
-
500
- spr->color.r = NUM2DBL(r_ary_entry(a, 10));
501
- spr->color.g = NUM2DBL(r_ary_entry(a, 11));
502
- spr->color.b = NUM2DBL(r_ary_entry(a, 12));
503
- spr->color.a = NUM2DBL(r_ary_entry(a, 13));
504
-
505
- R2D_DrawSprite(spr);
506
- return R_NIL;
507
- }
403
+ static R_VAL ruby2d_texture_ext_create(R_VAL self, R_VAL rubySurface, R_VAL width, R_VAL height) {
404
+ GLuint texture_id = 0;
405
+ SDL_Surface *surface;
406
+ Data_Get_Struct(rubySurface, SDL_Surface, surface);
407
+
408
+ // Detect image mode
409
+ GLint format = GL_RGB;
410
+ if (surface->format->BytesPerPixel == 4) {
411
+ format = GL_RGBA;
412
+ }
508
413
 
414
+ R2D_GL_CreateTexture(&texture_id, format,
415
+ NUM2INT(width), NUM2INT(height),
416
+ surface->pixels, GL_NEAREST);
509
417
 
510
- /*
511
- * Free sprite structure attached to Ruby 2D `Sprite` class
512
- */
513
- #if MRUBY
514
- static void free_sprite(mrb_state *mrb, void *p_) {
515
- R2D_Sprite *spr = (R2D_Sprite *)p_;
516
- #else
517
- static void free_sprite(R2D_Sprite *spr) {
518
- #endif
519
- R2D_FreeSprite(spr);
418
+ return INT2NUM(texture_id);
520
419
  }
521
420
 
522
-
523
421
  /*
524
- * Ruby2D::Tileset#ext_init
525
- * Initialize tileset data
422
+ * Ruby2D::Texture#ext_delete
526
423
  */
527
- static R_VAL ruby2d_tileset_ext_init(R_VAL self, R_VAL path) {
528
- R2D_Image *img = R2D_CreateImage(RSTRING_PTR(path));
529
- if (!img) return R_FALSE;
530
-
531
- // Get width and height from Ruby class. If set, use it, else choose the
532
- // native dimensions of the image.
533
- R_VAL w = r_iv_get(self, "@width");
534
- R_VAL h = r_iv_get(self, "@height");
535
- r_iv_set(self, "@width" , r_test(w) ? w : INT2NUM(img->width));
536
- r_iv_set(self, "@height", r_test(h) ? h : INT2NUM(img->height));
537
- r_iv_set(self, "@data", r_data_wrap_struct(image, img));
538
-
539
- return R_TRUE;
540
- }
424
+ static R_VAL ruby2d_texture_ext_delete(R_VAL self, R_VAL rubyTexture_id) {
425
+ GLuint texture_id = NUM2INT(rubyTexture_id);
541
426
 
427
+ R2D_GL_FreeTexture(&texture_id);
542
428
 
543
- /*
544
- * Ruby2D::Tileset#ext_draw
545
- * Draws a single tile, will be called once per individual tile to draw
546
- */
547
- static R_VAL ruby2d_tileset_ext_draw(R_VAL self, R_VAL a) {
548
- // `a` is the array representing the tileset
549
-
550
- R2D_Image *img;
551
- r_data_get_struct(r_ary_entry(a, 0), "@data", &image_data_type, R2D_Image, img);
552
-
553
- int tw = NUM2INT(r_ary_entry(a, 1));
554
- int th = NUM2INT(r_ary_entry(a, 2));
555
- int padding = NUM2INT(r_ary_entry(a, 3));
556
- int spacing = NUM2INT(r_ary_entry(a, 4));
557
- int tx = NUM2INT(r_ary_entry(a, 5));
558
- int ty = NUM2INT(r_ary_entry(a, 6));
559
- int x = NUM2INT(r_ary_entry(a, 7));
560
- int y = NUM2INT(r_ary_entry(a, 8));
561
-
562
- R2D_DrawTile(img, tw, th, padding, spacing, tx, ty, x, y);
563
429
  return R_NIL;
564
430
  }
565
431
 
566
432
 
567
433
  /*
568
- * Ruby2D::Text#ext_init
569
- * Initialize text structure data
434
+ * Ruby2D::Sound#ext_init
435
+ * Initialize sound structure data
570
436
  */
571
437
  #if MRUBY
572
- static R_VAL ruby2d_text_ext_init(mrb_state* mrb, R_VAL self) {
438
+ static R_VAL ruby2d_sound_ext_init(mrb_state* mrb, R_VAL self) {
439
+ mrb_value path;
440
+ mrb_get_args(mrb, "o", &path);
573
441
  #else
574
- static R_VAL ruby2d_text_ext_init(R_VAL self) {
442
+ static R_VAL ruby2d_sound_ext_init(R_VAL self, R_VAL path) {
575
443
  #endif
576
- // Trim the font file string to its actual length on MRuby
577
- #if MRUBY
578
- mrb_value s = r_iv_get(self, "@font");
579
- mrb_str_resize(mrb, s, RSTRING_LEN(s));
580
- #endif
581
-
582
- R2D_Text *txt = R2D_CreateText(
583
- RSTRING_PTR(r_iv_get(self, "@font")),
584
- RSTRING_PTR(r_iv_get(self, "@text")),
585
- NUM2DBL(r_iv_get(self, "@size"))
586
- );
587
- if (!txt) return R_FALSE;
588
-
589
- r_iv_set(self, "@width", INT2NUM(txt->width));
590
- r_iv_set(self, "@height", INT2NUM(txt->height));
591
- r_iv_set(self, "@data", r_data_wrap_struct(text, txt));
592
-
444
+ R2D_Sound *snd = R2D_CreateSound(RSTRING_PTR(path));
445
+ if (!snd) return R_FALSE;
446
+ r_iv_set(self, "@data", r_data_wrap_struct(sound, snd));
593
447
  return R_TRUE;
594
448
  }
595
449
 
596
450
 
597
451
  /*
598
- * Ruby2D::Text#ext_set
452
+ * Ruby2D::Sound#ext_play
599
453
  */
600
454
  #if MRUBY
601
- static R_VAL ruby2d_text_ext_set(mrb_state* mrb, R_VAL self) {
602
- mrb_value text;
603
- mrb_get_args(mrb, "o", &text);
455
+ static R_VAL ruby2d_sound_ext_play(mrb_state* mrb, R_VAL self) {
604
456
  #else
605
- static R_VAL ruby2d_text_ext_set(R_VAL self, R_VAL text) {
457
+ static R_VAL ruby2d_sound_ext_play(R_VAL self) {
606
458
  #endif
607
- R2D_Text *txt;
608
- r_data_get_struct(self, "@data", &text_data_type, R2D_Text, txt);
609
-
610
- R2D_SetText(txt, RSTRING_PTR(text));
611
-
612
- r_iv_set(self, "@width", INT2NUM(txt->width));
613
- r_iv_set(self, "@height", INT2NUM(txt->height));
614
-
459
+ R2D_Sound *snd;
460
+ r_data_get_struct(self, "@data", &sound_data_type, R2D_Sound, snd);
461
+ R2D_PlaySound(snd);
615
462
  return R_NIL;
616
463
  }
617
464
 
618
465
 
619
466
  /*
620
- * Ruby2D::Text#self.ext_draw
467
+ * Ruby2D::Sound#ext_length
621
468
  */
622
- #if MRUBY
623
- static R_VAL ruby2d_text_ext_draw(mrb_state* mrb, R_VAL self) {
624
- mrb_value a;
625
- mrb_get_args(mrb, "o", &a);
626
- #else
627
- static R_VAL ruby2d_text_ext_draw(R_VAL self, R_VAL a) {
628
- #endif
629
- // `a` is the array representing the text
630
-
631
- R2D_Text *txt;
632
- r_data_get_struct(r_ary_entry(a, 0), "@data", &text_data_type, R2D_Text, txt);
633
-
634
- txt->x = NUM2DBL(r_ary_entry(a, 1));
635
- txt->y = NUM2DBL(r_ary_entry(a, 2));
636
-
637
- R2D_RotateText(txt, NUM2DBL(r_ary_entry(a, 3)), R2D_CENTER);
638
-
639
- txt->color.r = NUM2DBL(r_ary_entry(a, 4));
640
- txt->color.g = NUM2DBL(r_ary_entry(a, 5));
641
- txt->color.b = NUM2DBL(r_ary_entry(a, 6));
642
- txt->color.a = NUM2DBL(r_ary_entry(a, 7));
643
-
644
- R2D_DrawText(txt);
645
- return R_NIL;
469
+ static R_VAL ruby2d_sound_ext_length(R_VAL self) {
470
+ R2D_Sound *snd;
471
+ r_data_get_struct(self, "@data", &sound_data_type, R2D_Sound, snd);
472
+ return INT2NUM(R2D_GetSoundLength(snd));
646
473
  }
647
474
 
648
475
 
649
476
  /*
650
- * Free text structure attached to Ruby 2D `Text` class
477
+ * Free sound structure attached to Ruby 2D `Sound` class
651
478
  */
652
479
  #if MRUBY
653
- static void free_text(mrb_state *mrb, void *p_) {
654
- R2D_Text *txt = (R2D_Text *)p_;
480
+ static void free_sound(mrb_state *mrb, void *p_) {
481
+ R2D_Sound *snd = (R2D_Sound *)p_;
655
482
  #else
656
- static void free_text(R2D_Text *txt) {
483
+ static void free_sound(R2D_Sound *snd) {
657
484
  #endif
658
- R2D_FreeText(txt);
485
+ R2D_FreeSound(snd);
659
486
  }
660
487
 
661
-
662
488
  /*
663
- * Ruby2D::Sound#ext_init
664
- * Initialize sound structure data
489
+ * Ruby2D::Sound#ext_get_volume
665
490
  */
666
491
  #if MRUBY
667
- static R_VAL ruby2d_sound_ext_init(mrb_state* mrb, R_VAL self) {
668
- mrb_value path;
669
- mrb_get_args(mrb, "o", &path);
492
+ static R_VAL ruby2d_sound_ext_get_volume(mrb_state* mrb, R_VAL self) {
670
493
  #else
671
- static R_VAL ruby2d_sound_ext_init(R_VAL self, R_VAL path) {
494
+ static R_VAL ruby2d_sound_ext_get_volume(R_VAL self) {
672
495
  #endif
673
- R2D_Sound *snd = R2D_CreateSound(RSTRING_PTR(path));
674
- if (!snd) return R_FALSE;
675
- r_iv_set(self, "@data", r_data_wrap_struct(sound, snd));
676
- return R_TRUE;
496
+ R2D_Sound *snd;
497
+ r_data_get_struct(self, "@data", &sound_data_type, R2D_Sound, snd);
498
+ return INT2NUM(ceil(Mix_VolumeChunk(snd->data, -1) * (100.0 / MIX_MAX_VOLUME)));
677
499
  }
678
500
 
679
-
680
501
  /*
681
- * Ruby2D::Sound#ext_play
502
+ * Ruby2D::Music#ext_set_volume
682
503
  */
683
504
  #if MRUBY
684
- static R_VAL ruby2d_sound_ext_play(mrb_state* mrb, R_VAL self) {
505
+ static R_VAL ruby2d_sound_ext_set_volume(mrb_state* mrb, R_VAL self) {
506
+ mrb_value volume;
507
+ mrb_get_args(mrb, "o", &volume);
685
508
  #else
686
- static R_VAL ruby2d_sound_ext_play(R_VAL self) {
509
+ static R_VAL ruby2d_sound_ext_set_volume(R_VAL self, R_VAL volume) {
687
510
  #endif
688
511
  R2D_Sound *snd;
689
512
  r_data_get_struct(self, "@data", &sound_data_type, R2D_Sound, snd);
690
- R2D_PlaySound(snd);
513
+ Mix_VolumeChunk(snd->data, (NUM2INT(volume) / 100.0) * MIX_MAX_VOLUME);
691
514
  return R_NIL;
692
515
  }
693
516
 
694
-
695
517
  /*
696
- * Ruby2D::Sound#ext_length
518
+ * Ruby2D::Sound#ext_get_mix_volume
697
519
  */
698
- static R_VAL ruby2d_sound_ext_length(R_VAL self) {
699
- R2D_Sound *snd;
700
- r_data_get_struct(self, "@data", &sound_data_type, R2D_Sound, snd);
701
- return INT2NUM(R2D_GetSoundLength(snd));
520
+ #if MRUBY
521
+ static R_VAL ruby2d_sound_ext_get_mix_volume(mrb_state* mrb, R_VAL self) {
522
+ #else
523
+ static R_VAL ruby2d_sound_ext_get_mix_volume(R_VAL self) {
524
+ #endif
525
+ return INT2NUM(ceil(Mix_Volume(-1, -1) * (100.0 / MIX_MAX_VOLUME)));
702
526
  }
703
527
 
704
-
705
528
  /*
706
- * Free sound structure attached to Ruby 2D `Sound` class
529
+ * Ruby2D::Music#ext_set_mix_volume
707
530
  */
708
531
  #if MRUBY
709
- static void free_sound(mrb_state *mrb, void *p_) {
710
- R2D_Sound *snd = (R2D_Sound *)p_;
532
+ static R_VAL ruby2d_sound_ext_set_mix_volume(mrb_state* mrb, R_VAL self) {
533
+ mrb_value volume;
534
+ mrb_get_args(mrb, "o", &volume);
711
535
  #else
712
- static void free_sound(R2D_Sound *snd) {
536
+ static R_VAL ruby2d_sound_ext_set_mix_volume(R_VAL self, R_VAL volume) {
713
537
  #endif
714
- R2D_FreeSound(snd);
538
+ Mix_Volume(-1, (NUM2INT(volume) / 100.0) * MIX_MAX_VOLUME);
539
+ return R_NIL;
715
540
  }
716
541
 
717
-
718
542
  /*
719
543
  * Ruby2D::Music#ext_init
720
544
  * Initialize music structure data
@@ -838,6 +662,52 @@ static R_VAL ruby2d_music_ext_length(R_VAL self) {
838
662
  return INT2NUM(R2D_GetMusicLength(ms));
839
663
  }
840
664
 
665
+ /*
666
+ * Ruby2D::Font#ext_load
667
+ */
668
+ static R_VAL ruby2d_font_ext_load(R_VAL self, R_VAL path, R_VAL size, R_VAL style) {
669
+ R2D_Init();
670
+
671
+ TTF_Font *font = R2D_FontCreateTTFFont(RSTRING_PTR(path), NUM2INT(size), RSTRING_PTR(style));
672
+ if (!font) {
673
+ return R_NIL;
674
+ }
675
+
676
+ return r_data_wrap_struct(font, font);
677
+ }
678
+
679
+
680
+ /*
681
+ * Ruby2D::Texture#ext_draw
682
+ */
683
+ static R_VAL ruby2d_texture_ext_draw(R_VAL self, R_VAL ruby_coordinates, R_VAL ruby_texture_coordinates, R_VAL ruby_color, R_VAL texture_id) {
684
+ GLfloat coordinates[8];
685
+ GLfloat texture_coordinates[8];
686
+ GLfloat color[4];
687
+
688
+ for(int i = 0; i < 8; i++) { coordinates[i] = NUM2DBL(r_ary_entry(ruby_coordinates, i)); }
689
+ for(int i = 0; i < 8; i++) { texture_coordinates[i] = NUM2DBL(r_ary_entry(ruby_texture_coordinates, i)); }
690
+ for(int i = 0; i < 4; i++) { color[i] = NUM2DBL(r_ary_entry(ruby_color, i)); }
691
+
692
+ R2D_GL_DrawTexture(coordinates, texture_coordinates, color, NUM2INT(texture_id));
693
+
694
+ return R_NIL;
695
+ }
696
+
697
+ /*
698
+ * Free font structure stored in the Ruby 2D `Font` class
699
+ */
700
+ static void free_font(TTF_Font *font) {
701
+ TTF_CloseFont(font);
702
+ }
703
+
704
+ /*
705
+ * Free surface structure used within the Ruby 2D `Texture` class
706
+ */
707
+ static void free_surface(SDL_Surface *surface) {
708
+ SDL_FreeSurface(surface);
709
+ }
710
+
841
711
 
842
712
  /*
843
713
  * Free music structure attached to Ruby 2D `Music` class
@@ -1275,41 +1145,14 @@ void Init_ruby2d() {
1275
1145
  // Ruby2D::Image
1276
1146
  R_CLASS ruby2d_image_class = r_define_class(ruby2d_module, "Image");
1277
1147
 
1278
- // Ruby2D::Image#ext_init
1279
- r_define_method(ruby2d_image_class, "ext_init", ruby2d_image_ext_init, r_args_req(1));
1280
-
1281
- // Ruby2D::Image#self.ext_draw
1282
- r_define_class_method(ruby2d_image_class, "ext_draw", ruby2d_image_ext_draw, r_args_req(1));
1283
-
1284
- // Ruby2D::Sprite
1285
- R_CLASS ruby2d_sprite_class = r_define_class(ruby2d_module, "Sprite");
1286
-
1287
- // Ruby2D::Sprite#ext_init
1288
- r_define_method(ruby2d_sprite_class, "ext_init", ruby2d_sprite_ext_init, r_args_req(1));
1289
-
1290
- // Ruby2D::Sprite#self.ext_draw
1291
- r_define_class_method(ruby2d_sprite_class, "ext_draw", ruby2d_sprite_ext_draw, r_args_req(1));
1292
-
1293
- // Ruby2D::Tileset
1294
- R_CLASS ruby2d_tileset_class = r_define_class(ruby2d_module, "Tileset");
1295
-
1296
- // Ruby2D::Tileset#ext_init
1297
- r_define_method(ruby2d_tileset_class, "ext_init", ruby2d_tileset_ext_init, r_args_req(1));
1298
-
1299
- // Ruby2D::Tileset#self.ext_draw
1300
- r_define_class_method(ruby2d_tileset_class, "ext_draw", ruby2d_tileset_ext_draw, r_args_req(1));
1148
+ // Ruby2D::Image#ext_load_image
1149
+ r_define_class_method(ruby2d_image_class, "ext_load_image", ruby2d_image_ext_load_image, r_args_req(1));
1301
1150
 
1302
1151
  // Ruby2D::Text
1303
1152
  R_CLASS ruby2d_text_class = r_define_class(ruby2d_module, "Text");
1304
1153
 
1305
- // Ruby2D::Text#ext_init
1306
- r_define_method(ruby2d_text_class, "ext_init", ruby2d_text_ext_init, r_args_none);
1307
-
1308
- // Ruby2D::Text#ext_set
1309
- r_define_method(ruby2d_text_class, "ext_set", ruby2d_text_ext_set, r_args_req(1));
1310
-
1311
- // Ruby2D::Text#self.ext_draw
1312
- r_define_class_method(ruby2d_text_class, "ext_draw", ruby2d_text_ext_draw, r_args_req(1));
1154
+ // Ruby2D::Text#ext_load_text
1155
+ r_define_class_method(ruby2d_text_class, "ext_load_text", ruby2d_text_ext_load_text, r_args_req(2));
1313
1156
 
1314
1157
  // Ruby2D::Sound
1315
1158
  R_CLASS ruby2d_sound_class = r_define_class(ruby2d_module, "Sound");
@@ -1319,6 +1162,18 @@ void Init_ruby2d() {
1319
1162
 
1320
1163
  // Ruby2D::Sound#ext_play
1321
1164
  r_define_method(ruby2d_sound_class, "ext_play", ruby2d_sound_ext_play, r_args_none);
1165
+
1166
+ // Ruby2D::Sound#ext_get_volume
1167
+ r_define_method(ruby2d_sound_class, "ext_get_volume", ruby2d_sound_ext_get_volume, r_args_none);
1168
+
1169
+ // Ruby2D::Sound#ext_set_volume
1170
+ r_define_method(ruby2d_sound_class, "ext_set_volume", ruby2d_sound_ext_set_volume, r_args_req(1));
1171
+
1172
+ // Ruby2D::Sound#self.ext_get_mix_volume
1173
+ r_define_class_method(ruby2d_sound_class, "ext_get_mix_volume", ruby2d_sound_ext_get_mix_volume, r_args_none);
1174
+
1175
+ // Ruby2D::Sound#self.ext_set_mix_volume
1176
+ r_define_class_method(ruby2d_sound_class, "ext_set_mix_volume", ruby2d_sound_ext_set_mix_volume, r_args_req(1));
1322
1177
 
1323
1178
  // Ruby2D::Sound#ext_length
1324
1179
  r_define_method(ruby2d_sound_class, "ext_length", ruby2d_sound_ext_length, r_args_none);
@@ -1353,6 +1208,24 @@ void Init_ruby2d() {
1353
1208
  // Ruby2D::Music#ext_length
1354
1209
  r_define_method(ruby2d_music_class, "ext_length", ruby2d_music_ext_length, r_args_none);
1355
1210
 
1211
+ // Ruby2D::Font
1212
+ R_CLASS ruby2d_font_class = r_define_class(ruby2d_module, "Font");
1213
+
1214
+ // Ruby2D::Font#ext_load
1215
+ r_define_class_method(ruby2d_font_class, "ext_load", ruby2d_font_ext_load, r_args_req(3));
1216
+
1217
+ // Ruby2D::Texture
1218
+ R_CLASS ruby2d_texture_class = r_define_class(ruby2d_module, "Texture");
1219
+
1220
+ // Ruby2D::Texture#ext_draw
1221
+ r_define_method(ruby2d_texture_class, "ext_draw", ruby2d_texture_ext_draw, r_args_req(4));
1222
+
1223
+ // Ruby2D::Texture#ext_create
1224
+ r_define_method(ruby2d_texture_class, "ext_create", ruby2d_texture_ext_create, r_args_req(3));
1225
+
1226
+ // Ruby2D::Texture#ext_delete
1227
+ r_define_method(ruby2d_texture_class, "ext_delete", ruby2d_texture_ext_delete, r_args_req(1));
1228
+
1356
1229
  // Ruby2D::Window
1357
1230
  R_CLASS ruby2d_window_class = r_define_class(ruby2d_module, "Window");
1358
1231