ruby2d 0.11.2 → 0.12.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 (231) hide show
  1. checksums.yaml +4 -4
  2. data/assets/include/GLES2/gl2.h +656 -0
  3. data/assets/include/GLES2/gl2ext.h +3949 -0
  4. data/assets/include/GLES2/gl2ext_angle.h +701 -0
  5. data/assets/include/GLES2/gl2platform.h +27 -0
  6. data/assets/include/GLES3/gl3.h +1192 -0
  7. data/assets/include/GLES3/gl31.h +1507 -0
  8. data/assets/include/GLES3/gl32.h +1808 -0
  9. data/assets/include/GLES3/gl3platform.h +27 -0
  10. data/assets/include/KHR/khrplatform.h +290 -0
  11. data/assets/include/SDL2/SDL.h +1 -0
  12. data/assets/include/SDL2/SDL_assert.h +4 -2
  13. data/assets/include/SDL2/SDL_atomic.h +20 -0
  14. data/assets/include/SDL2/SDL_audio.h +40 -4
  15. data/assets/include/SDL2/SDL_blendmode.h +4 -6
  16. data/assets/include/SDL2/SDL_clipboard.h +47 -0
  17. data/assets/include/SDL2/SDL_config.h +6 -2
  18. data/assets/include/SDL2/SDL_config_android.h +2 -0
  19. data/assets/include/SDL2/SDL_config_emscripten.h +2 -0
  20. data/assets/include/SDL2/SDL_config_iphoneos.h +3 -1
  21. data/assets/include/SDL2/SDL_config_macosx.h +3 -6
  22. data/assets/include/SDL2/SDL_config_minimal.h +18 -11
  23. data/assets/include/SDL2/SDL_config_ngage.h +89 -0
  24. data/assets/include/SDL2/SDL_config_os2.h +5 -3
  25. data/assets/include/SDL2/SDL_config_pandora.h +1 -0
  26. data/assets/include/SDL2/SDL_config_windows.h +71 -45
  27. data/assets/include/SDL2/SDL_config_wingdk.h +253 -0
  28. data/assets/include/SDL2/SDL_config_winrt.h +11 -49
  29. data/assets/include/SDL2/SDL_config_xbox.h +235 -0
  30. data/assets/include/SDL2/SDL_cpuinfo.h +39 -4
  31. data/assets/include/SDL2/SDL_egl.h +59 -9
  32. data/assets/include/SDL2/SDL_endian.h +34 -3
  33. data/assets/include/SDL2/SDL_events.h +32 -1
  34. data/assets/include/SDL2/SDL_filesystem.h +5 -1
  35. data/assets/include/SDL2/SDL_gamecontroller.h +78 -5
  36. data/assets/include/SDL2/SDL_guid.h +100 -0
  37. data/assets/include/SDL2/SDL_hints.h +645 -43
  38. data/assets/include/SDL2/SDL_image.h +2045 -33
  39. data/assets/include/SDL2/SDL_joystick.h +127 -7
  40. data/assets/include/SDL2/SDL_keyboard.h +38 -1
  41. data/assets/include/SDL2/SDL_keycode.h +6 -1
  42. data/assets/include/SDL2/SDL_log.h +2 -2
  43. data/assets/include/SDL2/SDL_main.h +42 -2
  44. data/assets/include/SDL2/SDL_metal.h +2 -1
  45. data/assets/include/SDL2/SDL_mixer.h +2529 -396
  46. data/assets/include/SDL2/SDL_mouse.h +12 -1
  47. data/assets/include/SDL2/SDL_opengl.h +0 -51
  48. data/assets/include/SDL2/SDL_opengl_glext.h +2260 -231
  49. data/assets/include/SDL2/SDL_opengles2_gl2.h +374 -339
  50. data/assets/include/SDL2/SDL_opengles2_gl2ext.h +3479 -1496
  51. data/assets/include/SDL2/SDL_opengles2_gl2platform.h +6 -9
  52. data/assets/include/SDL2/SDL_opengles2_khrplatform.h +43 -14
  53. data/assets/include/SDL2/SDL_platform.h +32 -6
  54. data/assets/include/SDL2/SDL_rect.h +154 -2
  55. data/assets/include/SDL2/SDL_render.h +46 -17
  56. data/assets/include/SDL2/SDL_revision.h +4 -0
  57. data/assets/include/SDL2/SDL_rwops.h +1 -15
  58. data/assets/include/SDL2/SDL_scancode.h +46 -21
  59. data/assets/include/SDL2/SDL_sensor.h +24 -3
  60. data/assets/include/SDL2/SDL_stdinc.h +119 -8
  61. data/assets/include/SDL2/SDL_surface.h +3 -1
  62. data/assets/include/SDL2/SDL_system.h +66 -6
  63. data/assets/include/SDL2/SDL_syswm.h +2 -0
  64. data/assets/include/SDL2/SDL_test_common.h +1 -0
  65. data/assets/include/SDL2/SDL_test_font.h +90 -3
  66. data/assets/include/SDL2/SDL_thread.h +3 -3
  67. data/assets/include/SDL2/SDL_touch.h +8 -0
  68. data/assets/include/SDL2/SDL_ttf.h +2084 -155
  69. data/assets/include/SDL2/SDL_version.h +19 -3
  70. data/assets/include/SDL2/SDL_video.h +71 -9
  71. data/assets/include/SDL2/begin_code.h +4 -4
  72. data/assets/include/mrbconf.h +15 -17
  73. data/assets/include/mruby/array.h +8 -21
  74. data/assets/include/mruby/boxing_nan.h +115 -86
  75. data/assets/include/mruby/boxing_word.h +104 -78
  76. data/assets/include/mruby/common.h +6 -0
  77. data/assets/include/mruby/compile.h +3 -4
  78. data/assets/include/mruby/debug.h +4 -2
  79. data/assets/include/mruby/dump.h +5 -2
  80. data/assets/include/mruby/error.h +12 -2
  81. data/assets/include/mruby/gc.h +2 -0
  82. data/assets/include/mruby/hash.h +1 -3
  83. data/assets/include/mruby/irep.h +4 -4
  84. data/assets/include/mruby/numeric.h +21 -13
  85. data/assets/include/mruby/opcode.h +30 -0
  86. data/assets/include/mruby/ops.h +99 -101
  87. data/assets/include/mruby/presym/scanning.h +15 -9
  88. data/assets/include/mruby/proc.h +4 -2
  89. data/assets/include/mruby/string.h +3 -24
  90. data/assets/include/mruby/value.h +80 -40
  91. data/assets/include/mruby/variable.h +0 -15
  92. data/assets/include/mruby/version.h +5 -5
  93. data/assets/include/mruby.h +86 -16
  94. data/assets/macos/universal/bin/mrbc +0 -0
  95. data/assets/macos/universal/lib/libFLAC.a +0 -0
  96. data/assets/macos/universal/lib/libSDL2.a +0 -0
  97. data/assets/macos/universal/lib/libSDL2_image.a +0 -0
  98. data/assets/macos/universal/lib/libSDL2_mixer.a +0 -0
  99. data/assets/macos/universal/lib/libSDL2_ttf.a +0 -0
  100. data/assets/macos/universal/lib/libavif.a +0 -0
  101. data/assets/macos/universal/lib/libbrotlicommon-static.a +0 -0
  102. data/assets/macos/universal/lib/libbrotlidec-static.a +0 -0
  103. data/assets/macos/universal/lib/libfreetype.a +0 -0
  104. data/assets/macos/universal/lib/libgraphite2.a +0 -0
  105. data/assets/macos/universal/lib/libharfbuzz.a +0 -0
  106. data/assets/macos/universal/lib/libhwy.a +0 -0
  107. data/assets/macos/universal/lib/libjpeg.a +0 -0
  108. data/assets/macos/universal/lib/libjxl.a +0 -0
  109. data/assets/macos/universal/lib/libmodplug.a +0 -0
  110. data/assets/macos/universal/lib/libmpg123.a +0 -0
  111. data/assets/macos/universal/lib/libmruby.a +0 -0
  112. data/assets/macos/universal/lib/libogg.a +0 -0
  113. data/assets/macos/universal/lib/libpng.a +0 -0
  114. data/assets/macos/universal/lib/libtiff.a +0 -0
  115. data/assets/macos/universal/lib/libvorbis.a +0 -0
  116. data/assets/macos/universal/lib/libvorbisfile.a +0 -0
  117. data/assets/macos/universal/lib/libwebp.a +0 -0
  118. data/assets/macos/universal/lib/libzstd.a +0 -0
  119. data/assets/wasm/libmruby.a +0 -0
  120. data/assets/wasm/template.html +52 -4
  121. data/assets/windows/mingw-w64-ucrt-x86_64/bin/mrbc.exe +0 -0
  122. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libFLAC.a +0 -0
  123. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libLerc.a +0 -0
  124. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libSDL2.a +0 -0
  125. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libSDL2_image.a +0 -0
  126. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libSDL2_mixer.a +0 -0
  127. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libSDL2_ttf.a +0 -0
  128. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libbrotlicommon.a +0 -0
  129. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libbrotlidec.a +0 -0
  130. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libbz2.a +0 -0
  131. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libdeflate.a +0 -0
  132. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libfreetype.a +0 -0
  133. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libglew32.a +0 -0
  134. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libgraphite2.a +0 -0
  135. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libharfbuzz.a +0 -0
  136. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libhwy.a +0 -0
  137. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libjbig.a +0 -0
  138. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libjpeg.a +0 -0
  139. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libjxl.a +0 -0
  140. data/assets/windows/mingw-w64-ucrt-x86_64/lib/liblzma.a +0 -0
  141. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libmodplug.a +0 -0
  142. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libmpg123.a +0 -0
  143. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libmruby.a +0 -0
  144. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libogg.a +0 -0
  145. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libopus.a +0 -0
  146. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libopusfile.a +0 -0
  147. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libpng.a +0 -0
  148. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libsndfile.a +0 -0
  149. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libssp.a +1 -0
  150. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libstdc++.a +0 -0
  151. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libtiff.a +0 -0
  152. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libvorbis.a +0 -0
  153. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libvorbisfile.a +0 -0
  154. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libwebp.a +0 -0
  155. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libz.a +0 -0
  156. data/assets/windows/mingw-w64-ucrt-x86_64/lib/libzstd.a +0 -0
  157. data/assets/windows/mingw-w64-x86_64/bin/mrbc.exe +0 -0
  158. data/assets/windows/mingw-w64-x86_64/lib/libFLAC.a +0 -0
  159. data/assets/windows/mingw-w64-x86_64/lib/libLerc.a +0 -0
  160. data/assets/windows/mingw-w64-x86_64/lib/libSDL2.a +0 -0
  161. data/assets/windows/mingw-w64-x86_64/lib/libSDL2_image.a +0 -0
  162. data/assets/windows/mingw-w64-x86_64/lib/libSDL2_mixer.a +0 -0
  163. data/assets/windows/mingw-w64-x86_64/lib/libSDL2_ttf.a +0 -0
  164. data/assets/windows/mingw-w64-x86_64/lib/libbrotlicommon.a +0 -0
  165. data/assets/windows/mingw-w64-x86_64/lib/libbrotlidec.a +0 -0
  166. data/assets/windows/mingw-w64-x86_64/lib/libdeflate.a +0 -0
  167. data/assets/windows/mingw-w64-x86_64/lib/libfreetype.a +0 -0
  168. data/assets/windows/mingw-w64-x86_64/lib/libglew32.a +0 -0
  169. data/assets/windows/mingw-w64-x86_64/lib/libharfbuzz.a +0 -0
  170. data/assets/windows/mingw-w64-x86_64/lib/libhwy.a +0 -0
  171. data/assets/windows/mingw-w64-x86_64/lib/libjpeg.a +0 -0
  172. data/assets/windows/mingw-w64-x86_64/lib/libjxl.a +0 -0
  173. data/assets/windows/mingw-w64-x86_64/lib/liblzma.a +0 -0
  174. data/assets/windows/mingw-w64-x86_64/lib/libmpg123.a +0 -0
  175. data/assets/windows/mingw-w64-x86_64/lib/libmruby.a +0 -0
  176. data/assets/windows/mingw-w64-x86_64/lib/libopus.a +0 -0
  177. data/assets/windows/mingw-w64-x86_64/lib/libpng.a +0 -0
  178. data/assets/windows/mingw-w64-x86_64/lib/libsndfile.a +0 -0
  179. data/assets/windows/mingw-w64-x86_64/lib/libssp.a +0 -0
  180. data/assets/windows/mingw-w64-x86_64/lib/libstdc++.a +0 -0
  181. data/assets/windows/mingw-w64-x86_64/lib/libtiff.a +0 -0
  182. data/assets/windows/mingw-w64-x86_64/lib/libwebp.a +0 -0
  183. data/assets/windows/mingw-w64-x86_64/lib/libz.a +0 -0
  184. data/assets/windows/mingw-w64-x86_64/lib/libzstd.a +0 -0
  185. data/ext/ruby2d/canvas.c +540 -0
  186. data/ext/ruby2d/extconf.rb +39 -21
  187. data/ext/ruby2d/gl.c +3 -3
  188. data/ext/ruby2d/image.c +7 -7
  189. data/ext/ruby2d/ruby2d.c +741 -24
  190. data/ext/ruby2d/ruby2d.h +66 -3
  191. data/ext/ruby2d/sound.c +16 -2
  192. data/lib/ruby2d/canvas.rb +315 -0
  193. data/lib/ruby2d/circle.rb +30 -15
  194. data/lib/ruby2d/cli/build.rb +11 -4
  195. data/lib/ruby2d/cli/enable_console.rb +3 -1
  196. data/lib/ruby2d/color.rb +133 -77
  197. data/lib/ruby2d/core.rb +32 -0
  198. data/lib/ruby2d/dsl.rb +38 -32
  199. data/lib/ruby2d/exceptions.rb +2 -1
  200. data/lib/ruby2d/font.rb +97 -62
  201. data/lib/ruby2d/image.rb +48 -27
  202. data/lib/ruby2d/line.rb +84 -45
  203. data/lib/ruby2d/music.rb +33 -23
  204. data/lib/ruby2d/pixel.rb +10 -9
  205. data/lib/ruby2d/pixmap.rb +39 -0
  206. data/lib/ruby2d/pixmap_atlas.rb +56 -0
  207. data/lib/ruby2d/quad.rb +98 -49
  208. data/lib/ruby2d/rectangle.rb +35 -36
  209. data/lib/ruby2d/renderable.rb +7 -6
  210. data/lib/ruby2d/sound.rb +23 -17
  211. data/lib/ruby2d/sprite.rb +181 -140
  212. data/lib/ruby2d/square.rb +21 -20
  213. data/lib/ruby2d/text.rb +47 -19
  214. data/lib/ruby2d/texture.rb +13 -3
  215. data/lib/ruby2d/tileset.rb +97 -44
  216. data/lib/ruby2d/triangle.rb +91 -42
  217. data/lib/ruby2d/version.rb +3 -1
  218. data/lib/ruby2d/vertices.rb +81 -45
  219. data/lib/ruby2d/window.rb +508 -371
  220. data/lib/ruby2d.rb +11 -29
  221. metadata +84 -16
  222. data/assets/include/SDL2/SDL_config_psp.h +0 -165
  223. data/assets/include/SDL2/SDL_config_wiz.h +0 -154
  224. data/assets/include/glew.h +0 -23686
  225. data/assets/macos/universal/lib/libpng16.a +0 -0
  226. data/assets/wasm/build_config.rb +0 -13
  227. data/assets/windows/glew/README.md +0 -10
  228. data/assets/windows/glew/glew.h +0 -23686
  229. data/assets/windows/glew/libglew32.a +0 -0
  230. data/assets/windows/mingw-w64-x86_64/lib/libpng16.a +0 -0
  231. data/lib/ruby2d/entity.rb +0 -17
