ruby2d 0.9.0 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. checksums.yaml +4 -4
  2. data/assets/README.md +8 -8
  3. data/assets/Rakefile +85 -0
  4. data/assets/include/SDL2/SDL.h +1 -1
  5. data/assets/include/SDL2/SDL_assert.h +1 -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 +7 -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 +178 -0
  13. data/assets/include/SDL2/SDL_config_iphoneos.h +201 -0
  14. data/assets/include/SDL2/SDL_config_macosx.h +240 -0
  15. data/assets/include/SDL2/SDL_config_minimal.h +85 -0
  16. data/assets/include/SDL2/SDL_config_os2.h +170 -0
  17. data/assets/include/SDL2/SDL_config_pandora.h +133 -0
  18. data/assets/include/SDL2/SDL_config_psp.h +164 -0
  19. data/assets/include/SDL2/SDL_config_windows.h +257 -0
  20. data/assets/include/SDL2/SDL_config_winrt.h +240 -0
  21. data/assets/include/SDL2/SDL_config_wiz.h +146 -0
  22. data/assets/include/SDL2/SDL_copying.h +20 -0
  23. data/assets/include/SDL2/SDL_cpuinfo.h +90 -8
  24. data/assets/include/SDL2/SDL_egl.h +1 -1
  25. data/assets/include/SDL2/SDL_endian.h +1 -1
  26. data/assets/include/SDL2/SDL_error.h +1 -1
  27. data/assets/include/SDL2/SDL_events.h +4 -1
  28. data/assets/include/SDL2/SDL_filesystem.h +1 -1
  29. data/assets/include/SDL2/SDL_gamecontroller.h +1 -1
  30. data/assets/include/SDL2/SDL_gesture.h +1 -1
  31. data/assets/include/SDL2/SDL_haptic.h +1 -1
  32. data/assets/include/SDL2/SDL_hints.h +145 -14
  33. data/assets/include/SDL2/SDL_image.h +2 -2
  34. data/assets/include/SDL2/SDL_joystick.h +1 -1
  35. data/assets/include/SDL2/SDL_keyboard.h +1 -1
  36. data/assets/include/SDL2/SDL_keycode.h +1 -1
  37. data/assets/include/SDL2/SDL_loadso.h +1 -1
  38. data/assets/include/SDL2/SDL_log.h +1 -1
  39. data/assets/include/SDL2/SDL_main.h +28 -16
  40. data/assets/include/SDL2/SDL_messagebox.h +1 -1
  41. data/assets/include/SDL2/SDL_mouse.h +1 -1
  42. data/assets/include/SDL2/SDL_mutex.h +1 -1
  43. data/assets/include/SDL2/SDL_name.h +1 -1
  44. data/assets/include/SDL2/SDL_opengl.h +1 -1
  45. data/assets/include/SDL2/SDL_opengles.h +1 -1
  46. data/assets/include/SDL2/SDL_opengles2.h +1 -1
  47. data/assets/include/SDL2/SDL_pixels.h +3 -3
  48. data/assets/include/SDL2/SDL_platform.h +1 -1
  49. data/assets/include/SDL2/SDL_power.h +1 -1
  50. data/assets/include/SDL2/SDL_quit.h +1 -1
  51. data/assets/include/SDL2/SDL_rect.h +29 -3
  52. data/assets/include/SDL2/SDL_render.h +168 -1
  53. data/assets/include/SDL2/SDL_revision.h +2 -2
  54. data/assets/include/SDL2/SDL_rwops.h +50 -13
  55. data/assets/include/SDL2/SDL_scancode.h +2 -2
  56. data/assets/include/SDL2/SDL_sensor.h +4 -4
  57. data/assets/include/SDL2/SDL_shape.h +1 -1
  58. data/assets/include/SDL2/SDL_stdinc.h +1 -1
  59. data/assets/include/SDL2/SDL_surface.h +2 -1
  60. data/assets/include/SDL2/SDL_system.h +1 -1
  61. data/assets/include/SDL2/SDL_syswm.h +11 -8
  62. data/assets/include/SDL2/SDL_test.h +1 -1
  63. data/assets/include/SDL2/SDL_test_assert.h +1 -1
  64. data/assets/include/SDL2/SDL_test_common.h +22 -5
  65. data/assets/include/SDL2/SDL_test_compare.h +1 -1
  66. data/assets/include/SDL2/SDL_test_crc32.h +1 -1
  67. data/assets/include/SDL2/SDL_test_font.h +1 -1
  68. data/assets/include/SDL2/SDL_test_fuzzer.h +1 -1
  69. data/assets/include/SDL2/SDL_test_harness.h +1 -1
  70. data/assets/include/SDL2/SDL_test_images.h +1 -1
  71. data/assets/include/SDL2/SDL_test_log.h +1 -1
  72. data/assets/include/SDL2/SDL_test_md5.h +1 -1
  73. data/assets/include/SDL2/SDL_test_memory.h +3 -3
  74. data/assets/include/SDL2/SDL_test_random.h +1 -1
  75. data/assets/include/SDL2/SDL_thread.h +1 -1
  76. data/assets/include/SDL2/SDL_timer.h +1 -1
  77. data/assets/include/SDL2/SDL_touch.h +17 -1
  78. data/assets/include/SDL2/SDL_types.h +1 -1
  79. data/assets/include/SDL2/SDL_version.h +2 -2
  80. data/assets/include/SDL2/SDL_video.h +1 -1
  81. data/assets/include/SDL2/SDL_vulkan.h +3 -3
  82. data/assets/include/SDL2/begin_code.h +4 -1
  83. data/assets/include/SDL2/close_code.h +4 -1
  84. data/assets/macos/lib/libFLAC.a +0 -0
  85. data/assets/macos/lib/libSDL2.a +0 -0
  86. data/assets/macos/lib/libSDL2_image.a +0 -0
  87. data/assets/macos/lib/libSDL2_mixer.a +0 -0
  88. data/assets/macos/lib/libSDL2_ttf.a +0 -0
  89. data/assets/macos/lib/libfreetype.a +0 -0
  90. data/assets/macos/lib/libjpeg.a +0 -0
  91. data/assets/macos/lib/libmpg123.a +0 -0
  92. data/assets/macos/lib/libogg.a +0 -0
  93. data/assets/macos/lib/libpng16.a +0 -0
  94. data/assets/macos/lib/libtiff.a +0 -0
  95. data/assets/macos/lib/libwebp.a +0 -0
  96. data/assets/mingw/bin/SDL2.dll +0 -0
  97. data/assets/mingw/bin/SDL2_image.dll +0 -0
  98. data/assets/mingw/bin/libpng16-16.dll +0 -0
  99. data/assets/mingw/bin/libtiff-5.dll +0 -0
  100. data/assets/mingw/bin/libwebp-7.dll +0 -0
  101. data/assets/mingw/lib/libSDL2.a +0 -0
  102. data/assets/mingw/lib/libSDL2.dll.a +0 -0
  103. data/assets/mingw/lib/libSDL2_image.a +0 -0
  104. data/assets/mingw/lib/libSDL2_image.dll.a +0 -0
  105. data/assets/mingw/lib/libSDL2_test.a +0 -0
  106. data/assets/mingw/lib/libSDL2main.a +0 -0
  107. data/bin/ruby2d +2 -1
  108. data/ext/ruby2d/common.c +185 -0
  109. data/ext/ruby2d/controllers.c +110 -0
  110. data/ext/ruby2d/extconf.rb +97 -46
  111. data/ext/ruby2d/gl.c +430 -0
  112. data/ext/ruby2d/gl2.c +146 -0
  113. data/ext/ruby2d/gl3.c +348 -0
  114. data/ext/ruby2d/gles.c +308 -0
  115. data/ext/ruby2d/image.c +138 -0
  116. data/ext/ruby2d/input.c +48 -0
  117. data/ext/ruby2d/music.c +114 -0
  118. data/ext/ruby2d/ruby2d.c +125 -126
  119. data/{assets/include/simple2d.h → ext/ruby2d/ruby2d.h} +223 -201
  120. data/ext/ruby2d/shapes.c +154 -0
  121. data/ext/ruby2d/sound.c +93 -0
  122. data/ext/ruby2d/sprite.c +147 -0
  123. data/ext/ruby2d/text.c +129 -0
  124. data/ext/ruby2d/window.c +414 -0
  125. data/lib/ruby2d.rb +1 -1
  126. data/lib/ruby2d/cli/build.rb +3 -8
  127. data/lib/ruby2d/cli/colorize.rb +10 -0
  128. data/lib/ruby2d/version.rb +1 -1
  129. metadata +34 -10
  130. data/assets/macos/lib/libsimple2d.a +0 -0
  131. data/assets/mingw/lib/libsimple2d.a +0 -0
  132. data/lib/ruby2d/colorize.rb +0 -10
