gosu 1.4.4 → 1.4.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/dependencies/SDL/include/SDL.h +1 -0
  3. data/dependencies/SDL/include/SDL_assert.h +4 -2
  4. data/dependencies/SDL/include/SDL_atomic.h +20 -0
  5. data/dependencies/SDL/include/SDL_audio.h +40 -4
  6. data/dependencies/SDL/include/SDL_blendmode.h +4 -6
  7. data/dependencies/SDL/include/SDL_clipboard.h +47 -0
  8. data/dependencies/SDL/include/SDL_config.h +71 -45
  9. data/dependencies/SDL/include/SDL_cpuinfo.h +39 -4
  10. data/dependencies/SDL/include/SDL_egl.h +59 -9
  11. data/dependencies/SDL/include/SDL_endian.h +34 -3
  12. data/dependencies/SDL/include/SDL_events.h +32 -1
  13. data/dependencies/SDL/include/SDL_filesystem.h +5 -1
  14. data/dependencies/SDL/include/SDL_gamecontroller.h +78 -5
  15. data/dependencies/SDL/include/SDL_guid.h +100 -0
  16. data/dependencies/SDL/include/SDL_hints.h +645 -43
  17. data/dependencies/SDL/include/SDL_joystick.h +127 -7
  18. data/dependencies/SDL/include/SDL_keyboard.h +38 -1
  19. data/dependencies/SDL/include/SDL_keycode.h +6 -1
  20. data/dependencies/SDL/include/SDL_log.h +2 -2
  21. data/dependencies/SDL/include/SDL_main.h +42 -2
  22. data/dependencies/SDL/include/SDL_metal.h +2 -1
  23. data/dependencies/SDL/include/SDL_mouse.h +12 -1
  24. data/dependencies/SDL/include/SDL_opengl.h +0 -51
  25. data/dependencies/SDL/include/SDL_opengl_glext.h +2260 -231
  26. data/dependencies/SDL/include/SDL_opengles2_gl2.h +374 -339
  27. data/dependencies/SDL/include/SDL_opengles2_gl2ext.h +3479 -1496
  28. data/dependencies/SDL/include/SDL_opengles2_gl2platform.h +6 -9
  29. data/dependencies/SDL/include/SDL_opengles2_khrplatform.h +43 -14
  30. data/dependencies/SDL/include/SDL_platform.h +32 -6
  31. data/dependencies/SDL/include/SDL_rect.h +154 -2
  32. data/dependencies/SDL/include/SDL_render.h +46 -17
  33. data/dependencies/SDL/include/SDL_revision.h +6 -1
  34. data/dependencies/SDL/include/SDL_rwops.h +1 -15
  35. data/dependencies/SDL/include/SDL_scancode.h +46 -21
  36. data/dependencies/SDL/include/SDL_sensor.h +24 -3
  37. data/dependencies/SDL/include/SDL_stdinc.h +119 -8
  38. data/dependencies/SDL/include/SDL_surface.h +3 -1
  39. data/dependencies/SDL/include/SDL_system.h +66 -6
  40. data/dependencies/SDL/include/SDL_syswm.h +2 -0
  41. data/dependencies/SDL/include/SDL_test_common.h +1 -0
  42. data/dependencies/SDL/include/SDL_test_font.h +90 -3
  43. data/dependencies/SDL/include/SDL_thread.h +3 -3
  44. data/dependencies/SDL/include/SDL_touch.h +8 -0
  45. data/dependencies/SDL/include/SDL_version.h +19 -3
  46. data/dependencies/SDL/include/SDL_video.h +71 -9
  47. data/dependencies/SDL/include/begin_code.h +4 -4
  48. data/dependencies/SDL/lib/x64/libSDL2.dll.a +0 -0
  49. data/dependencies/SDL/lib/x86/libSDL2.dll.a +0 -0
  50. data/dependencies/SDL_sound/SDL_sound.c +210 -71
  51. data/dependencies/SDL_sound/SDL_sound.h +1 -1
  52. data/dependencies/SDL_sound/SDL_sound_coreaudio.c +111 -168
  53. data/dependencies/SDL_sound/SDL_sound_flac.c +0 -6
  54. data/dependencies/SDL_sound/SDL_sound_internal.h +27 -5
  55. data/dependencies/SDL_sound/SDL_sound_modplug.c +20 -8
  56. data/dependencies/SDL_sound/SDL_sound_mp3.c +11 -7
  57. data/dependencies/SDL_sound/SDL_sound_raw.c +1 -1
  58. data/dependencies/SDL_sound/SDL_sound_shn.c +1 -5
  59. data/dependencies/SDL_sound/SDL_sound_voc.c +1 -1
  60. data/dependencies/SDL_sound/SDL_sound_vorbis.c +2 -4
  61. data/dependencies/SDL_sound/SDL_sound_wav.c +44 -20
  62. data/dependencies/SDL_sound/dr_flac.h +237 -95
  63. data/dependencies/SDL_sound/dr_mp3.h +46 -33
  64. data/dependencies/SDL_sound/libmodplug/fastmix.c +53 -39
  65. data/dependencies/SDL_sound/libmodplug/libmodplug.h +0 -12
  66. data/dependencies/SDL_sound/libmodplug/load_669.c +37 -32
  67. data/dependencies/SDL_sound/libmodplug/load_amf.c +57 -44
  68. data/dependencies/SDL_sound/libmodplug/load_ams.c +127 -100
  69. data/dependencies/SDL_sound/libmodplug/load_dbm.c +40 -37
  70. data/dependencies/SDL_sound/libmodplug/load_dmf.c +61 -49
  71. data/dependencies/SDL_sound/libmodplug/load_dsm.c +18 -13
  72. data/dependencies/SDL_sound/libmodplug/load_far.c +31 -24
  73. data/dependencies/SDL_sound/libmodplug/load_gdm.c +27 -21
  74. data/dependencies/SDL_sound/libmodplug/load_it.c +106 -91
  75. data/dependencies/SDL_sound/libmodplug/load_mdl.c +43 -35
  76. data/dependencies/SDL_sound/libmodplug/load_med.c +66 -52
  77. data/dependencies/SDL_sound/libmodplug/load_mod.c +30 -26
  78. data/dependencies/SDL_sound/libmodplug/load_mt2.c +61 -50
  79. data/dependencies/SDL_sound/libmodplug/load_mtm.c +23 -17
  80. data/dependencies/SDL_sound/libmodplug/load_okt.c +18 -16
  81. data/dependencies/SDL_sound/libmodplug/load_psm.c +44 -32
  82. data/dependencies/SDL_sound/libmodplug/load_ptm.c +18 -14
  83. data/dependencies/SDL_sound/libmodplug/load_s3m.c +59 -53
  84. data/dependencies/SDL_sound/libmodplug/load_stm.c +23 -18
  85. data/dependencies/SDL_sound/libmodplug/load_ult.c +33 -29
  86. data/dependencies/SDL_sound/libmodplug/load_xm.c +64 -57
  87. data/dependencies/SDL_sound/libmodplug/mmcmp.c +2 -1
  88. data/dependencies/SDL_sound/libmodplug/snd_dsp.c +30 -20
  89. data/dependencies/SDL_sound/libmodplug/snd_flt.c +6 -4
  90. data/dependencies/SDL_sound/libmodplug/snd_fx.c +91 -65
  91. data/dependencies/SDL_sound/libmodplug/sndfile.c +91 -66
  92. data/dependencies/SDL_sound/libmodplug/sndmix.c +58 -35
  93. data/dependencies/SDL_sound/stb_vorbis.h +14 -9
  94. data/dependencies/mojoAL/mojoal.c +41 -24
  95. data/dependencies/utf8proc/utf8proc.c +1 -1
  96. data/dependencies/utf8proc/utf8proc.h +1 -1
  97. data/dependencies/utf8proc/utf8proc_data.h +3366 -3184
  98. data/include/Gosu/Version.hpp +1 -1
  99. data/lib/SDL2.dll +0 -0
  100. data/lib64/SDL2.dll +0 -0
  101. data/src/RubyGosu.cxx +1 -1
  102. data/src/Window.cpp +6 -4
  103. metadata +3 -2