@@ -0,0 +1,540 @@
1
+ // canvas.c
2
+
3
+ #include "ruby2d.h"
4
+
5
+ typedef SDL_FPoint vector_t;
6
+
7
+ static float vector_magnitude(const vector_t *vec)
8
+ {
9
+ return sqrtf((vec->x * vec->x) + (vec->y * vec->y));
10
+ }
11
+
12
+ static vector_t *vector_normalize(vector_t *vec)
13
+ {
14
+ float mag = vector_magnitude(vec);
15
+ if (mag == 0)
16
+ mag = INFINITY;
17
+ vec->x /= mag;
18
+ vec->y /= mag;
19
+ return vec;
20
+ }
21
+
22
+ static vector_t *vector_perpendicular(vector_t *vec)
23
+ {
24
+ float tmp_x = vec->x;
25
+ vec->x = vec->y;
26
+ vec->y = -tmp_x;
27
+ return vec;
28
+ }
29
+
30
+ static vector_t *vector_times_scalar(vector_t *vec, float value)
31
+ {
32
+ vec->x *= value;
33
+ vec->y *= value;
34
+ return vec;
35
+ }
36
+
37
+ static vector_t *vector_minus_vector(vector_t *vec, const vector_t *other)
38
+ {
39
+ vec->x -= other->x;
40
+ vec->y -= other->y;
41
+ return vec;
42
+ }
43
+
44
+ /* Unused
45
+ static vector_t *vector_minus_xy(vector_t *vec, float other_x, float other_y)
46
+ {
47
+ vec->x -= other_x;
48
+ vec->y -= other_y;
49
+ return vec;
50
+ }
51
+ */
52
+
53
+ static vector_t *vector_plus_vector(vector_t *vec, const vector_t *other)
54
+ {
55
+ vec->x += other->x;
56
+ vec->y += other->y;
57
+ return vec;
58
+ }
59
+
60
+ /* Unused
61
+ static vector_t *vector_plus_xy(vector_t *vec, float other_x, float other_y)
62
+ {
63
+ vec->x += other_x;
64
+ vec->y += other_y;
65
+ return vec;
66
+ }
67
+ */
68
+
69
+ typedef enum { CONCAVE = -1, INVALID, CONVEX } poly_type_e;
70
+
71
+ //
72
+ // Go through each corner and identify and count the number of concave
73
+ // ones, also noting down the last concave point.
74
+ //
75
+ // TODO: collect all the concave points for a later ear-clipper.
76
+ // @param [int *] pconcave_ix Pointer to array of slots for concave point
77
+ // indices
78
+ // @param [int] max_pconcave Max number of clots for concave point indices
79
+ //
80
+ // @return number of concave points; note this may be > +max_pconcave+ so caller
81
+ // needs to check result carefully.
82
+ //
83
+ static int count_concave_corners(const SDL_FPoint *points, int num_points,
84
+ int *pconcave_ix, const int max_pconcave)
85
+ {
86
+ // triangles are always convex
87
+ if (num_points <= 3)
88
+ return (0);
89
+
90
+ int nconcave = 0;
91
+
92
+ // pick first last and first points
93
+ int x1 = points[0].x;
94
+ int y1 = points[0].y;
95
+ int x2 = points[1].x;
96
+ int y2 = points[1].y;
97
+ // start with second point and proceed point by point inspecting
98
+ // each corner
99
+ float z, zprev = 0;
100
+ for (int i = 1; i < num_points; i++, zprev = z) {
101
+ int j = (i + 1) % num_points;
102
+ int x3 = points[j].x;
103
+ int y3 = points[j].y;
104
+ // cross product
105
+ z = ((x1 - x2) * (y2 - y3)) - ((y1 - y2) * (x2 - x3));
106
+ if (z < 0) {
107
+ if (nconcave < max_pconcave)
108
+ *pconcave_ix++ = i;
109
+ nconcave++;
110
+ }
111
+ // shift points left so we
112
+ x1 = x2;
113
+ y1 = y2;
114
+ x2 = x3;
115
+ y2 = y3;
116
+ }
117
+ return nconcave;
118
+ }
119
+
120
+ //
121
+ // If a polygon is entirely conves, we triangulate trivially
122
+ // by using the first point as the anchor to fan out the triangles
123
+ static void fill_convex_polygon(SDL_Renderer *render, const SDL_FPoint *points,
124
+ int num_points, const SDL_Color *colors,
125
+ int num_colors)
126
+ {
127
+ // Setup the vertices from incoming arguments
128
+ SDL_Vertex verts[3];
129
+
130
+ // use first vertex as anchor and draw a triangle with
131
+ // subsequent pair of points.
132
+ verts[0].position = points[0];
133
+ verts[0].color = colors[0];
134
+ for (int i = 2; i < num_points; i++) {
135
+ verts[1].position = points[i - 1];
136
+ verts[1].color = colors[(i - 1) % num_colors];
137
+ verts[2].position = points[i];
138
+ verts[2].color = colors[i % num_colors];
139
+ SDL_RenderGeometry(render, NULL, verts, 3, NULL, 0);
140
+ }
141
+ }
142
+
143
+ //
144
+ // If a polygon has one concave corner, we can still do trivial
145
+ // triangulation as we do for convex polygons using the
146
+ // concave corner as the anchor point for the fan-out.
147
+ static void fill_concave1pt_polygon(SDL_Renderer *render,
148
+ const SDL_FPoint *points, int num_points,
149
+ int anchor_ix, const SDL_Color *colors,
150
+ int num_colors)
151
+ {
152
+ // Setup the vertices from incoming arguments
153
+ SDL_Vertex verts[3];
154
+
155
+ verts[0].position = points[anchor_ix];
156
+ verts[0].color = colors[anchor_ix % num_colors];
157
+ anchor_ix = (anchor_ix + 1) % num_points;
158
+ for (int i = 2; i < num_points; i++) {
159
+ verts[1].position = points[anchor_ix];
160
+ verts[1].color = colors[anchor_ix % num_colors];
161
+ anchor_ix = (anchor_ix + 1) % num_points;
162
+ verts[2].position = points[anchor_ix];
163
+ verts[2].color = colors[anchor_ix % num_colors];
164
+ SDL_RenderGeometry(render, NULL, verts, 3, NULL, 0);
165
+ }
166
+ }
167
+
168
+ #define MAX_CONCAVE_POINT_INDICES 32
169
+
170
+ /*
171
+ * Fill a polygon with a single colour.
172
+ * @param points Array of points
173
+ * @param num_points Number of points
174
+ * @param colors Array of colours
175
+ * @param num_colors Number of colors, must be at least 1, and may be less than
176
+ * +num_points+ in which case the colours will be repeated
177
+ * via modulo.
178
+ * @note Currently supports only: convex polygons or simple polygons with one
179
+ * concave corner. For now.
180
+ */
181
+ void R2D_Canvas_FillPolygon(SDL_Renderer *render, SDL_FPoint *points,
182
+ int num_points, SDL_Color *colors, int num_colors)
183
+ {
184
+ if (num_points < 3)
185
+ return;
186
+
187
+ // poly_type_e type = polygon_type(points, num_points);
188
+ int concave_point_indices[MAX_CONCAVE_POINT_INDICES];
189
+
190
+ int nconcave =
191
+ num_points == 3
192
+ ? 0 // triangles are always convex
193
+ : count_concave_corners(points, num_points, concave_point_indices,
194
+ MAX_CONCAVE_POINT_INDICES);
195
+
196
+ if (nconcave == 0) {
197
+ // convex
198
+ fill_convex_polygon(render, points, num_points, colors, num_colors);
199
+ }
200
+ else if (nconcave == 1) {
201
+ // use concave point as the origin if only one concave vertex
202
+ fill_concave1pt_polygon(render, points, num_points,
203
+ concave_point_indices[0], colors, num_colors);
204
+ }
205
+ // else
206
+ // printf("TODO: Non-convex polygon with %d concave corners\n", nconcave);
207
+ }
208
+
209
+ /*
210
+ * Draw a thick line on a canvas using a pre-converted RGBA colour value.
211
+ * @param [int] thickness must be > 1, else does nothing
212
+ */
213
+ void R2D_Canvas_DrawThickLine(SDL_Renderer *render, int x1, int y1, int x2,
214
+ int y2, int thickness, int r, int g, int b, int a)
215
+ {
216
+
217
+ if (thickness <= 1)
218
+ return;
219
+
220
+ vector_t vec = {.x = (x2 - x1), .y = (y2 - y1)};
221
+
222
+ // calculate perpendicular with half-thickness in place
223
+ vector_times_scalar(vector_perpendicular(vector_normalize(&vec)),
224
+ thickness / 2.0f);
225
+
226
+ // calculate perp vertices based on thickness
227
+ SDL_Vertex verts[4];
228
+
229
+ verts[0].position = (SDL_FPoint){.x = x1 + vec.x, .y = y1 + vec.y};
230
+ verts[1].position = (SDL_FPoint){.x = x2 + vec.x, .y = y2 + vec.y};
231
+ verts[2].position = (SDL_FPoint){.x = x2 - vec.x, .y = y2 - vec.y};
232
+ verts[3].position = (SDL_FPoint){.x = x1 - vec.x, .y = y1 - vec.y};
233
+
234
+ // set the vertex colour
235
+ for (register int i = 0; i < 4; i++) {
236
+ verts[i].color = (SDL_Color){.r = r, .g = g, .b = b, .a = a};
237
+ }
238
+
239
+ // sub-divide the two triangles; we know this is convex
240
+ int indices[] = {0, 1, 2, 2, 3, 0};
241
+ SDL_RenderGeometry(render, NULL, verts, 4, indices, 6);
242
+ }
243
+
244
+ /*
245
+ * Draw a thick rectangle on a canvas using a pre-converted RGBA colour value.
246
+ * @param [int] thickness must be > 1, else does nothing
247
+ */
248
+ void R2D_Canvas_DrawThickRect(SDL_Renderer *render, int x, int y, int width,
249
+ int height, int thickness, int r, int g, int b,
250
+ int a)
251
+ {
252
+ if (thickness <= 1) {
253
+ return;
254
+ }
255
+
256
+ float half_thick = thickness / 2.0f;
257
+ SDL_Vertex verts[8];
258
+
259
+ // all points have the same colour so
260
+ verts[0].color = (SDL_Color){.r = r, .g = g, .b = b, .a = a};
261
+ for (register int i = 1; i < 8; i++) {
262
+ verts[i].color = verts[0].color;
263
+ }
264
+
265
+ // outer coords
266
+ verts[0].position = (SDL_FPoint){.x = x - half_thick, .y = y - half_thick};
267
+ verts[1].position =
268
+ (SDL_FPoint){.x = x + width + half_thick, .y = y - half_thick};
269
+ verts[2].position =
270
+ (SDL_FPoint){.x = x + width + half_thick, .y = y + height + half_thick};
271
+ verts[3].position =
272
+ (SDL_FPoint){.x = x - half_thick, .y = y + height + half_thick};
273
+
274
+ // inner coords
275
+ verts[4].position = (SDL_FPoint){.x = x + half_thick, .y = y + half_thick};
276
+ verts[5].position =
277
+ (SDL_FPoint){.x = x + width - half_thick, .y = y + half_thick};
278
+ verts[6].position =
279
+ (SDL_FPoint){.x = x + width - half_thick, .y = y + height - half_thick};
280
+ verts[7].position =
281
+ (SDL_FPoint){.x = x + half_thick, .y = y + height - half_thick};
282
+
283
+ int indices[] = {
284
+ 0, 4, 1, // top outer triangle
285
+ 4, 1, 5, // inner
286
+ 1, 5, 2, // right outer
287
+ 5, 2, 6, // inner
288
+ 2, 6, 3, // bottom outer
289
+ 6, 3, 7, // inner
290
+ 3, 7, 0, // left outer
291
+ 7, 0, 4 // inner
292
+ };
293
+ SDL_RenderGeometry(render, NULL, verts, 8, indices, 24);
294
+ }
295
+
296
+ /*
297
+ * Draw a thick ellipse on a canvas using a pre-converted RGBA colour value.
298
+ * @param [int] thickness must be > 1, else does nothing
299
+ */
300
+ void R2D_Canvas_DrawThickEllipse(SDL_Renderer *render, int x, int y,
301
+ float xradius, float yradius, float sectors,
302
+ int thickness, int r, int g, int b, int a)
303
+ {
304
+ if (thickness <= 1) {
305
+ return;
306
+ }
307
+
308
+ // renders a thick circle by treating each segment as a monotonic quad
309
+ // and rendering as two triangles per segment
310
+ SDL_Vertex verts[4];
311
+
312
+ // colour all vertices
313
+ verts[3].color = verts[2].color = verts[1].color = verts[0].color =
314
+ (SDL_Color){.r = r, .g = g, .b = b, .a = a};
315
+ float half_thick = thickness / 2.0f;
316
+ SDL_FPoint outer_radius = {.x = xradius + half_thick,
317
+ .y = yradius + half_thick};
318
+ SDL_FPoint inner_radius = {.x = xradius - half_thick,
319
+ .y = yradius - half_thick};
320
+ float cache_cosf = cosf(0), cache_sinf = sinf(0);
321
+ float unit_angle = 2 * M_PI / sectors;
322
+
323
+ int indices[] = {0, 1, 3, 3, 1, 2};
324
+
325
+ // point at 0 radians
326
+ verts[0].position = (SDL_FPoint){.x = x + outer_radius.x * cache_cosf,
327
+ .y = y + outer_radius.y * cache_sinf};
328
+ verts[3].position = (SDL_FPoint){.x = x + inner_radius.x * cache_cosf,
329
+ .y = y + inner_radius.y * cache_sinf};
330
+ for (float i = 1; i <= sectors; i++) {
331
+ float angle = i * unit_angle;
332
+ // re-use index 0 and 3 from previous calculation
333
+ verts[1].position = verts[0].position;
334
+ verts[2].position = verts[3].position;
335
+ // calculate new index 0 and 3 values
336
+ cache_cosf = cosf(angle);
337
+ cache_sinf = sinf(angle);
338
+ verts[0].position = (SDL_FPoint){.x = x + outer_radius.x * cache_cosf,
339
+ .y = y + outer_radius.y * cache_sinf};
340
+ verts[3].position = (SDL_FPoint){.x = x + inner_radius.x * cache_cosf,
341
+ .y = y + inner_radius.y * cache_sinf};
342
+ SDL_RenderGeometry(render, NULL, verts, 4, indices, 6);
343
+ }
344
+ }
345
+
346
+ /*
347
+ * Draw a thin (single pixel) ellipse on a canvas using a pre-converted RGBA
348
+ * colour value.
349
+ */
350
+ void R2D_Canvas_DrawThinEllipse(SDL_Renderer *render, int x, int y,
351
+ float xradius, float yradius, float sectors,
352
+ int r, int g, int b, int a)
353
+ {
354
+ float unit_angle = 2 * M_PI / sectors;
355
+ // point at 0 radians
356
+ float x1 = x + xradius * cosf(0);
357
+ float y1 = y + yradius * sinf(0);
358
+ SDL_SetRenderDrawColor(render, r, g, b, a);
359
+ for (float i = 1; i <= sectors; i++) {
360
+ float angle = i * unit_angle;
361
+ // re-use from previous calculation
362
+ float x2 = x1;
363
+ float y2 = y1;
364
+ // calculate new point
365
+ x1 = x + xradius * cosf(angle);
366
+ y1 = y + yradius * sinf(angle);
367
+ SDL_RenderDrawLine(render, x1, y1, x2, y2);
368
+ }
369
+ }
370
+
371
+ /*
372
+ * Compute the intersection between two lines represented by the input line
373
+ * segments. Unlike a typical line segment collision detector, this function
374
+ * will find a possible intersection point even if that point is not on either
375
+ * of the input line "segments". This helps find where two line segments "would"
376
+ * intersect if they were long enough, in addition to the case when the segments
377
+ * intersect.
378
+ * @param line1_p1
379
+ * @param line1_p2
380
+ * @param line2_p1
381
+ * @param line2_p2
382
+ * @param intersection Pointer into which to write the point of intersection.
383
+ * @return true if an intersection is found, false if the lines are parallel
384
+ * (collinear).
385
+ */
386
+ static bool intersect_two_lines(const vector_t *line1_p1,
387
+ const vector_t *line1_p2,
388
+ const vector_t *line2_p1,
389
+ const vector_t *line2_p2,
390
+ vector_t *intersection)
391
+ {
392
+ vector_t alpha = {.x = line1_p2->x - line1_p1->x,
393
+ .y = line1_p2->y - line1_p1->y};
394
+ vector_t beta = {.x = line2_p1->x - line2_p2->x,
395
+ .y = line2_p1->y - line2_p2->y};
396
+ float denom = (alpha.y * beta.x) - (alpha.x * beta.y);
397
+
398
+ if (denom == 0)
399
+ return false; // collinear
400
+
401
+ vector_t theta = {.x = line1_p1->x - line2_p1->x,
402
+ .y = line1_p1->y - line2_p1->y};
403
+ float alpha_numerator = beta.y * theta.x - (beta.x * theta.y);
404
+
405
+ intersection->x = alpha.x;
406
+ intersection->y = alpha.y;
407
+ vector_times_scalar(intersection, alpha_numerator / denom);
408
+ vector_plus_vector(intersection, line1_p1);
409
+ return true;
410
+ }
411
+
412
+ #define POLYLINE_RENDER_NVERTS 6
413
+ #define POLYLINE_RENDER_NINDICES 6
414
+
415
+ /*
416
+ * Draw a thick N-point polyline, with a mitre join where two
417
+ * segments are joined.
418
+ * @param [int] thickness must be > 1, else does nothing
419
+ */
420
+ void R2D_Canvas_DrawThickPolyline(SDL_Renderer *render, SDL_FPoint *points,
421
+ int num_points, int thickness, int r, int g,
422
+ int b, int a, bool skip_first_last)
423
+ {
424
+ if (thickness <= 1)
425
+ return;
426
+ if (num_points < 3)
427
+ return;
428
+
429
+ float thick_half = thickness / 2.0f;
430
+
431
+ // Prepare to store the different points used map
432
+ // the triangles that render the thick polyline
433
+ SDL_Vertex verts[POLYLINE_RENDER_NVERTS];
434
+
435
+ // all points have the same colour so
436
+ for (int i = 0; i < POLYLINE_RENDER_NVERTS; i++) {
437
+ verts[i].color = (SDL_Color){.r = r, .g = g, .b = b, .a = a};
438
+ }
439
+
440
+ // the indices into the vertex, always the same two triangles
441
+ const int indices[] = {
442
+ 0, 1, 2, // left outer triangle
443
+ 0, 2, 3, // left inner triangle
444
+ };
445
+
446
+ // Setup the first segment
447
+ int x1 = points[0].x, y1 = points[0].y;
448
+ int x2 = points[1].x, y2 = points[1].y;
449
+
450
+ // calculate the unit perpendicular for each of the line segments
451
+ vector_t vec_one_perp = {.x = (x2 - x1), .y = (y2 - y1)};
452
+ vector_times_scalar(vector_normalize(vector_perpendicular(&vec_one_perp)),
453
+ thick_half);
454
+
455
+ // left outer bottom
456
+ verts[0].position =
457
+ (SDL_FPoint){.x = x1 + vec_one_perp.x, .y = y1 + vec_one_perp.y};
458
+ // left outer top
459
+ verts[1].position =
460
+ (SDL_FPoint){.x = x2 + vec_one_perp.x, .y = y2 + vec_one_perp.y};
461
+ // left inner top
462
+ verts[2].position =
463
+ (SDL_FPoint){.x = x2 - vec_one_perp.x, .y = y2 - vec_one_perp.y};
464
+ // left inner bottom
465
+ verts[3].position =
466
+ (SDL_FPoint){.x = x1 - vec_one_perp.x, .y = y1 - vec_one_perp.y};
467
+
468
+ //
469
+ // go through each subsequent point to work with the two segments and
470
+ // figure out how they join, and then render the
471
+ // left segment.
472
+ // then shift the vertices left to work on the next and so on
473
+ // until we have one last segment left after the loop is done
474
+ for (int pix = 2; pix < num_points; pix++) {
475
+
476
+ int x3 = points[pix].x, y3 = points[pix].y;
477
+ if (x3 == x2 && y3 == y2)
478
+ continue;
479
+
480
+ vector_t vec_two_perp = {.x = (x3 - x2), .y = (y3 - y2)};
481
+ vector_times_scalar(vector_normalize(vector_perpendicular(&vec_two_perp)),
482
+ thick_half);
483
+
484
+ // right inner bottom
485
+ verts[4].position =
486
+ (SDL_FPoint){.x = x3 - vec_two_perp.x, .y = y3 - vec_two_perp.y};
487
+ // right outer bottom
488
+ verts[5].position =
489
+ (SDL_FPoint){.x = x3 + vec_two_perp.x, .y = y3 + vec_two_perp.y};
490
+
491
+ // temporarily calculate the "right inner top" to
492
+ // figure out the intersection with the "left inner top" which
493
+ vector_t tmp = {.x = x2 - vec_two_perp.x, .y = y2 - vec_two_perp.y};
494
+ // find intersection of the left/right inner lines
495
+ bool has_intersect = intersect_two_lines(
496
+ &verts[3].position, &verts[2].position, // left inner line
497
+ &verts[4].position, &tmp, // right inner line
498
+ &verts[2].position // over-write with intersection
499
+ );
500
+
501
+ if (has_intersect) {
502
+ // not collinear
503
+ // adjust the "left outer top" point so that it's distance from (x2, y2)
504
+ // is the same as the left/right "inner top" intersection we calculated
505
+ // above
506
+ tmp = (vector_t){.x = x2, .y = y2};
507
+ vector_minus_vector(&tmp, &verts[2].position);
508
+ verts[1].position = (SDL_FPoint){.x = x2 + tmp.x, .y = y2 + tmp.y};
509
+ }
510
+ //
511
+ // TODO: handle degenerate case that can result in crazy long mitre join
512
+ // point
513
+ //
514
+ if (pix > 2 || !skip_first_last) {
515
+ // we only render the "left" segment of this particular segment pair
516
+ SDL_RenderGeometry(render, NULL, verts, POLYLINE_RENDER_NVERTS, indices,
517
+ POLYLINE_RENDER_NINDICES);
518
+ }
519
+
520
+ // shift left
521
+ // i.e. (x2, y2) becomes the first point in the next triple
522
+ // (x3, y3) becomes the second point
523
+ // and their respective calculated thick corners are shifted as well
524
+ // ans t
525
+ x1 = x2;
526
+ y1 = y2;
527
+ x2 = x3;
528
+ y2 = y3;
529
+ verts[0].position = verts[1].position;
530
+ verts[3].position = verts[2].position;
531
+ verts[2].position = verts[4].position;
532
+ verts[1].position = verts[5].position;
533
+ }
534
+
535
+ if (!skip_first_last) {
536
+ // we render the last segment.
537
+ SDL_RenderGeometry(render, NULL, verts, POLYLINE_RENDER_NVERTS, indices,
538
+ POLYLINE_RENDER_NINDICES);
539
+ }
540
+ }
@@ -75,19 +75,38 @@ def set_rpi_flags
75
75
  end
