gosu 1.1.0 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (220) hide show
  1. checksums.yaml +4 -4
  2. data/COPYING +1 -1
  3. data/dependencies/SDL/include/SDL.h +108 -14
  4. data/dependencies/SDL/include/SDL_assert.h +81 -50
  5. data/dependencies/SDL/include/SDL_atomic.h +135 -35
  6. data/dependencies/SDL/include/SDL_audio.h +960 -355
  7. data/dependencies/SDL/include/SDL_bits.h +11 -6
  8. data/dependencies/SDL/include/SDL_blendmode.h +91 -14
  9. data/dependencies/SDL/include/SDL_clipboard.h +30 -7
  10. data/dependencies/SDL/include/SDL_config.h +277 -27
  11. data/dependencies/SDL/include/SDL_config_android.h +13 -38
  12. data/dependencies/SDL/include/SDL_config_iphoneos.h +21 -62
  13. data/dependencies/SDL/include/SDL_config_macosx.h +23 -92
  14. data/dependencies/SDL/include/SDL_config_minimal.h +1 -4
  15. data/dependencies/SDL/include/SDL_config_pandora.h +15 -22
  16. data/dependencies/SDL/include/SDL_config_psp.h +16 -37
  17. data/dependencies/SDL/include/SDL_config_windows.h +28 -91
  18. data/dependencies/SDL/include/SDL_config_winrt.h +33 -61
  19. data/dependencies/SDL/include/SDL_config_wiz.h +28 -56
  20. data/dependencies/SDL/include/SDL_copying.h +1 -1
  21. data/dependencies/SDL/include/SDL_cpuinfo.h +331 -71
  22. data/dependencies/SDL/include/SDL_egl.h +906 -280
  23. data/dependencies/SDL/include/SDL_endian.h +101 -47
  24. data/dependencies/SDL/include/SDL_error.h +70 -19
  25. data/dependencies/SDL/include/SDL_events.h +387 -79
  26. data/dependencies/SDL/include/SDL_filesystem.h +73 -64
  27. data/dependencies/SDL/include/SDL_gamecontroller.h +585 -125
  28. data/dependencies/SDL/include/SDL_gesture.h +36 -6
  29. data/dependencies/SDL/include/SDL_haptic.h +304 -210
  30. data/dependencies/SDL/include/SDL_hidapi.h +451 -0
  31. data/dependencies/SDL/include/SDL_hints.h +1286 -897
  32. data/dependencies/SDL/include/SDL_joystick.h +577 -130
  33. data/dependencies/SDL/include/SDL_keyboard.h +162 -63
  34. data/dependencies/SDL/include/SDL_keycode.h +7 -5
  35. data/dependencies/SDL/include/SDL_loadso.h +42 -8
  36. data/dependencies/SDL/include/SDL_locale.h +34 -32
  37. data/dependencies/SDL/include/SDL_log.h +212 -19
  38. data/dependencies/SDL/include/SDL_main.h +72 -17
  39. data/dependencies/SDL/include/SDL_messagebox.h +70 -23
  40. data/dependencies/SDL/include/SDL_metal.h +27 -32
  41. data/dependencies/SDL/include/SDL_misc.h +19 -15
  42. data/dependencies/SDL/include/SDL_mouse.h +262 -110
  43. data/dependencies/SDL/include/SDL_mutex.h +286 -66
  44. data/dependencies/SDL/include/SDL_name.h +1 -1
  45. data/dependencies/SDL/include/SDL_opengl.h +1 -1
  46. data/dependencies/SDL/include/SDL_opengles.h +1 -1
  47. data/dependencies/SDL/include/SDL_opengles2.h +2 -2
  48. data/dependencies/SDL/include/SDL_pixels.h +199 -34
  49. data/dependencies/SDL/include/SDL_platform.h +39 -2
  50. data/dependencies/SDL/include/SDL_power.h +23 -10
  51. data/dependencies/SDL/include/SDL_quit.h +1 -1
  52. data/dependencies/SDL/include/SDL_rect.h +78 -28
  53. data/dependencies/SDL/include/SDL_render.h +1204 -472
  54. data/dependencies/SDL/include/SDL_revision.h +2 -2
  55. data/dependencies/SDL/include/SDL_rwops.h +605 -33
  56. data/dependencies/SDL/include/SDL_scancode.h +1 -1
  57. data/dependencies/SDL/include/SDL_sensor.h +76 -42
  58. data/dependencies/SDL/include/SDL_shape.h +38 -27
  59. data/dependencies/SDL/include/SDL_stdinc.h +96 -24
  60. data/dependencies/SDL/include/SDL_surface.h +571 -139
  61. data/dependencies/SDL/include/SDL_system.h +339 -101
  62. data/dependencies/SDL/include/SDL_syswm.h +50 -20
  63. data/dependencies/SDL/include/SDL_test.h +1 -1
  64. data/dependencies/SDL/include/SDL_test_assert.h +2 -2
  65. data/dependencies/SDL/include/SDL_test_common.h +23 -6
  66. data/dependencies/SDL/include/SDL_test_compare.h +1 -1
  67. data/dependencies/SDL/include/SDL_test_crc32.h +1 -1
  68. data/dependencies/SDL/include/SDL_test_font.h +3 -3
  69. data/dependencies/SDL/include/SDL_test_fuzzer.h +28 -26
  70. data/dependencies/SDL/include/SDL_test_harness.h +6 -6
  71. data/dependencies/SDL/include/SDL_test_images.h +1 -1
  72. data/dependencies/SDL/include/SDL_test_log.h +1 -1
  73. data/dependencies/SDL/include/SDL_test_md5.h +1 -1
  74. data/dependencies/SDL/include/SDL_test_memory.h +1 -1
  75. data/dependencies/SDL/include/SDL_test_random.h +2 -2
  76. data/dependencies/SDL/include/SDL_thread.h +226 -128
  77. data/dependencies/SDL/include/SDL_timer.h +129 -22
  78. data/dependencies/SDL/include/SDL_touch.h +48 -8
  79. data/dependencies/SDL/include/SDL_types.h +1 -1
  80. data/dependencies/SDL/include/SDL_version.h +72 -46
  81. data/dependencies/SDL/include/SDL_video.h +1266 -460
  82. data/dependencies/SDL/include/SDL_vulkan.h +100 -161
  83. data/dependencies/SDL/include/begin_code.h +22 -1
  84. data/dependencies/SDL/include/close_code.h +1 -1
  85. data/dependencies/SDL/lib/x64/libSDL2.dll.a +0 -0
  86. data/dependencies/SDL/lib/x86/libSDL2.dll.a +0 -0
  87. data/dependencies/SDL_sound/SDL_sound.c +83 -7
  88. data/dependencies/SDL_sound/SDL_sound.h +4 -4
  89. data/dependencies/SDL_sound/SDL_sound_aiff.c +9 -12
  90. data/dependencies/SDL_sound/SDL_sound_au.c +7 -7
  91. data/dependencies/SDL_sound/SDL_sound_coreaudio.c +3 -3
  92. data/dependencies/SDL_sound/SDL_sound_flac.c +1 -1
  93. data/dependencies/SDL_sound/SDL_sound_internal.h +17 -10
  94. data/dependencies/SDL_sound/SDL_sound_modplug.c +25 -27
  95. data/dependencies/SDL_sound/SDL_sound_mp3.c +5 -17
  96. data/dependencies/SDL_sound/SDL_sound_raw.c +11 -11
  97. data/dependencies/SDL_sound/SDL_sound_shn.c +8 -7
  98. data/dependencies/SDL_sound/SDL_sound_voc.c +6 -4
  99. data/dependencies/SDL_sound/SDL_sound_vorbis.c +6 -11
  100. data/dependencies/SDL_sound/SDL_sound_wav.c +35 -29
  101. data/dependencies/SDL_sound/dr_flac.h +618 -220
  102. data/dependencies/SDL_sound/dr_mp3.h +263 -94
  103. data/dependencies/SDL_sound/libmodplug/fastmix.c +58 -64
  104. data/dependencies/SDL_sound/libmodplug/libmodplug.h +25 -103
  105. data/dependencies/SDL_sound/libmodplug/load_669.c +14 -17
  106. data/dependencies/SDL_sound/libmodplug/load_amf.c +11 -7
  107. data/dependencies/SDL_sound/libmodplug/load_ams.c +65 -22
  108. data/dependencies/SDL_sound/libmodplug/load_dbm.c +8 -4
  109. data/dependencies/SDL_sound/libmodplug/load_dmf.c +55 -25
  110. data/dependencies/SDL_sound/libmodplug/load_far.c +9 -13
  111. data/dependencies/SDL_sound/libmodplug/load_gdm.c +448 -0
  112. data/dependencies/SDL_sound/libmodplug/load_it.c +45 -49
  113. data/dependencies/SDL_sound/libmodplug/load_mdl.c +80 -53
  114. data/dependencies/SDL_sound/libmodplug/load_med.c +20 -12
  115. data/dependencies/SDL_sound/libmodplug/load_mod.c +40 -15
  116. data/dependencies/SDL_sound/libmodplug/load_mt2.c +29 -17
  117. data/dependencies/SDL_sound/libmodplug/load_okt.c +12 -8
  118. data/dependencies/SDL_sound/libmodplug/load_psm.c +101 -78
  119. data/dependencies/SDL_sound/libmodplug/load_ptm.c +18 -17
  120. data/dependencies/SDL_sound/libmodplug/load_s3m.c +9 -7
  121. data/dependencies/SDL_sound/libmodplug/load_stm.c +3 -2
  122. data/dependencies/SDL_sound/libmodplug/load_ult.c +2 -2
  123. data/dependencies/SDL_sound/libmodplug/load_umx.c +315 -35
  124. data/dependencies/SDL_sound/libmodplug/load_xm.c +25 -21
  125. data/dependencies/SDL_sound/libmodplug/mmcmp.c +295 -149
  126. data/dependencies/SDL_sound/libmodplug/modplug.c +7 -123
  127. data/dependencies/SDL_sound/libmodplug/modplug.h +32 -29
  128. data/dependencies/SDL_sound/libmodplug/snd_dsp.c +0 -1
  129. data/dependencies/SDL_sound/libmodplug/snd_flt.c +2 -2
  130. data/dependencies/SDL_sound/libmodplug/snd_fx.c +24 -18
  131. data/dependencies/SDL_sound/libmodplug/sndfile.c +55 -156
  132. data/dependencies/SDL_sound/libmodplug/sndmix.c +7 -12
  133. data/dependencies/SDL_sound/libmodplug/tables.h +10 -15
  134. data/dependencies/SDL_sound/stb_vorbis.h +508 -325
  135. data/dependencies/{al_soft → mojoAL}/AL/al.h +38 -30
  136. data/dependencies/{al_soft → mojoAL}/AL/alc.h +27 -56
  137. data/dependencies/mojoAL/mojoal.c +4594 -0
  138. data/ext/gosu/extconf.rb +33 -30
  139. data/include/Gosu/Audio.hpp +70 -85
  140. data/include/Gosu/Color.hpp +63 -107
  141. data/include/Gosu/Font.hpp +44 -50
  142. data/include/Gosu/Fwd.hpp +1 -1
  143. data/include/Gosu/Graphics.hpp +64 -75
  144. data/include/Gosu/GraphicsBase.hpp +32 -39
  145. data/include/Gosu/Image.hpp +56 -62
  146. data/include/Gosu/ImageData.hpp +23 -27
  147. data/include/Gosu/Inspection.hpp +1 -4
  148. data/include/Gosu/Math.hpp +4 -16
  149. data/include/Gosu/Platform.hpp +1 -51
  150. data/include/Gosu/Text.hpp +37 -40
  151. data/include/Gosu/TextInput.hpp +34 -40
  152. data/include/Gosu/Utility.hpp +10 -8
  153. data/include/Gosu/Version.hpp +1 -1
  154. data/include/Gosu/Window.hpp +73 -70
  155. data/lib/SDL2.dll +0 -0
  156. data/lib/gosu/compat.rb +28 -37
  157. data/lib/gosu/swig_patches.rb +31 -3
  158. data/lib/gosu.rb +2 -2
  159. data/lib64/SDL2.dll +0 -0
  160. data/rdoc/gosu.rb +9 -1
  161. data/src/Audio.cpp +86 -86
  162. data/src/AudioFile.hpp +6 -6
  163. data/src/AudioFileAudioToolbox.cpp +1 -1
  164. data/src/AudioFileSDLSound.cpp +1 -1
  165. data/src/AudioImpl.hpp +5 -5
  166. data/src/Bitmap.cpp +13 -13
  167. data/src/BitmapIO.cpp +0 -20
  168. data/src/BlockAllocator.cpp +2 -1
  169. data/src/Channel.cpp +22 -20
  170. data/src/Color.cpp +62 -55
  171. data/src/EmptyImageData.hpp +16 -18
  172. data/src/FileUnix.cpp +1 -1
  173. data/src/FileWin.cpp +1 -1
  174. data/src/Font.cpp +52 -57
  175. data/src/GosuViewController.cpp +2 -0
  176. data/src/Graphics.cpp +135 -143
  177. data/src/Image.cpp +42 -42
  178. data/src/Input.cpp +1 -1
  179. data/src/InputUIKit.cpp +1 -1
  180. data/src/LargeImageData.cpp +120 -113
  181. data/src/LargeImageData.hpp +18 -16
  182. data/src/Log.hpp +6 -6
  183. data/src/Macro.cpp +124 -169
  184. data/src/Macro.hpp +11 -11
  185. data/src/Math.cpp +8 -1
  186. data/src/RenderState.hpp +5 -5
  187. data/src/Resolution.cpp +114 -61
  188. data/src/RubyGosu.cxx +470 -501
  189. data/src/RubyGosu.h +3 -2
  190. data/src/TexChunk.cpp +50 -41
  191. data/src/TexChunk.hpp +22 -22
  192. data/src/Text.cpp +58 -59
  193. data/src/TextBuilder.cpp +60 -57
  194. data/src/TextBuilder.hpp +20 -20
  195. data/src/TextInput.cpp +127 -135
  196. data/src/TrueTypeFont.cpp +108 -108
  197. data/src/TrueTypeFont.hpp +39 -38
  198. data/src/TrueTypeFontApple.cpp +27 -23
  199. data/src/TrueTypeFontUnix.cpp +21 -26
  200. data/src/TrueTypeFontWin.cpp +30 -30
  201. data/src/Utility.cpp +82 -23
  202. data/src/WinUtility.hpp +2 -1
  203. data/src/Window.cpp +103 -86
  204. data/src/WindowUIKit.cpp +48 -51
  205. metadata +8 -20
  206. data/dependencies/SDL/include/SDL_config_os2.h +0 -188
  207. data/dependencies/SDL_sound/libmodplug/load_abc.c +0 -4725
  208. data/dependencies/SDL_sound/libmodplug/load_mid.c +0 -1405
  209. data/dependencies/SDL_sound/libmodplug/load_pat.c +0 -1143
  210. data/dependencies/SDL_sound/libmodplug/load_pat.h +0 -25
  211. data/dependencies/al_soft/AL/alext.h +0 -585
  212. data/dependencies/al_soft/AL/efx-creative.h +0 -3
  213. data/dependencies/al_soft/AL/efx-presets.h +0 -402
  214. data/dependencies/al_soft/AL/efx.h +0 -762
  215. data/dependencies/al_soft/x64/libOpenAL32.dll.a +0 -0
  216. data/dependencies/al_soft/x86/libOpenAL32.dll.a +0 -0
  217. data/lib/OpenAL32.dll +0 -0
  218. data/lib64/OpenAL32.dll +0 -0
  219. data/src/UtilityApple.cpp +0 -16
  220. data/src/UtilityWin.cpp +0 -17