@@ -35,7 +35,7 @@
35
35
  #include "SDL_atomic.h"
36
36
  #include "SDL_mutex.h"
37
37
 
38
- #if defined(__WIN32__)
38
+ #if defined(__WIN32__) || defined(__GDK__)
39
39
  #include <process.h> /* _beginthreadex() and _endthreadex() */
40
40
  #endif
41
41
  #if defined(__OS2__) /* for _beginthread() and _endthread() */
@@ -88,7 +88,7 @@ typedef enum {
88
88
  typedef int (SDLCALL * SDL_ThreadFunction) (void *data);
89
89
 
90
90
 
91
- #if defined(__WIN32__)
91
+ #if defined(__WIN32__) || defined(__GDK__)
92
92
  /**
93
93
  * \file SDL_thread.h
94
94
  *
@@ -129,7 +129,7 @@ SDL_CreateThread(SDL_ThreadFunction fn, const char *name, void *data,
129
129
  pfnSDL_CurrentEndThread pfnEndThread);
130
130
 
131
131
  extern DECLSPEC SDL_Thread *SDLCALL
132
- SDL_CreateThreadWithStackSize(int (SDLCALL * fn) (void *),
132
+ SDL_CreateThreadWithStackSize(SDL_ThreadFunction fn,
133
133
  const char *name, const size_t stacksize, void *data,
134
134
  pfnSDL_CurrentBeginThread pfnBeginThread,
135
135
  pfnSDL_CurrentEndThread pfnEndThread);
@@ -95,6 +95,14 @@ extern DECLSPEC int SDLCALL SDL_GetNumTouchDevices(void);
95
95
  */
96
96
  extern DECLSPEC SDL_TouchID SDLCALL SDL_GetTouchDevice(int index);
97
97
 
98
+ /**
99
+ * Get the touch device name as reported from the driver or NULL if the index
100
+ * is invalid.
101
+ *
102
+ * \since This function is available since SDL 2.0.22.
103
+ */
104
+ extern DECLSPEC const char* SDLCALL SDL_GetTouchName(int index);
105
+
98
106
  /**
99
107
  * Get the type of the given touch device.
100
108
  *
@@ -58,8 +58,8 @@ typedef struct SDL_version
58
58
  /* Printable format: "%d.%d.%d", MAJOR, MINOR, PATCHLEVEL
59
59
  */
60
60
  #define SDL_MAJOR_VERSION 2
61
- #define SDL_MINOR_VERSION 0
62
- #define SDL_PATCHLEVEL 20
61
+ #define SDL_MINOR_VERSION 26
62
+ #define SDL_PATCHLEVEL 1
63
63
 
64
64
  /**
65
65
  * Macro to determine SDL version program was compiled against.
@@ -83,6 +83,8 @@ typedef struct SDL_version
83
83
  (x)->patch = SDL_PATCHLEVEL; \
84
84
  }
85
85
 
86
+ /* TODO: Remove this whole block in SDL 3 */
87
+ #if SDL_MAJOR_VERSION < 3
86
88
  /**
87
89
  * This macro turns the version numbers into a numeric value:
88
90
  * \verbatim
@@ -90,21 +92,35 @@ typedef struct SDL_version
90
92
  \endverbatim
91
93
  *
92
94
  * This assumes that there will never be more than 100 patchlevels.
95
+ *
96
+ * In versions higher than 2.9.0, the minor version overflows into
97
+ * the thousands digit: for example, 2.23.0 is encoded as 4300,
98
+ * and 2.255.99 would be encoded as 25799.
99
+ * This macro will not be available in SDL 3.x.
93
100
  */
94
101
  #define SDL_VERSIONNUM(X, Y, Z) \
95
102
  ((X)*1000 + (Y)*100 + (Z))
96
103
 
97
104
  /**
98
105
  * This is the version number macro for the current SDL version.
106
+ *
107
+ * In versions higher than 2.9.0, the minor version overflows into
108
+ * the thousands digit: for example, 2.23.0 is encoded as 4300.
109
+ * This macro will not be available in SDL 3.x.
110
+ *
111
+ * Deprecated, use SDL_VERSION_ATLEAST or SDL_VERSION instead.
99
112
  */
100
113
  #define SDL_COMPILEDVERSION \
101
114
  SDL_VERSIONNUM(SDL_MAJOR_VERSION, SDL_MINOR_VERSION, SDL_PATCHLEVEL)
115
+ #endif /* SDL_MAJOR_VERSION < 3 */
102
116
 
103
117
  /**
104
118
  * This macro will evaluate to true if compiled with SDL at least X.Y.Z.
105
119
  */
106
120
  #define SDL_VERSION_ATLEAST(X, Y, Z) \
107
- (SDL_COMPILEDVERSION >= SDL_VERSIONNUM(X, Y, Z))
121
+ ((SDL_MAJOR_VERSION >= X) && \
122
+ (SDL_MAJOR_VERSION > X || SDL_MINOR_VERSION >= Y) && \
123
+ (SDL_MAJOR_VERSION > X || SDL_MINOR_VERSION > Y || SDL_PATCHLEVEL >= Z))
108
124
 
109
125
  /**
110
126
  * Get the version of SDL that is linked against your program.
@@ -248,7 +248,8 @@ typedef enum
248
248
  SDL_GL_FRAMEBUFFER_SRGB_CAPABLE,
249
249
  SDL_GL_CONTEXT_RELEASE_BEHAVIOR,
250
250
  SDL_GL_CONTEXT_RESET_NOTIFICATION,
251
- SDL_GL_CONTEXT_NO_ERROR
251
+ SDL_GL_CONTEXT_NO_ERROR,
252
+ SDL_GL_FLOATBUFFERS
252
253
  } SDL_GLattr;
253
254
 
254
255
  typedef enum
@@ -444,6 +445,15 @@ extern DECLSPEC int SDLCALL SDL_GetDisplayUsableBounds(int displayIndex, SDL_Rec
444
445
  * A failure of this function usually means that either no DPI information is
445
446
  * available or the `displayIndex` is out of range.
446
447
  *
448
+ * **WARNING**: This reports the DPI that the hardware reports, and it is not
449
+ * always reliable! It is almost always better to use SDL_GetWindowSize() to
450
+ * find the window size, which might be in logical points instead of pixels,
451
+ * and then SDL_GL_GetDrawableSize(), SDL_Vulkan_GetDrawableSize(),
452
+ * SDL_Metal_GetDrawableSize(), or SDL_GetRendererOutputSize(), and compare
453
+ * the two values to get an actual scaling value between the two. We will be
454
+ * rethinking how high-dpi details should be managed in SDL3 to make things
455
+ * more consistent, reliable, and clear.
456
+ *
447
457
  * \param displayIndex the index of the display from which DPI information
448
458
  * should be queried
449
459
  * \param ddpi a pointer filled in with the diagonal DPI of the display; may
@@ -587,6 +597,35 @@ extern DECLSPEC int SDLCALL SDL_GetCurrentDisplayMode(int displayIndex, SDL_Disp
587
597
  */
588
598
  extern DECLSPEC SDL_DisplayMode * SDLCALL SDL_GetClosestDisplayMode(int displayIndex, const SDL_DisplayMode * mode, SDL_DisplayMode * closest);
589
599
 
600
+ /**
601
+ * Get the index of the display containing a point
602
+ *
603
+ * \param point the point to query
604
+ * \returns the index of the display containing the point or a negative error
605
+ * code on failure; call SDL_GetError() for more information.
606
+ *
607
+ * \since This function is available since SDL 2.24.0.
608
+ *
609
+ * \sa SDL_GetDisplayBounds
610
+ * \sa SDL_GetNumVideoDisplays
611
+ */
612
+ extern DECLSPEC int SDLCALL SDL_GetPointDisplayIndex(const SDL_Point * point);
613
+
614
+ /**
615
+ * Get the index of the display primarily containing a rect
616
+ *
617
+ * \param rect the rect to query
618
+ * \returns the index of the display entirely containing the rect or closest
619
+ * to the center of the rect on success or a negative error code on
620
+ * failure; call SDL_GetError() for more information.
621
+ *
622
+ * \since This function is available since SDL 2.24.0.
623
+ *
624
+ * \sa SDL_GetDisplayBounds
625
+ * \sa SDL_GetNumVideoDisplays
626
+ */
627
+ extern DECLSPEC int SDLCALL SDL_GetRectDisplayIndex(const SDL_Rect * rect);
628
+
590
629
  /**
591
630
  * Get the index of the display associated with a window.
592
631
  *
@@ -697,7 +736,10 @@ extern DECLSPEC Uint32 SDLCALL SDL_GetWindowPixelFormat(SDL_Window * window);
697
736
  * in pixels may differ from its size in screen coordinates on platforms with
698
737
  * high-DPI support (e.g. iOS and macOS). Use SDL_GetWindowSize() to query the
699
738
  * client area's size in screen coordinates, and SDL_GL_GetDrawableSize() or
700
- * SDL_GetRendererOutputSize() to query the drawable size in pixels.
739
+ * SDL_GetRendererOutputSize() to query the drawable size in pixels. Note that
740
+ * when this flag is set, the drawable size can vary after the window is
741
+ * created and should be queried after major window events such as when the
742
+ * window is resized or moved between displays.
701
743
  *
702
744
  * If the window is set fullscreen, the width and height parameters `w` and
703
745
  * `h` will not be used. However, invalid size parameters (e.g. too large) may
@@ -1004,6 +1046,27 @@ extern DECLSPEC int SDLCALL SDL_GetWindowBordersSize(SDL_Window * window,
1004
1046
  int *top, int *left,
1005
1047
  int *bottom, int *right);
1006
1048
 
1049
+ /**
1050
+ * Get the size of a window in pixels.
1051
+ *
1052
+ * This may differ from SDL_GetWindowSize() if we're rendering to a high-DPI
1053
+ * drawable, i.e. the window was created with `SDL_WINDOW_ALLOW_HIGHDPI` on a
1054
+ * platform with high-DPI support (Apple calls this "Retina"), and not
1055
+ * disabled by the `SDL_HINT_VIDEO_HIGHDPI_DISABLED` hint.
1056
+ *
1057
+ * \param window the window from which the drawable size should be queried
1058
+ * \param w a pointer to variable for storing the width in pixels, may be NULL
1059
+ * \param h a pointer to variable for storing the height in pixels, may be
1060
+ * NULL
1061
+ *
1062
+ * \since This function is available since SDL 2.26.0.
1063
+ *
1064
+ * \sa SDL_CreateWindow
1065
+ * \sa SDL_GetWindowSize
1066
+ */
1067
+ extern DECLSPEC void SDLCALL SDL_GetWindowSizeInPixels(SDL_Window * window,
1068
+ int *w, int *h);
1069
+
1007
1070
  /**
1008
1071
  * Set the minimum size of a window's client area.
1009
1072
  *
@@ -1337,6 +1400,7 @@ extern DECLSPEC void SDLCALL SDL_SetWindowKeyboardGrab(SDL_Window * window,
1337
1400
  * Mouse grab confines the mouse cursor to the window.
1338
1401
  *
1339
1402
  * \param window The window for which the mouse grab mode should be set.
1403
+ * \param grabbed This is SDL_TRUE to grab mouse, and SDL_FALSE to release.
1340
1404
  *
1341
1405
  * \since This function is available since SDL 2.0.16.
1342
1406
  *
@@ -1747,6 +1811,9 @@ extern DECLSPEC void SDLCALL SDL_EnableScreenSaver(void);
1747
1811
  * If you disable the screensaver, it is automatically re-enabled when SDL
1748
1812
  * quits.
1749
1813
  *
1814
+ * The screensaver is disabled by default since SDL 2.0.2. Before SDL 2.0.2
1815
+ * the screensaver was enabled by default.
1816
+ *
1750
1817
  * \since This function is available since SDL 2.0.0.
1751
1818
  *
1752
1819
  * \sa SDL_EnableScreenSaver
@@ -2008,13 +2075,8 @@ extern DECLSPEC void SDLCALL SDL_GL_GetDrawableSize(SDL_Window * window, int *w,
2008
2075
  * retry the call with 1 for the interval.
2009
2076
  *
2010
2077
  * Adaptive vsync is implemented for some glX drivers with
2011
- * GLX_EXT_swap_control_tear:
2012
- *
2013
- * https://www.opengl.org/registry/specs/EXT/glx_swap_control_tear.txt
2014
- *
2015
- * and for some Windows drivers with WGL_EXT_swap_control_tear:
2016
- *
2017
- * https://www.opengl.org/registry/specs/EXT/wgl_swap_control_tear.txt
2078
+ * GLX_EXT_swap_control_tear, and for some Windows drivers with
2079
+ * WGL_EXT_swap_control_tear.
2018
2080
  *
2019
2081
  * Read more on the Khronos wiki:
2020
2082
  * https://www.khronos.org/opengl/wiki/Swap_Interval#Adaptive_Vsync
@@ -34,7 +34,7 @@
34
34
  #define _begin_code_h
35
35
 
36
36
  #ifndef SDL_DEPRECATED
37
- # if (__GNUC__ >= 4) /* technically, this arrived in gcc 3.1, but oh well. */
37
+ # if defined(__GNUC__) && (__GNUC__ >= 4) /* technically, this arrived in gcc 3.1, but oh well. */
38
38
  # define SDL_DEPRECATED __attribute__((deprecated))
39
39
  # else
40
40
  # define SDL_DEPRECATED
@@ -51,7 +51,7 @@
51
51
 
52
52
  /* Some compilers use a special export keyword */
53
53
  #ifndef DECLSPEC
54
- # if defined(__WIN32__) || defined(__WINRT__) || defined(__CYGWIN__)
54
+ # if defined(__WIN32__) || defined(__WINRT__) || defined(__CYGWIN__) || defined(__GDK__)
55
55
  # ifdef DLL_EXPORT
56
56
  # define DECLSPEC __declspec(dllexport)
57
57
  # else
@@ -74,7 +74,7 @@
74
74
 
75
75
  /* By default SDL uses the C calling convention */
76
76
  #ifndef SDLCALL
77
- #if (defined(__WIN32__) || defined(__WINRT__)) && !defined(__GNUC__)
77
+ #if (defined(__WIN32__) || defined(__WINRT__) || defined(__GDK__)) && !defined(__GNUC__)
78
78
  #define SDLCALL __cdecl
79
79
  #elif defined(__OS2__) || defined(__EMX__)
80
80
  #define SDLCALL _System
@@ -107,7 +107,7 @@
107
107
  #ifdef __BORLANDC__
108
108
  #pragma nopackwarning
109
109
  #endif
110
- #ifdef _M_X64
110
+ #ifdef _WIN64
111
111
  /* Use 8-byte alignment on 64-bit architectures, so pointers are aligned */
112
112
  #pragma pack(push,8)
113
113
  #else
Binary file
Binary file
@@ -217,12 +217,6 @@ void Sound_ClearError(void)
217
217
  } /* Sound_ClearError */
