ruby2d-rpeck-windows 0.11.1

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 (289) hide show
  1. checksums.yaml +7 -0
  2. data/assets/README.md +22 -0
  3. data/assets/Rakefile +85 -0
  4. data/assets/app.icns +0 -0
  5. data/assets/include/SDL2/SDL.h +138 -0
  6. data/assets/include/SDL2/SDL_assert.h +293 -0
  7. data/assets/include/SDL2/SDL_atomic.h +295 -0
  8. data/assets/include/SDL2/SDL_audio.h +859 -0
  9. data/assets/include/SDL2/SDL_bits.h +121 -0
  10. data/assets/include/SDL2/SDL_blendmode.h +123 -0
  11. data/assets/include/SDL2/SDL_clipboard.h +71 -0
  12. data/assets/include/SDL2/SDL_config.h +55 -0
  13. data/assets/include/SDL2/SDL_config_android.h +182 -0
  14. data/assets/include/SDL2/SDL_config_iphoneos.h +207 -0
  15. data/assets/include/SDL2/SDL_config_macosx.h +266 -0
  16. data/assets/include/SDL2/SDL_config_minimal.h +85 -0
  17. data/assets/include/SDL2/SDL_config_os2.h +188 -0
  18. data/assets/include/SDL2/SDL_config_pandora.h +135 -0
  19. data/assets/include/SDL2/SDL_config_psp.h +165 -0
  20. data/assets/include/SDL2/SDL_config_windows.h +288 -0
  21. data/assets/include/SDL2/SDL_config_winrt.h +243 -0
  22. data/assets/include/SDL2/SDL_config_wiz.h +149 -0
  23. data/assets/include/SDL2/SDL_copying.h +20 -0
  24. data/assets/include/SDL2/SDL_cpuinfo.h +299 -0
  25. data/assets/include/SDL2/SDL_egl.h +1676 -0
  26. data/assets/include/SDL2/SDL_endian.h +263 -0
  27. data/assets/include/SDL2/SDL_error.h +112 -0
  28. data/assets/include/SDL2/SDL_events.h +827 -0
  29. data/assets/include/SDL2/SDL_filesystem.h +136 -0
  30. data/assets/include/SDL2/SDL_gamecontroller.h +541 -0
  31. data/assets/include/SDL2/SDL_gesture.h +87 -0
  32. data/assets/include/SDL2/SDL_haptic.h +1247 -0
  33. data/assets/include/SDL2/SDL_hints.h +1578 -0
  34. data/assets/include/SDL2/SDL_image.h +161 -0
  35. data/assets/include/SDL2/SDL_joystick.h +499 -0
  36. data/assets/include/SDL2/SDL_keyboard.h +217 -0
  37. data/assets/include/SDL2/SDL_keycode.h +351 -0
  38. data/assets/include/SDL2/SDL_loadso.h +81 -0
  39. data/assets/include/SDL2/SDL_locale.h +101 -0
  40. data/assets/include/SDL2/SDL_log.h +211 -0
  41. data/assets/include/SDL2/SDL_main.h +180 -0
  42. data/assets/include/SDL2/SDL_messagebox.h +146 -0
  43. data/assets/include/SDL2/SDL_metal.h +117 -0
  44. data/assets/include/SDL2/SDL_misc.h +75 -0
  45. data/assets/include/SDL2/SDL_mixer.h +651 -0
  46. data/assets/include/SDL2/SDL_mouse.h +302 -0
  47. data/assets/include/SDL2/SDL_mutex.h +251 -0
  48. data/assets/include/SDL2/SDL_name.h +33 -0
  49. data/assets/include/SDL2/SDL_opengl.h +2183 -0
  50. data/assets/include/SDL2/SDL_opengl_glext.h +11180 -0
  51. data/assets/include/SDL2/SDL_opengles.h +39 -0
  52. data/assets/include/SDL2/SDL_opengles2.h +52 -0
  53. data/assets/include/SDL2/SDL_opengles2_gl2.h +621 -0
  54. data/assets/include/SDL2/SDL_opengles2_gl2ext.h +2050 -0
  55. data/assets/include/SDL2/SDL_opengles2_gl2platform.h +30 -0
  56. data/assets/include/SDL2/SDL_opengles2_khrplatform.h +282 -0
  57. data/assets/include/SDL2/SDL_pixels.h +479 -0
  58. data/assets/include/SDL2/SDL_platform.h +198 -0
  59. data/assets/include/SDL2/SDL_power.h +75 -0
  60. data/assets/include/SDL2/SDL_quit.h +58 -0
  61. data/assets/include/SDL2/SDL_rect.h +174 -0
  62. data/assets/include/SDL2/SDL_render.h +1158 -0
  63. data/assets/include/SDL2/SDL_revision.h +2 -0
  64. data/assets/include/SDL2/SDL_rwops.h +283 -0
  65. data/assets/include/SDL2/SDL_scancode.h +413 -0
  66. data/assets/include/SDL2/SDL_sensor.h +267 -0
  67. data/assets/include/SDL2/SDL_shape.h +144 -0
  68. data/assets/include/SDL2/SDL_stdinc.h +647 -0
  69. data/assets/include/SDL2/SDL_surface.h +563 -0
  70. data/assets/include/SDL2/SDL_system.h +325 -0
  71. data/assets/include/SDL2/SDL_syswm.h +354 -0
  72. data/assets/include/SDL2/SDL_test.h +69 -0
  73. data/assets/include/SDL2/SDL_test_assert.h +105 -0
  74. data/assets/include/SDL2/SDL_test_common.h +218 -0
  75. data/assets/include/SDL2/SDL_test_compare.h +69 -0
  76. data/assets/include/SDL2/SDL_test_crc32.h +124 -0
  77. data/assets/include/SDL2/SDL_test_font.h +81 -0
  78. data/assets/include/SDL2/SDL_test_fuzzer.h +384 -0
  79. data/assets/include/SDL2/SDL_test_harness.h +134 -0
  80. data/assets/include/SDL2/SDL_test_images.h +78 -0
  81. data/assets/include/SDL2/SDL_test_log.h +67 -0
  82. data/assets/include/SDL2/SDL_test_md5.h +129 -0
  83. data/assets/include/SDL2/SDL_test_memory.h +63 -0
  84. data/assets/include/SDL2/SDL_test_random.h +115 -0
  85. data/assets/include/SDL2/SDL_thread.h +366 -0
  86. data/assets/include/SDL2/SDL_timer.h +115 -0
  87. data/assets/include/SDL2/SDL_touch.h +102 -0
  88. data/assets/include/SDL2/SDL_ttf.h +294 -0
  89. data/assets/include/SDL2/SDL_types.h +29 -0
  90. data/assets/include/SDL2/SDL_version.h +162 -0
  91. data/assets/include/SDL2/SDL_video.h +1282 -0
  92. data/assets/include/SDL2/SDL_vulkan.h +276 -0
  93. data/assets/include/SDL2/begin_code.h +166 -0
  94. data/assets/include/SDL2/close_code.h +40 -0
  95. data/assets/include/glew.h +23686 -0
  96. data/assets/ios/Assets.xcassets/AppIcon.appiconset/Contents.json +98 -0
  97. data/assets/ios/Assets.xcassets/Contents.json +6 -0
  98. data/assets/ios/Base.lproj/LaunchScreen.storyboard +27 -0
  99. data/assets/ios/Info.plist +43 -0
  100. data/assets/ios/MRuby.framework/Headers/mrbconf.h +143 -0
  101. data/assets/ios/MRuby.framework/Headers/mruby/array.h +280 -0
  102. data/assets/ios/MRuby.framework/Headers/mruby/boxing_nan.h +102 -0
  103. data/assets/ios/MRuby.framework/Headers/mruby/boxing_no.h +56 -0
  104. data/assets/ios/MRuby.framework/Headers/mruby/boxing_word.h +144 -0
  105. data/assets/ios/MRuby.framework/Headers/mruby/class.h +97 -0
  106. data/assets/ios/MRuby.framework/Headers/mruby/common.h +77 -0
  107. data/assets/ios/MRuby.framework/Headers/mruby/compile.h +195 -0
  108. data/assets/ios/MRuby.framework/Headers/mruby/data.h +75 -0
  109. data/assets/ios/MRuby.framework/Headers/mruby/debug.h +67 -0
  110. data/assets/ios/MRuby.framework/Headers/mruby/dump.h +196 -0
  111. data/assets/ios/MRuby.framework/Headers/mruby/error.h +75 -0
  112. data/assets/ios/MRuby.framework/Headers/mruby/gc.h +91 -0
  113. data/assets/ios/MRuby.framework/Headers/mruby/hash.h +215 -0
  114. data/assets/ios/MRuby.framework/Headers/mruby/irep.h +75 -0
  115. data/assets/ios/MRuby.framework/Headers/mruby/istruct.h +47 -0
  116. data/assets/ios/MRuby.framework/Headers/mruby/khash.h +274 -0
  117. data/assets/ios/MRuby.framework/Headers/mruby/numeric.h +161 -0
  118. data/assets/ios/MRuby.framework/Headers/mruby/object.h +44 -0
  119. data/assets/ios/MRuby.framework/Headers/mruby/opcode.h +69 -0
  120. data/assets/ios/MRuby.framework/Headers/mruby/ops.h +117 -0
  121. data/assets/ios/MRuby.framework/Headers/mruby/proc.h +131 -0
  122. data/assets/ios/MRuby.framework/Headers/mruby/range.h +49 -0
  123. data/assets/ios/MRuby.framework/Headers/mruby/re.h +16 -0
  124. data/assets/ios/MRuby.framework/Headers/mruby/string.h +444 -0
  125. data/assets/ios/MRuby.framework/Headers/mruby/throw.h +55 -0
  126. data/assets/ios/MRuby.framework/Headers/mruby/value.h +309 -0
  127. data/assets/ios/MRuby.framework/Headers/mruby/variable.h +136 -0
  128. data/assets/ios/MRuby.framework/Headers/mruby/version.h +110 -0
  129. data/assets/ios/MRuby.framework/Headers/mruby.h +1282 -0
  130. data/assets/ios/MRuby.framework/Info.plist +20 -0
  131. data/assets/ios/MRuby.framework/MRuby +0 -0
  132. data/assets/ios/MyApp.xcodeproj/project.pbxproj +368 -0
  133. data/assets/ios/MyApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  134. data/assets/ios/MyApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  135. data/assets/ios/MyApp.xcodeproj/project.xcworkspace/xcshareddata/MyApp.xcscmblueprint +30 -0
  136. data/assets/ios/main.c +1 -0
  137. data/assets/macos/lib/libFLAC.a +0 -0
  138. data/assets/macos/lib/libSDL2.a +0 -0
  139. data/assets/macos/lib/libSDL2_image.a +0 -0
  140. data/assets/macos/lib/libSDL2_mixer.a +0 -0
  141. data/assets/macos/lib/libSDL2_ttf.a +0 -0
  142. data/assets/macos/lib/libfreetype.a +0 -0
  143. data/assets/macos/lib/libjpeg.a +0 -0
  144. data/assets/macos/lib/libmodplug.a +0 -0
  145. data/assets/macos/lib/libmpg123.a +0 -0
  146. data/assets/macos/lib/libogg.a +0 -0
  147. data/assets/macos/lib/libpng16.a +0 -0
  148. data/assets/macos/lib/libtiff.a +0 -0
  149. data/assets/macos/lib/libvorbis.a +0 -0
  150. data/assets/macos/lib/libvorbisfile.a +0 -0
  151. data/assets/macos/lib/libwebp.a +0 -0
  152. data/assets/mingw/bin/SDL2.dll +0 -0
  153. data/assets/mingw/bin/SDL2_image.dll +0 -0
  154. data/assets/mingw/bin/SDL2_mixer.dll +0 -0
  155. data/assets/mingw/bin/SDL2_ttf.dll +0 -0
  156. data/assets/mingw/bin/glew32.dll +0 -0
  157. data/assets/mingw/bin/libFLAC-8.dll +0 -0
  158. data/assets/mingw/bin/libfreetype-6.dll +0 -0
  159. data/assets/mingw/bin/libjpeg-9.dll +0 -0
  160. data/assets/mingw/bin/libmodplug-1.dll +0 -0
  161. data/assets/mingw/bin/libmpg123-0.dll +0 -0
  162. data/assets/mingw/bin/libogg-0.dll +0 -0
  163. data/assets/mingw/bin/libopus-0.dll +0 -0
  164. data/assets/mingw/bin/libopusfile-0.dll +0 -0
  165. data/assets/mingw/bin/libpng16-16.dll +0 -0
  166. data/assets/mingw/bin/libtiff-5.dll +0 -0
  167. data/assets/mingw/bin/libvorbis-0.dll +0 -0
  168. data/assets/mingw/bin/libvorbisfile-3.dll +0 -0
  169. data/assets/mingw/bin/libwebp-7.dll +0 -0
  170. data/assets/mingw/bin/libwinpthread-1.dll +0 -0
  171. data/assets/mingw/bin/zlib1.dll +0 -0
  172. data/assets/mingw/lib/libSDL2.a +0 -0
  173. data/assets/mingw/lib/libSDL2.dll.a +0 -0
  174. data/assets/mingw/lib/libSDL2_image.a +0 -0
  175. data/assets/mingw/lib/libSDL2_image.dll.a +0 -0
  176. data/assets/mingw/lib/libSDL2_mixer.a +0 -0
  177. data/assets/mingw/lib/libSDL2_mixer.dll.a +0 -0
  178. data/assets/mingw/lib/libSDL2_test.a +0 -0
  179. data/assets/mingw/lib/libSDL2_ttf.a +0 -0
  180. data/assets/mingw/lib/libSDL2_ttf.dll.a +0 -0
  181. data/assets/mingw/lib/libSDL2main.a +0 -0
  182. data/assets/mingw/lib/libglew32.a +0 -0
  183. data/assets/mingw/lib/libglew32.dll.a +0 -0
  184. data/assets/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Contents.json +16 -0
  185. data/assets/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Contents.json +6 -0
  186. data/assets/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Contents.json +17 -0
  187. data/assets/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Content.imageset/Contents.json +16 -0
  188. data/assets/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Contents.json +6 -0
  189. data/assets/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json +16 -0
  190. data/assets/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Contents.json +6 -0
  191. data/assets/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Contents.json +16 -0
  192. data/assets/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Contents.json +6 -0
  193. data/assets/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Contents.json +17 -0
  194. data/assets/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Content.imageset/Contents.json +16 -0
  195. data/assets/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Contents.json +6 -0
  196. data/assets/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json +16 -0
  197. data/assets/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Contents.json +6 -0
  198. data/assets/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json +32 -0
  199. data/assets/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json +16 -0
  200. data/assets/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json +16 -0
  201. data/assets/tvos/Assets.xcassets/Contents.json +6 -0
  202. data/assets/tvos/Assets.xcassets/LaunchImage.launchimage/Contents.json +22 -0
  203. data/assets/tvos/Info.plist +30 -0
  204. data/assets/tvos/MRuby.framework/Headers/mrbconf.h +143 -0
  205. data/assets/tvos/MRuby.framework/Headers/mruby/array.h +280 -0
  206. data/assets/tvos/MRuby.framework/Headers/mruby/boxing_nan.h +102 -0
  207. data/assets/tvos/MRuby.framework/Headers/mruby/boxing_no.h +56 -0
  208. data/assets/tvos/MRuby.framework/Headers/mruby/boxing_word.h +144 -0
  209. data/assets/tvos/MRuby.framework/Headers/mruby/class.h +97 -0
  210. data/assets/tvos/MRuby.framework/Headers/mruby/common.h +77 -0
  211. data/assets/tvos/MRuby.framework/Headers/mruby/compile.h +195 -0
  212. data/assets/tvos/MRuby.framework/Headers/mruby/data.h +75 -0
  213. data/assets/tvos/MRuby.framework/Headers/mruby/debug.h +67 -0
  214. data/assets/tvos/MRuby.framework/Headers/mruby/dump.h +196 -0
  215. data/assets/tvos/MRuby.framework/Headers/mruby/error.h +75 -0
  216. data/assets/tvos/MRuby.framework/Headers/mruby/gc.h +91 -0
  217. data/assets/tvos/MRuby.framework/Headers/mruby/hash.h +215 -0
  218. data/assets/tvos/MRuby.framework/Headers/mruby/irep.h +75 -0
  219. data/assets/tvos/MRuby.framework/Headers/mruby/istruct.h +47 -0
  220. data/assets/tvos/MRuby.framework/Headers/mruby/khash.h +274 -0
  221. data/assets/tvos/MRuby.framework/Headers/mruby/numeric.h +161 -0
  222. data/assets/tvos/MRuby.framework/Headers/mruby/object.h +44 -0
  223. data/assets/tvos/MRuby.framework/Headers/mruby/opcode.h +69 -0
  224. data/assets/tvos/MRuby.framework/Headers/mruby/ops.h +117 -0
  225. data/assets/tvos/MRuby.framework/Headers/mruby/proc.h +131 -0
  226. data/assets/tvos/MRuby.framework/Headers/mruby/range.h +49 -0
  227. data/assets/tvos/MRuby.framework/Headers/mruby/re.h +16 -0
  228. data/assets/tvos/MRuby.framework/Headers/mruby/string.h +444 -0
  229. data/assets/tvos/MRuby.framework/Headers/mruby/throw.h +55 -0
  230. data/assets/tvos/MRuby.framework/Headers/mruby/value.h +309 -0
  231. data/assets/tvos/MRuby.framework/Headers/mruby/variable.h +136 -0
  232. data/assets/tvos/MRuby.framework/Headers/mruby/version.h +110 -0
  233. data/assets/tvos/MRuby.framework/Headers/mruby.h +1282 -0
  234. data/assets/tvos/MRuby.framework/Info.plist +20 -0
  235. data/assets/tvos/MRuby.framework/MRuby +0 -0
  236. data/assets/tvos/MyApp.xcodeproj/project.pbxproj +350 -0
  237. data/assets/tvos/MyApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -0
  238. data/assets/tvos/MyApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  239. data/assets/tvos/MyApp.xcodeproj/project.xcworkspace/xcshareddata/MyApp.xcscmblueprint +30 -0
  240. data/assets/tvos/main.c +1 -0
  241. data/bin/ruby2d +142 -0
  242. data/ext/ruby2d/common.c +185 -0
  243. data/ext/ruby2d/controllers.c +110 -0
  244. data/ext/ruby2d/extconf.rb +147 -0
  245. data/ext/ruby2d/font.c +35 -0
  246. data/ext/ruby2d/gl.c +398 -0
  247. data/ext/ruby2d/gl2.c +86 -0
  248. data/ext/ruby2d/gl3.c +305 -0
  249. data/ext/ruby2d/gles.c +249 -0
  250. data/ext/ruby2d/image.c +58 -0
  251. data/ext/ruby2d/input.c +48 -0
  252. data/ext/ruby2d/music.c +127 -0
  253. data/ext/ruby2d/ruby2d.c +1374 -0
  254. data/ext/ruby2d/ruby2d.h +656 -0
  255. data/ext/ruby2d/shapes.c +154 -0
  256. data/ext/ruby2d/sound.c +118 -0
  257. data/ext/ruby2d/text.c +22 -0
  258. data/ext/ruby2d/window.c +414 -0
  259. data/lib/ruby2d/circle.rb +43 -0
  260. data/lib/ruby2d/cli/build.rb +237 -0
  261. data/lib/ruby2d/cli/colorize.rb +10 -0
  262. data/lib/ruby2d/cli/console.rb +65 -0
  263. data/lib/ruby2d/cli/enable_console.rb +5 -0
  264. data/lib/ruby2d/cli/launch.rb +50 -0
  265. data/lib/ruby2d/color.rb +136 -0
  266. data/lib/ruby2d/dsl.rb +46 -0
  267. data/lib/ruby2d/entity.rb +17 -0
  268. data/lib/ruby2d/exceptions.rb +6 -0
  269. data/lib/ruby2d/font.rb +96 -0
  270. data/lib/ruby2d/image.rb +58 -0
  271. data/lib/ruby2d/line.rb +89 -0
  272. data/lib/ruby2d/music.rb +67 -0
  273. data/lib/ruby2d/pixel.rb +17 -0
  274. data/lib/ruby2d/quad.rb +96 -0
  275. data/lib/ruby2d/rectangle.rb +65 -0
  276. data/lib/ruby2d/renderable.rb +40 -0
  277. data/lib/ruby2d/ruby2d.so +0 -0
  278. data/lib/ruby2d/sound.rb +55 -0
  279. data/lib/ruby2d/sprite.rb +232 -0
  280. data/lib/ruby2d/square.rb +37 -0
  281. data/lib/ruby2d/text.rb +76 -0
  282. data/lib/ruby2d/texture.rb +28 -0
  283. data/lib/ruby2d/tileset.rb +87 -0
  284. data/lib/ruby2d/triangle.rb +82 -0
  285. data/lib/ruby2d/version.rb +5 -0
  286. data/lib/ruby2d/vertices.rb +84 -0
  287. data/lib/ruby2d/window.rb +673 -0
  288. data/lib/ruby2d.rb +69 -0
  289. metadata +346 -0