data/src/Macro.cpp CHANGED
@@ -1,179 +1,134 @@
1
1
  #include "Macro.hpp"
2
- #include "DrawOpQueue.hpp"
3
2
  #include <Gosu/Image.hpp>
4
- #include <cmath>
5
- #include <algorithm>
6
- #include <functional>
7
- #include <memory>
3
+ #include <Gosu/Utility.hpp>
4
+ #include "DrawOpQueue.hpp"
8
5
  #include <stdexcept>
9
- using namespace std;
10
6
 
11
- struct Gosu::Macro::Impl
7
+ struct Gosu::Macro::Impl : Gosu::Noncopyable
12
8
  {
13
- typedef double Float;
14
-
15
9
  VertexArrays vertex_arrays;
16
10
  int width, height;
17
-
18
- Transform find_transform_for_target(Float x1, Float y1, Float x2, Float y2,
19
- Float x3, Float y3, Float x4, Float y4) const
11
+
12
+ // Solves the 2x2 linear system for x:
13
+ // (a11 a12) (x1) = (b1)
14
+ // (a21 a22) (x2) = (b2)
15
+ // x1, x2 are output parameters. Returns false if the matrix is singular.
16
+ static bool solve_2x2(double a11, double a12, double a21, double a22, //
17
+ double b1, double b2, double& x1, double& x2)
18
+ {
19
+ const double det = a11 * a22 - a21 * a12;
20
+ if (det == 0) return false;
21
+ x1 = (a22 * b1 - a12 * b2) / det;
22
+ x2 = (a11 * b2 - a21 * b1) / det;
23
+ return true;
24
+ }
25
+
26
+ Transform find_transform_for_target(double x1, double y1, double x2, double y2, //
27
+ double x3, double y3, double x4, double y4) const
20
28
  {
21
29
  // Transformation logic follows a discussion on the ImageMagick mailing
22
30
  // list (on which ImageMagick's perspective_transform.pl is based).
23
-
31
+
24
32
  // To draw a macro at an arbitrary position, we solve the following system:
25
-
26
- // 0, 0, 1, 0, 0, 0, 0, 0 | x1
27
- // 0, 0, 0, 0, 0, 1, 0, 0 | y1
28
- // w, 0, 1, 0, 0, 0, -x2w, 0 | x2
29
- // 0, 0, 0, w, 0, 1, -y2w, 0 | y2
30
- // 0, h, 1, 0, 0, 0, 0, -x3h | x3
31
- // 0, 0, 0, 0, h, 1, 0, -y3h | y3
32
- // w, h, 1, 0, 0, 0, -x4w, -x4h | x4
33
- // 0, 0, 0, w, h, 1, -y4w, -y4h | y4
34
-
33
+
34
+ // 0, 0, 1, 0, 0, 0, 0, 0 | x1
35
+ // 0, 0, 0, 0, 0, 1, 0, 0 | y1
36
+ // w, 0, 1, 0, 0, 0, -x2 w, 0 | x2
37
+ // 0, 0, 0, w, 0, 1, -y2 w, 0 | y2
38
+ // 0, h, 1, 0, 0, 0, 0, -x3 h | x3
39
+ // 0, 0, 0, 0, h, 1, 0, -y3 h | y3
40
+ // w, h, 1, 0, 0, 0, -x4 w, -x4 h | x4
41
+ // 0, 0, 0, w, h, 1, -y4 w, -y4 h | y4
42
+
35
43
  // Equivalent:
36
-
37
- // 0, 0, 1, 0, 0, 0, 0, 0 | x1
38
- // 0, 0, 0, 0, 0, 1, 0, 0 | y1
39
- // w, 0, 0, 0, 0, 0, -x2w, 0 | x2-x1
40
- // 0, 0, 0, w, 0, 0, -y2w, 0 | y2-y1
41
- // 0, h, 0, 0, 0, 0, 0, -x3h | x3-x1
42
- // 0, 0, 0, 0, h, 0, 0, -y3h | y3-y1
43
- // 0, 0, 0, 0, 0, 0, (x2-x4)w, (x3-x4)h | x1-x2-x3+x4
44
- // 0, 0, 0, 0, 0, 0, (y2-y4)w, (y3-y4)h | y1-y2-y3+y4
45
-
46
- // Since this matrix is relatively sparse, we unroll all three solving paths.
47
-
48
- static const Transform null_transform = {{ 0 }};
49
-
50
- // Row 7 is completely useless
51
- if (x2 == x4 && x3 == x4) return null_transform;
52
- // Row 8 is completely useless
53
- if (y2 == y3 && y3 == y4) return null_transform;
54
- // Col 7 is completely useless
55
- if (x2 == x4 && y2 == y4) return null_transform;
56
- // Col 8 is completely useless
57
- if (x3 == x4 && y3 == y4) return null_transform;
58
-
59
- Float c[8];
60
-
61
- // Rows 1, 2
44
+
45
+ // 0, 0, 1, 0, 0, 0, 0, 0 | x1
46
+ // 0, 0, 0, 0, 0, 1, 0, 0 | y1
47
+ // w, 0, 0, 0, 0, 0, -x2 w, 0 | x2-x1
48
+ // 0, 0, 0, w, 0, 0, -y2 w, 0 | y2-y1
49
+ // 0, h, 0, 0, 0, 0, 0, -x3 h | x3-x1
50
+ // 0, 0, 0, 0, h, 0, 0, -y3 h | y3-y1
51
+ // 0, 0, 0, 0, 0, 0, (x2-x4) w, (x3-x4) h | x1-x2-x3+x4
52
+ // 0, 0, 0, 0, 0, 0, (y2-y4) w, (y3-y4) h | y1-y2-y3+y4
53
+
54
+ // The last two rows only involve the last two variables.
55
+ // We can directly solve this as a separate 2x2 linear system.
56
+
57
+ // Set up 2x2 linear system of the lower right corner entries.
58
+ const double a11 = (x2 - x4) * width;
59
+ const double a12 = (x3 - x4) * height;
60
+ const double a21 = (y2 - y4) * width;
61
+ const double a22 = (y3 - y4) * height;
62
+ const double b1 = x1 - x2 - x3 + x4;
63
+ const double b2 = y1 - y2 - y3 + y4;
64
+
65
+ // Solve:
66
+ double qx, qy;
67
+ if (!solve_2x2(a11, a12, a21, a22, b1, b2, qx, qy)) return Transform{{0}};
68
+
69
+ // Updating the last two rows with the computed solution yields
70
+
71
+ // 0, 0, 1, 0, 0, 0, 0, 0 | x1
72
+ // 0, 0, 0, 0, 0, 1, 0, 0 | y1
73
+ // w, 0, 0, 0, 0, 0, -x2 w, 0 | x2-x1
74
+ // 0, 0, 0, w, 0, 0, -y2 w, 0 | y2-y1
75
+ // 0, h, 0, 0, 0, 0, 0, -x3 h | x3-x1
76
+ // 0, 0, 0, 0, h, 0, 0, -y3 h | y3-y1
77
+ // 0, 0, 0, 0, 0, 0, 1, 0 | qx
78
+ // 0, 0, 0, 0, 0, 0, 0, 1 | qy
79
+
80
+ // We can use the last two rows to eliminate entries in rows 3, 4, 5, and 6:
81
+
82
+ // 0, 0, 1, 0, 0, 0, 0, 0 | x1
83
+ // 0, 0, 0, 0, 0, 1, 0, 0 | y1
84
+ // w, 0, 0, 0, 0, 0, 0, 0 | x2-x1 + qx x2 w
85
+ // 0, 0, 0, w, 0, 0, 0, 0 | y2-y1 + qx y2 w
86
+ // 0, h, 0, 0, 0, 0, 0, 0 | x3-x1 + qy x3 h
87
+ // 0, 0, 0, 0, h, 0, 0, 0 | y3-y1 + qy y3 h
88
+ // 0, 0, 0, 0, 0, 0, 1, 0 | qx
89
+ // 0, 0, 0, 0, 0, 0, 0, 1 | qy
90
+
91
+ // Normalize and reorder rows so we can read off the solution:
92
+
93
+ // 1, 0, 0, 0, 0, 0, 0, 0 | (x2-x1) / w + qx x2
94
+ // 0, 1, 0, 0, 0, 0, 0, 0 | (x3-x1) / h + qy x3
95
+ // 0, 0, 1, 0, 0, 0, 0, 0 | x1
96
+ // 0, 0, 0, 1, 0, 0, 0, 0 | (y2-y1) / w + qx y2
97
+ // 0, 0, 0, 0, 1, 0, 0, 0 | (y3-y1) / h + qy y3
98
+ // 0, 0, 0, 0, 0, 1, 0, 0 | y1
99
+ // 0, 0, 0, 0, 0, 0, 1, 0 | qx
100
+ // 0, 0, 0, 0, 0, 0, 0, 1 | qy
101
+
102
+ double c[8];
103
+ c[0] = (x2 - x1) / width + qx * x2;
104
+ c[1] = (x3 - x1) / height + qy * x3;
62
105
  c[2] = x1;
106
+ c[3] = (y2 - y1) / width + qx * y2;
107
+ c[4] = (y3 - y1) / height + qy * y3;
63
108
  c[5] = y1;
64
-
65
- // The logic below assumes x2 != x4, i.e. row7 can be used to eliminate
66
- // the leftmost value in row 8 and afterwards the values in rows 3 & 4.
67
- // If x2 == x4, we need to exchange rows 7 and 8.
68
-
69
- // TODO: x2==x4 is the normal case where an image is
70
- // drawn upright; the code should rather swap in the rare case that x3==x4!
71
-
72
- Float left_cell7 = (x2 - x4) * width;
73
- Float right_cell7 = (x3 - x4) * height;
74
- Float orig_right_side7 = (x1 - x2 - x3 + x4);
75
- Float left_cell8 = (y2 - y4) * width;
76
- Float right_cell8 = (y3 - y4) * height;
77
- Float orig_right_side8 = (y1 - y2 - y3 + y4);
78
-
79
- bool swap_rows78 = x2 == x4;
80
- if (swap_rows78) {
81
- swap(left_cell7, left_cell8);
82
- swap(right_cell7, right_cell8);
83
- swap(orig_right_side7, orig_right_side8);
84
- }
85
-
86
- // 0, 0, 1, 0, 0, 0, 0, 0 | x1
87
- // 0, 0, 0, 0, 0, 1, 0, 0 | y1
88
- // w, 0, 0, 0, 0, 0, -x2w, 0 | x2-x1
89
- // 0, 0, 0, w, 0, 0, -y2w, 0 | y2-y1
90
- // 0, h, 0, 0, 0, 0, 0, -x3h | x3-x1
91
- // 0, 0, 0, 0, h, 0, 0, -y3h | y3-y1
92
- // 0, 0, 0, 0, 0, 0, left_cell7, right_cell7 | orig_right_side7
93
- // 0, 0, 0, 0, 0, 0, left_cell8, right_cell8 | orig_right_side8
94
-
95
- // Use row 7 to eliminate the left cell in row 8
96
- // Row8 = Row8 - factor78 * Row7
97
- Float factor78 = left_cell8 / left_cell7;
98
- Float rem_cell8 = right_cell8 - right_cell7 * factor78;
99
- Float right_side8 = orig_right_side8 - orig_right_side7 * factor78;
100
- c[7] = right_side8 / rem_cell8;
101
-
102
- // 0, 0, 1, 0, 0, 0, 0, 0 | x1
103
- // 0, 0, 0, 0, 0, 1, 0, 0 | y1
104
- // w, 0, 0, 0, 0, 0, -x2w, 0 | x2-x1
105
- // 0, 0, 0, w, 0, 0, -y2w, 0 | y2-y1
106
- // 0, h, 0, 0, 0, 0, 0, -x3h | x3-x1
107
- // 0, 0, 0, 0, h, 0, 0, -y3h | y3-y1
108
- // 0, 0, 0, 0, 0, 0, left_cell7, right_cell7 | orig_right_side7
109
- // 0, 0, 0, 0, 0, 0, 0, rem_cell8 | right_side8
110
-
111
- // Use the remaining value in row 8 to eliminate the right value in row 7.
112
- // Row7 = Row7 - factor87 * Row8
113
- Float factor87 = right_cell7 / rem_cell8;
114
- Float rem_cell7 = left_cell7;
115
- Float right_side7 = orig_right_side7 - right_side8 * factor87;
116
- c[6] = right_side7 / rem_cell7;
117
-
118
- // 0, 0, 1, 0, 0, 0, 0, 0 | x1
119
- // 0, 0, 0, 0, 0, 1, 0, 0 | y1
120
- // w, 0, 0, 0, 0, 0, -x2w, 0 | x2-x1
121
- // 0, 0, 0, w, 0, 0, -y2w, 0 | y2-y1
122
- // 0, h, 0, 0, 0, 0, 0, -x3h | x3-x1
123
- // 0, 0, 0, 0, h, 0, 0, -y3h | y3-y1
124
- // 0, 0, 0, 0, 0, 0, rem_cell7, 0 | right_side7
125
- // 0, 0, 0, 0, 0, 0, 0, rem_cell8 | right_side8
126
-
127
- // Use the new rows 7 and 8 to calculate c0, c1, c3 & c4.
128
- // Row3 = Row3 - factor73 * Row7
129
- Float factor73 = -x2 * width / rem_cell7;
130
- Float rem_cell3 = width;
131
- Float right_side3 = (x2 - x1) - right_side7 * factor73;
132
- c[0] = right_side3 / rem_cell3;
133
- // Row4 = Row4 - factor74 * Row7
134
- Float factor74 = -y2 * width / rem_cell7;
135
- Float rem_cell4 = width;
136
- Float right_side4 = (y2 - y1) - right_side7 * factor74;
137
- c[3] = right_side4 / rem_cell4;
138
- // Row5 = Row5 - factor85 * Row7
139
- Float factor85 = -x3 * height / rem_cell8;
140
- Float rem_cell5 = height;
141
- Float right_side5 = (x3 - x1) - right_side8 * factor85;
142
- c[1] = right_side5 / rem_cell5;
143
- // Row6 = Row6 - factor86 * Row8
144
- Float factor86 = -y3 * height / rem_cell8;
145
- Float rem_cell6 = height;
146
- Float right_side6 = (y3 - y1) - right_side8 * factor86;
147
- c[4] = right_side6 / rem_cell6;
148
-
149
- if (swap_rows78) {
150
- swap(c[6], c[7]);
151
- }
152
-
153
- // Let's hope I never have to debug/understand this again! :D
154
-
155
- Transform result = {{
156
- c[0], c[3], 0, c[6],
157
- c[1], c[4], 0, c[7],
158
- 0, 0, 1, 0,
159
- c[2], c[5], 0, 1
160
- }};
109
+ c[6] = qx;
110
+ c[7] = qy;
111
+
112
+ Transform result = {{c[0], c[3], 0, c[6], //
113
+ c[1], c[4], 0, c[7], //
114
+ 0, 0, 1, 0, //
115
+ c[2], c[5], 0, 1}};
161
116
  return result;
162
117
  }
163
-
164
- void draw_vertex_arrays(Float x1, Float y1, Float x2, Float y2, Float x3, Float y3,
165
- Float x4, Float y4) const
118
+
119
+ void draw_vertex_arrays(double x1, double y1, double x2, double y2, //
120
+ double x3, double y3, double x4, double y4) const
166
121
  {
167
122
  // TODO: Macros should not be split up just because they have different transforms.
168
123
  // They should be premultiplied and have the same transform by definition. Then the
169
124
  // transformation only has to be performed once.
170
-
171
- #ifndef GOSU_IS_OPENGLES
125
+
126
+ #ifndef GOSU_IS_OPENGLES
172
127
  glEnable(GL_BLEND);
173
128
  glMatrixMode(GL_MODELVIEW);
174
-
129
+
175
130
  Transform transform = find_transform_for_target(x1, y1, x2, y2, x3, y3, x4, y4);
176
-
131
+
177
132
  for (const auto& vertex_array : vertex_arrays) {
178
133
  glPushMatrix();
179
134
  vertex_array.render_state.apply();
@@ -182,7 +137,7 @@ struct Gosu::Macro::Impl
182
137
  glDrawArrays(GL_QUADS, 0, (GLsizei) vertex_array.vertices.size());
183
138
  glPopMatrix();
184
139
  }
185
- #endif
140
+ #endif
186
141
  }
187
142
  };