218
218
 
219
219
 
220
- static void SDLCALL free_errmsg(void *errmsg)
221
- {
222
- SDL_free(errmsg);
223
- } /* free_errmsg */
224
-
225
-
226
220
  /*
227
221
  * This is declared in the internal header.
228
222
  */
@@ -245,7 +239,7 @@ void __Sound_SetError(const char *str)
245
239
  if (err == NULL)
246
240
  return; /* uhh...? */
247
241
 
248
- SDL_TLSSet(tlsid_errmsg, err, free_errmsg);
242
+ SDL_TLSSet(tlsid_errmsg, err, SDL_free);
249
243
  } /* if */
250
244
 
251
245
  err->error_available = SDL_TRUE;
@@ -288,7 +282,8 @@ static Sound_Sample *alloc_sample(SDL_RWops *rw, Sound_AudioInfo *desired,
288
282
  } /* if */
289
283
 
290
284
  SDL_assert(bufferSize > 0);
291
- retval->buffer = SDL_calloc(1, bufferSize); /* pure ugly. */
285
+
286
+ retval->buffer = __Sound_SIMDAlloc(bufferSize);
292
287
  if (!retval->buffer)
293
288
  {
294
289
  __Sound_SetError(ERR_OUT_OF_MEMORY);
@@ -296,6 +291,7 @@ static Sound_Sample *alloc_sample(SDL_RWops *rw, Sound_AudioInfo *desired,
296
291
  SDL_free(retval);
297
292
  return NULL;
298
293
  } /* if */
294
+ SDL_memset(retval->buffer, '\0', bufferSize);
299
295
  retval->buffer_size = bufferSize;
300
296
 
301
297
  if (desired != NULL)
@@ -362,7 +358,8 @@ static int init_sample(const Sound_DecoderFunctions *funcs,
362
358
 
363
359
  /* success; we've got a decoder! */
364
360
 
365
- /* Now we need to set up the conversion buffer... */
361
+ /* Now we need to set up an audio stream for data conversion if necessary... */
362
+ internal->stream = NULL;
366
363
 
367
364
  if (_desired == NULL)
368
365
  SDL_memcpy(&desired, &sample->actual, sizeof (Sound_AudioInfo));
@@ -371,40 +368,32 @@ static int init_sample(const Sound_DecoderFunctions *funcs,
371
368
  desired.format = _desired->format ? _desired->format : sample->actual.format;
372
369
  desired.channels = _desired->channels ? _desired->channels : sample->actual.channels;
373
370
  desired.rate = _desired->rate ? _desired->rate : sample->actual.rate;
374
- } /* else */
375
-
376
- if (SDL_BuildAudioCVT(&internal->sdlcvt,
377
- sample->actual.format,
378
- sample->actual.channels,
379
- sample->actual.rate,
380
- desired.format,
381
- desired.channels,
382
- desired.rate) == -1)
383
- {
384
- __Sound_SetError(SDL_GetError());
385
- funcs->close(sample);
386
- SDL_RWseek(internal->rw, pos, RW_SEEK_SET); /* set for next try... */
387
- return 0;
388
- } /* if */
389
371
 
390
- if (internal->sdlcvt.len_mult > 1)
391
- {
392
- void *rc = SDL_realloc(sample->buffer, sample->buffer_size * internal->sdlcvt.len_mult);
393
- if (rc == NULL)
372
+ if ( (sample->actual.format != desired.format) ||
373
+ (sample->actual.channels != desired.channels) ||
374
+ (sample->actual.rate != desired.rate) )
394
375
  {
395
- funcs->close(sample);
396
- SDL_RWseek(internal->rw, pos, RW_SEEK_SET); /* set for next try... */
397
- return 0;
376
+ internal->stream = SDL_NewAudioStream(sample->actual.format,
377
+ sample->actual.channels,
378
+ sample->actual.rate,
379
+ desired.format,
380
+ desired.channels,
381
+ desired.rate);
382
+
383
+ if (internal->stream == NULL)
384
+ {
385
+ __Sound_SetError(SDL_GetError());
386
+ funcs->close(sample);
387
+ SDL_RWseek(internal->rw, pos, RW_SEEK_SET); /* set for next try... */
388
+ return 0;
389
+ } /* if */
398
390
  } /* if */
399
-
400
- sample->buffer = rc;
401
- } /* if */
391
+ } /* else */
402
392
 
403
393
  /* these pointers are all one and the same. */
404
394
  SDL_memcpy(&sample->desired, &desired, sizeof (Sound_AudioInfo));
405
- internal->sdlcvt.buf = internal->buffer = sample->buffer;
406
- internal->buffer_size = sample->buffer_size / internal->sdlcvt.len_mult;
407
- internal->sdlcvt.len = internal->buffer_size;
395
+ internal->buffer = sample->buffer;
396
+ internal->buffer_size = sample->buffer_size;
408
397
 
409
398
  /* Prepend our new Sound_Sample to the sample_list... */
410
399
  SDL_LockMutex(samplelist_mutex);
@@ -425,7 +414,7 @@ static int init_sample(const Sound_DecoderFunctions *funcs,
425
414
  sample->actual.channels));
