ruby2d 0.9.3 → 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.
Files changed (166) hide show
  1. checksums.yaml +4 -4
  2. data/assets/README.md +7 -9
  3. data/assets/Rakefile +85 -0
  4. data/assets/include/SDL2/SDL.h +4 -1
  5. data/assets/include/SDL2/SDL_assert.h +3 -1
  6. data/assets/include/SDL2/SDL_atomic.h +20 -2
  7. data/assets/include/SDL2/SDL_audio.h +47 -14
  8. data/assets/include/SDL2/SDL_bits.h +10 -1
  9. data/assets/include/SDL2/SDL_blendmode.h +10 -7
  10. data/assets/include/SDL2/SDL_clipboard.h +1 -1
  11. data/assets/include/SDL2/SDL_config.h +24 -390
  12. data/assets/include/SDL2/SDL_config_android.h +182 -0
  13. data/assets/include/SDL2/SDL_config_iphoneos.h +207 -0
  14. data/assets/include/SDL2/SDL_config_macosx.h +266 -0
  15. data/assets/include/SDL2/SDL_config_minimal.h +85 -0
  16. data/assets/include/SDL2/SDL_config_os2.h +188 -0
  17. data/assets/include/SDL2/SDL_config_pandora.h +135 -0
  18. data/assets/include/SDL2/SDL_config_psp.h +165 -0
  19. data/assets/include/SDL2/SDL_config_windows.h +288 -0
  20. data/assets/include/SDL2/SDL_config_winrt.h +243 -0
  21. data/assets/include/SDL2/SDL_config_wiz.h +149 -0
  22. data/assets/include/SDL2/SDL_copying.h +20 -0
  23. data/assets/include/SDL2/SDL_cpuinfo.h +119 -8
  24. data/assets/include/SDL2/SDL_egl.h +4 -1
  25. data/assets/include/SDL2/SDL_endian.h +6 -3
  26. data/assets/include/SDL2/SDL_error.h +38 -2
  27. data/assets/include/SDL2/SDL_events.h +67 -28
  28. data/assets/include/SDL2/SDL_filesystem.h +1 -1
  29. data/assets/include/SDL2/SDL_gamecontroller.h +160 -9
  30. data/assets/include/SDL2/SDL_gesture.h +1 -1
  31. data/assets/include/SDL2/SDL_haptic.h +10 -1
  32. data/assets/include/SDL2/SDL_hints.h +460 -17
  33. data/assets/include/SDL2/SDL_image.h +2 -2
  34. data/assets/include/SDL2/SDL_joystick.h +115 -24
  35. data/assets/include/SDL2/SDL_keyboard.h +1 -1
  36. data/assets/include/SDL2/SDL_keycode.h +11 -9
  37. data/assets/include/SDL2/SDL_loadso.h +1 -1
  38. data/assets/include/SDL2/SDL_locale.h +101 -0
  39. data/assets/include/SDL2/SDL_log.h +3 -3
  40. data/assets/include/SDL2/SDL_main.h +28 -16
  41. data/assets/include/SDL2/SDL_messagebox.h +6 -4
  42. data/assets/include/SDL2/SDL_metal.h +117 -0
  43. data/assets/include/SDL2/SDL_misc.h +75 -0
  44. data/assets/include/SDL2/SDL_mouse.h +1 -1
  45. data/assets/include/SDL2/SDL_mutex.h +1 -1
  46. data/assets/include/SDL2/SDL_name.h +1 -1
  47. data/assets/include/SDL2/SDL_opengl.h +1 -1
  48. data/assets/include/SDL2/SDL_opengl_glext.h +3 -0
  49. data/assets/include/SDL2/SDL_opengles.h +1 -1
  50. data/assets/include/SDL2/SDL_opengles2.h +1 -1
  51. data/assets/include/SDL2/SDL_pixels.h +27 -18
  52. data/assets/include/SDL2/SDL_platform.h +1 -1
  53. data/assets/include/SDL2/SDL_power.h +1 -1
  54. data/assets/include/SDL2/SDL_quit.h +1 -1
  55. data/assets/include/SDL2/SDL_rect.h +29 -3
  56. data/assets/include/SDL2/SDL_render.h +230 -3
  57. data/assets/include/SDL2/SDL_revision.h +2 -2
  58. data/assets/include/SDL2/SDL_rwops.h +51 -22
  59. data/assets/include/SDL2/SDL_scancode.h +2 -2
  60. data/assets/include/SDL2/SDL_sensor.h +28 -12
  61. data/assets/include/SDL2/SDL_shape.h +1 -1
  62. data/assets/include/SDL2/SDL_stdinc.h +44 -4
  63. data/assets/include/SDL2/SDL_surface.h +12 -2
  64. data/assets/include/SDL2/SDL_system.h +50 -4
  65. data/assets/include/SDL2/SDL_syswm.h +39 -9
  66. data/assets/include/SDL2/SDL_test.h +1 -1
  67. data/assets/include/SDL2/SDL_test_assert.h +1 -1
  68. data/assets/include/SDL2/SDL_test_common.h +32 -2
  69. data/assets/include/SDL2/SDL_test_compare.h +1 -1
  70. data/assets/include/SDL2/SDL_test_crc32.h +1 -1
  71. data/assets/include/SDL2/SDL_test_font.h +1 -1
  72. data/assets/include/SDL2/SDL_test_fuzzer.h +1 -1
  73. data/assets/include/SDL2/SDL_test_harness.h +1 -1
  74. data/assets/include/SDL2/SDL_test_images.h +1 -1
  75. data/assets/include/SDL2/SDL_test_log.h +1 -1
  76. data/assets/include/SDL2/SDL_test_md5.h +1 -1
  77. data/assets/include/SDL2/SDL_test_memory.h +3 -3
  78. data/assets/include/SDL2/SDL_test_random.h +1 -1
  79. data/assets/include/SDL2/SDL_thread.h +34 -11
  80. data/assets/include/SDL2/SDL_timer.h +1 -1
  81. data/assets/include/SDL2/SDL_touch.h +17 -1
  82. data/assets/include/SDL2/SDL_types.h +1 -1
  83. data/assets/include/SDL2/SDL_version.h +2 -2
  84. data/assets/include/SDL2/SDL_video.h +11 -5
  85. data/assets/include/SDL2/SDL_vulkan.h +9 -11
  86. data/assets/include/SDL2/begin_code.h +8 -9
  87. data/assets/include/SDL2/close_code.h +4 -1
  88. data/assets/macos/lib/libFLAC.a +0 -0
  89. data/assets/macos/lib/libSDL2.a +0 -0
  90. data/assets/macos/lib/libSDL2_image.a +0 -0
  91. data/assets/macos/lib/libSDL2_mixer.a +0 -0
  92. data/assets/macos/lib/libSDL2_ttf.a +0 -0
  93. data/assets/macos/lib/libfreetype.a +0 -0
  94. data/assets/macos/lib/libjpeg.a +0 -0
  95. data/assets/macos/lib/libmpg123.a +0 -0
  96. data/assets/macos/lib/libogg.a +0 -0
  97. data/assets/macos/lib/libpng16.a +0 -0
  98. data/assets/macos/lib/libtiff.a +0 -0
  99. data/assets/macos/lib/libvorbis.a +0 -0
  100. data/assets/macos/lib/libvorbisfile.a +0 -0
  101. data/assets/macos/lib/libwebp.a +0 -0
  102. data/assets/mingw/bin/SDL2.dll +0 -0
  103. data/assets/mingw/bin/SDL2_image.dll +0 -0
  104. data/assets/mingw/bin/libpng16-16.dll +0 -0
  105. data/assets/mingw/bin/libtiff-5.dll +0 -0
  106. data/assets/mingw/bin/libwebp-7.dll +0 -0
  107. data/assets/mingw/lib/libSDL2.a +0 -0
  108. data/assets/mingw/lib/libSDL2.dll.a +0 -0
  109. data/assets/mingw/lib/libSDL2_image.a +0 -0
  110. data/assets/mingw/lib/libSDL2_image.dll.a +0 -0
  111. data/assets/mingw/lib/libSDL2_test.a +0 -0
  112. data/assets/mingw/lib/libSDL2main.a +0 -0
  113. data/bin/ruby2d +1 -0
  114. data/{assets/linux/simple2d/src/simple2d.c → ext/ruby2d/common.c} +32 -32
  115. data/{assets/linux/simple2d/src → ext/ruby2d}/controllers.c +17 -17
  116. data/ext/ruby2d/extconf.rb +36 -58
  117. data/ext/ruby2d/font.c +35 -0
  118. data/{assets/linux/simple2d/src → ext/ruby2d}/gl.c +72 -100
  119. data/ext/ruby2d/gl2.c +86 -0
  120. data/ext/ruby2d/gl3.c +305 -0
  121. data/{assets/linux/simple2d/src → ext/ruby2d}/gles.c +22 -81
  122. data/ext/ruby2d/image.c +58 -0
  123. data/{assets/linux/simple2d/src → ext/ruby2d}/input.c +8 -8
  124. data/{assets/linux/simple2d/src → ext/ruby2d}/music.c +30 -17
  125. data/ext/ruby2d/ruby2d.c +449 -439
  126. data/ext/ruby2d/ruby2d.h +652 -0
  127. data/{assets/linux/simple2d/src → ext/ruby2d}/shapes.c +18 -18
  128. data/ext/ruby2d/sound.c +118 -0
  129. data/ext/ruby2d/text.c +22 -0
  130. data/{assets/linux/simple2d/src → ext/ruby2d}/window.c +73 -62
  131. data/lib/ruby2d/circle.rb +21 -3
  132. data/lib/ruby2d/cli/build.rb +4 -7
  133. data/lib/ruby2d/dsl.rb +16 -9
  134. data/lib/ruby2d/entity.rb +17 -0
  135. data/lib/ruby2d/font.rb +23 -3
  136. data/lib/ruby2d/image.rb +35 -7
  137. data/lib/ruby2d/line.rb +23 -1
  138. data/lib/ruby2d/music.rb +5 -0
  139. data/lib/ruby2d/pixel.rb +17 -0
  140. data/lib/ruby2d/quad.rb +21 -1
  141. data/lib/ruby2d/rectangle.rb +12 -3
  142. data/lib/ruby2d/renderable.rb +4 -20
  143. data/lib/ruby2d/sound.rb +30 -0
  144. data/lib/ruby2d/sprite.rb +57 -75
  145. data/lib/ruby2d/square.rb +10 -1
  146. data/lib/ruby2d/text.rb +55 -12
  147. data/lib/ruby2d/texture.rb +28 -0
  148. data/lib/ruby2d/tileset.rb +87 -0
  149. data/lib/ruby2d/triangle.rb +19 -1
  150. data/lib/ruby2d/version.rb +1 -1
  151. data/lib/ruby2d/vertices.rb +84 -0
  152. data/lib/ruby2d/window.rb +259 -22
  153. data/lib/ruby2d.rb +6 -1
  154. metadata +41 -26
  155. data/assets/include/simple2d.h +0 -735
  156. data/assets/linux/simple2d/Makefile +0 -257
  157. data/assets/linux/simple2d/bin/simple2d.sh +0 -1312
  158. data/assets/linux/simple2d/include/simple2d.h +0 -735
  159. data/assets/linux/simple2d/src/gl2.c +0 -146
  160. data/assets/linux/simple2d/src/gl3.c +0 -275
  161. data/assets/linux/simple2d/src/image.c +0 -138
  162. data/assets/linux/simple2d/src/sound.c +0 -56
  163. data/assets/linux/simple2d/src/sprite.c +0 -147
  164. data/assets/linux/simple2d/src/text.c +0 -129
  165. data/assets/macos/lib/libsimple2d.a +0 -0
  166. data/assets/mingw/lib/libsimple2d.a +0 -0