188
143
 
@@ -204,15 +159,16 @@ int Gosu::Macro::height() const
204
159
  return pimpl->height;
205
160
  }
206
161
 
207
- void Gosu::Macro::draw(double x1, double y1, Color c1, double x2, double y2, Color c2,
208
- double x3, double y3, Color c3, double x4, double y4, Color c4, ZPos z, AlphaMode mode) const
162
+ void Gosu::Macro::draw(double x1, double y1, Color c1, double x2, double y2, Color c2, //
163
+ double x3, double y3, Color c3, double x4, double y4, Color c4, //
164
+ ZPos z, BlendMode mode) const
209
165
  {
210
166
  if (c1 != Color::WHITE || c2 != Color::WHITE || c3 != Color::WHITE || c4 != Color::WHITE) {
211
- throw invalid_argument("Macros cannot be tinted with colors");
167
+ throw std::invalid_argument{"Macros cannot be tinted with colors"};
212
168
  }
213
-
169
+
214
170
  normalize_coordinates(x1, y1, x2, y2, x3, y3, c3, x4, y4, c4);
215
-
171
+
216
172
  Gosu::Graphics::gl(z, [=] { pimpl->draw_vertex_arrays(x1, y1, x2, y2, x3, y3, x4, y4); });
217
173
  }