426
415
 
427
416
  SNDDBG(("On-the-fly conversion: %s.\n",
428
- internal->sdlcvt.needed ? "ENABLED" : "DISABLED"));
417
+ (internal->stream != NULL) ? "ENABLED" : "DISABLED"));
429
418
 
430
419
  return 1;
431
420
  } /* init_sample */
@@ -494,9 +483,14 @@ Sound_Sample *Sound_NewSample(SDL_RWops *rw, const char *ext,
494
483
  } /* for */
495
484
 
496
485
  /* nothing could handle the sound data... */
497
- SDL_free(retval->opaque);
498
- if (retval->buffer != NULL)
499
- SDL_free(retval->buffer);
486
+ /* !!! FIXME: can we just push this through Sound_FreeSample() ? */
487
+ if (retval->opaque != NULL)
488
+ {
489
+ SDL_FreeAudioStream(((Sound_SampleInternal *) retval->opaque)->stream);
490
+ SDL_free(retval->opaque);
491
+ } /* if */
492
+
493
+ __Sound_SIMDFree(retval->buffer);
500
494
  SDL_free(retval);
501
495
  SDL_RWclose(rw);
502
496
  __Sound_SetError(ERR_UNSUPPORTED_FORMAT);
@@ -592,14 +586,9 @@ void Sound_FreeSample(Sound_Sample *sample)
592
586
  if (internal->rw != NULL) /* this condition is a "just in case" thing. */
