SDL: rwops: Renamed SDL_RWops to SDL_IOStream, and other related symbols.

From fc7afa9cbf400d270f33a8eda5483825f323510e Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Thu, 14 Mar 2024 19:32:50 -0400
Subject: [PATCH] rwops: Renamed SDL_RWops to SDL_IOStream, and other related
 symbols.

---
 build-scripts/SDL_migration.cocci |  53 +++-
 docs/README-emscripten.md         |   2 +-
 docs/README-migration.md          |  99 +++---
 docs/README-winrt.md              |   2 +-
 include/SDL3/SDL_audio.h          |  10 +-
 include/SDL3/SDL_gamepad.h        |   4 +-
 include/SDL3/SDL_hints.h          |   6 +-
 include/SDL3/SDL_init.h           |   2 +-
 include/SDL3/SDL_oldnames.h       |  50 +--
 include/SDL3/SDL_rwops.h          | 454 ++++++++++++++--------------
 include/SDL3/SDL_surface.h        |  18 +-
 src/audio/SDL_wave.c              |  46 +--
 src/audio/disk/SDL_diskaudio.c    |  10 +-
 src/audio/disk/SDL_diskaudio.h    |   2 +-
 src/dynapi/SDL_dynapi.c           |  10 +-
 src/dynapi/SDL_dynapi.sym         |  30 +-
 src/dynapi/SDL_dynapi_overrides.h |  30 +-
 src/dynapi/SDL_dynapi_procs.h     |  90 +++---
 src/file/SDL_rwops.c              | 486 +++++++++++++++---------------
 src/joystick/SDL_gamepad.c        |   4 +-
 src/test/SDL_test_common.c        |  18 +-
 src/video/SDL_bmp.c               |  50 +--
 test/gamepadutils.c               |   4 +-
 test/testautomation.c             |   2 +-
 test/testautomation_rwops.c       | 444 +++++++++++++--------------
 test/testautomation_suites.h      |   2 +-
 test/testffmpeg.c                 |   4 +-
 test/testfile.c                   | 344 ++++++++++-----------
 test/testime.c                    |  12 +-
 test/testoverlay.c                |   8 +-
 test/testresample.c               |   8 +-
 test/testshape.c                  |   2 +-
 test/testspriteminimal.c          |   4 +-
 test/teststreaming.c              |   8 +-
 test/testutils.c                  |   6 +-
 test/testwaylandcustom.c          |   4 +-
 36 files changed, 1195 insertions(+), 1133 deletions(-)

diff --git a/build-scripts/SDL_migration.cocci b/build-scripts/SDL_migration.cocci
index 4a857728e091b..673c2f4d4f681 100644
--- a/build-scripts/SDL_migration.cocci
+++ b/build-scripts/SDL_migration.cocci
@@ -1804,15 +1804,15 @@ expression e2;
 @@
 @@
 - RW_SEEK_CUR
-+ SDL_RW_SEEK_CUR
++ SDL_IO_SEEK_CUR
 @@
 @@
 - RW_SEEK_END
-+ SDL_RW_SEEK_END
++ SDL_IO_SEEK_END
 @@
 @@
 - RW_SEEK_SET
-+ SDL_RW_SEEK_SET
++ SDL_IO_SEEK_SET
 @@
 @@
 - SDL_SensorClose
@@ -3051,30 +3051,65 @@ typedef SDL_version, SDL_Version;
 @@
 @@
 - SDL_RWclose
-+ SDL_CloseRW
++ SDL_CloseIO
   (...)
 @@
 @@
 - SDL_RWread
-+ SDL_ReadRW
++ SDL_ReadIO
   (...)
 @@
 @@
 - SDL_RWwrite
-+ SDL_WriteRW
++ SDL_WriteIO
   (...)
 @@
 @@
 - SDL_RWtell
-+ SDL_TellRW
++ SDL_TellIO
   (...)
 @@
 @@
 - SDL_RWsize
-+ SDL_SizeRW
++ SDL_SizeIO
   (...)
 @@
 @@
 - SDL_RWseek
-+ SDL_SeekRW
++ SDL_SeekIO
   (...)
+@@
+@@
+- SDL_LoadBMP_RW
++ SDL_LoadBMP_IO
+  (...)
+@@
+@@
+- SDL_LoadWAV_RW
++ SDL_LoadWAV_IO
+  (...)
+@@
+@@
+- SDL_SaveBMP_RW
++ SDL_SaveBMP_IO
+  (...)
+@@
+@@
+- SDL_RWFromFile
++ SDL_IOFromFile
+  (...)
+@@
+@@
+- SDL_RWFromMem
++ SDL_IOFromMem
+  (...)
+@@
+@@
+- SDL_RWFromConstMem
++ SDL_IOFromConstMem
+  (...)
+@@
+typedef SDL_RWops, SDL_IOStream;
+@@
+- SDL_RWops
++ SDL_IOStream
diff --git a/docs/README-emscripten.md b/docs/README-emscripten.md
index 31553e069a576..6a445bd46fe55 100644
--- a/docs/README-emscripten.md
+++ b/docs/README-emscripten.md
@@ -301,7 +301,7 @@ Your game probably has data files. Here's how to access them.
 Filesystem access works like a Unix filesystem; you have a single directory
 tree, possibly interpolated from several mounted locations, no drive letters,
 '/' for a path separator. You can access them with standard file APIs like