76
76
 
77
77
 
78
+ # Set flags for Linux and BSD
79
+ def set_linux_bsd_flags
80
+ check_sdl
81
+ set_rpi_flags
82
+ add_flags(:ld, "-lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lm")
83
+ if $RUBY2D_PLATFORM == :linux then add_flags(:ld, '-lGL') end
84
+ end
85
+
86
+
78
87
  # Use SDL and other libraries installed by the user (not those bundled with the gem)
79
88
  def use_usr_libs
80
- # Add flags
81
- set_rpi_flags
82
- add_flags(:c, '-I/usr/local/include')
89
+ case $RUBY2D_PLATFORM
90
+ when :macos
91
+ add_flags(:c, `sdl2-config --cflags`)
92
+ add_flags(:c, '-I/opt/homebrew/include')
93
+ add_flags(:ld, `sdl2-config --libs`)
94
+ add_flags(:ld, '-lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf')
95
+ add_flags(:ld, '-Wl,-framework,OpenGL')
96
+ when :windows
97
+ add_flags(:ld, '-lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf')
98
+ add_flags(:ld, '-lopengl32 -lglew32')
99
+ when :linux_rpi
100
+ set_linux_bsd_flags
101
+ end
83
102
  end
84
103
 
85
104
 
86
105
  # Configure native extension ###################################################