593
587
  SDL_RWclose(internal->rw);
594
588
 
595
- if ((internal->buffer != NULL) && (internal->buffer != sample->buffer))
596
- SDL_free(internal->buffer);
597
-
589
+ SDL_FreeAudioStream(internal->stream);
598
590
  SDL_free(internal);
599
-
600
- if (sample->buffer != NULL)
601
- SDL_free(sample->buffer);
602
-
591
+ __Sound_SIMDFree(sample->buffer);
603
592
  SDL_free(sample);
604
593
  } /* Sound_FreeSample */
605
594
 
@@ -612,13 +601,11 @@ int Sound_SetBufferSize(Sound_Sample *sample, Uint32 newSize)
612
601
  BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0);
613
602
  BAIL_IF_MACRO(sample == NULL, ERR_INVALID_ARGUMENT, 0);
614
603
  internal = ((Sound_SampleInternal *) sample->opaque);
615
- newBuf = SDL_realloc(sample->buffer, newSize * internal->sdlcvt.len_mult);
604
+ newBuf = __Sound_SIMDRealloc(sample->buffer, newSize);
616
605
  BAIL_IF_MACRO(newBuf == NULL, ERR_OUT_OF_MEMORY, 0);
617
606
 
618
- internal->sdlcvt.buf = internal->buffer = sample->buffer = newBuf;
619
- sample->buffer_size = newSize;
620
- internal->buffer_size = newSize / internal->sdlcvt.len_mult;
621
- internal->sdlcvt.len = internal->buffer_size;
607
+ internal->buffer = sample->buffer = newBuf;
608
+ internal->buffer_size = sample->buffer_size = newSize;
622
609
 