@@ -0,0 +1,58 @@
1
+ // image.c
2
+
3
+ #include "ruby2d.h"
4
+
5
+
6
+ SDL_Surface *R2D_CreateImageSurface(const char *path) {
7
+ R2D_Init();
8
+
9
+ // Check if image file exists
10
+ if (!R2D_FileExists(path)) {
11
+ R2D_Error("R2D_CreateImageSurface", "Image file `%s` not found", path);
12
+ return NULL;
13
+ }
14
+
15
+ // Load image from file as SDL_Surface
16
+ SDL_Surface *surface = IMG_Load(path);
17
+
18
+ int bits_per_color = surface->format->Amask == 0 ?
19
+ surface->format->BitsPerPixel / 3 :
20
+ surface->format->BitsPerPixel / 4;
21
+
22
+ if (bits_per_color < 8) {
23
+ R2D_Log(R2D_WARN, "`%s` has less than 8 bits per color and will likely not render correctly", path, bits_per_color);
24
+ }
25
+
26
+ return surface;
27
+ }
28
+
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;
33
+
34
+ if (r&0xFF000000 || r&0xFF0000) {
35
+ char *p = (char *)surface->pixels;
36
+ int bpp = surface->format->BytesPerPixel;
37
+ int w = surface->w;
38
+ int h = surface->h;
39
+ char tmp;
40
+ for (int i = 0; i < bpp * w * h; i += bpp) {
41
+ if (a&0xFF) {
42
+ tmp = p[i];
43
+ p[i] = p[i+3];
44
+ p[i+3] = tmp;
45
+ }
46
+ if (g&0xFF0000) {
47
+ tmp = p[i+1];
48
+ p[i+1] = p[i+2];
49
+ p[i+2] = tmp;
50
+ }
51
+ if (r&0xFF0000) {
52
+ tmp = p[i];
53
+ p[i] = p[i+2];
54
+ p[i+2] = tmp;
55
+ }
56
+ }
57
+ }
58
+ }
@@ -1,30 +1,30 @@
1
1
  // input.c
2
2
 
3
- #include "../include/simple2d.h"
3
+ #include "ruby2d.h"
4
4
 
5
5
 
6
6
  /*
7
7
  * Get the mouse coordinates relative to the viewport
8
8
  */