87
106
 
88
107
  # Build Ruby 2D native extention using libraries installed by user
89
- # To use install flag: `gem install ruby2d -- libs`
90
- if ARGV.include? 'libs'
108
+ # To use install flag: `gem install ruby2d -- dev`
109
+ if ARGV.include? 'dev'
91
110
  use_usr_libs
92
111
 
93
112
  # Use libraries provided by the gem (default)
@@ -101,25 +120,20 @@ else
101
120
  ldir = "#{Dir.pwd}/../../assets/macos/universal/lib"
102
121
 
103
122
  add_flags(:ld, "#{ldir}/libSDL2.a #{ldir}/libSDL2_image.a #{ldir}/libSDL2_mixer.a #{ldir}/libSDL2_ttf.a")
104
- add_flags(:ld, "#{ldir}/libjpeg.a #{ldir}/libpng16.a #{ldir}/libtiff.a #{ldir}/libwebp.a")
123
+ add_flags(:ld, "#{ldir}/libjpeg.a #{ldir}/libjxl.a #{ldir}/libavif.a #{ldir}/libzstd.a #{ldir}/libbrotlicommon-static.a #{ldir}/libbrotlidec-static.a #{ldir}/libhwy.a #{ldir}/libpng.a #{ldir}/libtiff.a #{ldir}/libwebp.a")
105
124
  add_flags(:ld, "#{ldir}/libmpg123.a #{ldir}/libogg.a #{ldir}/libFLAC.a #{ldir}/libvorbis.a #{ldir}/libvorbisfile.a #{ldir}/libmodplug.a")