623
610
  return 1;
624
611
  } /* Sound_SetBufferSize */
@@ -627,7 +614,7 @@ int Sound_SetBufferSize(Sound_Sample *sample, Uint32 newSize)
627
614
  Uint32 Sound_Decode(Sound_Sample *sample)
628
615
  {
629
616
  Sound_SampleInternal *internal = NULL;
630
- Uint32 retval = 0;
617
+ int available;
631
618
 
632
619
  /* a boatload of sanity checks... */
633
620
  BAIL_IF_MACRO(!initialized, ERR_NOT_INITIALIZED, 0);
@@ -642,18 +629,80 @@ Uint32 Sound_Decode(Sound_Sample *sample)
642
629
  SDL_assert(internal->buffer != NULL);
643
630
  SDL_assert(internal->buffer_size > 0);
644
631
 
632
+ /* No AudioStream? No conversion. Decode right into the buffer and return it. */
633
+ if (!internal->stream)
634
+ {
645
635
  /* reset EAGAIN. Decoder can flip it back on if it needs to. */
646
- sample->flags &= ~SOUND_SAMPLEFLAG_EAGAIN;
647
- retval = internal->funcs->read(sample);
636
+ sample->flags &= ~SOUND_SAMPLEFLAG_EAGAIN;
637
+ return internal->funcs->read(sample);
638
+ } /* if */
648
639
 
649
- if (retval > 0 && internal->sdlcvt.needed)
640
+ /* call into the decoder several times until we have enough data. */
641
+ while ((available = SDL_AudioStreamAvailable(internal->stream)) < internal->buffer_size)
650
642
  {
651
- internal->sdlcvt.len = retval;
652
- SDL_ConvertAudio(&internal->sdlcvt);
653
- retval = internal->sdlcvt.len_cvt;
643
+ SDL_bool flush_stream = SDL_FALSE;
644
+ Uint32 br;
645
+
646
+ if (internal->pending_eof || internal->pending_error)
647
+ break;
648
+
649
+ /* reset EAGAIN. Decoder can flip it back on if it needs to. */
650
+ sample->flags &= ~SOUND_SAMPLEFLAG_EAGAIN;
651
+ br = internal->funcs->read(sample);
652
+
653
+ /* if the sample hit an error or EOF, note it, but don't let these flags
654
+ be set for the calling app until the stream is empty too. */
655
+ if (sample->flags & SOUND_SAMPLEFLAG_EOF)
656
+ {
657
+ sample->flags &= ~SOUND_SAMPLEFLAG_EOF;
658
+ internal->pending_eof = SDL_TRUE;
659
+ flush_stream = SDL_TRUE;
660
+ } /* if */
661
+
662
+ if (sample->flags & SOUND_SAMPLEFLAG_ERROR)
663
+ {
664
+ sample->flags &= ~SOUND_SAMPLEFLAG_ERROR;
665
+ internal->pending_error = SDL_TRUE;
666
+ flush_stream = SDL_TRUE;
667
+ } /* if */
668
+
669
+ if ((br > 0) && (SDL_AudioStreamPut(internal->stream, internal->buffer, (int) br) == -1))
670
+ {
671
+ __Sound_SetError(SDL_GetError());
672
+ sample->flags |= SOUND_SAMPLEFLAG_ERROR;
673
+ return 0; /* oh well. */
674
+ } /* if */
675
+
676
+ if (flush_stream)
677
+ SDL_AudioStreamFlush(internal->stream);
678
+ } /* while */
679
+
680
+ /* if we hit eof or error, drain the stream before reporting that. */
681
+ if (available > 0)
682
+ {
683
+ const int readlen = SDL_min(available, sample->buffer_size);
684
+ const int br = SDL_AudioStreamGet(internal->stream, sample->buffer, readlen);
685
+ if (br != readlen)
686
+ {
687
+ __Sound_SetError(SDL_GetError());
688
+ sample->flags |= SOUND_SAMPLEFLAG_ERROR;
689
+ return 0; /* oh well. */
690
+ } /* if */
691
+
692
+ SDL_assert(br > 0);
693
+ return (Uint32) br;
654
694
  } /* if */
655
695
 
656
- return retval;
696
+ /* stream is empty, set final flags. */
697
+ if (internal->pending_eof)
698
+ sample->flags |= SOUND_SAMPLEFLAG_EOF;
699
+
700
+ if (internal->pending_error)
701
+ sample->flags |= SOUND_SAMPLEFLAG_ERROR;
702
+
703
+ internal->pending_eof = internal->pending_error = SDL_FALSE;
704
+
705
+ return 0;
657
706
  } /* Sound_Decode */