218
174
 
@@ -223,21 +179,20 @@ const Gosu::GLTexInfo* Gosu::Macro::gl_tex_info() const
223
179
 
224
180
  Gosu::Bitmap Gosu::Macro::to_bitmap() const
225
181
  {
226
- return Gosu::Graphics::render(pimpl->width, pimpl->height, [this] {
227
- draw(0, 0, Color::WHITE,
228
- pimpl->width, 0, Color::WHITE,
229
- 0, pimpl->height, Color::WHITE,
230
- pimpl->width, pimpl->height, Color::WHITE,
231
- 0, AM_DEFAULT);
232
- }).data().to_bitmap();
182
+ const auto render_this = [this] {
183
+ draw(0, 0, Color::WHITE, pimpl->width, 0, Color::WHITE, 0, pimpl->height, Color::WHITE,
184
+ pimpl->width, pimpl->height, Color::WHITE, 0, BM_DEFAULT);
185
+ };
186
+
187
+ return Gosu::Graphics::render(pimpl->width, pimpl->height, render_this).data().to_bitmap();
233
188
  }
234
189
 
235
- unique_ptr<Gosu::ImageData> Gosu::Macro::subimage(int x, int y, int width, int height) const
190
+ std::unique_ptr<Gosu::ImageData> Gosu::Macro::subimage(int x, int y, int width, int height) const
236
191
  {
237
- return unique_ptr<ImageData>();
192
+ return std::unique_ptr<ImageData>{};
238
193
  }