106
125
  add_flags(:ld, "#{ldir}/libfreetype.a #{ldir}/libharfbuzz.a #{ldir}/libgraphite2.a")
107
- add_flags(:ld, "-Wl,-framework,Cocoa -Wl,-framework,GameController -Wl,-framework,ForceFeedback")
108
-
109
- # Delete the quarantine attribute on the mruby compiler executable
110
- # (This may not be needed)
111
- # system "xattr -d com.apple.quarantine #{Dir.pwd}/../../assets/macos/universal/bin/mrbc"
112
-
113
- when :linux, :linux_rpi, :bsd
114
- check_sdl
115
-
116
- set_rpi_flags
117
- add_flags(:ld, "-lSDL2 -lSDL2_image -lSDL2_mixer -lSDL2_ttf -lm")
118
- if $RUBY2D_PLATFORM == :linux then add_flags(:ld, '-lGL') end
126
+ add_flags(:ld, "-lz -lbz2 -liconv -lstdc++")
127
+ add_flags(:ld, "-Wl,-framework,Cocoa -Wl,-framework,Carbon -Wl,-framework,GameController -Wl,-framework,ForceFeedback -Wl,-framework,OpenGL -Wl,-framework,AudioToolbox -Wl,-framework,CoreAudio -Wl,-framework,IOKit -Wl,-framework,CoreHaptics -Wl,-framework,CoreVideo -Wl,-framework,Metal")
119
128
 