658
707
 
659
708
 
@@ -673,7 +722,7 @@ Uint32 Sound_DecodeAll(Sound_Sample *sample)
673
722
  ((sample->flags & SOUND_SAMPLEFLAG_ERROR) == 0) )
674
723
  {
675
724
  Uint32 br = Sound_Decode(sample);
676
- void *ptr = SDL_realloc(buf, newBufSize + br);
725
+ void *ptr = __Sound_SIMDRealloc(buf, newBufSize + br);
677
726
  if (ptr == NULL)
678
727
  {
679
728
  sample->flags |= SOUND_SAMPLEFLAG_ERROR;
@@ -687,18 +736,13 @@ Uint32 Sound_DecodeAll(Sound_Sample *sample)
687
736
  } /* else */
688
737
  } /* while */
689
738
 
690
- if (buf == NULL) /* ...in case first call to SDL_realloc() fails... */
739
+ if (buf == NULL) /* ...in case first call to __Sound_SIMDRealloc() fails... */
691
740
  return sample->buffer_size;
692
741
 
693
- if (internal->buffer != sample->buffer)
694
- SDL_free(internal->buffer);
695
-
696
- SDL_free(sample->buffer);
742
+ __Sound_SIMDFree(sample->buffer);
697
743
 
698
- internal->sdlcvt.buf = internal->buffer = sample->buffer = buf;
699
- sample->buffer_size = newBufSize;
700
- internal->buffer_size = newBufSize / internal->sdlcvt.len_mult;
701
- internal->sdlcvt.len = internal->buffer_size;
744
+ internal->buffer = sample->buffer = buf;
745
+ internal->buffer_size = sample->buffer_size = newBufSize;
702
746
 