239
194
 
240
195
  void Gosu::Macro::insert(const Bitmap& bitmap, int x, int y)
241
196
  {
242
- throw logic_error("Gosu::Macro cannot be updated with a Gosu::Bitmap yet");
197
+ throw std::logic_error{"Gosu::Macro cannot be updated with a Gosu::Bitmap yet"};
243
198
  }
data/src/Macro.hpp CHANGED
@@ -1,30 +1,30 @@
1
1
  #pragma once
2
2
 
3
- #include "GraphicsImpl.hpp"
4
3
  #include <Gosu/Fwd.hpp>
5
4
  #include <Gosu/ImageData.hpp>
5
+ #include "GraphicsImpl.hpp"
6
6
  #include <memory>
7
7
 
8
8
  class Gosu::Macro : public Gosu::ImageData
9
9
  {
10
10
  struct Impl;
11
11
  std::shared_ptr<Impl> pimpl;
12
-
12
+
13
13
  public:
14
14
  Macro(DrawOpQueue& queue, int width, int height);
15
-
15
+
16
16
  int width() const override;
17
17
  int height() const override;
18
-
19
- void draw(double x1, double y1, Color c1, double x2, double y2, Color c2,
20
- double x3, double y3, Color c3, double x4, double y4, Color c4, ZPos z,
21
- AlphaMode mode) const override;
22
-
18
+
19
+ void draw(double x1, double y1, Color c1, double x2, double y2, Color c2, //
20
+ double x3, double y3, Color c3, double x4, double y4, Color c4, //
21
+ ZPos z, BlendMode mode) const override;
22
+
23
23
  const Gosu::GLTexInfo* gl_tex_info() const override;
24
-
24
+
25
25
  Gosu::Bitmap to_bitmap() const override;
26
-
26
+
27
27
  std::unique_ptr<ImageData> subimage(int x, int y, int width, int height) const override;
28
-
28
+
29
29
  void insert(const Bitmap& bitmap, int x, int y) override;
30
30
  };