120
129
  when :windows
121
130
  add_flags(:c, '-I../../assets/include')
122
- ldir = "#{Dir.pwd}/../../assets/windows/mingw-w64-x86_64/lib"
131
+
132
+ if RUBY_PLATFORM =~ /ucrt/
133
+ ldir = "#{Dir.pwd}/../../assets/windows/mingw-w64-ucrt-x86_64/lib"
134
+ else
135
+ ldir = "#{Dir.pwd}/../../assets/windows/mingw-w64-x86_64/lib"
136
+ end
123
137
 
124
138
  # Start linker flags (needed to avoid circular dependencies)
125
139
  add_flags(:ld, "-Wl,--start-group")
@@ -129,8 +143,8 @@ else
129
143
 
130
144
  # SDL2_image
131
145
  add_flags(:ld, "#{ldir}/libSDL2_image.a")
132
- add_flags(:ld, "#{ldir}/libjpeg.a #{ldir}/libpng16.a #{ldir}/libtiff.a #{ldir}/libwebp.a")
133
- add_flags(:ld, "#{ldir}/libjbig.a #{ldir}/libdeflate.a #{ldir}/liblzma.a #{ldir}/libzstd.a #{ldir}/libLerc.a")
146
+ add_flags(:ld, "#{ldir}/libjpeg.a #{ldir}/libpng.a #{ldir}/libtiff.a #{ldir}/libwebp.a")
147
+ add_flags(:ld, "#{ldir}/libjxl.a #{ldir}/libhwy.a #{ldir}/libjbig.a #{ldir}/libdeflate.a #{ldir}/liblzma.a #{ldir}/libzstd.a #{ldir}/libLerc.a")
134
148
 