-open() or fopen() or SDL_RWops. You can read or write from the filesystem.
+open() or fopen() or SDL_IOStream. You can read or write from the filesystem.
 
 By default, you probably have a "MEMFS" filesystem (all files are stored in
 memory, but access to them is immediate and doesn't need to block). There are
diff --git a/docs/README-migration.md b/docs/README-migration.md
index 0bc458dd8329d..d599f75fe5807 100644
--- a/docs/README-migration.md
+++ b/docs/README-migration.md
@@ -191,7 +191,7 @@ SDL_FreeWAV has been removed and calls can be replaced with SDL_free.
 
 SDL_LoadWAV() is a proper function now and no longer a macro (but offers the same functionality otherwise).
 
-SDL_LoadWAV_RW() and SDL_LoadWAV() return an int now: zero on success, -1 on error, like most of SDL. They no longer return a pointer to an SDL_AudioSpec.
+SDL_LoadWAV_IO() and SDL_LoadWAV() return an int now: zero on success, -1 on error, like most of SDL. They no longer return a pointer to an SDL_AudioSpec.
 
 SDL_AudioCVT interface has been removed, the SDL_AudioStream interface (for audio supplied in pieces) or the new SDL_ConvertAudioSamples() function (for converting a complete audio buffer in one call) can be used instead.
 
@@ -253,6 +253,7 @@ The following functions have been renamed:
 * SDL_AudioStreamGet() => SDL_GetAudioStreamData()
 * SDL_AudioStreamPut() => SDL_PutAudioStreamData()
 * SDL_FreeAudioStream() => SDL_DestroyAudioStream()
+* SDL_LoadWAV_RW() => SDL_LoadWAV_IO()
 * SDL_NewAudioStream() => SDL_CreateAudioStream()
 
 
@@ -1152,80 +1153,79 @@ The following symbols have been renamed:
 ## SDL_rwops.h
 
 The following symbols have been renamed:
-* RW_SEEK_CUR => SDL_RW_SEEK_CUR
-* RW_SEEK_END => SDL_RW_SEEK_END
-* RW_SEEK_SET => SDL_RW_SEEK_SET
+* RW_SEEK_CUR => SDL_IO_SEEK_CUR
+* RW_SEEK_END => SDL_IO_SEEK_END
+* RW_SEEK_SET => SDL_IO_SEEK_SET
 
-SDL_RWops is now an opaque structure. The existing APIs to create a RWops (SDL_RWFromFile, etc) still function as expected, but to make a custom RWops with app-provided function pointers, call SDL_OpenRW and provide the function pointers through there. To call into a RWops's functionality, use the standard APIs (SDL_ReadRW, etc) instead of calling into function pointers directly.
+SDL_RWops is now an opaque structure, and has been renamed to SDL_IOStream. The SDL3 APIs to create an SDL_IOStream (SDL_IOFromFile, etc) are renamed but otherwise still function as they did in SDL2. However, to make a custom SDL_IOStream with app-provided function pointers, call SDL_OpenIO and provide the function pointers through there. To call into an SDL_IOStream's functionality, use the standard APIs (SDL_ReadIO, etc), as the function pointers are concealed.
 
-The RWops function pointers are now in a separate structure called SDL_RWopsInteface, which is provided to SDL_OpenRW. All the functions now take a `void *` userdata argument for their first parameter instead of an SDL_RWops, since that's now an opaque structure.
+The RWops function pointers are now in a separate structure called SDL_IOStreamInterface, which is provided to SDL_OpenIO when creating a custom SDL_IOStream implementation. All the functions now take a `void *` userdata argument for their first parameter instead of an SDL_IOStream, since that's now an opaque structure.
 
-SDL_RWread and SDL_RWwrite (and the read and write function pointers) have a different function signature in SDL3 in addition to being renamed.
+SDL_RWread and SDL_RWwrite (and the read and write function pointers) have a different function signature in SDL3, in addition to being renamed.
 
 Previously they looked more like stdio:
 
 ```c
-size_t SDL_RWread(SDL_RWops *context, void *ptr, size_t size, size_t maxnum);
-size_t SDL_RWwrite(SDL_RWops *context, const void *ptr, size_t size, size_t maxnum);
+size_t SDL_RWread(SDL_IOStream *context, void *ptr, size_t size, size_t maxnum);
+size_t SDL_RWwrite(SDL_IOStream *context, const void *ptr, size_t size, size_t maxnum);

But now they look more like POSIX:

-size_t SDL_ReadRW(void *userdata, void *ptr, size_t size);
-size_t SDL_WriteRW(void *userdata, const void *ptr, size_t size);
+size_t SDL_ReadIO(void *userdata, void *ptr, size_t size);
+size_t SDL_WriteIO(void *userdata, const void *ptr, size_t size);

Code that used to look like this:

-size_t custom_read(void *ptr, size_t size, size_t nitems, SDL_RWops *stream)
+size_t custom_read(void *ptr, size_t size, size_t nitems, SDL_IOStream *stream)
{
    return SDL_RWread(stream, ptr, size, nitems);
}

should be changed to:

-size_t custom_read(void *ptr, size_t size, size_t nitems, SDL_RWops *stream)
+size_t custom_read(void *ptr, size_t size, size_t nitems, SDL_IOStream *stream, SDL_IOStatus *status)
{
    if (size > 0 && nitems > 0) {
-        return SDL_ReadRW(stream, ptr, size * nitems) / size;
+        return SDL_ReadIO(stream, ptr, size * nitems) / size;
    }
    return 0;
}

-SDL_RWops::type was removed and has no replacement; it wasn’t meaningful for app-provided implementations at all, and wasn’t much use for SDL’s internal implementations, either.
+SDL_IOStream::type was removed; it wasn’t meaningful for app-provided implementations at all, and wasn’t much use for SDL’s internal implementations, either. If you have to identify the type, you can examine the SDL_IOStream’s properties to detect built-in implementations.

-SDL_RWopsInterface::close implementations should clean up their own userdata, but not call SDL_CloseRW on themselves; now the contract is always that SDL_CloseRW is called, which calls ->close and then frees the opaque object.
+SDL_IOStreamInterface::close implementations should clean up their own userdata, but not call SDL_CloseIO on themselves; now the contract is always that SDL_CloseIO is called, which calls ->close before freeing the opaque object.

-SDL_RWFromFP has been removed from the API, due to issues when the SDL library uses a different C runtime from the application.

-SDL_AllocRW(), SDL_FreeRW(), SDL_CloseRW() and direct access to the ->close function pointer have been removed from the API, so there’s only one path to manage RWops lifetimes now: SDL_OpenRW() and SDL_CloseRW().
+SDL_AllocRW(), SDL_FreeRW(), SDL_RWclose() and direct access to the ->close function pointer have been removed from the API, so there’s only one path to manage RWops lifetimes now: SDL_OpenIO() and SDL_CloseIO().

+SDL_RWFromFP has been removed from the API, due to issues when the SDL library uses a different C runtime from the application.

You can implement this in your own code easily:

#include <stdio.h>

-typedef struct RWopsStdioFPData
+typedef struct IOStreamStdioFPData
{
    FILE *fp;
    SDL_bool autoclose;
-} RWopsStdioFPData;
+} IOStreamStdioFPData;

static Sint64 SDLCALL stdio_seek(void *userdata, Sint64 offset, int whence)
{
-    FILE *fp = ((RWopsStdioFPData *) userdata)->fp;
+    FILE *fp = ((IOStreamStdioFPData *) userdata)->fp;
    int stdiowhence;

    switch (whence) {
-    case SDL_RW_SEEK_SET:
+    case SDL_IO_SEEK_SET:
        stdiowhence = SEEK_SET;
        break;
-    case SDL_RW_SEEK_CUR:
+    case SDL_IO_SEEK_CUR:
        stdiowhence = SEEK_CUR;
        break;
-    case SDL_RW_SEEK_END:
+    case SDL_IO_SEEK_END:
        stdiowhence = SEEK_END;
        break;
    default:
@@ -1242,9 +1242,9 @@ static Sint64 SDLCALL stdio_seek(void *userdata, Sint64 offset, int whence)
    return SDL_Error(SDL_EFSEEK);
}

-static size_t SDLCALL stdio_read(void *userdata, void *ptr, size_t size)
+static size_t SDLCALL stdio_read(void *userdata, void *ptr, size_t size, SDL_IOStatus *status)
{
-    FILE *fp = ((RWopsStdioFPData *) userdata)->fp;
+    FILE *fp = ((IOStreamStdioFPData *) userdata)->fp;
    const size_t bytes = fread(ptr, 1, size, fp);
    if (bytes == 0 && ferror(fp)) {
        SDL_Error(SDL_EFREAD);
@@ -1252,9 +1252,9 @@ static size_t SDLCALL stdio_read(void *userdata, void *ptr, size_t size)
    return bytes;
}

-static size_t SDLCALL stdio_write(void *userdata, const void *ptr, size_t size)
+static size_t SDLCALL stdio_write(void *userdata, const void *ptr, size_t size, SDL_IOStatus *status)
{
-    FILE *fp = ((RWopsStdioFPData *) userdata)->fp;
+    FILE *fp = ((IOStreamStdioFPData *) userdata)->fp;
    const size_t bytes = fwrite(ptr, 1, size, fp);
    if (bytes == 0 && ferror(fp)) {
        SDL_Error(SDL_EFWRITE);
@@ -1264,7 +1264,7 @@ static size_t SDLCALL stdio_write(void *userdata, const void *ptr, size_t size)

static int SDLCALL stdio_close(void *userdata)
{
-    RWopsStdioData *rwopsdata = (RWopsStdioData *) userdata;
+    IOStreamStdioData *rwopsdata = (IOStreamStdioData *) userdata;
    int status = 0;
    if (rwopsdata->autoclose) {
        if (fclose(rwopsdata->fp) != 0) {
@@ -1274,19 +1274,19 @@ static int SDLCALL stdio_close(void *userdata)
    return status;
}

-SDL_RWops *SDL_RWFromFP(FILE *fp, SDL_bool autoclose)
+SDL_IOStream *SDL_RWFromFP(FILE *fp, SDL_bool autoclose)
{
-    SDL_RWopsInterface iface;
-    RWopsStdioFPData *rwopsdata;
-    SDL_RWops *rwops;
+    SDL_IOStreamInterface iface;
+    IOStreamStdioFPData *rwopsdata;
+    SDL_IOStream *rwops;

-    rwopsdata = (RWopsStdioFPData *) SDL_malloc(sizeof (*rwopsdata));
+    rwopsdata = (IOStreamStdioFPData *) SDL_malloc(sizeof (*rwopsdata));
    if (!rwopsdata) {
        return NULL;
    }

    SDL_zero(iface);
-    /* There's no stdio_size because SDL_SizeRW emulates it the same way we'd do it for stdio anyhow. */
+    /* There's no stdio_size because SDL_SizeIO emulates it the same way we'd do it for stdio anyhow. */
    iface.seek = stdio_seek;
    iface.read = stdio_read;
    iface.write = stdio_write;
@@ -1295,7 +1295,7 @@ SDL_RWops *SDL_RWFromFP(FILE *fp, SDL_bool autoclose)
    rwopsdata->fp = fp;
    rwopsdata->autoclose = autoclose;

-    rwops = SDL_OpenRW(&iface, rwopsdata);
+    rwops = SDL_OpenIO(&iface, rwopsdata);
    if (!rwops) {
        iface.close(rwopsdata);
    }
@@ -1303,15 +1303,22 @@ SDL_RWops *SDL_RWFromFP(FILE *fp, SDL_bool autoclose)
}

+The internal FILE * is available through a standard SDL_IOStream property, for streams made through SDL_IOFromFile() that use stdio behind the scenes; apps use this pointer at their own risk and should make sure that SDL and the app are using the same C runtime.
+
+
The functions SDL_ReadU8(), SDL_ReadU16LE(), SDL_ReadU16BE(), SDL_ReadU32LE(), SDL_ReadU32BE(), SDL_ReadU64LE(), and SDL_ReadU64BE() now return SDL_TRUE if the read succeeded and SDL_FALSE if it didn’t, and store the data in a pointer passed in as a parameter.

The following functions have been renamed:
-* SDL_RWclose() => SDL_CloseRW()
-* SDL_RWread() => SDL_ReadRW()
-* SDL_RWseek() => SDL_SeekRW()
-* SDL_RWsize() => SDL_SizeRW()
-* SDL_RWtell() => SDL_TellRW()
-* SDL_RWwrite() => SDL_WriteRW()
+* SDL_CloseRW() => SDL_CloseIO()
+* SDL_RWFromConstMem() => SDL_IOFromConstMem()
+* SDL_RWFromFile() => SDL_IOFromFile()
+* SDL_RWFromMem() => SDL_IOFromMem()
+* SDL_RWclose() => SDL_CloseIO()
+* SDL_RWread() => SDL_ReadIO()
+* SDL_RWseek() => SDL_SeekIO()
+* SDL_RWsize() => SDL_SizeIO()
+* SDL_RWtell() => SDL_TellIO()
+* SDL_RWwrite() => SDL_WriteIO()

  • SDL_ReadBE16() => SDL_ReadU16BE()
  • SDL_ReadBE32() => SDL_ReadU32BE()
  • SDL_ReadBE64() => SDL_ReadU64BE()
    @@ -1325,6 +1332,10 @@ The following functions have been renamed:
  • SDL_WriteLE32() => SDL_WriteU32LE()
  • SDL_WriteLE64() => SDL_WriteU64LE()

+The following structures have been renamed:
+* SDL_RWops => SDL_IOStream
+

SDL_sensor.h

SDL_SensorID has changed from Sint32 to Uint32, with an invalid ID being 0.
@@ -1448,8 +1459,10 @@ The following functions have been renamed:

  • SDL_GetColorKey() => SDL_GetSurfaceColorKey()
  • SDL_HasColorKey() => SDL_SurfaceHasColorKey()
  • SDL_HasSurfaceRLE() => SDL_SurfaceHasRLE()
    +* SDL_LoadBMP_RW() => SDL_LoadBMP_IO()
  • SDL_LowerBlit() => SDL_BlitSurfaceUnchecked()
  • SDL_LowerBlitScaled() => SDL_BlitSurfaceUncheckedScaled()
    +* SDL_SaveBMP_RW() => SDL_SaveBMP_IO()
  • SDL_SetClipRect() => SDL_SetSurfaceClipRect()
  • SDL_SetColorKey() => SDL_SetSurfaceColorKey()
  • SDL_UpperBlit() => SDL_BlitSurface()
    diff --git a/docs/README-winrt.md b/docs/README-winrt.md
    index 6e73c93f520c5…7ef21be69e27b 100644
    — a/docs/README-winrt.md
    +++ b/docs/README-winrt.md
    @@ -42,7 +42,7 @@ Here is a rough list of what works, and what doesn’t:
    • threads
    • timers (via SDL_GetTicks(), SDL_AddTimer(), SDL_GetPerformanceCounter(),
      SDL_GetPerformanceFrequency(), etc.)
    • file I/O via SDL_RWops
    • file I/O via SDL_IOStream
    • mouse input (unsupported on Windows Phone)
    • audio, via SDL’s WASAPI backend (if you want to record, your app must
      have “Microphone” capabilities enabled in its manifest, and the user must
      diff --git a/include/SDL3/SDL_audio.h b/include/SDL3/SDL_audio.h
      index 281af06b04db7…fca0b32052c57 100644
      — a/include/SDL3/SDL_audio.h
      +++ b/include/SDL3/SDL_audio.h
      @@ -1306,7 +1306,7 @@ extern DECLSPEC int SDLCALL SDL_SetAudioPostmixCallback(SDL_AudioDeviceID devid,
  • Example:
    • SDL_LoadWAV_RW(SDL_RWFromFile(“sample.wav”, “rb”), 1, &spec, &buf, &len);
    • SDL_LoadWAV_IO(SDL_IOFromFile(“sample.wav”, “rb”), 1, &spec, &buf, &len);
    • Note that the SDL_LoadWAV function does this same thing for you, but in a
      @@ -1317,7 +1317,7 @@ extern DECLSPEC int SDLCALL SDL_SetAudioPostmixCallback(SDL_AudioDeviceID devid,
    • \param src The data source for the WAVE data
    • \param freesrc If SDL_TRUE, calls SDL_CloseRW() on src before returning,
    • \param freesrc If SDL_TRUE, calls SDL_CloseIO() on src before returning,
    •            even in the case of an error
      
    • \param spec A pointer to an SDL_AudioSpec that will be set to the WAVE
    •         data's format details on successful return
      

@@ -1344,7 +1344,7 @@ extern DECLSPEC int SDLCALL SDL_SetAudioPostmixCallback(SDL_AudioDeviceID devid,

  • \sa SDL_free
  • \sa SDL_LoadWAV
    */
    -extern DECLSPEC int SDLCALL SDL_LoadWAV_RW(SDL_RWops * src, SDL_bool freesrc,
    +extern DECLSPEC int SDLCALL SDL_LoadWAV_IO(SDL_IOStream * src, SDL_bool freesrc,
    SDL_AudioSpec * spec, Uint8 ** audio_buf,
    Uint32 * audio_len);

@@ -1354,7 +1354,7 @@ extern DECLSPEC int SDLCALL SDL_LoadWAV_RW(SDL_RWops * src, SDL_bool freesrc,

  • This is a convenience function that is effectively the same as:
    • SDL_LoadWAV_RW(SDL_RWFromFile(path, “rb”), 1, spec, audio_buf, audio_len);
    • SDL_LoadWAV_IO(SDL_IOFromFile(path, “rb”), 1, spec, audio_buf, audio_len);
    • Note that in SDL2, this was a preprocessor macro and not a real function.
      @@ -1383,7 +1383,7 @@ extern DECLSPEC int SDLCALL SDL_LoadWAV_RW(SDL_RWops * src, SDL_bool freesrc,
    • \since This function is available since SDL 3.0.0.
    • \sa SDL_free
    • \sa SDL_LoadWAV_RW
    • \sa SDL_LoadWAV_IO
      */
      extern DECLSPEC int SDLCALL SDL_LoadWAV(const char *path, SDL_AudioSpec * spec,
      Uint8 ** audio_buf, Uint32 * audio_len);
      diff --git a/include/SDL3/SDL_gamepad.h b/include/SDL3/SDL_gamepad.h
      index 2a65a30748003…7e0fdfd8fa484 100644
      — a/include/SDL3/SDL_gamepad.h
      +++ b/include/SDL3/SDL_gamepad.h
      @@ -268,7 +268,7 @@ extern DECLSPEC int SDLCALL SDL_AddGamepadMapping(const char *mapping);
    • constrained environment.
    • \param src the data stream for the mappings to be added
    • \param freesrc if SDL_TRUE, calls SDL_CloseRW() on src before returning,
    • \param freesrc if SDL_TRUE, calls SDL_CloseIO() on src before returning,
    •            even in the case of an error
      
    • \returns the number of mappings added or -1 on error; call SDL_GetError()
    •      for more information.
      

@@ -279,7 +279,7 @@ extern DECLSPEC int SDLCALL SDL_AddGamepadMapping(const char *mapping);

  • \sa SDL_AddGamepadMappingsFromFile
  • \sa SDL_GetGamepadMappingForGUID
    */
    -extern DECLSPEC int SDLCALL SDL_AddGamepadMappingsFromRW(SDL_RWops *src, SDL_bool freesrc);
    +extern DECLSPEC int SDLCALL SDL_AddGamepadMappingsFromRW(SDL_IOStream *src, SDL_bool freesrc);

/**

  • Load a set of gamepad mappings from a file.
    diff --git a/include/SDL3/SDL_hints.h b/include/SDL3/SDL_hints.h
    index 493645598e98a…5b16a34516b4d 100644
    — a/include/SDL3/SDL_hints.h
    +++ b/include/SDL3/SDL_hints.h
    @@ -2261,7 +2261,7 @@ extern “C” {
  • “ignorezero” - Like “truncate”, but ignore fact chunk if the number of samples is zero.
  • “ignore” - Ignore fact chunk entirely. (default)
    • This hint should be set before calling SDL_LoadWAV() or SDL_LoadWAV_RW()
    • This hint should be set before calling SDL_LoadWAV() or SDL_LoadWAV_IO()
      */
      #define SDL_HINT_WAVE_FACT_CHUNK “SDL_WAVE_FACT_CHUNK”

@@ -2278,7 +2278,7 @@ extern “C” {

  • “ignore” - Ignore the RIFF chunk size and always search up to 4 GiB.
  • “maximum” - Search for chunks until the end of file. (not recommended)
    • This hint should be set before calling SDL_LoadWAV() or SDL_LoadWAV_RW()
    • This hint should be set before calling SDL_LoadWAV() or SDL_LoadWAV_IO()
      */
      #define SDL_HINT_WAVE_RIFF_CHUNK_SIZE “SDL_WAVE_RIFF_CHUNK_SIZE”

@@ -2293,7 +2293,7 @@ extern “C” {

  • “dropframe” - Decode until the first incomplete sample frame.
  • “dropblock” - Decode until the first incomplete block. (default)
    • This hint should be set before calling SDL_LoadWAV() or SDL_LoadWAV_RW()
    • This hint should be set before calling SDL_LoadWAV() or SDL_LoadWAV_IO()
      */
      #define SDL_HINT_WAVE_TRUNCATION “SDL_WAVE_TRUNCATION”

diff --git a/include/SDL3/SDL_init.h b/include/SDL3/SDL_init.h
index 8459bf9ebbb2f…eb80d6bf48df1 100644
— a/include/SDL3/SDL_init.h
+++ b/include/SDL3/SDL_init.h
@@ -70,7 +70,7 @@ typedef enum

  • two may be used interchangeably. Though for readability of your code
  • SDL_InitSubSystem() might be preferred.
    • The file I/O (for example: SDL_RWFromFile) and threading (SDL_CreateThread)
    • The file I/O (for example: SDL_IOFromFile) and threading (SDL_CreateThread)
    • subsystems are initialized by default. Message boxes
    • (SDL_ShowSimpleMessageBox) also attempt to work without initializing the
    • video subsystem, in hopes of being useful in showing an error dialog when
      diff --git a/include/SDL3/SDL_oldnames.h b/include/SDL3/SDL_oldnames.h
      index 345991ba0c5d0…0a16365949f26 100644
      — a/include/SDL3/SDL_oldnames.h
      +++ b/include/SDL3/SDL_oldnames.h
      @@ -69,6 +69,7 @@
      #define SDL_AudioStreamPut SDL_PutAudioStreamData
      #define SDL_FreeAudioStream SDL_DestroyAudioStream
      #define SDL_FreeWAV SDL_free
      +#define SDL_LoadWAV_RW SDL_LoadWAV_IO
      #define SDL_NewAudioStream SDL_CreateAudioStream

/* ##SDL_events.h */
@@ -449,15 +450,19 @@
#define SDL_ScaleModeNearest SDL_SCALEMODE_NEAREST

/* ##SDL_rwops.h */
-#define RW_SEEK_CUR SDL_RW_SEEK_CUR
-#define RW_SEEK_END SDL_RW_SEEK_END
-#define RW_SEEK_SET SDL_RW_SEEK_SET
-#define SDL_RWclose SDL_CloseRW
-#define SDL_RWread SDL_ReadRW
-#define SDL_RWseek SDL_SeekRW
-#define SDL_RWsize SDL_SizeRW
-#define SDL_RWtell SDL_TellRW
-#define SDL_RWwrite SDL_WriteRW
+#define RW_SEEK_CUR SDL_IO_SEEK_CUR
+#define RW_SEEK_END SDL_IO_SEEK_END
+#define RW_SEEK_SET SDL_IO_SEEK_SET
+#define SDL_RWFromConstMem SDL_IOFromConstMem
+#define SDL_RWFromFile SDL_IOFromFile
+#define SDL_RWFromMem SDL_IOFromMem
+#define SDL_RWclose SDL_CloseIO
+#define SDL_RWops SDL_IOStream
+#define SDL_RWread SDL_ReadIO
+#define SDL_RWseek SDL_SeekIO
+#define SDL_RWsize SDL_SizeIO
+#define SDL_RWtell SDL_TellIO
+#define SDL_RWwrite SDL_WriteIO
#define SDL_ReadBE16 SDL_ReadU16BE
#define SDL_ReadBE32 SDL_ReadU32BE
#define SDL_ReadBE64 SDL_ReadU64BE
@@ -493,8 +498,10 @@
#define SDL_GetColorKey SDL_GetSurfaceColorKey
#define SDL_HasColorKey SDL_SurfaceHasColorKey
#define SDL_HasSurfaceRLE SDL_SurfaceHasRLE
+#define SDL_LoadBMP_RW SDL_LoadBMP_IO
#define SDL_LowerBlit SDL_BlitSurfaceUnchecked
#define SDL_LowerBlitScaled SDL_BlitSurfaceUncheckedScaled
+#define SDL_SaveBMP_RW SDL_SaveBMP_IO
#define SDL_SetClipRect SDL_SetSurfaceClipRect
#define SDL_SetColorKey SDL_SetSurfaceColorKey
#define SDL_UpperBlit SDL_BlitSurface
@@ -558,6 +565,7 @@
#define SDL_AudioStreamPut SDL_AudioStreamPut_renamed_SDL_PutAudioStreamData
#define SDL_FreeAudioStream SDL_FreeAudioStream_renamed_SDL_DestroyAudioStream
#define SDL_FreeWAV SDL_FreeWAV_renamed_SDL_free
+#define SDL_LoadWAV_RW SDL_LoadWAV_RW_renamed_SDL_LoadWAV_IO
#define SDL_NewAudioStream SDL_NewAudioStream_renamed_SDL_CreateAudioStream

/* ##SDL_events.h */
@@ -939,15 +947,19 @@
#define SDL_ScaleModeNearest SDL_ScaleModeNearest_renamed_SDL_SCALEMODE_NEAREST

/* ##SDL_rwops.h */
-#define RW_SEEK_CUR RW_SEEK_CUR_renamed_SDL_RW_SEEK_CUR
-#define RW_SEEK_END RW_SEEK_END_renamed_SDL_RW_SEEK_END
-#define RW_SEEK_SET RW_SEEK_SET_renamed_SDL_RW_SEEK_SET
-#define SDL_RWclose SDL_RWclose_renamed_SDL_CloseRW
-#define SDL_RWread SDL_RWread_renamed_SDL_ReadRW
-#define SDL_RWseek SDL_RWseek_renamed_SDL_SeekRW
-#define SDL_RWsize SDL_RWsize_renamed_SDL_SizeRW
-#define SDL_RWtell SDL_RWtell_renamed_SDL_TellRW
-#define SDL_RWwrite SDL_RWwrite_renamed_SDL_WriteRW
+#define RW_SEEK_CUR RW_SEEK_CUR_renamed_SDL_IO_SEEK_CUR
+#define RW_SEEK_END RW_SEEK_END_renamed_SDL_IO_SEEK_END
+#define RW_SEEK_SET RW_SEEK_SET_renamed_SDL_IO_SEEK_SET
+#define SDL_RWFromConstMem SDL_RWFromConstMem_renamed_SDL_IOFromConstMem
+#define SDL_RWFromFile SDL_RWFromFile_renamed_SDL_IOFromFile
+#define SDL_RWFromMem SDL_RWFromMem_renamed_SDL_IOFromMem
+#define SDL_RWclose SDL_RWclose_renamed_SDL_CloseIO
+#define SDL_RWops SDL_RWops_renamed_SDL_IOStream
+#define SDL_RWread SDL_RWread_renamed_SDL_ReadIO
+#define SDL_RWseek SDL_RWseek_renamed_SDL_SeekIO
+#define SDL_RWsize SDL_RWsize_renamed_SDL_SizeIO
+#define SDL_RWtell SDL_RWtell_renamed_SDL_TellIO
+#define SDL_RWwrite SDL_RWwrite_renamed_SDL_WriteIO
#define SDL_ReadBE16 SDL_ReadBE16_renamed_SDL_ReadU16BE
#define SDL_ReadBE32 SDL_ReadBE32_renamed_SDL_ReadU32BE
#define SDL_ReadBE64 SDL_ReadBE64_renamed_SDL_ReadU64BE
@@ -983,8 +995,10 @@
#define SDL_GetColorKey SDL_GetColorKey_renamed_SDL_GetSurfaceColorKey
#define SDL_HasColorKey SDL_HasColorKey_renamed_SDL_SurfaceHasColorKey
#define SDL_HasSurfaceRLE SDL_HasSurfaceRLE_renamed_SDL_SurfaceHasRLE
+#define SDL_LoadBMP_RW SDL_LoadBMP_RW_renamed_SDL_LoadBMP_IO
#define SDL_LowerBlit SDL_LowerBlit_renamed_SDL_BlitSurfaceUnchecked
#define SDL_LowerBlitScaled SDL_LowerBlitScaled_renamed_SDL_BlitSurfaceUncheckedScaled
+#define SDL_SaveBMP_RW SDL_SaveBMP_RW_renamed_SDL_SaveBMP_IO
#define SDL_SetClipRect SDL_SetClipRect_renamed_SDL_SetSurfaceClipRect
#define SDL_SetColorKey SDL_SetColorKey_renamed_SDL_SetSurfaceColorKey
#define SDL_UpperBlit SDL_UpperBlit_renamed_SDL_BlitSurface
diff --git a/include/SDL3/SDL_rwops.h b/include/SDL3/SDL_rwops.h
index 4cb4321b45bcb…f867d116e9f92 100644
— a/include/SDL3/SDL_rwops.h
+++ b/include/SDL3/SDL_rwops.h
@@ -39,21 +39,21 @@
extern “C” {
#endif

-/* RWops status, set by a read or write operation /
-typedef enum SDL_RWopsStatus
+/
SDL_IOStream status, set by a read or write operation */
+typedef enum SDL_IOStatus
{

  • SDL_RWOPS_STATUS_READY, /**< Everything is ready */
  • SDL_RWOPS_STATUS_ERROR, /**< Read or write I/O error */
  • SDL_RWOPS_STATUS_EOF, /**< End of file */
  • SDL_RWOPS_STATUS_NOT_READY, /**< Non blocking I/O, not ready */
  • SDL_RWOPS_STATUS_READONLY, /**< Tried to write a read-only buffer */
  • SDL_RWOPS_STATUS_WRITEONLY /**< Tried to read a write-only buffer */
    -} SDL_RWopsStatus;

-typedef struct SDL_RWopsInterface

  • SDL_IO_STATUS_READY, /**< Everything is ready */
  • SDL_IO_STATUS_ERROR, /**< Read or write I/O error */
  • SDL_IO_STATUS_EOF, /**< End of file */
  • SDL_IO_STATUS_NOT_READY, /**< Non blocking I/O, not ready */
  • SDL_IO_STATUS_READONLY, /**< Tried to write a read-only buffer */
  • SDL_IO_STATUS_WRITEONLY /**< Tried to read a write-only buffer */
    +} SDL_IOStatus;

+typedef struct SDL_IOStreamInterface
{
/**

  • *  Return the number of bytes in this rwops
    
  • *  Return the number of bytes in this SDL_IOStream
    *
    *  \return the total size of the data stream, or -1 on error.
    */
    

@@ -61,7 +61,7 @@ typedef struct SDL_RWopsInterface

 /**
  *  Seek to \c offset relative to \c whence, one of stdio's whence values:
  • *  SDL_RW_SEEK_SET, SDL_RW_SEEK_CUR, SDL_RW_SEEK_END
    
  • *  SDL_IO_SEEK_SET, SDL_IO_SEEK_CUR, SDL_IO_SEEK_END
    *
    *  \return the final offset in the data stream, or -1 on error.
    */
    

@@ -72,52 +72,52 @@ typedef struct SDL_RWopsInterface
* at by \c ptr.
*
* On an incomplete read, you should set *status to a value from the

  • *  SDL_RWopsStatus enum. You do not have to explicitly set this on
    
  • *  SDL_IOStatus enum. You do not have to explicitly set this on
    *  a complete, successful read.
    *
    *  \return the number of bytes read
    */
    
  • size_t (SDLCALL *read)(void *userdata, void *ptr, size_t size, SDL_RWopsStatus *status);
  • size_t (SDLCALL *read)(void *userdata, void *ptr, size_t size, SDL_IOStatus *status);

    /**

    • Write exactly \c size bytes from the area pointed at by \c ptr
    • to data stream.
    • On an incomplete write, you should set *status to a value from the
  • *  SDL_RWopsStatus enum. You do not have to explicitly set this on
    
  • *  SDL_IOStatus enum. You do not have to explicitly set this on
    *  a complete, successful write.
    *
    *  \return the number of bytes written
    */
    
  • size_t (SDLCALL *write)(void *userdata, const void *ptr, size_t size, SDL_RWopsStatus *status);
  • size_t (SDLCALL *write)(void *userdata, const void *ptr, size_t size, SDL_IOStatus *status);

    /**

    • Close and free any allocated resources.
  • *  The RWops is still destroyed even if this fails, so clean up anything
    
  • *  The SDL_IOStream is still destroyed even if this fails, so clean up anything
    *  even if flushing to disk returns an error.
    *
    *  \return 0 if successful or -1 on write error when flushing data.
    */
    
    int (SDLCALL *close)(void *userdata);
    -} SDL_RWopsInterface;
    +} SDL_IOStreamInterface;

/**

  • This is the read/write operation structure – opaque, as of SDL3!
    */
    -typedef struct SDL_RWops SDL_RWops;
    +typedef struct SDL_IOStream SDL_IOStream;

/**

    • \name RWFrom functions
    • \name IOFrom functions
    • Functions to create SDL_RWops structures from various data streams.
    • Functions to create SDL_IOStream structures from various data streams.
      /
      /
      @{ */

/**

    • Use this function to create a new SDL_RWops structure for reading from
    • Use this function to create a new SDL_IOStream structure for reading from
    • and/or writing to a named file.
    • The mode string is treated roughly the same as in a call to the C
      @@ -155,168 +155,168 @@ typedef struct SDL_RWops SDL_RWops;
    • This function supports Unicode filenames, but they must be encoded in UTF-8
    • format, regardless of the underlying operating system.
    • As a fallback, SDL_RWFromFile() will transparently open a matching filename
    • As a fallback, SDL_IOFromFile() will transparently open a matching filename
    • in an Android app’s assets.
    • Destroying the SDL_RWops will close the file handle SDL is holding internally.
    • Destroying the SDL_IOStream will close the file handle SDL is holding internally.
    • The following properties may be set at creation time by SDL:
      • SDL_PROP_RWOPS_WINDOWS_HANDLE_POINTER: a pointer, that can be cast
    • to a win32 HANDLE, that this RWops is using to access the filesystem.
      • SDL_PROP_IOSTREAM_WINDOWS_HANDLE_POINTER: a pointer, that can be cast
    • to a win32 HANDLE, that t
(Patch may be truncated, please check the link at the top of this post.)