703
747
  return newBufSize;
704
748
  } /* Sound_DecodeAll */
@@ -825,5 +869,100 @@ char *__Sound_strtokr(char *s1, const char *s2, char **ptr)
825
869
  }
826
870
  #endif
827
871
 
872
+
873
+ /* This falls back to an included copy/paste of SDL's SIMDAlloc code if you aren't using a new enough SDL.
874
+ To keep this simple, the included copy assumes you need to align to 64 bytes, which is a little
875
+ wasteful but should work on everything from MMX to AVX-512. The real SDL checks the CPU at runtime
876
+ to decide what's available and aligns to smaller numbers if all you have is SSE, Altivec or NEON.
877
+ Not to mention this is just a second copy of the code that doesn't get attention...you should really
878
+ upgrade your SDL. Ideally this copy goes away at some point. */
879
+
880
+ #define USE_REAL_SDL_SIMDALLOC SDL_VERSION_ATLEAST(2, 0, 14)
881
+
882
+ void *__Sound_SIMDAlloc(const size_t len)
883
+ {
884
+ #if USE_REAL_SDL_SIMDALLOC
885
+ return SDL_SIMDAlloc(len);
886
+ #else
887
+ const size_t alignment = 64;
888
+ const size_t padding = alignment - (len % alignment);
889
+ const size_t padded = (padding != alignment) ? (len + padding) : len;
890
+ Uint8 *retval = NULL;
891
+ Uint8 *ptr = (Uint8 *) SDL_malloc(padded + alignment + sizeof (void *));
892
+ if (ptr) {
893
+ /* store the actual allocated pointer right before our aligned pointer. */
894
+ retval = ptr + sizeof (void *);
895
+ retval += alignment - (((size_t) retval) % alignment);
896
+ *(((void **) retval) - 1) = ptr;
897
+ }
898
+ return retval;
899
+ #endif
900
+ }
901
+
902
+ void *__Sound_SIMDRealloc(void *mem, const size_t len)
903
+ {
904
+ #if USE_REAL_SDL_SIMDALLOC
905
+ return SDL_SIMDRealloc(mem, len);
906
+ #else
907
+ const size_t alignment = 64;
908
+ const size_t padding = alignment - (len % alignment);
909
+ const size_t padded = (padding != alignment) ? (len + padding) : len;
910
+ Uint8 *retval = (Uint8*) mem;
911
+ void *oldmem = mem;
912
+ size_t memdiff = 0, ptrdiff;
913
+ Uint8 *ptr;
914
+
915
+ if (mem) {
916
+ void **realptr = (void **) mem;
917
+ realptr--;
918
+ mem = *(((void **) mem) - 1);
919
+
920
+ /* Check the delta between the real pointer and user pointer */
921
+ memdiff = ((size_t) oldmem) - ((size_t) mem);
922
+ }
923
+
924
+ ptr = (Uint8 *) SDL_realloc(mem, padded + alignment + sizeof (void *));
925
+
926
+ if (ptr == NULL) {
927
+ return NULL; /* Out of memory, bail! */
928
+ }
929
+
930
+ /* Store the actual allocated pointer right before our aligned pointer. */
931
+ retval = ptr + sizeof (void *);
932
+ retval += alignment - (((size_t) retval) % alignment);
933
+
934
+ /* Make sure the delta is the same! */
935
+ if (mem) {
936
+ ptrdiff = ((size_t) retval) - ((size_t) ptr);
937
+ if (memdiff != ptrdiff) { /* Delta has changed, copy to new offset! */
938
+ oldmem = (void*) (((uintptr_t) ptr) + memdiff);
939
+
940
+ /* Even though the data past the old `len` is undefined, this is the
941
+ * only length value we have, and it guarantees that we copy all the
942
+ * previous memory anyhow.
943
+ */
944
+ SDL_memmove(retval, oldmem, len);
945
+ }
946
+ }
947
+
948
+ /* Actually store the allocated pointer, finally. */
949
+ *(((void **) retval) - 1) = ptr;
950
+ return retval;
951
+ #endif
952
+ }
953
+
954
+ void __Sound_SIMDFree(void *ptr)
955
+ {
956
+ #if USE_REAL_SDL_SIMDALLOC
957
+ SDL_SIMDFree(ptr);
958
+ #else
959
+ if (ptr) {
960
+ void **realptr = (void **) ptr;
961
+ realptr--;
962
+ SDL_free(*(((void **) ptr) - 1));
963
+ }
964
+ #endif
965
+ }
966
+
828
967
  /* end of SDL_sound.c ... */
829
968
 
@@ -72,7 +72,7 @@ extern "C" {
72
72
 
73
73
  #define SOUND_VER_MAJOR 2
74
74
  #define SOUND_VER_MINOR 0
75
- #define SOUND_VER_PATCH 0
75
+ #define SOUND_VER_PATCH 1
76
76
  #endif
77
77
 
78
78