135
149
  # SDL2_mixer
136
150
  add_flags(:ld, "#{ldir}/libSDL2_mixer.a")
@@ -149,12 +163,16 @@ else
149
163
  # End linker flags
150
164
  add_flags(:ld, "-Wl,--end-group")
151
165
 
166
+ when :linux, :linux_rpi, :bsd
167
+ set_linux_bsd_flags
168
+
152
169
  # If can't detect the platform, use libraries installed by the user
153
170
  else
154
171
  use_usr_libs
155
172
  end
156
173
  end
157
174
 
175
+ $CFLAGS.gsub!(/\n/, ' ') # remove newlines in flags, they can cause problems
158
176
  $LDFLAGS.gsub!(/\n/, ' ') # remove newlines in flags, they can cause problems
159
177
 
160
178
  # Create Makefile
data/ext/ruby2d/gl.c CHANGED
@@ -299,7 +299,7 @@ int R2D_GL_Init(R2D_Window *window) {
299
299
  /*
300
300
  * Creates a texture for rendering
301
301
  */
302
- void R2D_GL_CreateTexture(GLuint *id, GLint format,
302
+ void R2D_GL_CreateTexture(GLuint *id, GLint internalFormat, GLint format, GLenum type,
303
303
  int w, int h,
304
304
  const GLvoid *data, GLint filter) {
305
305
 
@@ -311,8 +311,8 @@ void R2D_GL_CreateTexture(GLuint *id, GLint format,
311
311
 
312
312
  // Specifies the 2D texture image
313
313
  glTexImage2D(
314
- GL_TEXTURE_2D, 0, format, w, h,
315
- 0, format, GL_UNSIGNED_BYTE, data
314
+ GL_TEXTURE_2D, 0, internalFormat, w, h,
315
+ 0, format, type, data
316
316
  );
317
317
 
318
318
  // Set the filtering mode
data/ext/ruby2d/image.c CHANGED
@@ -14,15 +14,15 @@ SDL_Surface *R2D_CreateImageSurface(const char *path) {
14
14
 
15
15
  // Load image from file as SDL_Surface
16
16
  SDL_Surface *surface = IMG_Load(path);
17
+ if (surface != NULL) {
18
+ int bits_per_color = surface->format->Amask == 0 ?
19
+ surface->format->BitsPerPixel / 3 :
20
+ surface->format->BitsPerPixel / 4;
17
21
 
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);
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
+ }
24
25
  }
25
-
26
26
  return surface;
27
27
  }
28
28