data/src/Math.cpp CHANGED
@@ -23,7 +23,14 @@ double Gosu::angle(double from_x, double from_y, double to_x, double to_y, doubl
23
23
  double dist_x = to_x - from_x;
24
24
  double dist_y = to_y - from_y;
25
25
 
26
- if (dist_x == 0 && dist_y == 0) return def;
26
+ if (dist_x == 0) {
27
+ // Special-case these values so that for a result of 0°/360° we never
28
+ // run into subtle precision errors by converting from radian to angles.
29
+ if (dist_y < 0) return 0;
30
+ if (dist_y > 0) return 180;
31
+ // dist_y == 0
32
+ return 0;
33
+ }
27
34
 
28
35
  return normalize_angle(radians_to_gosu(atan2(dist_y, dist_x)));
29
36
  }
data/src/RenderState.hpp CHANGED
@@ -10,10 +10,10 @@ struct Gosu::RenderState
10
10
  std::shared_ptr<Texture> texture;
11
11
  const Transform* transform;
12
12
  ClipRect clip_rect;
13
- AlphaMode mode;
13
+ BlendMode mode;
14
14
 
15
15
  RenderState()
16
- : transform(0), mode(AM_DEFAULT)
16
+ : transform(0), mode(BM_DEFAULT)
17
17
  {
18
18
  clip_rect.width = NO_CLIPPING;
19
19
  }