@@ -0,0 +1,154 @@
1
+ // shapes.c
2
+
3
+ #include "ruby2d.h"
4
+
5
+
6
+ /*
7
+ * Rotate a point around a given point
8
+ * Params:
9
+ * p The point to rotate
10
+ * angle The angle in degrees
11
+ * rx The x coordinate to rotate around
12
+ * ry The y coordinate to rotate around
13
+ */
14
+ R2D_GL_Point R2D_RotatePoint(R2D_GL_Point p, GLfloat angle, GLfloat rx, GLfloat ry) {
15
+
16
+ // Convert from degrees to radians
17
+ angle = angle * M_PI / 180.0;
18
+
19
+ // Get the sine and cosine of the angle
20
+ GLfloat sa = sin(angle);
21
+ GLfloat ca = cos(angle);
22
+
23
+ // Translate point to origin
24
+ p.x -= rx;
25
+ p.y -= ry;
26
+
27
+ // Rotate point
28
+ GLfloat xnew = p.x * ca - p.y * sa;
29
+ GLfloat ynew = p.x * sa + p.y * ca;
30
+
31
+ // Translate point back
32
+ p.x = xnew + rx;
33
+ p.y = ynew + ry;
34
+
35
+ return p;
36
+ }
37
+
38
+
39
+ /*
40
+ * Get the point to be rotated around given a position in a rectangle
41
+ */
42
+ R2D_GL_Point R2D_GetRectRotationPoint(int x, int y, int w, int h, int position) {
43
+
44
+ R2D_GL_Point p;
45
+
46
+ switch (position) {
47
+ case R2D_CENTER:
48
+ p.x = x + (w / 2.0);
49
+ p.y = y + (h / 2.0);
50
+ break;
51
+ case R2D_TOP_LEFT:
52
+ p.x = x;
53
+ p.y = y;
54
+ break;
55
+ case R2D_TOP_RIGHT:
56
+ p.x = x + w;
57
+ p.y = y;
58
+ break;
59
+ case R2D_BOTTOM_LEFT:
60
+ p.x = x;
61
+ p.y = y + h;
62
+ break;
63
+ case R2D_BOTTOM_RIGHT:
64
+ p.x = x + w;
65
+ p.y = y + h;
66
+ break;
67
+ }
68
+
69
+ return p;
70
+ }
71
+
72
+
73
+ /*
74
+ * Draw a triangle
75
+ */
76
+ void R2D_DrawTriangle(GLfloat x1, GLfloat y1,
77
+ GLfloat r1, GLfloat g1, GLfloat b1, GLfloat a1,
78
+ GLfloat x2, GLfloat y2,
79
+ GLfloat r2, GLfloat g2, GLfloat b2, GLfloat a2,
80
+ GLfloat x3, GLfloat y3,
81
+ GLfloat r3, GLfloat g3, GLfloat b3, GLfloat a3) {
82
+
83
+ R2D_GL_DrawTriangle(x1, y1, r1, g1, b1, a1,
84
+ x2, y2, r2, g2, b2, a2,
85
+ x3, y3, r3, g3, b3, a3);
86
+ }
87
+
88
+
89
+ /*
90
+ * Draw a quad, using two triangles
91
+ */
92
+ void R2D_DrawQuad(GLfloat x1, GLfloat y1,
93
+ GLfloat r1, GLfloat g1, GLfloat b1, GLfloat a1,
94
+ GLfloat x2, GLfloat y2,
95
+ GLfloat r2, GLfloat g2, GLfloat b2, GLfloat a2,
96
+ GLfloat x3, GLfloat y3,
97
+ GLfloat r3, GLfloat g3, GLfloat b3, GLfloat a3,
98
+ GLfloat x4, GLfloat y4,
99
+ GLfloat r4, GLfloat g4, GLfloat b4, GLfloat a4) {
100
+
101
+ R2D_GL_DrawTriangle(x1, y1, r1, g1, b1, a1,
102
+ x2, y2, r2, g2, b2, a2,
103
+ x3, y3, r3, g3, b3, a3);
104
+
105
+ R2D_GL_DrawTriangle(x3, y3, r3, g3, b3, a3,
106
+ x4, y4, r4, g4, b4, a4,
107
+ x1, y1, r1, g1, b1, a1);
108
+ };
109
+
110
+
111
+ /*
112
+ * Draw a line from a quad
113
+ */
114
+ void R2D_DrawLine(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2,
115
+ GLfloat width,
116
+ GLfloat r1, GLfloat g1, GLfloat b1, GLfloat a1,
117
+ GLfloat r2, GLfloat g2, GLfloat b2, GLfloat a2,
118
+ GLfloat r3, GLfloat g3, GLfloat b3, GLfloat a3,
119
+ GLfloat r4, GLfloat g4, GLfloat b4, GLfloat a4) {
120
+
121
+ double length = sqrt(powf(x1 - x2, 2) + powf(y1 - y2, 2));
122
+ double x = ((x2 - x1) / length) * width / 2;
123
+ double y = ((y2 - y1) / length) * width / 2;
124
+
125
+ R2D_DrawQuad(
126
+ x1 - y, y1 + x, r1, g1, b1, a1,
127
+ x1 + y, y1 - x, r2, g2, b2, a2,
128
+ x2 + y, y2 - x, r3, g3, b3, a3,
129
+ x2 - y, y2 + x, r4, g4, b4, a4
130
+ );
131
+ };
132
+
133
+
134
+ /*
135
+ * Draw a circle from triangles
136
+ */
137
+ void R2D_DrawCircle(GLfloat x, GLfloat y, GLfloat radius, int sectors,
138
+ GLfloat r, GLfloat g, GLfloat b, GLfloat a) {
139
+
140
+ double angle = 2 * M_PI / sectors;
141
+
142
+ for (int i = 0; i < sectors; i++) {
143
+
144
+ GLfloat x1 = x + radius * cos(i * angle);
145
+ GLfloat y1 = y + radius * sin(i * angle);
146
+
147
+ GLfloat x2 = x + radius * cos((i - 1) * angle);
148
+ GLfloat y2 = y + radius * sin((i - 1) * angle);
149
+
150
+ R2D_GL_DrawTriangle( x, y, r, g, b, a,
151
+ x1, y1, r, g, b, a,
152
+ x2, y2, r, g, b, a);
153
+ }
154
+ }
@@ -0,0 +1,93 @@
1
+ // sound.c
2
+
3
+ #include "ruby2d.h"
4
+
5
+
6
+ /*
7
+ * Create a sound, given an audio file path
8
+ */
9
+ R2D_Sound *R2D_CreateSound(const char *path) {
10
+ R2D_Init();
11
+
12
+ // Check if sound file exists
13
+ if (!R2D_FileExists(path)) {
14
+ R2D_Error("R2D_CreateSound", "Sound file `%s` not found", path);
15
+ return NULL;
16
+ }
17
+
18
+ // Allocate the sound structure
19
+ R2D_Sound *snd = (R2D_Sound *) malloc(sizeof(R2D_Sound));
20
+ if (!snd) {
21
+ R2D_Error("R2D_CreateSound", "Out of memory!");
22
+ return NULL;
23
+ }
24
+
25
+ // Load the sound data from file
26
+ snd->data = Mix_LoadWAV(path);
27
+ if (!snd->data) {
28
+ R2D_Error("Mix_LoadWAV", Mix_GetError());
29
+ free(snd);
30
+ return NULL;
31
+ }
32
+
33
+ // Initialize values
34
+ snd->path = path;
35
+
36
+ return snd;
37
+ }
38
+
39
+
40
+ /*
41
+ * Play the sound
42
+ */
43
+ void R2D_PlaySound(R2D_Sound *snd) {
44
+ if (!snd) return;
45
+ Mix_PlayChannel(-1, snd->data, 0);
46
+ }
47
+
48
+
49
+ /*
50
+ * Get the sound's volume
51
+ */
52
+ int R2D_GetSoundVolume(R2D_Sound *snd) {
53
+ if (!snd) return -1;
54
+ return ceil(Mix_VolumeChunk(snd->data, -1) * (100.0 / MIX_MAX_VOLUME));
55
+ }
56
+
57
+
58
+ /*
59
+ * Set the sound's volume a given percentage
60
+ */
61
+ void R2D_SetSoundVolume(R2D_Sound *snd, int volume) {
62
+ if (!snd) return;
63
+ // Set volume to be a percentage of the maximum mix volume
64
+ Mix_VolumeChunk(snd->data, (volume / 100.0) * MIX_MAX_VOLUME);
65
+ }
66
+
67
+
68
+ /*
69
+ * Get the sound mixer volume
70
+ */
71
+ int R2D_GetSoundMixVolume() {
72
+ return ceil(Mix_Volume(-1, -1) * (100.0 / MIX_MAX_VOLUME));
73
+ }
74
+
75
+
76
+ /*
77
+ * Set the sound mixer volume a given percentage
78
+ */
79
+ void R2D_SetSoundMixVolume(int volume) {
80
+ // This sets the volume value across all channels
81
+ // Set volume to be a percentage of the maximum mix volume
82
+ Mix_Volume(-1, (volume / 100.0) * MIX_MAX_VOLUME);
83
+ }
84
+
85
+
86
+ /*
87
+ * Free the sound
88
+ */
89
+ void R2D_FreeSound(R2D_Sound *snd) {
90
+ if (!snd) return;
91
+ Mix_FreeChunk(snd->data);
92
+ free(snd);
93
+ }
@@ -0,0 +1,147 @@
1
+ // sprite.c
2
+
3
+ #include "ruby2d.h"
4
+
5
+
6
+ /*
7
+ * Create a sprite, given an image file path
8
+ */
9
+ R2D_Sprite *R2D_CreateSprite(const char *path) {
10
+
11
+ // Check if image file exists
12
+ if (!R2D_FileExists(path)) {
13
+ R2D_Error("R2D_CreateSprite", "Sprite image file `%s` not found", path);
14
+ return NULL;
15
+ }
16
+
17
+ // Allocate the sprite structure
18
+ R2D_Sprite *spr = (R2D_Sprite *) malloc(sizeof(R2D_Sprite));
19
+ if (!spr) {
20
+ R2D_Error("R2D_CreateSprite", "Out of memory!");
21
+ return NULL;
22
+ }
23
+
24
+ // Load the sprite image file
25
+ spr->img = R2D_CreateImage(path);
26
+ if (!spr->img) {
27
+ R2D_Error("R2D_CreateSprite", "Cannot create sprite image `%s`", path);
28
+ free(spr);
29
+ return NULL;
30
+ }
31
+
32
+ // Initialize values
33
+ spr->path = path;
34
+ spr->x = 0;
35
+ spr->y = 0;
36
+ spr->color.r = 1.f;
37
+ spr->color.g = 1.f;
38
+ spr->color.b = 1.f;
39
+ spr->color.a = 1.f;
40
+ spr->width = spr->img->width;
41
+ spr->height = spr->img->height;
42
+ spr->clip_width = spr->img->width;
43
+ spr->clip_height = spr->img->height;
44
+ spr->rotate = 0;
45
+ spr->rx = 0;
46
+ spr->ry = 0;
47
+ spr->tx1 = 0.f;
48
+ spr->ty1 = 0.f;
49
+ spr->tx2 = 1.f;
50
+ spr->ty2 = 0.f;
51
+ spr->tx3 = 1.f;
52
+ spr->ty3 = 1.f;
53
+ spr->tx4 = 0.f;
54
+ spr->ty4 = 1.f;
55
+
56
+ return spr;
57
+ }
58
+
59
+
60
+ /*
61
+ * Clip a sprite
62
+ */
63
+ void R2D_ClipSprite(R2D_Sprite *spr, int x, int y, int w, int h) {
64
+ if (!spr) return;
65
+
66
+ // Calculate ratios
67
+ // rw = ratio width; rh = ratio height
68
+ double rw = w / (double)spr->img->width;
69
+ double rh = h / (double)spr->img->height;
70
+
71
+ // Apply ratios to x, y coordinates
72
+ // cx = crop x coord; cy = crop y coord
73
+ double cx = x * rw;
74
+ double cy = y * rh;
75
+
76
+ // Convert given width, height to doubles
77
+ // cw = crop width; ch = crop height
78
+ double cw = (double)w;
79
+ double ch = (double)h;
80
+
81
+ // Apply ratio to texture width and height
82
+ // tw = texture width; th = texture height
83
+ double tw = rw * w;
84
+ double th = rh * h;
85
+
86
+ // Calculate and store sprite texture values
87
+
88
+ spr->tx1 = cx / cw;
89
+ spr->ty1 = cy / ch;
90
+
91
+ spr->tx2 = (cx + tw) / cw;
92
+ spr->ty2 = cy / ch;
93
+
94
+ spr->tx3 = (cx + tw) / cw;
95
+ spr->ty3 = (cy + th) / ch;
96
+
97
+ spr->tx4 = cx / cw;
98
+ spr->ty4 = (cy + th) / ch;
99
+
100
+ // Store the sprite dimensions
101
+ spr->width = (spr->width / (double)spr->clip_width ) * w;
102
+ spr->height = (spr->height / (double)spr->clip_height) * h;
103
+ spr->clip_width = w;
104
+ spr->clip_height = h;
105
+ }
106
+
107
+
108
+ /*
109
+ * Rotate a sprite
110
+ */
111
+ void R2D_RotateSprite(R2D_Sprite *spr, GLfloat angle, int position) {
112
+
113
+ R2D_GL_Point p = R2D_GetRectRotationPoint(
114
+ spr->x, spr->y, spr->width, spr->height, position
115
+ );
116
+
117
+ spr->rotate = angle;
118
+ spr->rx = p.x;
119
+ spr->ry = p.y;
120
+ }
121
+
122
+
123
+ /*
124
+ * Draw a sprite
125
+ */
126
+ void R2D_DrawSprite(R2D_Sprite *spr) {
127
+ if (!spr) return;
128
+
129
+ if (spr->img->texture_id == 0) {
130
+ R2D_GL_CreateTexture(&spr->img->texture_id, spr->img->format,
131
+ spr->img->width, spr->img->height,
132
+ spr->img->surface->pixels, GL_NEAREST);
133
+ SDL_FreeSurface(spr->img->surface);
134
+ }
135
+
136
+ R2D_GL_DrawSprite(spr);
137
+ }
138
+
139
+
140
+ /*
141
+ * Free a sprite
142
+ */
143
+ void R2D_FreeSprite(R2D_Sprite *spr) {
144
+ if (!spr) return;
145
+ R2D_FreeImage(spr->img);
146
+ free(spr);
147
+ }
data/ext/ruby2d/text.c ADDED
@@ -0,0 +1,129 @@
1
+ // text.c
2
+
3
+ #include "ruby2d.h"
4
+
5
+
6
+ /*
7
+ * Create text, given a font file path, the message, and size
8
+ */
9
+ R2D_Text *R2D_CreateText(const char *font, const char *msg, int size) {
10
+ R2D_Init();
11
+
12
+ // Check if font file exists
13
+ if (!R2D_FileExists(font)) {
14
+ R2D_Error("R2D_CreateText", "Font file `%s` not found", font);
15
+ return NULL;
16
+ }
17
+
18
+ // `msg` cannot be an empty string or NULL for TTF_SizeText
19
+ if (msg == NULL || strlen(msg) == 0) msg = " ";
20
+
21
+ // Allocate the text structure
22
+ R2D_Text *txt = (R2D_Text *) malloc(sizeof(R2D_Text));
23
+ if (!txt) {
24
+ R2D_Error("R2D_CreateText", "Out of memory!");
25
+ return NULL;
26
+ }
27
+
28
+ // Open the font
29
+ txt->font_data = TTF_OpenFont(font, size);
30
+ if (!txt->font_data) {
31
+ R2D_Error("TTF_OpenFont", TTF_GetError());
32
+ free(txt);
33
+ return NULL;
34
+ }
35
+
36
+ // Initialize values
37
+ txt->font = font;
38
+ txt->msg = (char *) malloc(strlen(msg) + 1 * sizeof(char));
39
+ strcpy(txt->msg, msg);
40
+ txt->x = 0;
41
+ txt->y = 0;
42
+ txt->color.r = 1.f;
43
+ txt->color.g = 1.f;
44
+ txt->color.b = 1.f;
45
+ txt->color.a = 1.f;
46
+ txt->rotate = 0;
47
+ txt->rx = 0;
48
+ txt->ry = 0;
49
+ txt->texture_id = 0;
50
+
51
+ // Save the width and height of the text
52
+ TTF_SizeUTF8(txt->font_data, txt->msg, &txt->width, &txt->height);
53
+
54
+ return txt;
55
+ }
56
+
57
+
58
+ /*
59
+ * Set the text message
60
+ */
61
+ void R2D_SetText(R2D_Text *txt, const char *msg, ...) {
62
+ if (!txt) return;
63
+
64
+ // `msg` cannot be an empty string or NULL for TTF_SizeUTF8
65
+ if (msg == NULL || strlen(msg) == 0) msg = " ";
66
+
67
+ // Format and store new text string
68
+ va_list args;
69
+ va_start(args, msg);
70
+ free(txt->msg);
71
+ vasprintf(&txt->msg, msg, args);
72
+ va_end(args);
73
+
74
+ // Save the width and height of the text
75
+ TTF_SizeUTF8(txt->font_data, txt->msg, &txt->width, &txt->height);
76
+
77
+ // Delete the current texture so a new one can be generated
78
+ R2D_GL_FreeTexture(&txt->texture_id);
79
+ }
80
+
81
+
82
+ /*
83
+ * Rotate text
84
+ */
85
+ void R2D_RotateText(R2D_Text *txt, GLfloat angle, int position) {
86
+
87
+ R2D_GL_Point p = R2D_GetRectRotationPoint(
88
+ txt->x, txt->y, txt->width, txt->height, position
89
+ );
90
+
91
+ txt->rotate = angle;
92
+ txt->rx = p.x;
93
+ txt->ry = p.y;
94
+ }
95
+
96
+
97
+ /*
98
+ * Draw text
99
+ */
100
+ void R2D_DrawText(R2D_Text *txt) {
101
+ if (!txt) return;
102
+
103
+ if (txt->texture_id == 0) {
104
+ SDL_Color color = { 255, 255, 255 };
105
+ txt->surface = TTF_RenderUTF8_Blended(txt->font_data, txt->msg, color);
106
+ if (!txt->surface) {
107
+ R2D_Error("TTF_RenderUTF8_Blended", TTF_GetError());
108
+ return;
109
+ }
110
+ R2D_GL_CreateTexture(&txt->texture_id, GL_RGBA,
111
+ txt->width, txt->height,
112
+ txt->surface->pixels, GL_NEAREST);
113
+ SDL_FreeSurface(txt->surface);
114
+ }
115
+
116
+ R2D_GL_DrawText(txt);
117
+ }
118
+
119
+
120
+ /*
121
+ * Free the text
122
+ */
123
+ void R2D_FreeText(R2D_Text *txt) {
124
+ if (!txt) return;
125
+ free(txt->msg);
126
+ R2D_GL_FreeTexture(&txt->texture_id);
127
+ TTF_CloseFont(txt->font_data);
128
+ free(txt);
129
+ }