@@ -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,118 @@
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 length in seconds
51
+ */
52
+ int R2D_GetSoundLength(R2D_Sound *snd) {
53
+ float points = 0;
54
+ float frames = 0;
55
+ int frequency = 0;
56
+ Uint16 format = 0;
57
+ int channels = 0;
58
+
59
+ // Populate the frequency, format and channel variables
60
+ if (!Mix_QuerySpec(&frequency, &format, &channels)) return -1; // Querying audio details failed
61
+ if (!snd) return -1;
62
+
63
+ // points = bytes / samplesize
64
+ points = (snd->data->alen / ((format & 0xFF) / 8));
65
+
66
+ // frames = sample points / channels
67
+ frames = (points / channels);
68
+
69
+ // frames / frequency is seconds of audio
70
+ return ceil(frames / frequency);
71
+ }
72
+
73
+
74
+ /*
75
+ * Get the sound's volume
76
+ */
77
+ int R2D_GetSoundVolume(R2D_Sound *snd) {
78
+ if (!snd) return -1;
79
+ return ceil(Mix_VolumeChunk(snd->data, -1) * (100.0 / MIX_MAX_VOLUME));
80
+ }
81
+
82
+
83
+ /*
84
+ * Set the sound's volume a given percentage
85
+ */
86
+ void R2D_SetSoundVolume(R2D_Sound *snd, int volume) {
87
+ if (!snd) return;
88
+ // Set volume to be a percentage of the maximum mix volume
89
+ Mix_VolumeChunk(snd->data, (volume / 100.0) * MIX_MAX_VOLUME);
90
+ }
91
+
92
+
93
+ /*
94
+ * Get the sound mixer volume
95
+ */
96
+ int R2D_GetSoundMixVolume() {
97
+ return ceil(Mix_Volume(-1, -1) * (100.0 / MIX_MAX_VOLUME));
98
+ }
99
+
100
+
101
+ /*
102
+ * Set the sound mixer volume a given percentage
103
+ */
104
+ void R2D_SetSoundMixVolume(int volume) {
105
+ // This sets the volume value across all channels
106
+ // Set volume to be a percentage of the maximum mix volume
107
+ Mix_Volume(-1, (volume / 100.0) * MIX_MAX_VOLUME);
108
+ }
109
+
110
+
111
+ /*
112
+ * Free the sound
113
+ */
114
+ void R2D_FreeSound(R2D_Sound *snd) {
115
+ if (!snd) return;
116
+ Mix_FreeChunk(snd->data);
117
+ free(snd);
118
+ }
data/ext/ruby2d/text.c ADDED
@@ -0,0 +1,22 @@
1
+ // text.c
2
+
3
+ #include "ruby2d.h"
4
+
5
+
6
+ /*
7
+ * Create a SDL_Surface that contains the pixel data to render text, given a font and message
8
+ */
9
+ SDL_Surface *R2D_TextCreateSurface(TTF_Font *font, const char *message) {
10
+ // `msg` cannot be an empty string or NULL for TTF_SizeText
11
+ if (message == NULL || strlen(message) == 0) message = " ";
12
+
13
+ SDL_Color color = {255, 255, 255};
14
+ SDL_Surface *surface = TTF_RenderUTF8_Blended(font, message, color);
15
+ if (!surface)
16
+ {
17
+ R2D_Error("TTF_RenderUTF8_Blended", TTF_GetError());
18
+ return NULL;
19
+ }
20
+
21
+ return surface;
22
+ }
@@ -0,0 +1,414 @@
1
+ // window.c
2
+
3
+ #include "ruby2d.h"
4
+
5
+
6
+ /*
7
+ * Create a window
8
+ */
9
+ R2D_Window *R2D_CreateWindow(const char *title, int width, int height,
10
+ R2D_Update update, R2D_Render render, int flags) {
11
+
12
+ R2D_Init();
13
+
14
+ SDL_DisplayMode dm;
15
+ SDL_GetCurrentDisplayMode(0, &dm);
16
+ R2D_Log(R2D_INFO, "Current display mode is %dx%dpx @ %dhz", dm.w, dm.h, dm.refresh_rate);
17
+
18
+ width = width == R2D_DISPLAY_WIDTH ? dm.w : width;
19
+ height = height == R2D_DISPLAY_HEIGHT ? dm.h : height;
20
+
21
+ // Allocate window and set default values
22
+ R2D_Window *window = (R2D_Window *) malloc(sizeof(R2D_Window));
23
+ window->sdl = NULL;
24
+ window->glcontext = NULL;
25
+ window->title = title;
26
+ window->width = width;
27
+ window->height = height;
28
+ window->orig_width = width;
29
+ window->orig_height = height;
30
+ window->viewport.width = width;
31
+ window->viewport.height = height;
32
+ window->viewport.mode = R2D_SCALE;
33
+ window->update = update;
34
+ window->render = render;
35
+ window->flags = flags;
36
+ window->on_key = NULL;
37
+ window->on_mouse = NULL;
38
+ window->on_controller = NULL;
39
+ window->vsync = true;
40
+ window->fps_cap = 60;
41
+ window->background.r = 0.0;
42
+ window->background.g = 0.0;
43
+ window->background.b = 0.0;
44
+ window->background.a = 1.0;
45
+ window->icon = NULL;
46
+ window->close = true;
47
+
48
+ // Return the window structure
49
+ return window;
50
+ }
51
+
52
+
53
+ /*
54
+ * Show the window
55
+ */
56
+ int R2D_Show(R2D_Window *window) {
57
+
58
+ if (!window) {
59
+ R2D_Error("R2D_Show", "Window cannot be shown (because it's NULL)");
60
+ return 1;
61
+ }
62
+
63
+ // Create SDL window
64
+ window->sdl = SDL_CreateWindow(
65
+ window->title, // title
66
+ SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, // window position
67
+ window->width, window->height, // window size
68
+ SDL_WINDOW_OPENGL | window->flags // flags
69
+ );
70
+
71
+ if (!window->sdl) R2D_Error("SDL_CreateWindow", SDL_GetError());
72
+ if (window->icon) R2D_SetIcon(window, window->icon);
73
+
74
+ // The window created by SDL might not actually be the requested size.
75
+ // If it's not the same, retrieve and store the actual window size.
76
+ int actual_width, actual_height;
77
+ SDL_GetWindowSize(window->sdl, &actual_width, &actual_height);
78
+
79
+ if ((window->width != actual_width) || (window->height != actual_height)) {
80
+ R2D_Log(R2D_INFO,
81
+ "Scaling window to %ix%i (requested size was %ix%i)",
82
+ actual_width, actual_height, window->width, window->height
83
+ );
84
+ window->width = actual_width;
85
+ window->height = actual_height;
86
+ window->orig_width = actual_width;
87
+ window->orig_height = actual_height;
88
+ }
89
+
90
+ // Set Up OpenGL /////////////////////////////////////////////////////////////
91
+
92
+ R2D_GL_Init(window);
93
+
94
+ // SDL 2.0.10 and macOS 10.15 fix ////////////////////////////////////////////
95
+
96
+ #if MACOS
97
+ SDL_SetWindowSize(window->sdl, window->width, window->height);
98
+ #endif
99
+
100
+ // Set Main Loop Data ////////////////////////////////////////////////////////
101
+
102
+ const Uint8 *key_state;
103
+
104
+ Uint32 frames = 0; // Total frames since start
105
+ Uint32 frames_last_sec = 0; // Frames in the last second
106
+ Uint32 start_ms = SDL_GetTicks(); // Elapsed time since start
107
+ Uint32 next_second_ms = SDL_GetTicks(); // The last time plus a second
108
+ Uint32 begin_ms = start_ms; // Time at beginning of loop
109
+ Uint32 end_ms; // Time at end of loop
110
+ Uint32 elapsed_ms; // Total elapsed time
111
+ Uint32 loop_ms; // Elapsed time of loop
112
+ int delay_ms; // Amount of delay to achieve desired frame rate
113
+ const double decay_rate = 0.5; // Determines how fast an average decays over time
114
+ double fps = window->fps_cap; // Moving average of actual FPS, initial value a guess
115
+
116
+ // Enable VSync
117
+ if (window->vsync) {
118
+ if (!SDL_SetHint(SDL_HINT_RENDER_VSYNC, "1")) {
119
+ R2D_Log(R2D_WARN, "VSync cannot be enabled");
120
+ }
121
+ }
122
+
123
+ window->close = false;
124
+
125
+ // Main Loop /////////////////////////////////////////////////////////////////
126
+
127
+ while (!window->close) {
128
+
129
+ // Clear Frame /////////////////////////////////////////////////////////////
130
+
131
+ R2D_GL_Clear(window->background);
132
+
133
+ // Set FPS /////////////////////////////////////////////////////////////////
134
+
135
+ frames++;
136
+ frames_last_sec++;
137
+ end_ms = SDL_GetTicks();
138
+ elapsed_ms = end_ms - start_ms;
139
+
140
+ // Calculate the frame rate using an exponential moving average
141
+ if (next_second_ms < end_ms) {
142
+ fps = decay_rate * fps + (1.0 - decay_rate) * frames_last_sec;
143
+ frames_last_sec = 0;
144
+ next_second_ms = SDL_GetTicks() + 1000;
145
+ }
146
+
147
+ loop_ms = end_ms - begin_ms;
148
+ delay_ms = (1000 / window->fps_cap) - loop_ms;
149
+
150
+ if (delay_ms < 0) delay_ms = 0;
151
+
152
+ // Note: `loop_ms + delay_ms` should equal `1000 / fps_cap`
153
+
154
+ SDL_Delay(delay_ms);
155
+ begin_ms = SDL_GetTicks();
156
+
157
+ // Handle Input and Window Events //////////////////////////////////////////
158
+
159
+ int mx, my; // mouse x, y coordinates
160
+
161
+ SDL_Event e;
162
+ while (SDL_PollEvent(&e)) {
163
+ switch (e.type) {
164
+
165
+ case SDL_KEYDOWN:
166
+ if (window->on_key && e.key.repeat == 0) {
167
+ R2D_Event event = {
168
+ .type = R2D_KEY_DOWN, .key = SDL_GetScancodeName(e.key.keysym.scancode)
169
+ };
170
+ window->on_key(event);
171
+ }
172
+ break;
173
+
174
+ case SDL_KEYUP:
175
+ if (window->on_key) {
176
+ R2D_Event event = {
177
+ .type = R2D_KEY_UP, .key = SDL_GetScancodeName(e.key.keysym.scancode)
178
+ };
179
+ window->on_key(event);
180
+ }
181
+ break;
182
+
183
+ case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP:
184
+ if (window->on_mouse) {
185
+ R2D_GetMouseOnViewport(window, e.button.x, e.button.y, &mx, &my);
186
+ R2D_Event event = {
187
+ .button = e.button.button, .x = mx, .y = my
188
+ };
189
+ event.type = e.type == SDL_MOUSEBUTTONDOWN ? R2D_MOUSE_DOWN : R2D_MOUSE_UP;
190
+ event.dblclick = e.button.clicks == 2 ? true : false;
191
+ window->on_mouse(event);
192
+ }
193
+ break;
194
+
195
+ case SDL_MOUSEWHEEL:
196
+ if (window->on_mouse) {
197
+ R2D_Event event = {
198
+ .type = R2D_MOUSE_SCROLL, .direction = e.wheel.direction,
199
+ .delta_x = e.wheel.x, .delta_y = -e.wheel.y
200
+ };
201
+ window->on_mouse(event);
202
+ }
203
+ break;
204
+
205
+ case SDL_MOUSEMOTION:
206
+ if (window->on_mouse) {
207
+ R2D_GetMouseOnViewport(window, e.motion.x, e.motion.y, &mx, &my);
208
+ R2D_Event event = {
209
+ .type = R2D_MOUSE_MOVE,
210
+ .x = mx, .y = my, .delta_x = e.motion.xrel, .delta_y = e.motion.yrel
211
+ };
212
+ window->on_mouse(event);
213
+ }
214
+ break;
215
+
216
+ case SDL_CONTROLLERAXISMOTION:
217
+ if (window->on_controller) {
218
+ R2D_Event event = {
219
+ .which = e.caxis.which, .type = R2D_AXIS,
220
+ .axis = e.caxis.axis, .value = e.caxis.value
221
+ };
222
+ window->on_controller(event);
223
+ }
224
+ break;
225
+
226
+ case SDL_JOYAXISMOTION:
227
+ if (window->on_controller && !R2D_IsController(e.jbutton.which)) {
228
+ R2D_Event event = {
229
+ .which = e.jaxis.which, .type = R2D_AXIS,
230
+ .axis = e.jaxis.axis, .value = e.jaxis.value
231
+ };
232
+ window->on_controller(event);
233
+ }
234
+ break;
235
+
236
+ case SDL_CONTROLLERBUTTONDOWN: case SDL_CONTROLLERBUTTONUP:
237
+ if (window->on_controller) {
238
+ R2D_Event event = {
239
+ .which = e.cbutton.which, .button = e.cbutton.button
240
+ };
241
+ event.type = e.type == SDL_CONTROLLERBUTTONDOWN ? R2D_BUTTON_DOWN : R2D_BUTTON_UP;
242
+ window->on_controller(event);
243
+ }
244
+ break;
245
+
246
+ case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP:
247
+ if (window->on_controller && !R2D_IsController(e.jbutton.which)) {
248
+ R2D_Event event = {
249
+ .which = e.jbutton.which, .button = e.jbutton.button
250
+ };
251
+ event.type = e.type == SDL_JOYBUTTONDOWN ? R2D_BUTTON_DOWN : R2D_BUTTON_UP;
252
+ window->on_controller(event);
253
+ }
254
+ break;
255
+
256
+ case SDL_JOYDEVICEADDED:
257
+ R2D_Log(R2D_INFO, "Controller connected (%i total)", SDL_NumJoysticks());
258
+ R2D_OpenControllers();
259
+ break;
260
+
261
+ case SDL_JOYDEVICEREMOVED:
262
+ if (R2D_IsController(e.jdevice.which)) {
263
+ R2D_Log(R2D_INFO, "Controller #%i: %s removed (%i remaining)", e.jdevice.which, SDL_GameControllerName(SDL_GameControllerFromInstanceID(e.jdevice.which)), SDL_NumJoysticks());
264
+ SDL_GameControllerClose(SDL_GameControllerFromInstanceID(e.jdevice.which));
265
+ } else {
266
+ R2D_Log(R2D_INFO, "Controller #%i: %s removed (%i remaining)", e.jdevice.which, SDL_JoystickName(SDL_JoystickFromInstanceID(e.jdevice.which)), SDL_NumJoysticks());
267
+ SDL_JoystickClose(SDL_JoystickFromInstanceID(e.jdevice.which));
268
+ }
269
+ break;
270
+
271
+ case SDL_WINDOWEVENT:
272
+ switch (e.window.event) {
273
+ case SDL_WINDOWEVENT_RESIZED:
274
+ // Store new window size, set viewport
275
+ window->width = e.window.data1;
276
+ window->height = e.window.data2;
277
+ R2D_GL_SetViewport(window);
278
+ break;
279
+ }
280
+ break;
281
+
282
+ case SDL_QUIT:
283
+ R2D_Close(window);
284
+ break;
285
+ }
286
+ }
287
+
288
+ // Detect keys held down
289
+ int num_keys;
290
+ key_state = SDL_GetKeyboardState(&num_keys);
291
+
292
+ for (int i = 0; i < num_keys; i++) {
293
+ if (window->on_key) {
294
+ if (key_state[i] == 1) {
295
+ R2D_Event event = {
296
+ .type = R2D_KEY_HELD, .key = SDL_GetScancodeName(i)
297
+ };
298
+ window->on_key(event);
299
+ }
300
+ }
301
+ }
302
+
303
+ // Get and store mouse position relative to the viewport
304
+ int wx, wy; // mouse x, y coordinates relative to the window
305
+ SDL_GetMouseState(&wx, &wy);
306
+ R2D_GetMouseOnViewport(window, wx, wy, &window->mouse.x, &window->mouse.y);
307
+
308
+ // Update Window State /////////////////////////////////////////////////////
309
+
310
+ // Store new values in the window
311
+ window->frames = frames;
312
+ window->elapsed_ms = elapsed_ms;
313
+ window->loop_ms = loop_ms;
314
+ window->delay_ms = delay_ms;
315
+ window->fps = fps;
316
+
317
+ // Call update and render callbacks
318
+ if (window->update) window->update();
319
+ if (window->render) window->render();
320
+
321
+ // Draw Frame //////////////////////////////////////////////////////////////
322
+
323
+ // Render and flush all OpenGL buffers
324
+ R2D_GL_FlushBuffers();
325
+
326
+ // Swap buffers to display drawn contents in the window
327
+ SDL_GL_SwapWindow(window->sdl);
328
+ }
329
+
330
+ return 0;
331
+ }
332
+
333
+
334
+ /*
335
+ * Set the icon for the window
336
+ */
337
+ void R2D_SetIcon(R2D_Window *window, const char *icon) {
338
+ SDL_Surface *iconSurface = R2D_CreateImageSurface(icon);
339
+ if (iconSurface) {
340
+ window->icon = icon;
341
+ SDL_SetWindowIcon(window->sdl, iconSurface);
342
+ SDL_FreeSurface(iconSurface);
343
+ } else {
344
+ R2D_Log(R2D_WARN, "Could not set window icon");
345
+ }
346
+ }
347
+
348
+
349
+ /*
350
+ * Take a screenshot of the window
351
+ */
352
+ void R2D_Screenshot(R2D_Window *window, const char *path) {
353
+
354
+ #if GLES
355
+ R2D_Error("R2D_Screenshot", "Not supported in OpenGL ES");
356
+ #else
357
+ // Create a surface the size of the window
358
+ SDL_Surface *surface = SDL_CreateRGBSurface(
359
+ SDL_SWSURFACE, window->width, window->height, 24,
360
+ 0x000000FF, 0x0000FF00, 0x00FF0000, 0
361
+ );
362
+
363
+ // Grab the pixels from the front buffer, save to surface
364
+ glReadBuffer(GL_FRONT);
365
+ glReadPixels(0, 0, window->width, window->height, GL_RGB, GL_UNSIGNED_BYTE, surface->pixels);
366
+
367
+ // Flip image vertically
368
+
369
+ void *temp_row = (void *)malloc(surface->pitch);
370
+ if (!temp_row) {
371
+ R2D_Error("R2D_Screenshot", "Out of memory!");
372
+ SDL_FreeSurface(surface);
373
+ return;
374
+ }
375
+
376
+ int height_div_2 = (int) (surface->h * 0.5);
377
+
378
+ for (int index = 0; index < height_div_2; index++) {
379
+ memcpy((Uint8 *)temp_row,(Uint8 *)(surface->pixels) + surface->pitch * index, surface->pitch);
380
+ memcpy((Uint8 *)(surface->pixels) + surface->pitch * index, (Uint8 *)(surface->pixels) + surface->pitch * (surface->h - index-1), surface->pitch);
381
+ memcpy((Uint8 *)(surface->pixels) + surface->pitch * (surface->h - index-1), temp_row, surface->pitch);
382
+ }
383
+
384
+ free(temp_row);
385
+
386
+ // Save image to disk
387
+ IMG_SavePNG(surface, path);
388
+ SDL_FreeSurface(surface);
389
+ #endif
390
+ }
391
+
392
+
393
+ /*
394
+ * Close the window
395
+ */
396
+ int R2D_Close(R2D_Window *window) {
397
+ if (!window->close) {
398
+ R2D_Log(R2D_INFO, "Closing window");
399
+ window->close = true;
400
+ }
401
+ return 0;
402
+ }
403
+
404
+
405
+ /*
406
+ * Free all resources
407
+ */
408
+ int R2D_FreeWindow(R2D_Window *window) {
409
+ R2D_Close(window);
410
+ SDL_GL_DeleteContext(window->glcontext);
411
+ SDL_DestroyWindow(window->sdl);
412
+ free(window);
413
+ return 0;
414
+ }