@@ -39,10 +39,10 @@ struct Gosu::RenderState
39
39
 
40
40
  void apply_alpha_mode() const
41
41
  {
42
- if (mode == AM_ADD) {
42
+ if (mode == BM_ADD) {
43
43
  glBlendFunc(GL_SRC_ALPHA, GL_ONE);
44
44
  }
45
- else if (mode == AM_MULTIPLY) {
45
+ else if (mode == BM_MULTIPLY) {
46
46
  glBlendFunc(GL_DST_COLOR, GL_ZERO);
47
47
  }
48
48
  else {
@@ -174,7 +174,7 @@ public:
174
174
  }
175
175
  }
176
176
 
177
- void set_alpha_mode(AlphaMode new_mode)
177
+ void set_alpha_mode(BlendMode new_mode)
178
178
  {
179
179
  if (new_mode == mode) return;
180
180
 
data/src/Resolution.cpp CHANGED
@@ -7,11 +7,12 @@
7
7
 
8
8
  static SDL_DisplayMode display_mode(Gosu::Window* window)
9
9
  {
10
- static struct VideoSubsystem {
11
- VideoSubsystem() { SDL_InitSubSystem(SDL_INIT_VIDEO); };
10
+ static struct VideoSubsystem
11
+ {
12
+ VideoSubsystem() { SDL_InitSubSystem(SDL_INIT_VIDEO); };
12
13
  ~VideoSubsystem() { SDL_QuitSubSystem(SDL_INIT_VIDEO); };
13
14
  } subsystem;
14
-
15
+
15
16
  int index = window ? SDL_GetWindowDisplayIndex(Gosu::shared_window()) : 0;
16
17
  SDL_DisplayMode result;
17
18
  SDL_GetDesktopDisplayMode(index, &result);
@@ -31,88 +32,140 @@ int Gosu::screen_height(Window* window)
31
32
  #ifdef GOSU_IS_MAC
32
33
  #import <AppKit/AppKit.h>
33
34
 
34
- static NSSize max_window_size(Gosu::Window* window)
35
+ static SDL_Rect max_window_size(Gosu::Window* window)
35
36
  {
36
- // Keep in sync with SDL_cocoawindow.m.
37
- auto style = NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask;
37
+ // The extra size that a window needs depends on its style.
38
+ // This logic must be kept in sync with SDL_cocoawindow.m to be 100% accurate.
39
+ NSUInteger style;
40
+ if (window && window->borderless()) {
41
+ style = NSWindowStyleMaskBorderless;
42
+ }
43
+ else {
44
+ style = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable |
45
+ NSWindowStyleMaskMiniaturizable;
46
+ }
47
+ if (window && window->resizable()) {
48
+ style |= NSWindowStyleMaskResizable;
49
+ }
38
50
 
39
51
  auto index = window ? SDL_GetWindowDisplayIndex(Gosu::shared_window()) : 0;
40
- auto screen_frame = NSScreen.screens[index].visibleFrame;
41
- return [NSWindow contentRectForFrameRect:screen_frame styleMask:style].size;
42
- }
43
-
44
- int Gosu::available_width(Window* window)
45
- {
46
- return max_window_size(window).width;
47
- }
48
-
49
- int Gosu::available_height(Window* window)
50
- {
51
- return max_window_size(window).height;
52
+ NSRect screen_frame = NSScreen.screens[index].visibleFrame;
53
+ NSRect content_rect = [NSWindow contentRectForFrameRect:screen_frame styleMask:style];
54
+
55
+ SDL_Rect result;
56
+ result.x = 0;
57
+ result.y = 0;
58
+ result.w = content_rect.size.width;
59
+ result.h = content_rect.size.height;
60
+ return result;
52
61
  }
53
62
  #endif
54
63
 
64
+ // TODO: Remove this implementation and remove ifdef for GOSU_IS_X once WIN_GetWindowBordersSize is patched
55
65
  #ifdef GOSU_IS_WIN
56
- #include <windows.h>
57
66
  #include <SDL_syswm.h>
67
+ #include <dwmapi.h>
68
+ #include <windows.h>
69
+ #pragma comment(lib, "Dwmapi.lib")
58
70
 
59
- static SIZE max_window_size(Gosu::Window* window)
71
+ static SDL_Rect max_window_size(Gosu::Window* window)
60
72
  {
61
- RECT work_area;
62
-
63
- if (window == nullptr) {
64
- // Easy case: Return the work area of the primary monitor.
65
- SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0);
66
- }
67
- else {
68
- // Return the work area of the monitor the window is on.
69
- SDL_SysWMinfo wm_info;
70
- SDL_VERSION(&wm_info.version);
71
- SDL_GetWindowWMInfo(Gosu::shared_window(), &wm_info);
72
- HMONITOR monitor = MonitorFromWindow(wm_info.info.win.window, MONITOR_DEFAULTTONEAREST);
73
-
74
- MONITORINFO monitor_info;
75
- monitor_info.cbSize = sizeof(monitor_info);
76
- GetMonitorInfo(monitor, &monitor_info);
77
- work_area = monitor_info.rcWork;
73
+ // Replicate SDL's WIN_GetWindowBordersSize implementation (https://github.com/libsdl-org/SDL/blob/9f71a809e9bd6fbb5fa401a45c1537fc26abc1b4/src/video/windows/SDL_windowswindow.c#L514-L554)
74
+ // until it's patched to ignore the window drop shadow (window border is 1px but with drop shadow it's reported as 8px)
75
+ // REF: https://github.com/libsdl-org/SDL/issues/3835
76
+
77
+ static struct VideoSubsystem
78
+ {
79
+ VideoSubsystem() { SDL_InitSubSystem(SDL_INIT_VIDEO); };
80
+ ~VideoSubsystem() { SDL_QuitSubSystem(SDL_INIT_VIDEO); };
81
+ } subsystem;
82
+
83
+ int index = window ? SDL_GetWindowDisplayIndex(Gosu::shared_window()) : 0;
84
+ SDL_Rect rect;
85
+ SDL_GetDisplayUsableBounds(index, &rect);
86
+
87
+ if (window) {
88
+ SDL_SysWMinfo info;
89
+ SDL_VERSION(&info.version);
90
+ SDL_GetWindowWMInfo(Gosu::shared_window(), &info);
91
+ HWND hwnd = info.info.win.window;
92
+
93
+ RECT rcClient, rcWindow;
94
+ POINT ptDiff;
95
+ int top = 0, left = 0, bottom = 0, right = 0;
96
+
97
+ /* rcClient stores the size of the inner window, while rcWindow stores the outer size relative to the top-left
98
+ * screen position; so the top/left values of rcClient are always {0,0} and bottom/right are {height,width} */
99
+ GetClientRect(hwnd, &rcClient);
100
+ DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &rcWindow, sizeof(rcWindow));
101
+
102
+ /* convert the top/left values to make them relative to
103
+ * the window; they will end up being slightly negative */
104
+ ptDiff.y = rcWindow.top;
105
+ ptDiff.x = rcWindow.left;
106
+
107
+ ScreenToClient(hwnd, &ptDiff);
108
+
109
+ rcWindow.top = ptDiff.y;
110
+ rcWindow.left = ptDiff.x;
111
+
112
+ /* convert the bottom/right values to make them relative to the window,
113
+ * these will be slightly bigger than the inner width/height */
114
+ ptDiff.y = rcWindow.bottom;
115
+ ptDiff.x = rcWindow.right;
116
+
117
+ ScreenToClient(hwnd, &ptDiff);
118
+
119
+ rcWindow.bottom = ptDiff.y;
120
+ rcWindow.right = ptDiff.x;
121
+
122
+ /* Now that both the inner and outer rects use the same coordinate system we can substract them to get the border size.
123
+ * Keep in mind that the top/left coordinates of rcWindow are negative because the border lies slightly before {0,0},
124
+ * so switch them around because SDL2 wants them in positive. */
125
+ top = rcClient.top - rcWindow.top;
126
+ left = rcClient.left - rcWindow.left;
127
+ bottom = rcWindow.bottom - rcClient.bottom;
128
+ right = rcWindow.right - rcClient.right;
129
+
130
+ rect.w -= left + right;
131
+ rect.h -= top + bottom;
78
132
  }
79
-
80
- RECT window_size = work_area;
81
- // Keep in sync with STYLE_NORMAL in SDL_windowswindow.c.
82
- DWORD style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
83
- AdjustWindowRectEx(&window_size, style, FALSE, 0);
84
-
85
- // Because AdjustWindowRectEx will make our rect larger, not smaller, we need to perform some
86
- // unintuitive math here.
87
- SIZE size;
88
- size.cx = 2 * (work_area.right - work_area.left) - (window_size.right - window_size.left);
89
- size.cy = 2 * (work_area.bottom - work_area.top) - (window_size.bottom - window_size.top);
90
- return size;
91
- }
92
133
 
93
- int Gosu::available_width(Window* window)
94
- {
95
- return max_window_size(window).cx;
134
+ // Return a rect to have one less Gosu::available_width/height implementation.
135
+ return rect;
96
136
  }
137
+ #endif
97
138
 
98
- int Gosu::available_height(Window* window)
139
+ #ifdef GOSU_IS_X
140
+ static SDL_Rect max_window_size(Gosu::Window* window)
99
141
  {
100
- return max_window_size(window).cy;
142
+ static struct VideoSubsystem
143
+ {
144
+ VideoSubsystem() { SDL_InitSubSystem(SDL_INIT_VIDEO); };
145
+ ~VideoSubsystem() { SDL_QuitSubSystem(SDL_INIT_VIDEO); };
146
+ } subsystem;
147
+
148
+ int index = window ? SDL_GetWindowDisplayIndex(Gosu::shared_window()) : 0;
149
+ SDL_Rect rect;
150
+ int top, left, bottom, right;
151
+ SDL_GetDisplayUsableBounds(index, &rect);
152
+ SDL_GetWindowBordersSize(Gosu::shared_window(), &top, &left, &bottom, &right);
153
+
154
+ rect.w -= left + right;
155
+ rect.h -= top + bottom;
156
+
157
+ return rect;
101
158
  }
102
159
  #endif
103
160
 
104
- #ifdef GOSU_IS_X
105
- // Pessimistic fallback implementation for available_width / available_height.
106
- // TODO: Look at this NET_WORKAREA based implementation: https://github.com/glfw/glfw/pull/989/files
107
161
  int Gosu::available_width(Window* window)
108
162
  {
109
- return static_cast<unsigned>(Gosu::screen_width(window) * 0.9);
163
+ return max_window_size(window).w;
110
164
  }
111
165
 
112
166
  int Gosu::available_height(Window* window)
113
167
  {
114
- return static_cast<unsigned>(Gosu::screen_height(window) * 0.8);
168
+ return max_window_size(window).h;
115
169
  }
116
- #endif
117
170
 
118
171
  #endif