9
- void S2D_GetMouseOnViewport(S2D_Window *window, int wx, int wy, int *x, int *y) {
9
+ void R2D_GetMouseOnViewport(R2D_Window *window, int wx, int wy, int *x, int *y) {
10
10
 
11
11
  double scale; // viewport scale factor
12
12
  int w, h; // width and height of scaled viewport
13
13
 
14
14
  switch (window->viewport.mode) {
15
15
 
16
- case S2D_FIXED: case S2D_EXPAND:
16
+ case R2D_FIXED: case R2D_EXPAND:
17
17
  *x = wx / (window->orig_width / (double)window->viewport.width);
18
18
  *y = wy / (window->orig_height / (double)window->viewport.height);
19
19
  break;
20
20
 
21
- case S2D_SCALE:
22
- S2D_GL_GetViewportScale(window, &w, &h, &scale);
21
+ case R2D_SCALE:
22
+ R2D_GL_GetViewportScale(window, &w, &h, &scale);
23
23
  *x = wx * 1 / scale - (window->width - w) / (2.0 * scale);
24
24
  *y = wy * 1 / scale - (window->height - h) / (2.0 * scale);
25
25
  break;
26
26
 
27
- case S2D_STRETCH:
27
+ case R2D_STRETCH:
28
28
  *x = wx * window->viewport.width / (double)window->width;
29
29
  *y = wy * window->viewport.height / (double)window->height;
30
30
  break;
@@ -35,7 +35,7 @@ void S2D_GetMouseOnViewport(S2D_Window *window, int wx, int wy, int *x, int *y)
35
35
  /*
36
36
  * Show the cursor over the window
37
37
  */
38
- void S2D_ShowCursor() {
38
+ void R2D_ShowCursor() {
39
39
  SDL_ShowCursor(SDL_ENABLE);
40
40
  }
41
41
 
@@ -43,6 +43,6 @@ void S2D_ShowCursor() {
43
43
  /*
44
44
  * Hide the cursor over the window
45
45
  */
46
- void S2D_HideCursor() {
46
+ void R2D_HideCursor() {
47
47
  SDL_ShowCursor(SDL_DISABLE);
48
48
  }
@@ -1,31 +1,31 @@
1
1
  // music.c
2
2
 
3
- #include "../include/simple2d.h"
3
+ #include "ruby2d.h"
4
4
 
5
5
 
6
6
  /*
7
7
  * Create the music
8
8
  */
9
- S2D_Music *S2D_CreateMusic(const char *path) {
10
- S2D_Init();
9
+ R2D_Music *R2D_CreateMusic(const char *path) {
10
+ R2D_Init();
11
11
 
12
12
  // Check if music file exists
13
- if (!S2D_FileExists(path)) {
14
- S2D_Error("S2D_CreateMusic", "Music file `%s` not found", path);
13
+ if (!R2D_FileExists(path)) {
14
+ R2D_Error("R2D_CreateMusic", "Music file `%s` not found", path);
15
15
  return NULL;
16
16
  }
17
17
 
18
18
  // Allocate the music structure
19
- S2D_Music *mus = (S2D_Music *) malloc(sizeof(S2D_Music));
19
+ R2D_Music *mus = (R2D_Music *) malloc(sizeof(R2D_Music));
20
20
  if (!mus) {
21
- S2D_Error("S2D_CreateMusic", "Out of memory!");
21
+ R2D_Error("R2D_CreateMusic", "Out of memory!");
22
22
  return NULL;
23
23
  }
24
24
 
25
25
  // Load the music data from file
26
26
  mus->data = Mix_LoadMUS(path);
27
27
  if (!mus->data) {
28
- S2D_Error("Mix_LoadMUS", Mix_GetError());
28
+ R2D_Error("Mix_LoadMUS", Mix_GetError());
29
29
  free(mus);
30
30
  return NULL;
31
31
  }
@@ -33,6 +33,11 @@ S2D_Music *S2D_CreateMusic(const char *path) {
33
33
  // Initialize values
34
34
  mus->path = path;
35
35
 
36
+ // Calculate the length of music by creating a temporary R2D_Sound object
37
+ R2D_Sound *snd = R2D_CreateSound(path);
38
+ mus->length = R2D_GetSoundLength(snd);
39
+ R2D_FreeSound(snd);
40
+
36
41
  return mus;
37
42
  }
38
43
 
@@ -40,7 +45,7 @@ S2D_Music *S2D_CreateMusic(const char *path) {
40
45
  /*
41
46
  * Play the music
42
47
  */
43
- void S2D_PlayMusic(S2D_Music *mus, bool loop) {
48
+ void R2D_PlayMusic(R2D_Music *mus, bool loop) {
44
49
  if (!mus) return;
45
50
 
46
51
  // If looping, set to -1 times; else 0
@@ -49,7 +54,7 @@ void S2D_PlayMusic(S2D_Music *mus, bool loop) {
49
54
  // times: 0 == once, -1 == forever
50
55
  if (Mix_PlayMusic(mus->data, times) == -1) {
51
56
  // No music for you
52
- S2D_Error("S2D_PlayMusic", Mix_GetError());
57
+ R2D_Error("R2D_PlayMusic", Mix_GetError());
53
58
  }
54
59
  }
55
60
 
@@ -57,7 +62,7 @@ void S2D_PlayMusic(S2D_Music *mus, bool loop) {
57
62
  /*
58
63
  * Pause the playing music
59
64
  */
60
- void S2D_PauseMusic() {
65
+ void R2D_PauseMusic() {
61
66
  Mix_PauseMusic();
62
67
  }
63
68
 
@@ -65,7 +70,7 @@ void S2D_PauseMusic() {
65
70
  /*
66
71
  * Resume the current music
67
72
  */
68
- void S2D_ResumeMusic() {
73
+ void R2D_ResumeMusic() {
69
74
  Mix_ResumeMusic();
70
75
  }
71
76
 
@@ -73,7 +78,7 @@ void S2D_ResumeMusic() {
73
78
  /*
74
79
  * Stop the playing music; interrupts fader effects
75
80
  */
76
- void S2D_StopMusic() {
81
+ void R2D_StopMusic() {
77
82
  Mix_HaltMusic();
78
83
  }
79
84
 
@@ -81,7 +86,7 @@ void S2D_StopMusic() {
81
86
  /*
82
87
  * Get the music volume
83
88
  */
84
- int S2D_GetMusicVolume() {
89
+ int R2D_GetMusicVolume() {
85
90
  // Get music volume as percentage of maximum mix volume
86
91
  return ceil(Mix_VolumeMusic(-1) * (100.0 / MIX_MAX_VOLUME));
87
92
  }
@@ -90,7 +95,7 @@ int S2D_GetMusicVolume() {
90
95
  /*
91
96
  * Set the music volume a given percentage
92
97
  */
93
- void S2D_SetMusicVolume(int volume) {
98
+ void R2D_SetMusicVolume(int volume) {
94
99
  // Set volume to be a percentage of the maximum mix volume
95
100
  Mix_VolumeMusic((volume / 100.0) * MIX_MAX_VOLUME);
96
101
  }
@@ -99,15 +104,23 @@ void S2D_SetMusicVolume(int volume) {
99
104
  /*
100
105
  * Fade out the playing music
101
106
  */
102
- void S2D_FadeOutMusic(int ms) {
107
+ void R2D_FadeOutMusic(int ms) {
103
108
  Mix_FadeOutMusic(ms);
104
109
  }
105
110
 
106
111
 
112
+ /*
113
+ * Get the length of the music in seconds
114
+ */
115
+ int R2D_GetMusicLength(R2D_Music *mus) {
116
+ return mus->length;
117
+ }
118
+
119
+
107
120
  /*
108
121
  * Free the music
109
122
  */
110
- void S2D_FreeMusic(S2D_Music *mus) {
123
+ void R2D_FreeMusic(R2D_Music *mus) {
111
124
  if (!mus) return;
112
125
  Mix_FreeMusic(mus->data);
113
126
  free(mus);
data/ext/ruby2d/ruby2d.c CHANGED
@@ -1,10 +1,9 @@
1
1
  // Native C extension for Ruby and MRuby
2
2
 
3
- // Simple 2D includes
3
+ // Ruby 2D includes
4
4
  #if RUBY2D_IOS_TVOS
5
- #include <Simple2D/simple2d.h>
6
5
  #else
7
- #include <simple2d.h>
6
+ #include <ruby2d.h>
8
7
  #endif
9
8
 
10
9
  // Ruby includes
@@ -100,27 +99,15 @@
100
99
  static mrb_state *mrb;
101
100
  #endif
102
101
 
103
- // Ruby 2D window
102
+ // Ruby 2D interpreter window
104
103
  static R_VAL ruby2d_window;
105
104
 
106
- // Simple 2D window
107
- static S2D_Window *window;
105
+ // Ruby 2D native window
106
+ static R2D_Window *window;
108
107
 
109
108
 
110
109
  // Method signatures and structures for Ruby 2D classes
111
110
  #if MRUBY
112
- static void free_image(mrb_state *mrb, void *p_);
113
- static const struct mrb_data_type image_data_type = {
114
- "image", free_image
115
- };
116
- static void free_sprite(mrb_state *mrb, void *p_);
117
- static const struct mrb_data_type sprite_data_type = {
118
- "sprite", free_sprite
119
- };
120
- static void free_text(mrb_state *mrb, void *p_);
121
- static const struct mrb_data_type text_data_type = {
122
- "text", free_text
123
- };
124
111
  static void free_sound(mrb_state *mrb, void *p_);
125
112
  static const struct mrb_data_type sound_data_type = {
126
113
  "sound", free_sound
@@ -130,19 +117,18 @@ static S2D_Window *window;
130
117
  "music", free_music
131
118
  };
132
119
  #else
133
- static void free_image(S2D_Image *img);
134
- static void free_sprite(S2D_Sprite *spr);
135
- static void free_text(S2D_Text *txt);
136
- static void free_sound(S2D_Sound *snd);
137
- static void free_music(S2D_Music *mus);
120
+ static void free_sound(R2D_Sound *snd);
121
+ static void free_music(R2D_Music *mus);
122
+ static void free_font(TTF_Font *font);
123
+ static void free_surface(SDL_Surface *font);
138
124
  #endif
139
125
 
140
126
 
141
127
  /*
142
- * Function pointer to free the Simple 2D window
128
+ * Function pointer to free the Ruby 2D native window
143
129
  */
144
130
  static void free_window() {
145
- S2D_FreeWindow(window);
131
+ R2D_FreeWindow(window);
146
132
  }
147
133
 
148
134
 
@@ -167,38 +153,45 @@ static R_VAL ruby2d_ext_base_path(R_VAL self) {
167
153
 
168
154
 
169
155
  /*
170
- * Ruby2D::Triangle#ext_render
156
+ * Ruby2D::Pixel#self.ext_draw
171
157
  */
172
158
  #if MRUBY
173
- static R_VAL ruby2d_triangle_ext_render(mrb_state* mrb, R_VAL self) {
159
+ static R_VAL ruby2d_pixel_ext_draw(mrb_state* mrb, R_VAL self) {
160
+ mrb_value a;
161
+ mrb_get_args(mrb, "o", &a);
174
162
  #else
175
- static R_VAL ruby2d_triangle_ext_render(R_VAL self) {
163
+ static R_VAL ruby2d_pixel_ext_draw(R_VAL self, R_VAL a) {
176
164
  #endif
177
- R_VAL c1 = r_iv_get(self, "@c1");
178
- R_VAL c2 = r_iv_get(self, "@c2");
179
- R_VAL c3 = r_iv_get(self, "@c3");
180
-
181
- S2D_DrawTriangle(
182
- NUM2DBL(r_iv_get(self, "@x1")),
183
- NUM2DBL(r_iv_get(self, "@y1")),
184
- NUM2DBL(r_iv_get(c1, "@r")),
185
- NUM2DBL(r_iv_get(c1, "@g")),
186
- NUM2DBL(r_iv_get(c1, "@b")),
187
- NUM2DBL(r_iv_get(c1, "@a")),
188
-
189
- NUM2DBL(r_iv_get(self, "@x2")),
190
- NUM2DBL(r_iv_get(self, "@y2")),
191
- NUM2DBL(r_iv_get(c2, "@r")),
192
- NUM2DBL(r_iv_get(c2, "@g")),
193
- NUM2DBL(r_iv_get(c2, "@b")),
194
- NUM2DBL(r_iv_get(c2, "@a")),
195
-
196
- NUM2DBL(r_iv_get(self, "@x3")),
197
- NUM2DBL(r_iv_get(self, "@y3")),
198
- NUM2DBL(r_iv_get(c3, "@r")),
199
- NUM2DBL(r_iv_get(c3, "@g")),
200
- NUM2DBL(r_iv_get(c3, "@b")),
201
- NUM2DBL(r_iv_get(c3, "@a"))
165
+ // `a` is the array representing the pixel
166
+
167
+ R2D_DrawQuad(
168
+ NUM2DBL(r_ary_entry(a, 0)), // x1
169
+ NUM2DBL(r_ary_entry(a, 1)), // y1
170
+ NUM2DBL(r_ary_entry(a, 8)), // color
171
+ NUM2DBL(r_ary_entry(a, 9)), // color
172
+ NUM2DBL(r_ary_entry(a, 10)), // color
173
+ NUM2DBL(r_ary_entry(a, 11)), // color
174
+
175
+ NUM2DBL(r_ary_entry(a, 2)), // x2
176
+ NUM2DBL(r_ary_entry(a, 3)), // y2
177
+ NUM2DBL(r_ary_entry(a, 8)), // color
178
+ NUM2DBL(r_ary_entry(a, 9)), // color
179
+ NUM2DBL(r_ary_entry(a, 10)), // color
180
+ NUM2DBL(r_ary_entry(a, 11)), // color
181
+
182
+ NUM2DBL(r_ary_entry(a, 4)), // x3
183
+ NUM2DBL(r_ary_entry(a, 5)), // y3
184
+ NUM2DBL(r_ary_entry(a, 8)), // color
185
+ NUM2DBL(r_ary_entry(a, 9)), // color
186
+ NUM2DBL(r_ary_entry(a, 10)), // color
187
+ NUM2DBL(r_ary_entry(a, 11)), // color
188
+
189
+ NUM2DBL(r_ary_entry(a, 6)), // x4
190
+ NUM2DBL(r_ary_entry(a, 7)), // y4
191
+ NUM2DBL(r_ary_entry(a, 8)), // color
192
+ NUM2DBL(r_ary_entry(a, 9)), // color
193
+ NUM2DBL(r_ary_entry(a, 10)), // color
194
+ NUM2DBL(r_ary_entry(a, 11)) // color
202
195
  );
203
196
 
204
197
  return R_NIL;
@@ -206,46 +199,38 @@ static R_VAL ruby2d_triangle_ext_render(R_VAL self) {
206
199
 
207
200
 
208
201
  /*
209
- * Ruby2D::Quad#ext_render
202
+ * Ruby2D::Triangle#self.ext_draw
210
203
  */
211
204
  #if MRUBY
212
- static R_VAL ruby2d_quad_ext_render(mrb_state* mrb, R_VAL self) {
205
+ static R_VAL ruby2d_triangle_ext_draw(mrb_state* mrb, R_VAL self) {
206
+ mrb_value a;
207
+ mrb_get_args(mrb, "o", &a);
213
208
  #else
214
- static R_VAL ruby2d_quad_ext_render(R_VAL self) {
209
+ static R_VAL ruby2d_triangle_ext_draw(R_VAL self, R_VAL a) {
215
210
  #endif
216
- R_VAL c1 = r_iv_get(self, "@c1");
217
- R_VAL c2 = r_iv_get(self, "@c2");
218
- R_VAL c3 = r_iv_get(self, "@c3");
219
- R_VAL c4 = r_iv_get(self, "@c4");
220
-
221
- S2D_DrawQuad(
222
- NUM2DBL(r_iv_get(self, "@x1")),
223
- NUM2DBL(r_iv_get(self, "@y1")),
224
- NUM2DBL(r_iv_get(c1, "@r")),
225
- NUM2DBL(r_iv_get(c1, "@g")),
226
- NUM2DBL(r_iv_get(c1, "@b")),
227
- NUM2DBL(r_iv_get(c1, "@a")),
228
-
229
- NUM2DBL(r_iv_get(self, "@x2")),
230
- NUM2DBL(r_iv_get(self, "@y2")),
231
- NUM2DBL(r_iv_get(c2, "@r")),
232
- NUM2DBL(r_iv_get(c2, "@g")),
233
- NUM2DBL(r_iv_get(c2, "@b")),
234
- NUM2DBL(r_iv_get(c2, "@a")),
235
-
236
- NUM2DBL(r_iv_get(self, "@x3")),
237
- NUM2DBL(r_iv_get(self, "@y3")),
238
- NUM2DBL(r_iv_get(c3, "@r")),
239
- NUM2DBL(r_iv_get(c3, "@g")),
240
- NUM2DBL(r_iv_get(c3, "@b")),
241
- NUM2DBL(r_iv_get(c3, "@a")),
242
-
243
- NUM2DBL(r_iv_get(self, "@x4")),
244
- NUM2DBL(r_iv_get(self, "@y4")),
245
- NUM2DBL(r_iv_get(c4, "@r")),
246
- NUM2DBL(r_iv_get(c4, "@g")),
247
- NUM2DBL(r_iv_get(c4, "@b")),
248
- NUM2DBL(r_iv_get(c4, "@a"))
211
+ // `a` is the array representing the triangle
212
+
213
+ R2D_DrawTriangle(
214
+ NUM2DBL(r_ary_entry(a, 0)), // x1
215
+ NUM2DBL(r_ary_entry(a, 1)), // y1
216
+ NUM2DBL(r_ary_entry(a, 2)), // c1 red
217
+ NUM2DBL(r_ary_entry(a, 3)), // c1 green
218
+ NUM2DBL(r_ary_entry(a, 4)), // c1 blue
219
+ NUM2DBL(r_ary_entry(a, 5)), // c1 alpha
220
+
221
+ NUM2DBL(r_ary_entry(a, 6)), // x2
222
+ NUM2DBL(r_ary_entry(a, 7)), // y2
223
+ NUM2DBL(r_ary_entry(a, 8)), // c2 red
224
+ NUM2DBL(r_ary_entry(a, 9)), // c2 green
225
+ NUM2DBL(r_ary_entry(a, 10)), // c2 blue
226
+ NUM2DBL(r_ary_entry(a, 11)), // c2 alpha
227
+
228
+ NUM2DBL(r_ary_entry(a, 12)), // x3
229
+ NUM2DBL(r_ary_entry(a, 13)), // y3
230
+ NUM2DBL(r_ary_entry(a, 14)), // c3 red
231
+ NUM2DBL(r_ary_entry(a, 15)), // c3 green
232
+ NUM2DBL(r_ary_entry(a, 16)), // c3 blue
233
+ NUM2DBL(r_ary_entry(a, 17)) // c3 alpha
249
234
  );
250
235
 
251
236
  return R_NIL;
@@ -253,44 +238,45 @@ static R_VAL ruby2d_quad_ext_render(R_VAL self) {
253
238
 
254
239
 
255
240
  /*
256
- * Ruby2D::Line#ext_render
241
+ * Ruby2D::Quad#self.ext_draw
257
242
  */
258
243
  #if MRUBY
259
- static R_VAL ruby2d_line_ext_render(mrb_state* mrb, R_VAL self) {
244
+ static R_VAL ruby2d_quad_ext_draw(mrb_state* mrb, R_VAL self) {
245
+ mrb_value a;
246
+ mrb_get_args(mrb, "o", &a);
260
247
  #else
261
- static R_VAL ruby2d_line_ext_render(R_VAL self) {
248
+ static R_VAL ruby2d_quad_ext_draw(R_VAL self, R_VAL a) {
262
249
  #endif
263
- R_VAL c1 = r_iv_get(self, "@c1");
264
- R_VAL c2 = r_iv_get(self, "@c2");
265
- R_VAL c3 = r_iv_get(self, "@c3");
266
- R_VAL c4 = r_iv_get(self, "@c4");
267
-
268
- S2D_DrawLine(
269
- NUM2DBL(r_iv_get(self, "@x1")),
270
- NUM2DBL(r_iv_get(self, "@y1")),
271
- NUM2DBL(r_iv_get(self, "@x2")),
272
- NUM2DBL(r_iv_get(self, "@y2")),
273
- NUM2DBL(r_iv_get(self, "@width")),
274
-
275
- NUM2DBL(r_iv_get(c1, "@r")),
276
- NUM2DBL(r_iv_get(c1, "@g")),
277
- NUM2DBL(r_iv_get(c1, "@b")),
278
- NUM2DBL(r_iv_get(c1, "@a")),
279
-
280
- NUM2DBL(r_iv_get(c2, "@r")),
281
- NUM2DBL(r_iv_get(c2, "@g")),
282
- NUM2DBL(r_iv_get(c2, "@b")),
283
- NUM2DBL(r_iv_get(c2, "@a")),
284
-
285
- NUM2DBL(r_iv_get(c3, "@r")),
286
- NUM2DBL(r_iv_get(c3, "@g")),
287
- NUM2DBL(r_iv_get(c3, "@b")),
288
- NUM2DBL(r_iv_get(c3, "@a")),
289
-
290
- NUM2DBL(r_iv_get(c4, "@r")),
291
- NUM2DBL(r_iv_get(c4, "@g")),
292
- NUM2DBL(r_iv_get(c4, "@b")),
293
- NUM2DBL(r_iv_get(c4, "@a"))
250
+ // `a` is the array representing the quad
251
+
252
+ R2D_DrawQuad(
253
+ NUM2DBL(r_ary_entry(a, 0)), // x1
254
+ NUM2DBL(r_ary_entry(a, 1)), // y1
255
+ NUM2DBL(r_ary_entry(a, 2)), // c1 red
256
+ NUM2DBL(r_ary_entry(a, 3)), // c1 green
257
+ NUM2DBL(r_ary_entry(a, 4)), // c1 blue
258
+ NUM2DBL(r_ary_entry(a, 5)), // c1 alpha
259
+
260
+ NUM2DBL(r_ary_entry(a, 6)), // x2
261
+ NUM2DBL(r_ary_entry(a, 7)), // y2
262
+ NUM2DBL(r_ary_entry(a, 8)), // c2 red
263
+ NUM2DBL(r_ary_entry(a, 9)), // c2 green
264
+ NUM2DBL(r_ary_entry(a, 10)), // c2 blue
265
+ NUM2DBL(r_ary_entry(a, 11)), // c2 alpha
266
+
267
+ NUM2DBL(r_ary_entry(a, 12)), // x3
268
+ NUM2DBL(r_ary_entry(a, 13)), // y3
269
+ NUM2DBL(r_ary_entry(a, 14)), // c3 red
270
+ NUM2DBL(r_ary_entry(a, 15)), // c3 green
271
+ NUM2DBL(r_ary_entry(a, 16)), // c3 blue
272
+ NUM2DBL(r_ary_entry(a, 17)), // c3 alpha
273
+
274
+ NUM2DBL(r_ary_entry(a, 18)), // x4
275
+ NUM2DBL(r_ary_entry(a, 19)), // y4
276
+ NUM2DBL(r_ary_entry(a, 20)), // c4 red
277
+ NUM2DBL(r_ary_entry(a, 21)), // c4 green
278
+ NUM2DBL(r_ary_entry(a, 22)), // c4 blue
279
+ NUM2DBL(r_ary_entry(a, 23)) // c4 alpha
294
280
  );
295
281
 
296
282
  return R_NIL;
@@ -298,24 +284,43 @@ static R_VAL ruby2d_line_ext_render(R_VAL self) {
298
284
 
299
285
 
300
286
  /*
301
- * Ruby2D::Circle#ext_render
287
+ * Ruby2D::Line#self.ext_draw
302
288
  */
303
289
  #if MRUBY
304
- static R_VAL ruby2d_circle_ext_render(mrb_state* mrb, R_VAL self) {
290
+ static R_VAL ruby2d_line_ext_draw(mrb_state* mrb, R_VAL self) {
291
+ mrb_value a;
292
+ mrb_get_args(mrb, "o", &a);
305
293
  #else
306
- static R_VAL ruby2d_circle_ext_render(R_VAL self) {
294
+ static R_VAL ruby2d_line_ext_draw(R_VAL self, R_VAL a) {
307
295
  #endif
308
- R_VAL c = r_iv_get(self, "@color");
309
-
310
- S2D_DrawCircle(
311
- NUM2DBL(r_iv_get(self, "@x")),
312
- NUM2DBL(r_iv_get(self, "@y")),
313
- NUM2DBL(r_iv_get(self, "@radius")),
314
- NUM2DBL(r_iv_get(self, "@sectors")),
315
- NUM2DBL(r_iv_get(c, "@r")),
316
- NUM2DBL(r_iv_get(c, "@g")),
317
- NUM2DBL(r_iv_get(c, "@b")),
318
- NUM2DBL(r_iv_get(c, "@a"))
296
+ // `a` is the array representing the line
297
+
298
+ R2D_DrawLine(
299
+ NUM2DBL(r_ary_entry(a, 0)), // x1
300
+ NUM2DBL(r_ary_entry(a, 1)), // y1
301
+ NUM2DBL(r_ary_entry(a, 2)), // x2
302
+ NUM2DBL(r_ary_entry(a, 3)), // y2
303
+ NUM2DBL(r_ary_entry(a, 4)), // width
304
+
305
+ NUM2DBL(r_ary_entry(a, 5)), // c1 red
306
+ NUM2DBL(r_ary_entry(a, 6)), // c1 green
307
+ NUM2DBL(r_ary_entry(a, 7)), // c1 blue
308
+ NUM2DBL(r_ary_entry(a, 8)), // c1 alpha
309
+
310
+ NUM2DBL(r_ary_entry(a, 9)), // c2 red
311
+ NUM2DBL(r_ary_entry(a, 10)), // c2 green
312
+ NUM2DBL(r_ary_entry(a, 11)), // c2 blue
313
+ NUM2DBL(r_ary_entry(a, 12)), // c2 alpha
314
+
315
+ NUM2DBL(r_ary_entry(a, 13)), // c3 red
316
+ NUM2DBL(r_ary_entry(a, 14)), // c3 green
317
+ NUM2DBL(r_ary_entry(a, 15)), // c3 blue
318
+ NUM2DBL(r_ary_entry(a, 16)), // c3 alpha
319
+
320
+ NUM2DBL(r_ary_entry(a, 17)), // c4 red
321
+ NUM2DBL(r_ary_entry(a, 18)), // c4 green
322
+ NUM2DBL(r_ary_entry(a, 19)), // c4 blue
323
+ NUM2DBL(r_ary_entry(a, 20)) // c4 alpha
319
324
  );
320
325
 
321
326
  return R_NIL;
@@ -323,295 +328,217 @@ static R_VAL ruby2d_circle_ext_render(R_VAL self) {
323
328
 
324
329
 
325
330
  /*
326
- * Ruby2D::Image#ext_init
327
- * Initialize image structure data
331
+ * Ruby2D::Circle#self.ext_draw
328
332
  */
329
333
  #if MRUBY
330
- static R_VAL ruby2d_image_ext_init(mrb_state* mrb, R_VAL self) {
331
- mrb_value path;
332
- mrb_get_args(mrb, "o", &path);
334
+ static R_VAL ruby2d_circle_ext_draw(mrb_state* mrb, R_VAL self) {
335
+ mrb_value a;
336
+ mrb_get_args(mrb, "o", &a);
333
337
  #else
334
- static R_VAL ruby2d_image_ext_init(R_VAL self, R_VAL path) {
338
+ static R_VAL ruby2d_circle_ext_draw(R_VAL self, R_VAL a) {
335
339
  #endif
336
- S2D_Image *img = S2D_CreateImage(RSTRING_PTR(path));
337
- if (!img) return R_FALSE;
338
-
339
- // Get width and height from Ruby class. If set, use it, else choose the
340
- // native dimensions of the image.
341
- R_VAL w = r_iv_get(self, "@width");
342
- R_VAL h = r_iv_get(self, "@height");
343
- r_iv_set(self, "@width" , r_test(w) ? w : INT2NUM(img->width));
344
- r_iv_set(self, "@height", r_test(h) ? h : INT2NUM(img->height));
345
- r_iv_set(self, "@data", r_data_wrap_struct(image, img));
340
+ // `a` is the array representing the circle
341
+
342
+ R2D_DrawCircle(
343
+ NUM2DBL(r_ary_entry(a, 0)), // x
344
+ NUM2DBL(r_ary_entry(a, 1)), // y
345
+ NUM2DBL(r_ary_entry(a, 2)), // radius
346
+ NUM2DBL(r_ary_entry(a, 3)), // sectors
347
+ NUM2DBL(r_ary_entry(a, 4)), // red
348
+ NUM2DBL(r_ary_entry(a, 5)), // green
349
+ NUM2DBL(r_ary_entry(a, 6)), // blue
350
+ NUM2DBL(r_ary_entry(a, 7)) // alpha
351
+ );
346
352
 
347
- return R_TRUE;
353
+ return R_NIL;
348
354
  }
349
355
 
350
356
 
351
357
  /*
352
- * Ruby2D::Image#ext_render
358
+ * Ruby2D::Image#ext_load_image
359
+ * Create an SDL surface from an image path, return the surface, width, and height
353
360
  */
354
- #if MRUBY
355
- static R_VAL ruby2d_image_ext_render(mrb_state* mrb, R_VAL self) {
356
- #else
357
- static R_VAL ruby2d_image_ext_render(R_VAL self) {
358
- #endif
359
- S2D_Image *img;
360
- r_data_get_struct(self, "@data", &image_data_type, S2D_Image, img);
361
-
362
- img->x = NUM2DBL(r_iv_get(self, "@x"));
363
- img->y = NUM2DBL(r_iv_get(self, "@y"));
361
+ static R_VAL ruby2d_image_ext_load_image(R_VAL self, R_VAL path) {
362
+ R2D_Init();
364
363
 
365
- R_VAL w = r_iv_get(self, "@width");
366
- R_VAL h = r_iv_get(self, "@height");
367
- if (r_test(w)) img->width = NUM2INT(w);
368
- if (r_test(h)) img->height = NUM2INT(h);
364
+ VALUE result = rb_ary_new2(3);
369
365
 
370
- S2D_RotateImage(img, NUM2DBL(r_iv_get(self, "@rotate")), S2D_CENTER);
366
+ SDL_Surface *surface = R2D_CreateImageSurface(RSTRING_PTR(path));
367
+ R2D_ImageConvertToRGB(surface);
371
368
 
372
- R_VAL c = r_iv_get(self, "@color");
373
- img->color.r = NUM2DBL(r_iv_get(c, "@r"));
374
- img->color.g = NUM2DBL(r_iv_get(c, "@g"));
375
- img->color.b = NUM2DBL(r_iv_get(c, "@b"));
376
- img->color.a = NUM2DBL(r_iv_get(c, "@a"));
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));
377
372
 
378
- S2D_DrawImage(img);
379
-
380
- return R_NIL;
373
+ return result;
381
374
  }
382
375
 
383
376
 
384
377
  /*
385
- * Free image structure attached to Ruby 2D `Image` class
378
+ * Ruby2D::Text#ext_load_text
386
379
  */
387
- #if MRUBY
388
- static void free_image(mrb_state *mrb, void *p_) {
389
- S2D_Image *img = (S2D_Image *)p_;
390
- #else
391
- static void free_image(S2D_Image *img) {
392
- #endif
393
- S2D_FreeImage(img);
394
- }
380
+ static R_VAL ruby2d_text_ext_load_text(R_VAL self, R_VAL font, R_VAL message) {
381
+ R2D_Init();
395
382
 
383
+ VALUE result = rb_ary_new2(3);
396
384
 
397
- /*
398
- * Ruby2D::Sprite#ext_init
399
- * Initialize sprite structure data
400
- */
401
- #if MRUBY
402
- static R_VAL ruby2d_sprite_ext_init(mrb_state* mrb, R_VAL self) {
403
- mrb_value path;
404
- mrb_get_args(mrb, "o", &path);
405
- #else
406
- static R_VAL ruby2d_sprite_ext_init(R_VAL self, R_VAL path) {
407
- #endif
408
- S2D_Sprite *spr = S2D_CreateSprite(RSTRING_PTR(path));
409
- if (!spr) return R_FALSE;
385
+ TTF_Font *ttf_font;
386
+ Data_Get_Struct(font, TTF_Font, ttf_font);
410
387
 
411
- r_iv_set(self, "@img_width" , INT2NUM(spr->width));
412
- r_iv_set(self, "@img_height", INT2NUM(spr->height));
413
- 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
+ }
414
392
 
415
- return R_TRUE;
416
- }
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));
417
396
 
397
+ return result;
398
+ }
418
399
 
419
400
  /*
420
- * Ruby2D::Sprite#ext_render
401
+ * Ruby2D::Texture#ext_create
421
402
  */
422
- #if MRUBY
423
- static R_VAL ruby2d_sprite_ext_render(mrb_state* mrb, R_VAL self) {
424
- #else
425
- static R_VAL ruby2d_sprite_ext_render(R_VAL self) {
426
- #endif
427
- r_funcall(self, "update", 0);
428
-
429
- S2D_Sprite *spr;
430
- r_data_get_struct(self, "@data", &sprite_data_type, S2D_Sprite, spr);
431
-
432
- spr->x = NUM2DBL(r_iv_get(self, "@flip_x"));
433
- spr->y = NUM2DBL(r_iv_get(self, "@flip_y"));
434
-
435
- R_VAL w = r_iv_get(self, "@flip_width");
436
- if (r_test(w)) spr->width = NUM2DBL(w);
437
-
438
- R_VAL h = r_iv_get(self, "@flip_height");
439
- if (r_test(h)) spr->height = NUM2DBL(h);
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
+ }
440
413
 
441
- S2D_RotateSprite(spr, NUM2DBL(r_iv_get(self, "@rotate")), S2D_CENTER);
414
+ R2D_GL_CreateTexture(&texture_id, format,
415
+ NUM2INT(width), NUM2INT(height),
416
+ surface->pixels, GL_NEAREST);
442
417
 
443
- R_VAL c = r_iv_get(self, "@color");
444
- spr->color.r = NUM2DBL(r_iv_get(c, "@r"));
445
- spr->color.g = NUM2DBL(r_iv_get(c, "@g"));
446
- spr->color.b = NUM2DBL(r_iv_get(c, "@b"));
447
- spr->color.a = NUM2DBL(r_iv_get(c, "@a"));
418
+ return INT2NUM(texture_id);
419
+ }
448
420
 
449
- S2D_ClipSprite(
450
- spr,
451
- NUM2INT(r_iv_get(self, "@clip_x")),
452
- NUM2INT(r_iv_get(self, "@clip_y")),
453
- NUM2INT(r_iv_get(self, "@clip_width")),
454
- NUM2INT(r_iv_get(self, "@clip_height"))
455
- );
421
+ /*
422
+ * Ruby2D::Texture#ext_delete
423
+ */
424
+ static R_VAL ruby2d_texture_ext_delete(R_VAL self, R_VAL rubyTexture_id) {
425
+ GLuint texture_id = NUM2INT(rubyTexture_id);
456
426
 
457
- S2D_DrawSprite(spr);
427
+ R2D_GL_FreeTexture(&texture_id);
458
428
 
459
429
  return R_NIL;
460
430
  }
461
431
 
462
432
 
463
433
  /*
464
- * Free sprite structure attached to Ruby 2D `Sprite` class
434
+ * Ruby2D::Sound#ext_init
435
+ * Initialize sound structure data
465
436
  */
466
437
  #if MRUBY
467
- static void free_sprite(mrb_state *mrb, void *p_) {
468
- S2D_Sprite *spr = (S2D_Sprite *)p_;
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);
469
441
  #else
470
- static void free_sprite(S2D_Sprite *spr) {
442
+ static R_VAL ruby2d_sound_ext_init(R_VAL self, R_VAL path) {
471
443
  #endif
472
- S2D_FreeSprite(spr);
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));
447
+ return R_TRUE;
473
448
  }
474
449
 
475
450
 
476
451
  /*
477
- * Ruby2D::Text#ext_init
478
- * Initialize text structure data
452
+ * Ruby2D::Sound#ext_play
479
453
  */
480
454
  #if MRUBY
481
- static R_VAL ruby2d_text_ext_init(mrb_state* mrb, R_VAL self) {
455
+ static R_VAL ruby2d_sound_ext_play(mrb_state* mrb, R_VAL self) {
482
456
  #else
483
- static R_VAL ruby2d_text_ext_init(R_VAL self) {
457
+ static R_VAL ruby2d_sound_ext_play(R_VAL self) {
484
458
  #endif
485
- // Trim the font file string to its actual length on MRuby
486
- #if MRUBY
487
- mrb_value s = r_iv_get(self, "@font");
488
- mrb_str_resize(mrb, s, RSTRING_LEN(s));
489
- #endif
490
-
491
- S2D_Text *txt = S2D_CreateText(
492
- RSTRING_PTR(r_iv_get(self, "@font")),
493
- RSTRING_PTR(r_iv_get(self, "@text")),
494
- NUM2DBL(r_iv_get(self, "@size"))
495
- );
496
- if (!txt) return R_FALSE;
497
-
498
- r_iv_set(self, "@width", INT2NUM(txt->width));
499
- r_iv_set(self, "@height", INT2NUM(txt->height));
500
- r_iv_set(self, "@data", r_data_wrap_struct(text, txt));
501
-
502
- return R_TRUE;
459
+ R2D_Sound *snd;
460
+ r_data_get_struct(self, "@data", &sound_data_type, R2D_Sound, snd);
461
+ R2D_PlaySound(snd);
462
+ return R_NIL;
503
463
  }
504
464
 
505
465
 
506
466
  /*
507
- * Ruby2D::Text#ext_set
467
+ * Ruby2D::Sound#ext_length
508
468
  */
509
- #if MRUBY
510
- static R_VAL ruby2d_text_ext_set(mrb_state* mrb, R_VAL self) {
511
- mrb_value text;
512
- mrb_get_args(mrb, "o", &text);
513
- #else
514
- static R_VAL ruby2d_text_ext_set(R_VAL self, R_VAL text) {
515
- #endif
516
- S2D_Text *txt;
517
- r_data_get_struct(self, "@data", &text_data_type, S2D_Text, txt);
518
-
519
- S2D_SetText(txt, RSTRING_PTR(text));
520
-
521
- r_iv_set(self, "@width", INT2NUM(txt->width));
522
- r_iv_set(self, "@height", INT2NUM(txt->height));
523
-
524
- 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));
525
473
  }
526
474
 
527
475
 
528
476
  /*
529
- * Ruby2D::Text#ext_render
477
+ * Free sound structure attached to Ruby 2D `Sound` class
530
478
  */
531
479
  #if MRUBY
532
- static R_VAL ruby2d_text_ext_render(mrb_state* mrb, R_VAL self) {
480
+ static void free_sound(mrb_state *mrb, void *p_) {
481
+ R2D_Sound *snd = (R2D_Sound *)p_;
533
482
  #else
534
- static R_VAL ruby2d_text_ext_render(R_VAL self) {
483
+ static void free_sound(R2D_Sound *snd) {
535
484
  #endif
536
- S2D_Text *txt;
537
- r_data_get_struct(self, "@data", &text_data_type, S2D_Text, txt);
538
-
539
- txt->x = NUM2DBL(r_iv_get(self, "@x"));
540
- txt->y = NUM2DBL(r_iv_get(self, "@y"));
541
-
542
- S2D_RotateText(txt, NUM2DBL(r_iv_get(self, "@rotate")), S2D_CENTER);
543
-
544
- R_VAL c = r_iv_get(self, "@color");
545
- txt->color.r = NUM2DBL(r_iv_get(c, "@r"));
546
- txt->color.g = NUM2DBL(r_iv_get(c, "@g"));
547
- txt->color.b = NUM2DBL(r_iv_get(c, "@b"));
548
- txt->color.a = NUM2DBL(r_iv_get(c, "@a"));
549
-
550
- S2D_DrawText(txt);
551
-
552
- return R_NIL;
485
+ R2D_FreeSound(snd);
553
486
  }
554
487
 
555
-
556
488
  /*
557
- * Free text structure attached to Ruby 2D `Text` class
489
+ * Ruby2D::Sound#ext_get_volume
558
490
  */
559
491
  #if MRUBY
560
- static void free_text(mrb_state *mrb, void *p_) {
561
- S2D_Text *txt = (S2D_Text *)p_;
492
+ static R_VAL ruby2d_sound_ext_get_volume(mrb_state* mrb, R_VAL self) {
562
493
  #else
563
- static void free_text(S2D_Text *txt) {
494
+ static R_VAL ruby2d_sound_ext_get_volume(R_VAL self) {
564
495
  #endif
565
- S2D_FreeText(txt);
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)));
566
499
  }
567
500
 
568
-
569
501
  /*
570
- * Ruby2D::Sound#ext_init
571
- * Initialize sound structure data
502
+ * Ruby2D::Music#ext_set_volume
572
503
  */
573
504
  #if MRUBY
574
- static R_VAL ruby2d_sound_ext_init(mrb_state* mrb, R_VAL self) {
575
- mrb_value path;
576
- mrb_get_args(mrb, "o", &path);
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);
577
508
  #else
578
- static R_VAL ruby2d_sound_ext_init(R_VAL self, R_VAL path) {
509
+ static R_VAL ruby2d_sound_ext_set_volume(R_VAL self, R_VAL volume) {
579
510
  #endif
580
- S2D_Sound *snd = S2D_CreateSound(RSTRING_PTR(path));
581
- if (!snd) return R_FALSE;
582
- r_iv_set(self, "@data", r_data_wrap_struct(sound, snd));
583
- return R_TRUE;
511
+ R2D_Sound *snd;
512
+ r_data_get_struct(self, "@data", &sound_data_type, R2D_Sound, snd);
513
+ Mix_VolumeChunk(snd->data, (NUM2INT(volume) / 100.0) * MIX_MAX_VOLUME);
514
+ return R_NIL;
584
515
  }
585
516
 
586
-
587
517
  /*
588
- * Ruby2D::Sound#ext_play
518
+ * Ruby2D::Sound#ext_get_mix_volume
589
519
  */
590
520
  #if MRUBY
591
- static R_VAL ruby2d_sound_ext_play(mrb_state* mrb, R_VAL self) {
521
+ static R_VAL ruby2d_sound_ext_get_mix_volume(mrb_state* mrb, R_VAL self) {
592
522
  #else
593
- static R_VAL ruby2d_sound_ext_play(R_VAL self) {
523
+ static R_VAL ruby2d_sound_ext_get_mix_volume(R_VAL self) {
594
524
  #endif
595
- S2D_Sound *snd;
596
- r_data_get_struct(self, "@data", &sound_data_type, S2D_Sound, snd);
597
- S2D_PlaySound(snd);
598
- return R_NIL;
525
+ return INT2NUM(ceil(Mix_Volume(-1, -1) * (100.0 / MIX_MAX_VOLUME)));
599
526
  }
600
527
 
601
-
602
528
  /*
603
- * Free sound structure attached to Ruby 2D `Sound` class
529
+ * Ruby2D::Music#ext_set_mix_volume
604
530
  */
605
531
  #if MRUBY
606
- static void free_sound(mrb_state *mrb, void *p_) {
607
- S2D_Sound *snd = (S2D_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);
608
535
  #else
609
- static void free_sound(S2D_Sound *snd) {
536
+ static R_VAL ruby2d_sound_ext_set_mix_volume(R_VAL self, R_VAL volume) {
610
537
  #endif
611
- S2D_FreeSound(snd);
538
+ Mix_Volume(-1, (NUM2INT(volume) / 100.0) * MIX_MAX_VOLUME);
539
+ return R_NIL;
612
540
  }
613
541
 
614
-
615
542
  /*
616
543
  * Ruby2D::Music#ext_init
617
544
  * Initialize music structure data
@@ -623,7 +550,7 @@ static R_VAL ruby2d_music_ext_init(mrb_state* mrb, R_VAL self) {
623
550
  #else
624
551
  static R_VAL ruby2d_music_ext_init(R_VAL self, R_VAL path) {
625
552
  #endif
626
- S2D_Music *mus = S2D_CreateMusic(RSTRING_PTR(path));
553
+ R2D_Music *mus = R2D_CreateMusic(RSTRING_PTR(path));
627
554
  if (!mus) return R_FALSE;
628
555
  r_iv_set(self, "@data", r_data_wrap_struct(music, mus));
629
556
  return R_TRUE;
@@ -638,9 +565,9 @@ static R_VAL ruby2d_music_ext_play(mrb_state* mrb, R_VAL self) {
638
565
  #else
639
566
  static R_VAL ruby2d_music_ext_play(R_VAL self) {
640
567
  #endif
641
- S2D_Music *mus;
642
- r_data_get_struct(self, "@data", &music_data_type, S2D_Music, mus);
643
- S2D_PlayMusic(mus, r_test(r_iv_get(self, "@loop")));
568
+ R2D_Music *mus;
569
+ r_data_get_struct(self, "@data", &music_data_type, R2D_Music, mus);
570
+ R2D_PlayMusic(mus, r_test(r_iv_get(self, "@loop")));
644
571
  return R_NIL;
645
572
  }
646
573
 
@@ -653,7 +580,7 @@ static R_VAL ruby2d_music_ext_pause(mrb_state* mrb, R_VAL self) {
653
580
  #else
654
581
  static R_VAL ruby2d_music_ext_pause(R_VAL self) {
655
582
  #endif
656
- S2D_PauseMusic();
583
+ R2D_PauseMusic();
657
584
  return R_NIL;
658
585
  }
659
586
 
@@ -666,7 +593,7 @@ static R_VAL ruby2d_music_ext_resume(mrb_state* mrb, R_VAL self) {
666
593
  #else
667
594
  static R_VAL ruby2d_music_ext_resume(R_VAL self) {
668
595
  #endif
669
- S2D_ResumeMusic();
596
+ R2D_ResumeMusic();
670
597
  return R_NIL;
671
598
  }
672
599
 
@@ -679,7 +606,7 @@ static R_VAL ruby2d_music_ext_stop(mrb_state* mrb, R_VAL self) {
679
606
  #else
680
607
  static R_VAL ruby2d_music_ext_stop(R_VAL self) {
681
608
  #endif
682
- S2D_StopMusic();
609
+ R2D_StopMusic();
683
610
  return R_NIL;
684
611
  }
685
612
 
@@ -692,7 +619,7 @@ static R_VAL ruby2d_music_ext_get_volume(mrb_state* mrb, R_VAL self) {
692
619
  #else
693
620
  static R_VAL ruby2d_music_ext_get_volume(R_VAL self) {
694
621
  #endif
695
- return INT2NUM(S2D_GetMusicVolume());
622
+ return INT2NUM(R2D_GetMusicVolume());
696
623
  }
697
624
 
698
625
 
@@ -706,7 +633,7 @@ static R_VAL ruby2d_music_ext_set_volume(mrb_state* mrb, R_VAL self) {
706
633
  #else
707
634
  static R_VAL ruby2d_music_ext_set_volume(R_VAL self, R_VAL volume) {
708
635
  #endif
709
- S2D_SetMusicVolume(NUM2INT(volume));
636
+ R2D_SetMusicVolume(NUM2INT(volume));
710
637
  return R_NIL;
711
638
  }
712
639
 
@@ -721,39 +648,95 @@ static R_VAL ruby2d_music_ext_fadeout(mrb_state* mrb, R_VAL self) {
721
648
  #else
722
649
  static R_VAL ruby2d_music_ext_fadeout(R_VAL self, R_VAL ms) {
723
650
  #endif
724
- S2D_FadeOutMusic(NUM2INT(ms));
651
+ R2D_FadeOutMusic(NUM2INT(ms));
652
+ return R_NIL;
653
+ }
654
+
655
+
656
+ /*
657
+ * Ruby2D::Music#ext_length
658
+ */
659
+ static R_VAL ruby2d_music_ext_length(R_VAL self) {
660
+ R2D_Music *ms;
661
+ r_data_get_struct(self, "@data", &music_data_type, R2D_Music, ms);
662
+ return INT2NUM(R2D_GetMusicLength(ms));
663
+ }
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
+
725
694
  return R_NIL;
726
695
  }
727
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
+
728
711
 
729
712
  /*
730
713
  * Free music structure attached to Ruby 2D `Music` class
731
714
  */
732
715
  #if MRUBY
733
716
  static void free_music(mrb_state *mrb, void *p_) {
734
- S2D_Music *mus = (S2D_Music *)p_;
717
+ R2D_Music *mus = (R2D_Music *)p_;
735
718
  #else
736
- static void free_music(S2D_Music *mus) {
719
+ static void free_music(R2D_Music *mus) {
737
720
  #endif
738
- S2D_FreeMusic(mus);
721
+ R2D_FreeMusic(mus);
739
722
  }
740
723
 
741
724
 
742
725
  /*
743
- * Simple 2D `on_key` input callback function
726
+ * Ruby 2D native `on_key` input callback function
744
727
  */
745
- static void on_key(S2D_Event e) {
728
+ static void on_key(R2D_Event e) {
746
729
 
747
730
  R_VAL type;
748
731
 
749
732
  switch (e.type) {
750
- case S2D_KEY_DOWN:
733
+ case R2D_KEY_DOWN:
751
734
  type = r_char_to_sym("down");
752
735
  break;
753
- case S2D_KEY_HELD:
736
+ case R2D_KEY_HELD:
754
737
  type = r_char_to_sym("held");
755
738
  break;
756
- case S2D_KEY_UP:
739
+ case R2D_KEY_UP:
757
740
  type = r_char_to_sym("up");
758
741
  break;
759
742
  }
@@ -763,48 +746,48 @@ static void on_key(S2D_Event e) {
763
746
 
764
747
 
765
748
  /*
766
- * Simple 2D `on_mouse` input callback function
749
+ * Ruby 2D native `on_mouse` input callback function
767
750
  */
768
- void on_mouse(S2D_Event e) {
751
+ void on_mouse(R2D_Event e) {
769
752
 
770
753
  R_VAL type = R_NIL; R_VAL button = R_NIL; R_VAL direction = R_NIL;
771
754
 
772
755
  switch (e.type) {
773
- case S2D_MOUSE_DOWN:
756
+ case R2D_MOUSE_DOWN:
774
757
  // type, button, x, y
775
758
  type = r_char_to_sym("down");
776
759
  break;
777
- case S2D_MOUSE_UP:
760
+ case R2D_MOUSE_UP:
778
761
  // type, button, x, y
779
762
  type = r_char_to_sym("up");
780
763
  break;
781
- case S2D_MOUSE_SCROLL:
764
+ case R2D_MOUSE_SCROLL:
782
765
  // type, direction, delta_x, delta_y
783
766
  type = r_char_to_sym("scroll");
784
- direction = e.direction == S2D_MOUSE_SCROLL_NORMAL ?
767
+ direction = e.direction == R2D_MOUSE_SCROLL_NORMAL ?
785
768
  r_char_to_sym("normal") : r_char_to_sym("inverted");
786
769
  break;
787
- case S2D_MOUSE_MOVE:
770
+ case R2D_MOUSE_MOVE:
788
771
  // type, x, y, delta_x, delta_y
789
772
  type = r_char_to_sym("move");
790
773
  break;
791
774
  }
792
775
 
793
- if (e.type == S2D_MOUSE_DOWN || e.type == S2D_MOUSE_UP) {
776
+ if (e.type == R2D_MOUSE_DOWN || e.type == R2D_MOUSE_UP) {
794
777
  switch (e.button) {
795
- case S2D_MOUSE_LEFT:
778
+ case R2D_MOUSE_LEFT:
796
779
  button = r_char_to_sym("left");
797
780
  break;
798
- case S2D_MOUSE_MIDDLE:
781
+ case R2D_MOUSE_MIDDLE:
799
782
  button = r_char_to_sym("middle");
800
783
  break;
801
- case S2D_MOUSE_RIGHT:
784
+ case R2D_MOUSE_RIGHT:
802
785
  button = r_char_to_sym("right");
803
786
  break;
804
- case S2D_MOUSE_X1:
787
+ case R2D_MOUSE_X1:
805
788
  button = r_char_to_sym("x1");
806
789
  break;
807
- case S2D_MOUSE_X2:
790
+ case R2D_MOUSE_X2:
808
791
  button = r_char_to_sym("x2");
809
792
  break;
810
793
  }
@@ -818,88 +801,88 @@ void on_mouse(S2D_Event e) {
818
801
 
819
802
 
820
803
  /*
821
- * Simple 2D `on_controller` input callback function
804
+ * Ruby 2D native `on_controller` input callback function
822
805
  */
823
- static void on_controller(S2D_Event e) {
806
+ static void on_controller(R2D_Event e) {
824
807
 
825
808
  R_VAL type = R_NIL; R_VAL axis = R_NIL; R_VAL button = R_NIL;
826
809
 
827
810
  switch (e.type) {
828
- case S2D_AXIS:
811
+ case R2D_AXIS:
829
812
  type = r_char_to_sym("axis");
830
813
  switch (e.axis) {
831
- case S2D_AXIS_LEFTX:
814
+ case R2D_AXIS_LEFTX:
832
815
  axis = r_char_to_sym("left_x");
833
816
  break;
834
- case S2D_AXIS_LEFTY:
817
+ case R2D_AXIS_LEFTY:
835
818
  axis = r_char_to_sym("left_y");
836
819
  break;
837
- case S2D_AXIS_RIGHTX:
820
+ case R2D_AXIS_RIGHTX:
838
821
  axis = r_char_to_sym("right_x");
839
822
  break;
840
- case S2D_AXIS_RIGHTY:
823
+ case R2D_AXIS_RIGHTY:
841
824
  axis = r_char_to_sym("right_y");
842
825
  break;
843
- case S2D_AXIS_TRIGGERLEFT:
826
+ case R2D_AXIS_TRIGGERLEFT:
844
827
  axis = r_char_to_sym("trigger_left");
845
828
  break;
846
- case S2D_AXIS_TRIGGERRIGHT:
829
+ case R2D_AXIS_TRIGGERRIGHT:
847
830
  axis = r_char_to_sym("trigger_right");
848
831
  break;
849
- case S2D_AXIS_INVALID:
832
+ case R2D_AXIS_INVALID:
850
833
  axis = r_char_to_sym("invalid");
851
834
  break;
852
835
  }
853
836
  break;
854
- case S2D_BUTTON_DOWN: case S2D_BUTTON_UP:
855
- type = e.type == S2D_BUTTON_DOWN ? r_char_to_sym("button_down") : r_char_to_sym("button_up");
837
+ case R2D_BUTTON_DOWN: case R2D_BUTTON_UP:
838
+ type = e.type == R2D_BUTTON_DOWN ? r_char_to_sym("button_down") : r_char_to_sym("button_up");
856
839
  switch (e.button) {
857
- case S2D_BUTTON_A:
840
+ case R2D_BUTTON_A:
858
841
  button = r_char_to_sym("a");
859
842
  break;
860
- case S2D_BUTTON_B:
843
+ case R2D_BUTTON_B:
861
844
  button = r_char_to_sym("b");
862
845
  break;
863
- case S2D_BUTTON_X:
846
+ case R2D_BUTTON_X:
864
847
  button = r_char_to_sym("x");
865
848
  break;
866
- case S2D_BUTTON_Y:
849
+ case R2D_BUTTON_Y:
867
850
  button = r_char_to_sym("y");
868
851
  break;
869
- case S2D_BUTTON_BACK:
852
+ case R2D_BUTTON_BACK:
870
853
  button = r_char_to_sym("back");
871
854
  break;
872
- case S2D_BUTTON_GUIDE:
855
+ case R2D_BUTTON_GUIDE:
873
856
  button = r_char_to_sym("guide");
874
857
  break;
875
- case S2D_BUTTON_START:
858
+ case R2D_BUTTON_START:
876
859
  button = r_char_to_sym("start");
877
860
  break;
878
- case S2D_BUTTON_LEFTSTICK:
861
+ case R2D_BUTTON_LEFTSTICK:
879
862
  button = r_char_to_sym("left_stick");
880
863
  break;
881
- case S2D_BUTTON_RIGHTSTICK:
864
+ case R2D_BUTTON_RIGHTSTICK:
882
865
  button = r_char_to_sym("right_stick");
883
866
  break;
884
- case S2D_BUTTON_LEFTSHOULDER:
867
+ case R2D_BUTTON_LEFTSHOULDER:
885
868
  button = r_char_to_sym("left_shoulder");
886
869
  break;
887
- case S2D_BUTTON_RIGHTSHOULDER:
870
+ case R2D_BUTTON_RIGHTSHOULDER:
888
871
  button = r_char_to_sym("right_shoulder");
889
872
  break;
890
- case S2D_BUTTON_DPAD_UP:
873
+ case R2D_BUTTON_DPAD_UP:
891
874
  button = r_char_to_sym("up");
892
875
  break;
893
- case S2D_BUTTON_DPAD_DOWN:
876
+ case R2D_BUTTON_DPAD_DOWN:
894
877
  button = r_char_to_sym("down");
895
878
  break;
896
- case S2D_BUTTON_DPAD_LEFT:
879
+ case R2D_BUTTON_DPAD_LEFT:
897
880
  button = r_char_to_sym("left");
898
881
  break;
899
- case S2D_BUTTON_DPAD_RIGHT:
882
+ case R2D_BUTTON_DPAD_RIGHT:
900
883
  button = r_char_to_sym("right");
901
884
  break;
902
- case S2D_BUTTON_INVALID:
885
+ case R2D_BUTTON_INVALID:
903
886
  button = r_char_to_sym("invalid");
904
887
  break;
905
888
  }
@@ -914,7 +897,7 @@ static void on_controller(S2D_Event e) {
914
897
 
915
898
 
916
899
  /*
917
- * Simple 2D `update` callback function
900
+ * Ruby 2D native `update` callback function
918
901
  */
919
902
  static void update() {
920
903
 
@@ -934,7 +917,7 @@ static void update() {
934
917
 
935
918
 
936
919
  /*
937
- * Simple 2D `render` callback function
920
+ * Ruby 2D native `render` callback function
938
921
  */
939
922
  static void render() {
940
923
 
@@ -952,8 +935,11 @@ static void render() {
952
935
  // Switch on each object type
953
936
  for (int i = 0; i < num_objects; ++i) {
954
937
  R_VAL el = r_ary_entry(objects, i);
955
- r_funcall(el, "ext_render", 0);
938
+ r_funcall(el, "render", 0); // call the object's `render` function
956
939
  }
940
+
941
+ // Call render proc, `window.render`
942
+ r_funcall(ruby2d_window, "render_callback", 0);
957
943
  }
958
944
 
959
945
 
@@ -967,8 +953,8 @@ static R_VAL ruby2d_ext_diagnostics(mrb_state* mrb, R_VAL self) {
967
953
  #else
968
954
  static R_VAL ruby2d_ext_diagnostics(R_VAL self, R_VAL enable) {
969
955
  #endif
970
- // Set Simple 2D diagnostics
971
- S2D_Diagnostics(r_test(enable));
956
+ // Set Ruby 2D native diagnostics
957
+ R2D_Diagnostics(r_test(enable));
972
958
  return R_TRUE;
973
959
  }
974
960
 
@@ -982,7 +968,7 @@ static R_VAL ruby2d_window_ext_get_display_dimensions(mrb_state* mrb, R_VAL self
982
968
  static R_VAL ruby2d_window_ext_get_display_dimensions(R_VAL self) {
983
969
  #endif
984
970
  int w; int h;
985
- S2D_GetDisplayDimensions(&w, &h);
971
+ R2D_GetDisplayDimensions(&w, &h);
986
972
  r_iv_set(self, "@display_width" , INT2NUM(w));
987
973
  r_iv_set(self, "@display_height", INT2NUM(h));
988
974
  return R_NIL;
@@ -999,8 +985,8 @@ static R_VAL ruby2d_window_ext_add_controller_mappings(mrb_state* mrb, R_VAL sel
999
985
  #else
1000
986
  static R_VAL ruby2d_window_ext_add_controller_mappings(R_VAL self, R_VAL path) {
1001
987
  #endif
1002
- S2D_Log(S2D_INFO, "Adding controller mappings from `%s`", RSTRING_PTR(path));
1003
- S2D_AddControllerMappingsFromFile(RSTRING_PTR(path));
988
+ R2D_Log(R2D_INFO, "Adding controller mappings from `%s`", RSTRING_PTR(path));
989
+ R2D_AddControllerMappingsFromFile(RSTRING_PTR(path));
1004
990
  return R_NIL;
1005
991
  }
1006
992
 
@@ -1032,16 +1018,16 @@ static R_VAL ruby2d_window_ext_show(R_VAL self) {
1032
1018
  // Get window flags
1033
1019
  int flags = 0;
1034
1020
  if (r_test(r_iv_get(self, "@resizable"))) {
1035
- flags = flags | S2D_RESIZABLE;
1021
+ flags = flags | R2D_RESIZABLE;
1036
1022
  }
1037
1023
  if (r_test(r_iv_get(self, "@borderless"))) {
1038
- flags = flags | S2D_BORDERLESS;
1024
+ flags = flags | R2D_BORDERLESS;
1039
1025
  }
1040
1026
  if (r_test(r_iv_get(self, "@fullscreen"))) {
1041
- flags = flags | S2D_FULLSCREEN;
1027
+ flags = flags | R2D_FULLSCREEN;
1042
1028
  }
1043
1029
  if (r_test(r_iv_get(self, "@highdpi"))) {
1044
- flags = flags | S2D_HIGHDPI;
1030
+ flags = flags | R2D_HIGHDPI;
1045
1031
  }
1046
1032
 
1047
1033
  // Check viewport size and set
@@ -1054,7 +1040,7 @@ static R_VAL ruby2d_window_ext_show(R_VAL self) {
1054
1040
 
1055
1041
  // Create and show window
1056
1042
 
1057
- window = S2D_CreateWindow(
1043
+ window = R2D_CreateWindow(
1058
1044
  title, width, height, update, render, flags
1059
1045
  );
1060
1046
 
@@ -1066,7 +1052,7 @@ static R_VAL ruby2d_window_ext_show(R_VAL self) {
1066
1052
  window->on_mouse = on_mouse;
1067
1053
  window->on_controller = on_controller;
1068
1054
 
1069
- S2D_Show(window);
1055
+ R2D_Show(window);
1070
1056
 
1071
1057
  atexit(free_window);
1072
1058
  return R_NIL;
@@ -1084,7 +1070,7 @@ static R_VAL ruby2d_ext_screenshot(mrb_state* mrb, R_VAL self) {
1084
1070
  static R_VAL ruby2d_ext_screenshot(R_VAL self, R_VAL path) {
1085
1071
  #endif
1086
1072
  if (window) {
1087
- S2D_Screenshot(window, RSTRING_PTR(path));
1073
+ R2D_Screenshot(window, RSTRING_PTR(path));
1088
1074
  return path;
1089
1075
  } else {
1090
1076
  return R_FALSE;
@@ -1096,7 +1082,7 @@ static R_VAL ruby2d_ext_screenshot(R_VAL self, R_VAL path) {
1096
1082
  * Ruby2D::Window#ext_close
1097
1083
  */
1098
1084
  static R_VAL ruby2d_window_ext_close() {
1099
- S2D_Close(window);
1085
+ R2D_Close(window);
1100
1086
  return R_NIL;
1101
1087
  }
1102
1088
 
@@ -1126,59 +1112,47 @@ void Init_ruby2d() {
1126
1112
  // Ruby2D#self.ext_base_path
1127
1113
  r_define_class_method(ruby2d_module, "ext_base_path", ruby2d_ext_base_path, r_args_none);
1128
1114
 
1115
+ // Ruby2D::Pixel
1116
+ R_CLASS ruby2d_pixel_class = r_define_class(ruby2d_module, "Pixel");
1117
+
1118
+ // Ruby2D::Pixel#self.ext_draw
1119
+ r_define_class_method(ruby2d_pixel_class, "ext_draw", ruby2d_pixel_ext_draw, r_args_req(1));
1120
+
1129
1121
  // Ruby2D::Triangle
1130
1122
  R_CLASS ruby2d_triangle_class = r_define_class(ruby2d_module, "Triangle");
1131
1123
 
1132
- // Ruby2D::Triangle#ext_render
1133
- r_define_method(ruby2d_triangle_class, "ext_render", ruby2d_triangle_ext_render, r_args_none);
1124
+ // Ruby2D::Triangle#self.ext_draw
1125
+ r_define_class_method(ruby2d_triangle_class, "ext_draw", ruby2d_triangle_ext_draw, r_args_req(1));
1134
1126
 
1135
1127
  // Ruby2D::Quad
1136
1128
  R_CLASS ruby2d_quad_class = r_define_class(ruby2d_module, "Quad");
1137
1129
 
1138
- // Ruby2D::Quad#ext_render
1139
- r_define_method(ruby2d_quad_class, "ext_render", ruby2d_quad_ext_render, r_args_none);
1130
+ // Ruby2D::Quad#self.ext_draw
1131
+ r_define_class_method(ruby2d_quad_class, "ext_draw", ruby2d_quad_ext_draw, r_args_req(1));
1140
1132
 
1141
1133
  // Ruby2D::Line
1142
1134
  R_CLASS ruby2d_line_class = r_define_class(ruby2d_module, "Line");
1143
1135
 
1144
- // Ruby2D::Line#ext_render
1145
- r_define_method(ruby2d_line_class, "ext_render", ruby2d_line_ext_render, r_args_none);
1136
+ // Ruby2D::Line#self.ext_draw
1137
+ r_define_class_method(ruby2d_line_class, "ext_draw", ruby2d_line_ext_draw, r_args_req(1));
1146
1138
 
1147
1139
  // Ruby2D::Circle
1148
1140
  R_CLASS ruby2d_circle_class = r_define_class(ruby2d_module, "Circle");
1149
1141
 
1150
- // Ruby2D::Circle#ext_render
1151
- r_define_method(ruby2d_circle_class, "ext_render", ruby2d_circle_ext_render, r_args_none);
1142
+ // Ruby2D::Circle#self.ext_draw
1143
+ r_define_class_method(ruby2d_circle_class, "ext_draw", ruby2d_circle_ext_draw, r_args_req(1));
1152
1144
 
1153
1145
  // Ruby2D::Image
1154
1146
  R_CLASS ruby2d_image_class = r_define_class(ruby2d_module, "Image");
1155
1147
 
1156
- // Ruby2D::Image#ext_init
1157
- r_define_method(ruby2d_image_class, "ext_init", ruby2d_image_ext_init, r_args_req(1));
1158
-
1159
- // Ruby2D::Image#ext_render
1160
- r_define_method(ruby2d_image_class, "ext_render", ruby2d_image_ext_render, r_args_none);
1161
-
1162
- // Ruby2D::Sprite
1163
- R_CLASS ruby2d_sprite_class = r_define_class(ruby2d_module, "Sprite");
1164
-
1165
- // Ruby2D::Sprite#ext_init
1166
- r_define_method(ruby2d_sprite_class, "ext_init", ruby2d_sprite_ext_init, r_args_req(1));
1167
-
1168
- // Ruby2D::Sprite#ext_render
1169
- r_define_method(ruby2d_sprite_class, "ext_render", ruby2d_sprite_ext_render, r_args_none);
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));
1170
1150
 
1171
1151
  // Ruby2D::Text
1172
1152
  R_CLASS ruby2d_text_class = r_define_class(ruby2d_module, "Text");
1173
1153
 
1174
- // Ruby2D::Text#ext_init
1175
- r_define_method(ruby2d_text_class, "ext_init", ruby2d_text_ext_init, r_args_none);
1176
-
1177
- // Ruby2D::Text#ext_set
1178
- r_define_method(ruby2d_text_class, "ext_set", ruby2d_text_ext_set, r_args_req(1));
1179
-
1180
- // Ruby2D::Text#ext_render
1181
- r_define_method(ruby2d_text_class, "ext_render", ruby2d_text_ext_render, r_args_none);
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));
1182
1156
 
1183
1157
  // Ruby2D::Sound
1184
1158
  R_CLASS ruby2d_sound_class = r_define_class(ruby2d_module, "Sound");
@@ -1188,6 +1162,21 @@ void Init_ruby2d() {
1188
1162
 
1189
1163
  // Ruby2D::Sound#ext_play
1190
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));
1177
+
1178
+ // Ruby2D::Sound#ext_length
1179
+ r_define_method(ruby2d_sound_class, "ext_length", ruby2d_sound_ext_length, r_args_none);
1191
1180
 
1192
1181
  // Ruby2D::Music
1193
1182
  R_CLASS ruby2d_music_class = r_define_class(ruby2d_module, "Music");
@@ -1216,6 +1205,27 @@ void Init_ruby2d() {
1216
1205
  // Ruby2D::Music#ext_fadeout
1217
1206
  r_define_method(ruby2d_music_class, "ext_fadeout", ruby2d_music_ext_fadeout, r_args_req(1));
1218
1207
 
1208
+ // Ruby2D::Music#ext_length
1209
+ r_define_method(ruby2d_music_class, "ext_length", ruby2d_music_ext_length, r_args_none);
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
+
1219
1229
  // Ruby2D::Window
1220
1230
  R_CLASS ruby2d_window_class = r_define_class(ruby2d_module, "Window");
1221
1231